Merge "Revert "SF: Flow DisplayModeRequest through mode set FSM"" into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 83b336c..b99f443 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -178,6 +178,7 @@
#define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
#define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
#define XFRM_STAT_PROC_FILE "/proc/net/xfrm_stat"
+#define KERNEL_CONFIG "/proc/config.gz"
#define WLUTIL "/vendor/xbin/wlutil"
#define WMTRACE_DATA_DIR "/data/misc/wmtrace"
#define OTA_METADATA_DIR "/metadata/ota"
@@ -1951,6 +1952,8 @@
DumpFile("PSI memory", "/proc/pressure/memory");
DumpFile("PSI io", "/proc/pressure/io");
+ ds.AddZipEntry(ZIP_ROOT_DIR + KERNEL_CONFIG, KERNEL_CONFIG);
+
RunCommand("SDK EXTENSIONS", {SDK_EXT_INFO, "--dump"},
CommandOptions::WithTimeout(10).Always().DropRoot().Build());
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index e54f9d3..870e8eb 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -44,6 +44,7 @@
#include "Timeout.h"
#include "utils.h"
+using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hidl::base::V1_0::DebugInfo;
@@ -522,27 +523,35 @@
using namespace ::android::hardware;
using namespace ::android::hidl::manager::V1_0;
using namespace ::android::hidl::base::V1_0;
- using std::literals::chrono_literals::operator""s;
- auto ret = timeoutIPC(10s, manager, &IServiceManager::debugDump, [&] (const auto &infos) {
- std::map<std::string, TableEntry> entries;
- for (const auto &info : infos) {
- std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" +
- std::string{info.instanceName.c_str()};
- entries.emplace(interfaceName, TableEntry{
- .interfaceName = interfaceName,
- .transport = vintf::Transport::PASSTHROUGH,
- .clientPids = info.clientPids,
- }).first->second.arch |= fromBaseArchitecture(info.arch);
- }
- for (auto &&pair : entries) {
- putEntry(HalType::PASSTHROUGH_LIBRARIES, std::move(pair.second));
- }
- });
+
+ // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+ // even though the interface function call is synchronous.
+ // However, there's no need to lock because if ret.isOk(), the background thread has
+ // already ended, so it is safe to dereference entries.
+ auto entries = std::make_shared<std::map<std::string, TableEntry>>();
+ auto ret =
+ timeoutIPC(mLshal.getDebugDumpWait(), manager, &IServiceManager::debugDump,
+ [entries](const auto& infos) {
+ for (const auto& info : infos) {
+ std::string interfaceName = std::string{info.interfaceName.c_str()} +
+ "/" + std::string{info.instanceName.c_str()};
+ entries->emplace(interfaceName,
+ TableEntry{
+ .interfaceName = interfaceName,
+ .transport = vintf::Transport::PASSTHROUGH,
+ .clientPids = info.clientPids,
+ })
+ .first->second.arch |= fromBaseArchitecture(info.arch);
+ }
+ });
if (!ret.isOk()) {
err() << "Error: Failed to call list on getPassthroughServiceManager(): "
<< ret.description() << std::endl;
return DUMP_ALL_LIBS_ERROR;
}
+ for (auto&& pair : *entries) {
+ putEntry(HalType::PASSTHROUGH_LIBRARIES, std::move(pair.second));
+ }
return OK;
}
@@ -553,27 +562,40 @@
using namespace ::android::hardware::details;
using namespace ::android::hidl::manager::V1_0;
using namespace ::android::hidl::base::V1_0;
- auto ret = timeoutIPC(manager, &IServiceManager::debugDump, [&] (const auto &infos) {
- for (const auto &info : infos) {
- if (info.clientPids.size() <= 0) {
- continue;
- }
- putEntry(HalType::PASSTHROUGH_CLIENTS, {
- .interfaceName =
- std::string{info.interfaceName.c_str()} + "/" +
- std::string{info.instanceName.c_str()},
- .transport = vintf::Transport::PASSTHROUGH,
- .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
- .clientPids = info.clientPids,
- .arch = fromBaseArchitecture(info.arch)
- });
- }
- });
+
+ // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+ // even though the interface function call is synchronous.
+ // However, there's no need to lock because if ret.isOk(), the background thread has
+ // already ended, so it is safe to dereference entries.
+ auto entries = std::make_shared<std::vector<TableEntry>>();
+ auto ret =
+ timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::debugDump,
+ [entries](const auto& infos) {
+ for (const auto& info : infos) {
+ if (info.clientPids.size() <= 0) {
+ continue;
+ }
+ entries->emplace_back(
+ TableEntry{.interfaceName =
+ std::string{info.interfaceName.c_str()} +
+ "/" +
+ std::string{info.instanceName.c_str()},
+ .transport = vintf::Transport::PASSTHROUGH,
+ .serverPid = info.clientPids.size() == 1
+ ? info.clientPids[0]
+ : NO_PID,
+ .clientPids = info.clientPids,
+ .arch = fromBaseArchitecture(info.arch)});
+ }
+ });
if (!ret.isOk()) {
err() << "Error: Failed to call debugDump on defaultServiceManager(): "
<< ret.description() << std::endl;
return DUMP_PASSTHROUGH_ERROR;
}
+ for (auto&& entry : *entries) {
+ putEntry(HalType::PASSTHROUGH_CLIENTS, std::move(entry));
+ }
return OK;
}
@@ -583,11 +605,14 @@
if (!shouldFetchHalType(HalType::BINDERIZED_SERVICES)) { return OK; }
const vintf::Transport mode = vintf::Transport::HWBINDER;
- hidl_vec<hidl_string> fqInstanceNames;
- // copying out for timeoutIPC
- auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
- fqInstanceNames = names;
- });
+
+ // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+ // even though the interface function call is synchronous.
+ // However, there's no need to lock because if listRet.isOk(), the background thread has
+ // already ended, so it is safe to dereference fqInstanceNames.
+ auto fqInstanceNames = std::make_shared<hidl_vec<hidl_string>>();
+ auto listRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::list,
+ [fqInstanceNames](const auto& names) { *fqInstanceNames = names; });
if (!listRet.isOk()) {
err() << "Error: Failed to list services for " << mode << ": "
<< listRet.description() << std::endl;
@@ -596,7 +621,7 @@
Status status = OK;
std::map<std::string, TableEntry> allTableEntries;
- for (const auto &fqInstanceName : fqInstanceNames) {
+ for (const auto& fqInstanceName : *fqInstanceNames) {
// create entry and default assign all fields.
TableEntry& entry = allTableEntries[fqInstanceName];
entry.interfaceName = fqInstanceName;
@@ -623,7 +648,8 @@
const auto pair = splitFirst(entry->interfaceName, '/');
const auto &serviceName = pair.first;
const auto &instanceName = pair.second;
- auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
+ auto getRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::get, serviceName,
+ instanceName);
if (!getRet.isOk()) {
handleError(TRANSACTION_ERROR,
"cannot be fetched from service manager:" + getRet.description());
@@ -637,30 +663,33 @@
// getDebugInfo
do {
- DebugInfo debugInfo;
- auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &received) {
- debugInfo = received;
- });
+ // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+ // even though the interface function call is synchronous.
+ // However, there's no need to lock because if debugRet.isOk(), the background thread has
+ // already ended, so it is safe to dereference debugInfo.
+ auto debugInfo = std::make_shared<DebugInfo>();
+ auto debugRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getDebugInfo,
+ [debugInfo](const auto& received) { *debugInfo = received; });
if (!debugRet.isOk()) {
handleError(TRANSACTION_ERROR,
"debugging information cannot be retrieved: " + debugRet.description());
break; // skip getPidInfo
}
- entry->serverPid = debugInfo.pid;
- entry->serverObjectAddress = debugInfo.ptr;
- entry->arch = fromBaseArchitecture(debugInfo.arch);
+ entry->serverPid = debugInfo->pid;
+ entry->serverObjectAddress = debugInfo->ptr;
+ entry->arch = fromBaseArchitecture(debugInfo->arch);
- if (debugInfo.pid != NO_PID) {
- const BinderPidInfo* pidInfo = getPidInfoCached(debugInfo.pid);
+ if (debugInfo->pid != NO_PID) {
+ const BinderPidInfo* pidInfo = getPidInfoCached(debugInfo->pid);
if (pidInfo == nullptr) {
handleError(IO_ERROR,
- "no information for PID " + std::to_string(debugInfo.pid) +
- ", are you root?");
+ "no information for PID " + std::to_string(debugInfo->pid) +
+ ", are you root?");
break;
}
- if (debugInfo.ptr != NO_PTR) {
- auto it = pidInfo->refPids.find(debugInfo.ptr);
+ if (debugInfo->ptr != NO_PTR) {
+ auto it = pidInfo->refPids.find(debugInfo->ptr);
if (it != pidInfo->refPids.end()) {
entry->clientPids = it->second;
}
@@ -672,39 +701,46 @@
// hash
do {
- ssize_t hashIndex = -1;
- auto ifaceChainRet = timeoutIPC(service, &IBase::interfaceChain, [&] (const auto& c) {
- for (size_t i = 0; i < c.size(); ++i) {
- if (serviceName == c[i]) {
- hashIndex = static_cast<ssize_t>(i);
- break;
- }
- }
- });
+ // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+ // even though the interface function call is synchronous.
+ auto hashIndexStore = std::make_shared<ssize_t>(-1);
+ auto ifaceChainRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::interfaceChain,
+ [hashIndexStore, serviceName](const auto& c) {
+ for (size_t i = 0; i < c.size(); ++i) {
+ if (serviceName == c[i]) {
+ *hashIndexStore = static_cast<ssize_t>(i);
+ break;
+ }
+ }
+ });
if (!ifaceChainRet.isOk()) {
handleError(TRANSACTION_ERROR,
"interfaceChain fails: " + ifaceChainRet.description());
break; // skip getHashChain
}
+ // if ifaceChainRet.isOk(), the background thread has already ended, so it is safe to
+ // dereference hashIndex without any locking.
+ auto hashIndex = *hashIndexStore;
if (hashIndex < 0) {
handleError(BAD_IMPL, "Interface name does not exist in interfaceChain.");
break; // skip getHashChain
}
- auto hashRet = timeoutIPC(service, &IBase::getHashChain, [&] (const auto& hashChain) {
- if (static_cast<size_t>(hashIndex) >= hashChain.size()) {
- handleError(BAD_IMPL,
- "interfaceChain indicates position " + std::to_string(hashIndex) +
- " but getHashChain returns " + std::to_string(hashChain.size()) +
- " hashes");
- return;
- }
-
- auto&& hashArray = hashChain[hashIndex];
- entry->hash = android::base::HexString(hashArray.data(), hashArray.size());
- });
+ // See comments about hashIndex above.
+ auto hashChain = std::make_shared<hidl_vec<hidl_array<uint8_t, 32>>>();
+ auto hashRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getHashChain,
+ [hashChain](const auto& ret) { *hashChain = std::move(ret); });
if (!hashRet.isOk()) {
handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description());
}
+ if (static_cast<size_t>(hashIndex) >= hashChain->size()) {
+ handleError(BAD_IMPL,
+ "interfaceChain indicates position " + std::to_string(hashIndex) +
+ " but getHashChain returns " + std::to_string(hashChain->size()) +
+ " hashes");
+ } else {
+ auto&& hashArray = (*hashChain)[hashIndex];
+ entry->hash = android::base::HexString(hashArray.data(), hashArray.size());
+ }
} while (0);
if (status == OK) {
entry->serviceStatus = ServiceStatus::ALIVE;
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index a5f98c2..6115da7 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -250,5 +250,17 @@
return mPassthroughManager;
}
+void Lshal::setWaitTimeForTest(std::chrono::milliseconds ipcCallWait,
+ std::chrono::milliseconds debugDumpWait) {
+ mIpcCallWait = ipcCallWait;
+ mDebugDumpWait = debugDumpWait;
+}
+std::chrono::milliseconds Lshal::getIpcCallWait() const {
+ return mIpcCallWait;
+}
+std::chrono::milliseconds Lshal::getDebugDumpWait() const {
+ return mDebugDumpWait;
+}
+
} // namespace lshal
} // namespace android
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index 50279d4..cb2820c 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -16,6 +16,7 @@
#pragma once
+#include <chrono>
#include <iostream>
#include <string>
@@ -58,6 +59,11 @@
void forEachCommand(const std::function<void(const Command* c)>& f) const;
+ void setWaitTimeForTest(std::chrono::milliseconds ipcCallWait,
+ std::chrono::milliseconds debugDumpWait);
+ std::chrono::milliseconds getIpcCallWait() const;
+ std::chrono::milliseconds getDebugDumpWait() const;
+
private:
Status parseArgs(const Arg &arg);
@@ -70,6 +76,9 @@
std::vector<std::unique_ptr<Command>> mRegisteredCommands;
+ std::chrono::milliseconds mIpcCallWait{500};
+ std::chrono::milliseconds mDebugDumpWait{10000};
+
DISALLOW_COPY_AND_ASSIGN(Lshal);
};
diff --git a/cmds/lshal/Timeout.h b/cmds/lshal/Timeout.h
index e8d22d9..805e8dc 100644
--- a/cmds/lshal/Timeout.h
+++ b/cmds/lshal/Timeout.h
@@ -27,8 +27,6 @@
namespace android {
namespace lshal {
-static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500};
-
class BackgroundTaskState {
public:
explicit BackgroundTaskState(std::function<void(void)> &&func)
@@ -96,12 +94,5 @@
return ret;
}
-template<class Function, class I, class... Args>
-typename std::result_of<Function(I *, Args...)>::type
-timeoutIPC(const sp<I> &interfaceObject, Function &&func, Args &&... args) {
- return timeoutIPC(IPC_CALL_WAIT, interfaceObject, func, args...);
-}
-
-
} // namespace lshal
} // namespace android
diff --git a/include/input/Input.h b/include/input/Input.h
index 1c4ea6b..7b253a5 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -515,6 +515,8 @@
PointerProperties& operator=(const PointerProperties&) = default;
};
+std::ostream& operator<<(std::ostream& out, const PointerProperties& properties);
+
// TODO(b/211379801) : Use a strong type from ftl/mixins.h instead
using DeviceId = int32_t;
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index 83fffa3..3470be4 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -117,11 +117,12 @@
template <typename T>
std::string dumpVector(const std::vector<T>& values,
std::string (*valueToString)(const T&) = constToString) {
- std::string dump = valueToString(values[0]);
- for (size_t i = 1; i < values.size(); i++) {
- dump += ", " + valueToString(values[i]);
+ std::string out;
+ for (const auto& value : values) {
+ out += out.empty() ? "[" : ", ";
+ out += valueToString(value);
}
- return dump;
+ return out.empty() ? "[]" : (out + "]");
}
const char* toString(bool value);
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index bf3699c..ae0fb01 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -258,7 +258,9 @@
"-DBINDER_DISABLE_NATIVE_HANDLE",
"-DBINDER_DISABLE_BLOB",
"-DBINDER_NO_LIBBASE",
+ // TODO: switch to "vendor: true" rather than copying this
// Trusty libbinder uses vendor stability for its binders
+ "-D__ANDROID_VENDOR__",
"-D__ANDROID_VNDK__",
"-U__ANDROID__",
"-D__TRUSTY__",
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 9341eff..b92e504 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -67,28 +67,28 @@
// Static const and functions will be optimized out if not used,
// when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
-static const char *kReturnStrings[] = {
- "BR_ERROR",
- "BR_OK",
- "BR_TRANSACTION",
- "BR_REPLY",
- "BR_ACQUIRE_RESULT",
- "BR_DEAD_REPLY",
- "BR_TRANSACTION_COMPLETE",
- "BR_INCREFS",
- "BR_ACQUIRE",
- "BR_RELEASE",
- "BR_DECREFS",
- "BR_ATTEMPT_ACQUIRE",
- "BR_NOOP",
- "BR_SPAWN_LOOPER",
- "BR_FINISHED",
- "BR_DEAD_BINDER",
- "BR_CLEAR_DEATH_NOTIFICATION_DONE",
- "BR_FAILED_REPLY",
- "BR_FROZEN_REPLY",
- "BR_ONEWAY_SPAM_SUSPECT",
- "BR_TRANSACTION_SEC_CTX",
+static const char* kReturnStrings[] = {
+ "BR_ERROR",
+ "BR_OK",
+ "BR_TRANSACTION/BR_TRANSACTION_SEC_CTX",
+ "BR_REPLY",
+ "BR_ACQUIRE_RESULT",
+ "BR_DEAD_REPLY",
+ "BR_TRANSACTION_COMPLETE",
+ "BR_INCREFS",
+ "BR_ACQUIRE",
+ "BR_RELEASE",
+ "BR_DECREFS",
+ "BR_ATTEMPT_ACQUIRE",
+ "BR_NOOP",
+ "BR_SPAWN_LOOPER",
+ "BR_FINISHED",
+ "BR_DEAD_BINDER",
+ "BR_CLEAR_DEATH_NOTIFICATION_DONE",
+ "BR_FAILED_REPLY",
+ "BR_FROZEN_REPLY",
+ "BR_ONEWAY_SPAM_SUSPECT",
+ "BR_TRANSACTION_PENDING_FROZEN",
};
static const char *kCommandStrings[] = {
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index c432b3a..665dfea 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -73,6 +73,14 @@
(void)setRepr(binder, getLocalLevel(), REPR_NONE);
}
+// after deprecation of the VNDK, these should be aliases. At some point
+// all references to __ANDROID_VNDK__ should be replaced by __ANDROID_VENDOR__
+// but for right now, check that this condition holds because some
+// places check __ANDROID_VNDK__ and some places check __ANDROID_VENDOR__
+#if defined(__ANDROID_VNDK__) != defined(__ANDROID_VENDOR__)
+#error "__ANDROID_VNDK__ and __ANDROID_VENDOR__ should be aliases"
+#endif
+
Stability::Level Stability::getLocalLevel() {
#ifdef __ANDROID_APEX__
#error "APEX can't use libbinder (must use libbinder_ndk)"
diff --git a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
index f178027..8d2944a 100644
--- a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
+++ b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
@@ -31,7 +31,11 @@
*/
class PersistableBundle {
public:
- PersistableBundle() noexcept : mPBundle(APersistableBundle_new()) {}
+ PersistableBundle() noexcept {
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ mPBundle = APersistableBundle_new();
+ }
+ }
// takes ownership of the APersistableBundle*
PersistableBundle(APersistableBundle* _Nonnull bundle) noexcept : mPBundle(bundle) {}
// takes ownership of the APersistableBundle*
@@ -327,20 +331,32 @@
}
bool getBooleanVector(const std::string& key, std::vector<bool>* _Nonnull vec) {
- return getVecInternal<bool>(&APersistableBundle_getBooleanVector, mPBundle, key.c_str(),
- vec);
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ return getVecInternal<bool>(&APersistableBundle_getBooleanVector, mPBundle, key.c_str(),
+ vec);
+ }
+ return false;
}
bool getIntVector(const std::string& key, std::vector<int32_t>* _Nonnull vec) {
- return getVecInternal<int32_t>(&APersistableBundle_getIntVector, mPBundle, key.c_str(),
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ return getVecInternal<int32_t>(&APersistableBundle_getIntVector, mPBundle, key.c_str(),
vec);
+ }
+ return false;
}
bool getLongVector(const std::string& key, std::vector<int64_t>* _Nonnull vec) {
- return getVecInternal<int64_t>(&APersistableBundle_getLongVector, mPBundle, key.c_str(),
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ return getVecInternal<int64_t>(&APersistableBundle_getLongVector, mPBundle, key.c_str(),
vec);
+ }
+ return false;
}
bool getDoubleVector(const std::string& key, std::vector<double>* _Nonnull vec) {
- return getVecInternal<double>(&APersistableBundle_getDoubleVector, mPBundle, key.c_str(),
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ return getVecInternal<double>(&APersistableBundle_getDoubleVector, mPBundle, key.c_str(),
vec);
+ }
+ return false;
}
// Takes ownership of and frees the char** and its elements.
@@ -361,15 +377,17 @@
}
bool getStringVector(const std::string& key, std::vector<std::string>* _Nonnull vec) {
- int32_t bytes = APersistableBundle_getStringVector(mPBundle, key.c_str(), nullptr, 0,
- &stringAllocator, nullptr);
- if (bytes > 0) {
- char** strings = (char**)malloc(bytes);
- if (strings) {
- bytes = APersistableBundle_getStringVector(mPBundle, key.c_str(), strings, bytes,
- &stringAllocator, nullptr);
- *vec = moveStringsInternal<std::vector<std::string>>(strings, bytes);
- return true;
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ int32_t bytes = APersistableBundle_getStringVector(mPBundle, key.c_str(), nullptr, 0,
+ &stringAllocator, nullptr);
+ if (bytes > 0) {
+ char** strings = (char**)malloc(bytes);
+ if (strings) {
+ bytes = APersistableBundle_getStringVector(mPBundle, key.c_str(), strings, bytes,
+ &stringAllocator, nullptr);
+ *vec = moveStringsInternal<std::vector<std::string>>(strings, bytes);
+ return true;
+ }
}
}
return false;
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index e4d4de8..dd2be94 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -256,6 +256,12 @@
// contention on the device. b/276820894
test_options: {
unit_test: false,
+ test_runner_options: [
+ {
+ name: "native-test-timeout",
+ value: "10m",
+ },
+ ],
},
test_suites: ["general-tests"],
@@ -830,6 +836,7 @@
],
// Adds bugs to hotlist "AIDL fuzzers bugs" on buganizer
hotlists: ["4637097"],
+ use_for_presubmit: true,
},
}
diff --git a/libs/binder/trusty/kernel/rules.mk b/libs/binder/trusty/kernel/rules.mk
index 788184d..5cbe0af 100644
--- a/libs/binder/trusty/kernel/rules.mk
+++ b/libs/binder/trusty/kernel/rules.mk
@@ -69,6 +69,7 @@
-DBINDER_DISABLE_NATIVE_HANDLE \
-DBINDER_DISABLE_BLOB \
-DBINDER_NO_LIBBASE \
+ -D__ANDROID_VENDOR__ \
-D__ANDROID_VNDK__ \
MODULE_DEPS += \
diff --git a/libs/binder/trusty/rules.mk b/libs/binder/trusty/rules.mk
index e0f821f..f2f140d 100644
--- a/libs/binder/trusty/rules.mk
+++ b/libs/binder/trusty/rules.mk
@@ -72,6 +72,7 @@
-DBINDER_DISABLE_NATIVE_HANDLE \
-DBINDER_DISABLE_BLOB \
-DBINDER_NO_LIBBASE \
+ -D__ANDROID_VENDOR__ \
-D__ANDROID_VNDK__ \
# libbinder has some deprecated declarations that we want to produce warnings
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 44a9e52..eb4d3df 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -423,7 +423,6 @@
"libhidlbase",
"liblog",
"libnativewindow",
- "libselinux",
"libsync",
"libui",
"libutils",
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 744201a..11f5174 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -38,43 +38,10 @@
#include <private/gui/BufferQueueThreadState.h>
#if !defined(__ANDROID_VNDK__) && !defined(NO_BINDER)
#include <binder/PermissionCache.h>
-#include <selinux/android.h>
-#include <selinux/selinux.h>
#endif
#include <system/window.h>
-namespace {
-#if !defined(__ANDROID_VNDK__) && !defined(NO_BINDER)
-int selinux_log_suppress_callback(int, const char*, ...) { // NOLINT
- // DO NOTHING
- return 0;
-}
-
-bool hasAccessToPermissionService() {
- char* ctx;
-
- if (getcon(&ctx) == -1) {
- // Failed to get current selinux context
- return false;
- }
-
- union selinux_callback cb;
-
- cb.func_log = selinux_log_suppress_callback;
- selinux_set_callback(SELINUX_CB_LOG, cb);
-
- bool hasAccess = selinux_check_access(ctx, "u:object_r:permission_service:s0",
- "service_manager", "find", NULL) == 0;
- freecon(ctx);
- cb.func_log = hasAccess ? selinux_log_callback : selinux_vendor_log_callback;
- selinux_set_callback(SELINUX_CB_LOG, cb);
-
- return hasAccess;
-}
-#endif
-} // namespace
-
namespace android {
// Macros for include BufferQueueCore information in log messages
@@ -843,18 +810,14 @@
const uid_t uid = BufferQueueThreadState::getCallingUid();
#if !defined(__ANDROID_VNDK__) && !defined(NO_BINDER)
// permission check can't be done for vendors as vendors have no access to
- // the PermissionController. We need to do a runtime check as well, since
- // the system variant of libgui can be loaded in a vendor process. For eg:
- // if a HAL uses an llndk library that depends on libgui (libmediandk etc).
- if (hasAccessToPermissionService()) {
- const pid_t pid = BufferQueueThreadState::getCallingPid();
- if ((uid != shellUid) &&
- !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
- outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
- "from pid=%d, uid=%d\n",
- pid, uid);
- denied = true;
- }
+ // the PermissionController.
+ const pid_t pid = BufferQueueThreadState::getCallingPid();
+ if ((uid != shellUid) &&
+ !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
+ outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
+ "from pid=%d, uid=%d\n",
+ pid, uid);
+ denied = true;
}
#else
if (uid != shellUid) {
diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp
index 93df124..c6f3363 100644
--- a/libs/gui/Choreographer.cpp
+++ b/libs/gui/Choreographer.cpp
@@ -344,6 +344,10 @@
handleRefreshRateUpdates();
}
+void Choreographer::dispatchHdcpLevelsChanged(PhysicalDisplayId, int32_t, int32_t) {
+ LOG_ALWAYS_FATAL("dispatchHdcpLevelsChanged was called but was never registered");
+}
+
void Choreographer::handleMessage(const Message& message) {
switch (message.what) {
case MSG_SCHEDULE_CALLBACKS:
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 5dd058c..f3de96d 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -195,6 +195,11 @@
dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId,
std::move(mFrameRateOverrides));
break;
+ case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ dispatchHdcpLevelsChanged(ev.header.displayId,
+ ev.hdcpLevelsChange.connectedLevel,
+ ev.hdcpLevelsChange.maxLevel);
+ break;
default:
ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
break;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8b6f202..8d18551 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -3117,7 +3117,6 @@
->removeWindowInfosListener(windowInfosListener,
ComposerServiceAIDL::getComposerService());
}
-
// ----------------------------------------------------------------------------
status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h
index 9933680..c952ba2 100644
--- a/libs/gui/fuzzer/libgui_fuzzer_utils.h
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -207,6 +207,7 @@
MOCK_METHOD2(dispatchNullEvent, void(nsecs_t, PhysicalDisplayId));
MOCK_METHOD3(dispatchFrameRateOverrides,
void(nsecs_t, PhysicalDisplayId, std::vector<FrameRateOverride>));
+ MOCK_METHOD3(dispatchHdcpLevelsChanged, void(PhysicalDisplayId, int32_t, int32_t));
};
} // namespace android
diff --git a/libs/gui/include/gui/Choreographer.h b/libs/gui/include/gui/Choreographer.h
index 9fef512..55a7aa7 100644
--- a/libs/gui/include/gui/Choreographer.h
+++ b/libs/gui/include/gui/Choreographer.h
@@ -116,6 +116,8 @@
void dispatchNullEvent(nsecs_t, PhysicalDisplayId) override;
void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId,
std::vector<FrameRateOverride> overrides) override;
+ void dispatchHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) override;
void scheduleCallbacks();
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index fe2dd20..82cd50c 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -65,6 +65,9 @@
virtual void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId,
std::vector<FrameRateOverride> overrides) = 0;
+ virtual void dispatchHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) = 0;
+
bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
uint32_t* outCount, VsyncEventData* outVsyncEventData);
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 79582ce..8c1103b 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -58,7 +58,6 @@
// ----------------------------------------------------------------------------
class DisplayEventReceiver {
public:
-
enum {
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
@@ -66,6 +65,7 @@
DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'),
DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'),
DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'),
+ DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
};
struct Event {
@@ -101,12 +101,22 @@
float frameRateHz __attribute__((aligned(8)));
};
+ /*
+ * The values are defined in aidl:
+ * hardware/interfaces/drm/aidl/android/hardware/drm/HdcpLevel.aidl
+ */
+ struct HdcpLevelsChange {
+ int32_t connectedLevel;
+ int32_t maxLevel;
+ };
+
Header header;
union {
VSync vsync;
Hotplug hotplug;
ModeChange modeChange;
FrameRateOverride frameRateOverride;
+ HdcpLevelsChange hdcpLevelsChange;
};
};
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index 4d4c5e4..b72b71a 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -176,6 +176,8 @@
static_cast<uint32_t>(os::InputConfig::INTERCEPTS_STYLUS),
CLONE =
static_cast<uint32_t>(os::InputConfig::CLONE),
+ GLOBAL_STYLUS_BLOCKS_TOUCH =
+ static_cast<uint32_t>(os::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH),
// clang-format on
};
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index bd5b67b..8eaff00 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -379,6 +379,11 @@
return out;
}
+std::ostream& operator<<(std::ostream& out, const PointerProperties& properties) {
+ out << "Pointer(id=" << properties.id << ", " << ftl::enum_string(properties.toolType) << ")";
+ return out;
+}
+
// --- PointerCoords ---
float PointerCoords::getAxisValue(int32_t axis) const {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 09e98d0..669f801 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -646,7 +646,7 @@
"action=%s, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
"metaState=0x%x, buttonState=0x%x, classification=%s,"
"xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
- "pointerCount=%" PRIu32 " \n%s",
+ "pointerCount=%" PRIu32 "\n%s",
mChannel->getName().c_str(), __func__, seq, eventId, deviceId,
inputEventSourceToString(source).c_str(), displayId,
MotionEvent::actionToString(action).c_str(), actionButton, flags, edgeFlags,
diff --git a/libs/input/android/os/InputConfig.aidl b/libs/input/android/os/InputConfig.aidl
index 4e644ff..5d39155 100644
--- a/libs/input/android/os/InputConfig.aidl
+++ b/libs/input/android/os/InputConfig.aidl
@@ -150,4 +150,11 @@
* likely a duplicate window with the same client token, but different bounds.
*/
CLONE = 1 << 16,
+
+ /**
+ * If the stylus is currently down *anywhere* on the screen, new touches will not be delivered
+ * to the window with this flag. This helps prevent unexpected clicks on some system windows,
+ * like StatusBar and TaskBar.
+ */
+ GLOBAL_STYLUS_BLOCKS_TOUCH = 1 << 17,
}
diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig
index 54eeb39..11f6994 100644
--- a/libs/input/input_flags.aconfig
+++ b/libs/input/input_flags.aconfig
@@ -52,7 +52,14 @@
flag {
name: "enable_touchpad_typing_palm_rejection"
namespace: "input"
- description: "Enable additional palm rejection on touchpad while typing"
+ description: "Enabling additional touchpad palm rejection will disable the tap to click while the user is typing on a physical keyboard"
+ bug: "301055381"
+}
+
+flag {
+ name: "enable_v2_touchpad_typing_palm_rejection"
+ namespace: "input"
+ description: "In addition to touchpad palm rejection v1, v2 will also cancel ongoing move gestures while typing and add delay in re-enabling the tap to click."
bug: "301055381"
}
diff --git a/libs/nativewindow/include/android/native_window_aidl.h b/libs/nativewindow/include/android/native_window_aidl.h
index 0d5727d..68ac7e0 100644
--- a/libs/nativewindow/include/android/native_window_aidl.h
+++ b/libs/nativewindow/include/android/native_window_aidl.h
@@ -103,14 +103,22 @@
binder_status_t readFromParcel(const AParcel* _Nonnull parcel) {
reset();
- return ANativeWindow_readFromParcel(parcel, &mWindow);
+ if (__builtin_available(android __ANDROID_API_U__, *)) {
+ return ANativeWindow_readFromParcel(parcel, &mWindow);
+ } else {
+ return STATUS_FAILED_TRANSACTION;
+ }
}
binder_status_t writeToParcel(AParcel* _Nonnull parcel) const {
if (!mWindow) {
return STATUS_BAD_VALUE;
}
- return ANativeWindow_writeToParcel(mWindow, parcel);
+ if (__builtin_available(android __ANDROID_API_U__, *)) {
+ return ANativeWindow_writeToParcel(mWindow, parcel);
+ } else {
+ return STATUS_FAILED_TRANSACTION;
+ }
}
/**
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index d112a12..f8ee3fc 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -248,6 +248,22 @@
return static_cast<ssize_t>(mSensors.size());
}
+ssize_t SensorManager::getDefaultDeviceSensorList(Vector<Sensor> & list) {
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return static_cast<ssize_t>(err);
+ }
+
+ if (mDeviceId == DEVICE_ID_DEFAULT) {
+ list = mSensors;
+ } else {
+ list = mSensorServer->getSensorList(mOpPackageName);
+ }
+
+ return static_cast<ssize_t>(list.size());
+}
+
ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) {
Mutex::Autolock _l(mLock);
status_t err = assertStateLocked();
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index e67fac7..49f050a 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -58,6 +58,7 @@
~SensorManager();
ssize_t getSensorList(Sensor const* const** list);
+ ssize_t getDefaultDeviceSensorList(Vector<Sensor> & list);
ssize_t getDynamicSensorList(Vector<Sensor>& list);
ssize_t getDynamicSensorList(Sensor const* const** list);
ssize_t getRuntimeSensorList(int deviceId, Vector<Sensor>& list);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6033398..112f16b 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -72,7 +72,8 @@
using android::os::InputEventInjectionSync;
namespace input_flags = com::android::input::flags;
-static const bool REMOVE_APP_SWITCH_DROPS = input_flags::remove_app_switch_drops();
+// TODO(b/312714754): remove the corresponding code, as well.
+static const bool REMOVE_APP_SWITCH_DROPS = true;
namespace android::inputdispatcher {
@@ -252,6 +253,14 @@
}
}
+std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
+ std::bitset<MAX_POINTER_ID + 1> pointerIds;
+ for (const PointerProperties& pointer : pointers) {
+ pointerIds.set(pointer.id);
+ }
+ return pointerIds;
+}
+
std::string dumpRegion(const Region& region) {
if (region.isEmpty()) {
return "<empty>";
@@ -630,15 +639,15 @@
}
// We should consider all hovering pointers here. But for now, just use the first one
- const int32_t pointerId = entry.pointerProperties[0].id;
+ const PointerProperties& pointer = entry.pointerProperties[0];
std::set<sp<WindowInfoHandle>> oldWindows;
if (oldState != nullptr) {
- oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId);
+ oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
}
std::set<sp<WindowInfoHandle>> newWindows =
- newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId);
+ newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
// If the pointer is no longer in the new window set, send HOVER_EXIT.
for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
@@ -672,7 +681,7 @@
}
touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
}
- touchedWindow.addHoveringPointer(entry.deviceId, pointerId);
+ touchedWindow.addHoveringPointer(entry.deviceId, pointer);
if (canReceiveForegroundTouches(*newWindow->getInfo())) {
touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
}
@@ -740,6 +749,20 @@
return true;
}
+/**
+ * Return true if stylus is currently down anywhere on the specified display, and false otherwise.
+ */
+bool isStylusActiveInDisplay(
+ int32_t displayId,
+ const std::unordered_map<int32_t /*displayId*/, TouchState>& touchStatesByDisplay) {
+ const auto it = touchStatesByDisplay.find(displayId);
+ if (it == touchStatesByDisplay.end()) {
+ return false;
+ }
+ const TouchState& state = it->second;
+ return state.hasActiveStylus();
+}
+
} // namespace
// --- InputDispatcher ---
@@ -2135,7 +2158,6 @@
sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
InputEventInjectionResult& outInjectionResult) {
- std::string reason;
outInjectionResult = InputEventInjectionResult::FAILED; // Default result
int32_t displayId = getTargetDisplayId(entry);
@@ -2320,7 +2342,7 @@
/* Case 1: New splittable pointer going down, or need target for hover or scroll. */
const auto [x, y] = resolveTouchedPosition(entry);
const int32_t pointerIndex = MotionEvent::getActionIndex(action);
- const int32_t pointerId = entry.pointerProperties[pointerIndex].id;
+ const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
// Outside targets should be added upon first dispatched DOWN event. That means, this should
// be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
const bool isStylus = isPointerFromStylus(entry, pointerIndex);
@@ -2328,7 +2350,7 @@
findTouchedWindowAtLocked(displayId, x, y, isStylus);
if (isDown) {
- targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId);
+ targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
}
// Handle the case where we did not find a window.
if (newTouchedWindowHandle == nullptr) {
@@ -2386,7 +2408,7 @@
if (isHoverAction) {
// The "windowHandle" is the target of this hovering pointer.
- tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId);
+ tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer);
}
// Set target flags.
@@ -2409,12 +2431,10 @@
// Update the temporary touch state.
if (!isHoverAction) {
- std::bitset<MAX_POINTER_ID + 1> pointerIds;
- pointerIds.set(pointerId);
const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS,
- targetFlags, entry.deviceId, pointerIds,
+ targetFlags, entry.deviceId, {pointer},
isDownOrPointerDown
? std::make_optional(entry.eventTime)
: std::nullopt);
@@ -2437,7 +2457,7 @@
}
tempTouchState.addOrUpdateWindow(wallpaper,
InputTarget::DispatchMode::AS_IS,
- wallpaperFlags, entry.deviceId, pointerIds,
+ wallpaperFlags, entry.deviceId, {pointer},
entry.eventTime);
}
}
@@ -2448,12 +2468,12 @@
// make it pilfering. This will prevent other non-spy windows from getting this pointer,
// which is a specific behaviour that we want.
for (TouchedWindow& touchedWindow : tempTouchState.windows) {
- if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) &&
+ if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
touchedWindow.hasPilferingPointers(entry.deviceId)) {
// This window is already pilfering some pointers, and this new pointer is also
// going to it. Therefore, take over this pointer and don't give it to anyone
// else.
- touchedWindow.addPilferingPointer(entry.deviceId, pointerId);
+ touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
}
}
@@ -2522,8 +2542,8 @@
// Make a slippery exit from the old window.
std::bitset<MAX_POINTER_ID + 1> pointerIds;
- const int32_t pointerId = entry.pointerProperties[0].id;
- pointerIds.set(pointerId);
+ const PointerProperties& pointer = entry.pointerProperties[0];
+ pointerIds.set(pointer.id);
const TouchedWindow& touchedWindow =
tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
@@ -2553,13 +2573,13 @@
tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
InputTarget::DispatchMode::SLIPPERY_ENTER,
- targetFlags, entry.deviceId, pointerIds,
+ targetFlags, entry.deviceId, {pointer},
entry.eventTime);
// Check if the wallpaper window should deliver the corresponding event.
slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
- tempTouchState, entry.deviceId, pointerId, targets);
- tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId,
+ tempTouchState, entry.deviceId, pointer, targets);
+ tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
oldTouchedWindowHandle);
}
}
@@ -2568,14 +2588,12 @@
if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
// If no split, we suppose all touched windows should receive pointer down.
const int32_t pointerIndex = MotionEvent::getActionIndex(action);
- for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
- TouchedWindow& touchedWindow = tempTouchState.windows[i];
+ std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
+ for (TouchedWindow& touchedWindow : tempTouchState.windows) {
// Ignore drag window for it should just track one pointer.
if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
continue;
}
- std::bitset<MAX_POINTER_ID + 1> touchingPointers;
- touchingPointers.set(entry.pointerProperties[pointerIndex].id);
touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
}
}
@@ -2646,13 +2664,13 @@
// Output targets from the touch state.
for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
- std::bitset<MAX_POINTER_ID + 1> touchingPointers =
+ std::vector<PointerProperties> touchingPointers =
touchedWindow.getTouchingPointers(entry.deviceId);
- if (touchingPointers.none()) {
+ if (touchingPointers.empty()) {
continue;
}
addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
- touchedWindow.targetFlags, touchingPointers,
+ touchedWindow.targetFlags, getPointerIds(touchingPointers),
touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
}
@@ -3371,27 +3389,40 @@
dispatchEntry->resolvedFlags = resolvedFlags;
if (resolvedAction != motionEntry.action) {
+ std::optional<std::vector<PointerProperties>> usingProperties;
+ std::optional<std::vector<PointerCoords>> usingCoords;
+ if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT ||
+ resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ // This is a HOVER_EXIT or an ACTION_CANCEL event that was synthesized by
+ // the dispatcher, and therefore the coordinates of this event are currently
+ // incorrect. These events should use the coordinates of the last dispatched
+ // ACTION_MOVE or HOVER_MOVE. We need to query InputState to get this data.
+ const bool hovering = resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT;
+ std::optional<std::pair<std::vector<PointerProperties>,
+ std::vector<PointerCoords>>>
+ pointerInfo =
+ connection->inputState.getPointersOfLastEvent(motionEntry,
+ hovering);
+ if (pointerInfo) {
+ usingProperties = pointerInfo->first;
+ usingCoords = pointerInfo->second;
+ }
+ }
// Generate a new MotionEntry with a new eventId using the resolved action and
// flags.
- resolvedMotion =
- std::make_shared<MotionEntry>(mIdGenerator.nextId(),
- motionEntry.injectionState,
- motionEntry.eventTime,
- motionEntry.deviceId, motionEntry.source,
- motionEntry.displayId,
- motionEntry.policyFlags, resolvedAction,
- motionEntry.actionButton, resolvedFlags,
- motionEntry.metaState,
- motionEntry.buttonState,
- motionEntry.classification,
- motionEntry.edgeFlags,
- motionEntry.xPrecision,
- motionEntry.yPrecision,
- motionEntry.xCursorPosition,
- motionEntry.yCursorPosition,
- motionEntry.downTime,
- motionEntry.pointerProperties,
- motionEntry.pointerCoords);
+ resolvedMotion = std::make_shared<
+ MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
+ motionEntry.eventTime, motionEntry.deviceId,
+ motionEntry.source, motionEntry.displayId,
+ motionEntry.policyFlags, resolvedAction,
+ motionEntry.actionButton, resolvedFlags,
+ motionEntry.metaState, motionEntry.buttonState,
+ motionEntry.classification, motionEntry.edgeFlags,
+ motionEntry.xPrecision, motionEntry.yPrecision,
+ motionEntry.xCursorPosition, motionEntry.yCursorPosition,
+ motionEntry.downTime,
+ usingProperties.value_or(motionEntry.pointerProperties),
+ usingCoords.value_or(motionEntry.pointerCoords));
if (ATRACE_ENABLED()) {
std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
") to MotionEvent(id=0x%" PRIx32 ").",
@@ -4418,7 +4449,8 @@
policyFlags |= POLICY_FLAG_TRUSTED;
android::base::Timer t;
- mPolicy.interceptMotionBeforeQueueing(args.displayId, args.eventTime, policyFlags);
+ mPolicy.interceptMotionBeforeQueueing(args.displayId, args.source, args.action, args.eventTime,
+ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
@@ -4679,7 +4711,9 @@
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
nsecs_t eventTime = motionEvent.getEventTime();
android::base::Timer t;
- mPolicy.interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
+ mPolicy.interceptMotionBeforeQueueing(displayId, motionEvent.getSource(),
+ motionEvent.getAction(), eventTime,
+ /*byref*/ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
@@ -5047,6 +5081,13 @@
return false;
}
+ // Ignore touches if stylus is down anywhere on screen
+ if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
+ isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) {
+ LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
+ return false;
+ }
+
return true;
}
@@ -5481,7 +5522,7 @@
// Erase old window.
ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
- std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId);
+ std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
state->removeWindowByToken(fromToken);
@@ -5493,17 +5534,17 @@
newTargetFlags |= InputTarget::Flags::FOREGROUND;
}
state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
- deviceId, pointerIds, downTimeInTarget);
+ deviceId, pointers, downTimeInTarget);
// Store the dragging window.
if (isDragDrop) {
- if (pointerIds.count() != 1) {
+ if (pointers.size() != 1) {
ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
" pointer on the window.");
return false;
}
// Track the pointer id for drag window and generate the drag state.
- const size_t id = firstMarkedBit(pointerIds);
+ const size_t id = pointers.begin()->id;
mDragState = std::make_unique<DragState>(toWindowHandle, id);
}
@@ -5520,7 +5561,7 @@
// Check if the wallpaper window should deliver the corresponding event.
transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
- *state, deviceId, pointerIds);
+ *state, deviceId, pointers);
}
} // release lock
@@ -5997,8 +6038,10 @@
"input channel stole pointer stream");
options.deviceId = deviceId;
options.displayId = displayId;
- std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId);
+ std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
+ std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
options.pointerIds = pointerIds;
+
std::string canceledWindows;
for (const TouchedWindow& w : state.windows) {
const std::shared_ptr<InputChannel> channel =
@@ -6794,10 +6837,10 @@
void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
const sp<WindowInfoHandle>& oldWindowHandle,
const sp<WindowInfoHandle>& newWindowHandle,
- TouchState& state, int32_t deviceId, int32_t pointerId,
+ TouchState& state, int32_t deviceId,
+ const PointerProperties& pointerProperties,
std::vector<InputTarget>& targets) const {
- std::bitset<MAX_POINTER_ID + 1> pointerIds;
- pointerIds.set(pointerId);
+ std::vector<PointerProperties> pointers{pointerProperties};
const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
@@ -6814,16 +6857,16 @@
if (oldWallpaper != nullptr) {
const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
- oldTouchedWindow.targetFlags, pointerIds,
+ oldTouchedWindow.targetFlags, getPointerIds(pointers),
oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
- state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper);
+ state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
}
if (newWallpaper != nullptr) {
state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
InputTarget::Flags::WINDOW_IS_OBSCURED |
InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
- deviceId, pointerIds);
+ deviceId, pointers);
}
}
@@ -6832,7 +6875,7 @@
const sp<WindowInfoHandle> fromWindowHandle,
const sp<WindowInfoHandle> toWindowHandle,
TouchState& state, int32_t deviceId,
- std::bitset<MAX_POINTER_ID + 1> pointerIds) {
+ const std::vector<PointerProperties>& pointers) {
const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
fromWindowHandle->getInfo()->inputConfig.test(
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
@@ -6861,7 +6904,7 @@
wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
- deviceId, pointerIds, downTimeInTarget);
+ deviceId, pointers, downTimeInTarget);
std::shared_ptr<Connection> wallpaperConnection =
getConnectionLocked(newWallpaper->getToken());
if (wallpaperConnection != nullptr) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 3f99b2d..010dbb2 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -690,14 +690,15 @@
void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
const sp<android::gui::WindowInfoHandle>& oldWindowHandle,
const sp<android::gui::WindowInfoHandle>& newWindowHandle,
- TouchState& state, int32_t deviceId, int32_t pointerId,
+ TouchState& state, int32_t deviceId,
+ const PointerProperties& pointerProperties,
std::vector<InputTarget>& targets) const REQUIRES(mLock);
void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
ftl::Flags<InputTarget::Flags> newTargetFlags,
const sp<android::gui::WindowInfoHandle> fromWindowHandle,
const sp<android::gui::WindowInfoHandle> toWindowHandle,
TouchState& state, int32_t deviceId,
- std::bitset<MAX_POINTER_ID + 1> pointerIds) REQUIRES(mLock);
+ const std::vector<PointerProperties>& pointers) REQUIRES(mLock);
sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow(
const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index a4ac4fb..1fec9b7 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -195,6 +195,16 @@
}
}
+std::optional<std::pair<std::vector<PointerProperties>, std::vector<PointerCoords>>>
+InputState::getPointersOfLastEvent(const MotionEntry& entry, bool hovering) const {
+ ssize_t index = findMotionMemento(entry, hovering);
+ if (index == -1) {
+ return std::nullopt;
+ }
+ return std::make_pair(mMotionMementos[index].pointerProperties,
+ mMotionMementos[index].pointerCoords);
+}
+
ssize_t InputState::findKeyMemento(const KeyEntry& entry) const {
for (size_t i = 0; i < mKeyMementos.size(); i++) {
const KeyMemento& memento = mKeyMementos[i];
@@ -311,16 +321,6 @@
return true;
}
- // Use the previous stream cancellation logic to generate all HOVER_EXIT events.
- // If this hover event was generated as a result of the pointer leaving the window,
- // the HOVER_EXIT event should have the same coordinates as the previous
- // HOVER_MOVE event in this stream. Ensure that all HOVER_EXITs have the same
- // coordinates as the previous event by cancelling the stream here. With this approach, the
- // HOVER_EXIT event is generated from the previous event.
- if (actionMasked == AMOTION_EVENT_ACTION_HOVER_EXIT && lastMemento.hovering) {
- return true;
- }
-
// If the stream changes its source, just cancel the current gesture to be safe. It's
// possible that the app isn't handling source changes properly
if (motionEntry.source != lastMemento.source) {
diff --git a/services/inputflinger/dispatcher/InputState.h b/services/inputflinger/dispatcher/InputState.h
index b0e4209..d49469d 100644
--- a/services/inputflinger/dispatcher/InputState.h
+++ b/services/inputflinger/dispatcher/InputState.h
@@ -48,6 +48,15 @@
// and should be skipped.
bool trackMotion(const MotionEntry& entry, int32_t flags);
+ /**
+ * Return the PointerProperties and the PointerCoords for the last event, if found. Return
+ * std::nullopt if not found. We should not return std::vector<PointerCoords> in isolation,
+ * because the pointers can technically be stored in the vector in any order, so the
+ * PointerProperties are needed to specify the order in which the pointer coords are stored.
+ */
+ std::optional<std::pair<std::vector<PointerProperties>, std::vector<PointerCoords>>>
+ getPointersOfLastEvent(const MotionEntry& entry, bool hovering) const;
+
// Create cancel events for the previous stream if the current motionEntry requires it.
std::unique_ptr<EventEntry> cancelConflictingInputStream(const MotionEntry& motionEntry);
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index e8d8c18..f8aa625 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -73,9 +73,9 @@
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle,
InputTarget::DispatchMode dispatchMode,
ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId,
- std::bitset<MAX_POINTER_ID + 1> touchingPointerIds,
+ const std::vector<PointerProperties>& touchingPointers,
std::optional<nsecs_t> firstDownTimeInTarget) {
- if (touchingPointerIds.none()) {
+ if (touchingPointers.empty()) {
LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName();
return;
}
@@ -91,7 +91,7 @@
// For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have
// downTime set initially. Need to update existing window when a pointer is down for the
// window.
- touchedWindow.addTouchingPointers(deviceId, touchingPointerIds);
+ touchedWindow.addTouchingPointers(deviceId, touchingPointers);
if (firstDownTimeInTarget) {
touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget);
}
@@ -102,7 +102,7 @@
touchedWindow.windowHandle = windowHandle;
touchedWindow.dispatchMode = dispatchMode;
touchedWindow.targetFlags = targetFlags;
- touchedWindow.addTouchingPointers(deviceId, touchingPointerIds);
+ touchedWindow.addTouchingPointers(deviceId, touchingPointers);
if (firstDownTimeInTarget) {
touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget);
}
@@ -110,17 +110,17 @@
}
void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle,
- DeviceId deviceId, int32_t hoveringPointerId) {
+ DeviceId deviceId, const PointerProperties& pointer) {
for (TouchedWindow& touchedWindow : windows) {
if (touchedWindow.windowHandle == windowHandle) {
- touchedWindow.addHoveringPointer(deviceId, hoveringPointerId);
+ touchedWindow.addHoveringPointer(deviceId, pointer);
return;
}
}
TouchedWindow touchedWindow;
touchedWindow.windowHandle = windowHandle;
- touchedWindow.addHoveringPointer(deviceId, hoveringPointerId);
+ touchedWindow.addHoveringPointer(deviceId, pointer);
windows.push_back(touchedWindow);
}
@@ -234,6 +234,11 @@
});
}
+bool TouchState::hasActiveStylus() const {
+ return std::any_of(windows.begin(), windows.end(),
+ [](const TouchedWindow& window) { return window.hasActiveStylus(); });
+}
+
std::set<sp<WindowInfoHandle>> TouchState::getWindowsWithHoveringPointer(DeviceId deviceId,
int32_t pointerId) const {
std::set<sp<WindowInfoHandle>> out;
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index e0a84e8..3d534bc 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -46,11 +46,11 @@
void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
InputTarget::DispatchMode dispatchMode,
ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId,
- std::bitset<MAX_POINTER_ID + 1> touchingPointerIds,
+ const std::vector<PointerProperties>& touchingPointers,
std::optional<nsecs_t> firstDownTimeInTarget = std::nullopt);
void addHoveringPointerToWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
- DeviceId deviceId, int32_t hoveringPointerId);
- void removeHoveringPointer(DeviceId deviceId, int32_t hoveringPointerId);
+ DeviceId deviceId, const PointerProperties& pointer);
+ void removeHoveringPointer(DeviceId deviceId, int32_t pointerId);
void clearHoveringPointers(DeviceId deviceId);
void removeAllPointersForDevice(DeviceId deviceId);
@@ -73,6 +73,8 @@
bool isDown(DeviceId deviceId) const;
bool hasHoveringPointers(DeviceId deviceId) const;
+ bool hasActiveStylus() const;
+
std::set<sp<android::gui::WindowInfoHandle>> getWindowsWithHoveringPointer(
DeviceId deviceId, int32_t pointerId) const;
std::string dump() const;
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index cd0500c..037d7c8 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -26,9 +26,20 @@
namespace inputdispatcher {
+namespace {
+
+bool hasPointerId(const std::vector<PointerProperties>& pointers, int32_t pointerId) {
+ return std::find_if(pointers.begin(), pointers.end(),
+ [&pointerId](const PointerProperties& properties) {
+ return properties.id == pointerId;
+ }) != pointers.end();
+}
+
+} // namespace
+
bool TouchedWindow::hasHoveringPointers() const {
for (const auto& [_, state] : mDeviceStates) {
- if (state.hoveringPointerIds.any()) {
+ if (!state.hoveringPointers.empty()) {
return true;
}
}
@@ -42,7 +53,7 @@
}
const DeviceState& state = stateIt->second;
- return state.hoveringPointerIds.any();
+ return !state.hoveringPointers.empty();
}
void TouchedWindow::clearHoveringPointers(DeviceId deviceId) {
@@ -51,7 +62,7 @@
return;
}
DeviceState& state = stateIt->second;
- state.hoveringPointerIds.reset();
+ state.hoveringPointers.clear();
if (!state.hasPointers()) {
mDeviceStates.erase(stateIt);
}
@@ -63,22 +74,40 @@
return false;
}
const DeviceState& state = stateIt->second;
-
- return state.hoveringPointerIds.test(pointerId);
+ return hasPointerId(state.hoveringPointers, pointerId);
}
-void TouchedWindow::addHoveringPointer(DeviceId deviceId, int32_t pointerId) {
- mDeviceStates[deviceId].hoveringPointerIds.set(pointerId);
+void TouchedWindow::addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer) {
+ std::vector<PointerProperties>& hoveringPointers = mDeviceStates[deviceId].hoveringPointers;
+ const size_t initialSize = hoveringPointers.size();
+ std::erase_if(hoveringPointers, [&pointer](const PointerProperties& properties) {
+ return properties.id == pointer.id;
+ });
+ if (hoveringPointers.size() != initialSize) {
+ LOG(ERROR) << __func__ << ": " << pointer << ", device " << deviceId << " was in " << *this;
+ }
+ hoveringPointers.push_back(pointer);
}
void TouchedWindow::addTouchingPointers(DeviceId deviceId,
- std::bitset<MAX_POINTER_ID + 1> pointers) {
- mDeviceStates[deviceId].touchingPointerIds |= pointers;
+ const std::vector<PointerProperties>& pointers) {
+ std::vector<PointerProperties>& touchingPointers = mDeviceStates[deviceId].touchingPointers;
+ const size_t initialSize = touchingPointers.size();
+ for (const PointerProperties& pointer : pointers) {
+ std::erase_if(touchingPointers, [&pointer](const PointerProperties& properties) {
+ return properties.id == pointer.id;
+ });
+ }
+ if (touchingPointers.size() != initialSize) {
+ LOG(ERROR) << __func__ << ": " << dumpVector(pointers, streamableToString) << ", device "
+ << deviceId << " already in " << *this;
+ }
+ touchingPointers.insert(touchingPointers.end(), pointers.begin(), pointers.end());
}
bool TouchedWindow::hasTouchingPointers() const {
for (const auto& [_, state] : mDeviceStates) {
- if (state.touchingPointerIds.any()) {
+ if (!state.touchingPointers.empty()) {
return true;
}
}
@@ -86,21 +115,25 @@
}
bool TouchedWindow::hasTouchingPointers(DeviceId deviceId) const {
- return getTouchingPointers(deviceId).any();
+ return !getTouchingPointers(deviceId).empty();
}
bool TouchedWindow::hasTouchingPointer(DeviceId deviceId, int32_t pointerId) const {
- return getTouchingPointers(deviceId).test(pointerId);
+ const auto stateIt = mDeviceStates.find(deviceId);
+ if (stateIt == mDeviceStates.end()) {
+ return false;
+ }
+ const DeviceState& state = stateIt->second;
+ return hasPointerId(state.touchingPointers, pointerId);
}
-std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getTouchingPointers(DeviceId deviceId) const {
+std::vector<PointerProperties> TouchedWindow::getTouchingPointers(DeviceId deviceId) const {
const auto stateIt = mDeviceStates.find(deviceId);
if (stateIt == mDeviceStates.end()) {
return {};
}
const DeviceState& state = stateIt->second;
-
- return state.touchingPointerIds;
+ return state.touchingPointers;
}
void TouchedWindow::removeTouchingPointer(DeviceId deviceId, int32_t pointerId) {
@@ -118,7 +151,10 @@
}
DeviceState& state = stateIt->second;
- state.touchingPointerIds &= ~pointers;
+ std::erase_if(state.touchingPointers, [&pointers](const PointerProperties& properties) {
+ return pointers.test(properties.id);
+ });
+
state.pilferingPointerIds &= ~pointers;
if (!state.hasPointers()) {
@@ -126,10 +162,26 @@
}
}
+bool TouchedWindow::hasActiveStylus() const {
+ for (const auto& [_, state] : mDeviceStates) {
+ for (const PointerProperties& properties : state.touchingPointers) {
+ if (properties.toolType == ToolType::STYLUS) {
+ return true;
+ }
+ }
+ for (const PointerProperties& properties : state.hoveringPointers) {
+ if (properties.toolType == ToolType::STYLUS) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
std::set<DeviceId> TouchedWindow::getTouchingDeviceIds() const {
std::set<DeviceId> deviceIds;
for (const auto& [deviceId, deviceState] : mDeviceStates) {
- if (deviceState.touchingPointerIds.any()) {
+ if (!deviceState.touchingPointers.empty()) {
deviceIds.insert(deviceId);
}
}
@@ -198,7 +250,7 @@
}
DeviceState& state = stateIt->second;
- state.touchingPointerIds.reset();
+ state.touchingPointers.clear();
state.pilferingPointerIds.reset();
state.downTimeInTarget.reset();
@@ -214,7 +266,9 @@
}
DeviceState& state = stateIt->second;
- state.hoveringPointerIds.set(pointerId, false);
+ std::erase_if(state.hoveringPointers, [&pointerId](const PointerProperties& properties) {
+ return properties.id == pointerId;
+ });
if (!state.hasPointers()) {
mDeviceStates.erase(stateIt);
@@ -228,7 +282,7 @@
}
DeviceState& state = stateIt->second;
- state.hoveringPointerIds.reset();
+ state.hoveringPointers.clear();
if (!state.hasPointers()) {
mDeviceStates.erase(stateIt);
@@ -236,11 +290,11 @@
}
std::string TouchedWindow::deviceStateToString(const TouchedWindow::DeviceState& state) {
- return StringPrintf("[touchingPointerIds=%s, "
- "downTimeInTarget=%s, hoveringPointerIds=%s, pilferingPointerIds=%s]",
- bitsetToString(state.touchingPointerIds).c_str(),
+ return StringPrintf("[touchingPointers=%s, "
+ "downTimeInTarget=%s, hoveringPointers=%s, pilferingPointerIds=%s]",
+ dumpVector(state.touchingPointers, streamableToString).c_str(),
toString(state.downTimeInTarget).c_str(),
- bitsetToString(state.hoveringPointerIds).c_str(),
+ dumpVector(state.hoveringPointers, streamableToString).c_str(),
bitsetToString(state.pilferingPointerIds).c_str());
}
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index c604353..0d1531f 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -38,17 +38,18 @@
bool hasHoveringPointers() const;
bool hasHoveringPointers(DeviceId deviceId) const;
bool hasHoveringPointer(DeviceId deviceId, int32_t pointerId) const;
- void addHoveringPointer(DeviceId deviceId, int32_t pointerId);
+ void addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer);
void removeHoveringPointer(DeviceId deviceId, int32_t pointerId);
// Touching
bool hasTouchingPointer(DeviceId deviceId, int32_t pointerId) const;
bool hasTouchingPointers() const;
bool hasTouchingPointers(DeviceId deviceId) const;
- std::bitset<MAX_POINTER_ID + 1> getTouchingPointers(DeviceId deviceId) const;
- void addTouchingPointers(DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> pointers);
+ std::vector<PointerProperties> getTouchingPointers(DeviceId deviceId) const;
+ void addTouchingPointers(DeviceId deviceId, const std::vector<PointerProperties>& pointers);
void removeTouchingPointer(DeviceId deviceId, int32_t pointerId);
void removeTouchingPointers(DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> pointers);
+ bool hasActiveStylus() const;
std::set<DeviceId> getTouchingDeviceIds() const;
// Pilfering pointers
@@ -69,16 +70,16 @@
private:
struct DeviceState {
- std::bitset<MAX_POINTER_ID + 1> touchingPointerIds;
+ std::vector<PointerProperties> touchingPointers;
// The pointer ids of the pointers that this window is currently pilfering, by device
std::bitset<MAX_POINTER_ID + 1> pilferingPointerIds;
// Time at which the first action down occurred on this window, for each device
// NOTE: This is not initialized in case of HOVER entry/exit and DISPATCH_AS_OUTSIDE
// scenario.
std::optional<nsecs_t> downTimeInTarget;
- std::bitset<MAX_POINTER_ID + 1> hoveringPointerIds;
+ std::vector<PointerProperties> hoveringPointers;
- bool hasPointers() const { return touchingPointerIds.any() || hoveringPointerIds.any(); };
+ bool hasPointers() const { return !touchingPointers.empty() || !hoveringPointers.empty(); };
};
std::map<DeviceId, DeviceState> mDeviceStates;
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 1c23720..9e6209b 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -99,8 +99,8 @@
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
- virtual void interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when,
- uint32_t& policyFlags) = 0;
+ virtual void interceptMotionBeforeQueueing(int32_t displayId, uint32_t source, int32_t action,
+ nsecs_t when, uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 5a74a42..2dd05f5 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -35,10 +35,12 @@
MultiTouchInputMapper::~MultiTouchInputMapper() {}
std::list<NotifyArgs> MultiTouchInputMapper::reset(nsecs_t when) {
- // TODO(b/291626046): Sync the MT state with the kernel using EVIOCGMTSLOTS.
- mMultiTouchMotionAccumulator.reset(getDeviceContext());
- mPointerIdBits.clear();
-
+ // The evdev multi-touch protocol does not allow userspace applications to query the initial or
+ // current state of the pointers at any time. This means if we clear our accumulated state when
+ // resetting the input mapper, there's no way to rebuild the full initial state of the pointers.
+ // We can only wait for updates to all the pointers and axes. Rather than clearing the state and
+ // rebuilding the state from scratch, we work around this kernel API limitation by never
+ // fully clearing any state specific to the multi-touch protocol.
return TouchInputMapper::reset(when);
}
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 34ca0b3..255f02d 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -21,9 +21,11 @@
#include <iterator>
#include <limits>
#include <map>
+#include <mutex>
#include <optional>
#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
#include <android/input.h>
#include <com_android_input_flags.h>
#include <ftl/enum.h>
@@ -156,13 +158,20 @@
return sAccumulator;
}
- void recordFinger(const TouchpadInputMapper::MetricsIdentifier& id) { mCounters[id].fingers++; }
+ void recordFinger(const TouchpadInputMapper::MetricsIdentifier& id) {
+ std::scoped_lock lock(mLock);
+ mCounters[id].fingers++;
+ }
- void recordPalm(const TouchpadInputMapper::MetricsIdentifier& id) { mCounters[id].palms++; }
+ void recordPalm(const TouchpadInputMapper::MetricsIdentifier& id) {
+ std::scoped_lock lock(mLock);
+ mCounters[id].palms++;
+ }
// Checks whether a Gesture struct is for the end of a gesture that we log metrics for, and
// records it if so.
void processGesture(const TouchpadInputMapper::MetricsIdentifier& id, const Gesture& gesture) {
+ std::scoped_lock lock(mLock);
switch (gesture.type) {
case kGestureTypeFling:
if (gesture.details.fling.fling_state == GESTURES_FLING_START) {
@@ -200,15 +209,20 @@
void* cookie) {
LOG_ALWAYS_FATAL_IF(atomTag != android::util::TOUCHPAD_USAGE);
MetricsAccumulator& accumulator = MetricsAccumulator::getInstance();
- accumulator.produceAtoms(outEventList);
- accumulator.resetCounters();
+ accumulator.produceAtomsAndReset(*outEventList);
return AStatsManager_PULL_SUCCESS;
}
- void produceAtoms(AStatsEventList* outEventList) const {
+ void produceAtomsAndReset(AStatsEventList& outEventList) {
+ std::scoped_lock lock(mLock);
+ produceAtomsLocked(outEventList);
+ resetCountersLocked();
+ }
+
+ void produceAtomsLocked(AStatsEventList& outEventList) const REQUIRES(mLock) {
for (auto& [id, counters] : mCounters) {
auto [busId, vendorId, productId, versionId] = id;
- addAStatsEvent(outEventList, android::util::TOUCHPAD_USAGE, vendorId, productId,
+ addAStatsEvent(&outEventList, android::util::TOUCHPAD_USAGE, vendorId, productId,
versionId, linuxBusToInputDeviceBusEnum(busId, /*isUsi=*/false),
counters.fingers, counters.palms, counters.twoFingerSwipeGestures,
counters.threeFingerSwipeGestures, counters.fourFingerSwipeGestures,
@@ -216,7 +230,7 @@
}
}
- void resetCounters() { mCounters.clear(); }
+ void resetCountersLocked() REQUIRES(mLock) { mCounters.clear(); }
// Stores the counters for a specific touchpad model. Fields have the same meanings as those of
// the TouchpadUsage atom; see that definition for detailed documentation.
@@ -232,7 +246,10 @@
// Metrics are aggregated by device model and version, so if two devices of the same model and
// version are connected at once, they will have the same counters.
- std::map<TouchpadInputMapper::MetricsIdentifier, Counters> mCounters;
+ std::map<TouchpadInputMapper::MetricsIdentifier, Counters> mCounters GUARDED_BY(mLock);
+
+ // Metrics are pulled by a binder thread, so we need to guard them with a mutex.
+ mutable std::mutex mLock;
};
} // namespace
@@ -449,6 +466,9 @@
if (mPointerCaptured) {
return mCapturedEventConverter.process(*rawEvent);
}
+ if (mMotionAccumulator.getActiveSlotsCount() == 0) {
+ mGestureStartTime = rawEvent->when;
+ }
std::optional<SelfContainedHardwareState> state = mStateConverter.processRawEvent(rawEvent);
if (state) {
updatePalmDetectionMetrics();
@@ -514,7 +534,7 @@
if (mDisplayId) {
MetricsAccumulator& metricsAccumulator = MetricsAccumulator::getInstance();
for (Gesture& gesture : mGesturesToProcess) {
- out += mGestureConverter.handleGesture(when, readTime, gesture);
+ out += mGestureConverter.handleGesture(when, readTime, mGestureStartTime, gesture);
metricsAccumulator.processGesture(mMetricsId, gesture);
}
}
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index ece0eca..897edca 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -113,6 +113,8 @@
// ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e.
// std::nullopt), all events will be ignored.
std::optional<int32_t> mDisplayId;
+
+ nsecs_t mGestureStartTime{0};
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
index d06514a..b0fc903 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
@@ -30,29 +30,23 @@
size_t slotCount, bool usingSlotsProtocol) {
mUsingSlotsProtocol = usingSlotsProtocol;
mSlots = std::vector<Slot>(slotCount);
- reset(deviceContext);
-}
-void MultiTouchMotionAccumulator::reset(const InputDeviceContext& deviceContext) {
- resetSlots();
-
- if (!mUsingSlotsProtocol) {
- return;
- }
-
- // Query the driver for the current slot index and use it as the initial slot before we
- // start reading events from the device. It is possible that the current slot index will
- // not be the same as it was when the first event was written into the evdev buffer, which
- // means the input mapper could start out of sync with the initial state of the events in
- // the evdev buffer. In the extremely unlikely case that this happens, the data from two
- // slots will be confused until the next ABS_MT_SLOT event is received. This can cause the
- // touch point to "jump", but at least there will be no stuck touches.
- int32_t initialSlot;
- if (const auto status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
- status == OK) {
- mCurrentSlot = initialSlot;
- } else {
- ALOGD("Could not retrieve current multi-touch slot index. status=%d", status);
+ mCurrentSlot = -1;
+ if (mUsingSlotsProtocol) {
+ // Query the driver for the current slot index and use it as the initial slot before we
+ // start reading events from the device. It is possible that the current slot index will
+ // not be the same as it was when the first event was written into the evdev buffer, which
+ // means the input mapper could start out of sync with the initial state of the events in
+ // the evdev buffer. In the extremely unlikely case that this happens, the data from two
+ // slots will be confused until the next ABS_MT_SLOT event is received. This can cause the
+ // touch point to "jump", but at least there will be no stuck touches.
+ int32_t initialSlot;
+ if (const auto status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
+ status == OK) {
+ mCurrentSlot = initialSlot;
+ } else {
+ ALOGD("Could not retrieve current multi-touch slot index. status=%d", status);
+ }
}
}
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
index 5b55e3d..0e3e2bb 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
@@ -83,7 +83,6 @@
LOG_ALWAYS_FATAL_IF(index < 0 || index >= mSlots.size(), "Invalid index: %zu", index);
return mSlots[index];
}
- void reset(const InputDeviceContext& deviceContext);
private:
int32_t mCurrentSlot;
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
index 9552104..01e983a 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.cpp
@@ -35,8 +35,14 @@
namespace {
+// This will disable the tap to click while the user is typing on a physical keyboard
const bool ENABLE_TOUCHPAD_PALM_REJECTION = input_flags::enable_touchpad_typing_palm_rejection();
+// In addition to v1, v2 will also cancel ongoing move gestures while typing and add delay in
+// re-enabling the tap to click.
+const bool ENABLE_TOUCHPAD_PALM_REJECTION_V2 =
+ input_flags::enable_v2_touchpad_typing_palm_rejection();
+
uint32_t gesturesButtonToMotionEventButton(uint32_t gesturesButton) {
switch (gesturesButton) {
case GESTURES_BUTTON_LEFT:
@@ -75,6 +81,7 @@
out << StringPrintf("Button state: 0x%08x\n", mButtonState);
out << "Down time: " << mDownTime << "\n";
out << "Current classification: " << ftl::enum_string(mCurrentClassification) << "\n";
+ out << "Enable Tap Timestamp: " << mWhenToEnableTapToClick << "\n";
return out.str();
}
@@ -109,8 +116,6 @@
void GestureConverter::populateMotionRanges(InputDeviceInfo& info) const {
info.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, SOURCE, 0.0f, 1.0f, 0, 0, 0);
- // TODO(b/259547750): set this using the raw axis ranges from the touchpad when pointer capture
- // is enabled.
if (!mBoundsInLogicalDisplay.isEmpty()) {
info.addMotionRange(AMOTION_EVENT_AXIS_X, SOURCE, mBoundsInLogicalDisplay.left,
mBoundsInLogicalDisplay.right, 0, 0, 0);
@@ -131,6 +136,7 @@
}
std::list<NotifyArgs> GestureConverter::handleGesture(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
const Gesture& gesture) {
if (!mDisplayId) {
// Ignore gestures when there is no target display configured.
@@ -139,13 +145,13 @@
switch (gesture.type) {
case kGestureTypeMove:
- return {handleMove(when, readTime, gesture)};
+ return handleMove(when, readTime, gestureStartTime, gesture);
case kGestureTypeButtonsChange:
return handleButtonsChange(when, readTime, gesture);
case kGestureTypeScroll:
return handleScroll(when, readTime, gesture);
case kGestureTypeFling:
- return handleFling(when, readTime, gesture);
+ return handleFling(when, readTime, gestureStartTime, gesture);
case kGestureTypeSwipe:
return handleMultiFingerSwipe(when, readTime, 3, gesture.details.swipe.dx,
gesture.details.swipe.dy);
@@ -162,18 +168,41 @@
}
}
-NotifyMotionArgs GestureConverter::handleMove(nsecs_t when, nsecs_t readTime,
- const Gesture& gesture) {
+std::list<NotifyArgs> GestureConverter::handleMove(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
+ const Gesture& gesture) {
float deltaX = gesture.details.move.dx;
float deltaY = gesture.details.move.dy;
- if (ENABLE_TOUCHPAD_PALM_REJECTION && (std::abs(deltaX) > 0 || std::abs(deltaY) > 0)) {
- enableTapToClick();
+ if (ENABLE_TOUCHPAD_PALM_REJECTION_V2) {
+ bool wasHoverCancelled = mIsHoverCancelled;
+ // Gesture will be cancelled if it started before the user started typing and
+ // there is a active IME connection.
+ mIsHoverCancelled = gestureStartTime <= mReaderContext.getLastKeyDownTimestamp() &&
+ mReaderContext.getPolicy()->isInputMethodConnectionActive();
+
+ if (!wasHoverCancelled && mIsHoverCancelled) {
+ // This is the first event of the cancelled gesture, we won't return because we need to
+ // generate a HOVER_EXIT event
+ mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
+ } else if (mIsHoverCancelled) {
+ return {};
+ }
}
+
rotateDelta(mOrientation, &deltaX, &deltaY);
- mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
- mPointerController->move(deltaX, deltaY);
- mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
+ // Update the cursor, and enable tap to click if the gesture is not cancelled
+ if (!mIsHoverCancelled) {
+ // handleFling calls hoverMove with zero delta on FLING_TAP_DOWN. Don't enable tap to click
+ // for this case as subsequent handleButtonsChange may choose to ignore this tap.
+ if ((ENABLE_TOUCHPAD_PALM_REJECTION || ENABLE_TOUCHPAD_PALM_REJECTION_V2) &&
+ (std::abs(deltaX) > 0 || std::abs(deltaY) > 0)) {
+ enableTapToClick(when);
+ }
+ mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
+ mPointerController->move(deltaX, deltaY);
+ mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE);
+ }
const auto [xCursorPosition, yCursorPosition] =
mEnablePointerChoreographer ? FloatPoint{0, 0} : mPointerController->getPosition();
@@ -187,10 +216,12 @@
const bool down = isPointerDown(mButtonState);
coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
- const int32_t action = down ? AMOTION_EVENT_ACTION_MOVE : AMOTION_EVENT_ACTION_HOVER_MOVE;
- return makeMotionArgs(when, readTime, action, /* actionButton= */ 0, mButtonState,
- /* pointerCount= */ 1, mFingerProps.data(), &coords, xCursorPosition,
- yCursorPosition);
+ const int32_t action = mIsHoverCancelled
+ ? AMOTION_EVENT_ACTION_HOVER_EXIT
+ : (down ? AMOTION_EVENT_ACTION_MOVE : AMOTION_EVENT_ACTION_HOVER_MOVE);
+ return {makeMotionArgs(when, readTime, action, /* actionButton= */ 0, mButtonState,
+ /* pointerCount= */ 1, mFingerProps.data(), &coords, xCursorPosition,
+ yCursorPosition)};
}
std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_t readTime,
@@ -210,8 +241,15 @@
coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0);
coords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0);
- if (ENABLE_TOUCHPAD_PALM_REJECTION && mReaderContext.isPreventingTouchpadTaps()) {
- enableTapToClick();
+ // V2 palm rejection should override V1
+ if (ENABLE_TOUCHPAD_PALM_REJECTION_V2) {
+ enableTapToClick(when);
+ if (gesture.details.buttons.is_tap && when <= mWhenToEnableTapToClick) {
+ // return early to prevent this tap
+ return out;
+ }
+ } else if (ENABLE_TOUCHPAD_PALM_REJECTION && mReaderContext.isPreventingTouchpadTaps()) {
+ enableTapToClick(when);
if (gesture.details.buttons.is_tap) {
// return early to prevent this tap
return out;
@@ -348,6 +386,7 @@
}
std::list<NotifyArgs> GestureConverter::handleFling(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
const Gesture& gesture) {
switch (gesture.details.fling.fling_state) {
case GESTURES_FLING_START:
@@ -366,13 +405,10 @@
// magnitude, which will also result in the pointer icon being updated.
// TODO(b/282023644): Add a signal in libgestures for when a stable contact has been
// initiated with a touchpad.
- if (!mReaderContext.isPreventingTouchpadTaps()) {
- enableTapToClick();
- }
- return {handleMove(when, readTime,
- Gesture(kGestureMove, gesture.start_time, gesture.end_time,
- /*dx=*/0.f,
- /*dy=*/0.f))};
+ return handleMove(when, readTime, gestureStartTime,
+ Gesture(kGestureMove, gesture.start_time, gesture.end_time,
+ /*dx=*/0.f,
+ /*dy=*/0.f));
}
break;
default:
@@ -598,8 +634,11 @@
/* videoFrames= */ {}};
}
-void GestureConverter::enableTapToClick() {
- mReaderContext.setPreventingTouchpadTaps(false);
+void GestureConverter::enableTapToClick(nsecs_t when) {
+ if (mReaderContext.isPreventingTouchpadTaps()) {
+ mWhenToEnableTapToClick = when + TAP_ENABLE_DELAY_NANOS.count();
+ mReaderContext.setPreventingTouchpadTaps(false);
+ }
}
} // namespace android
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index 732a4b2..88e7b99 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -34,6 +34,13 @@
namespace android {
+using std::chrono_literals::operator""ms;
+/**
+ * This duration is decided based on internal team testing, it may be updated after testing with
+ * larger groups
+ */
+constexpr std::chrono::nanoseconds TAP_ENABLE_DELAY_NANOS = 400ms;
+
// Converts Gesture structs from the gestures library into NotifyArgs and the appropriate
// PointerController calls.
class GestureConverter {
@@ -53,17 +60,20 @@
void populateMotionRanges(InputDeviceInfo& info) const;
[[nodiscard]] std::list<NotifyArgs> handleGesture(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
const Gesture& gesture);
private:
- [[nodiscard]] NotifyMotionArgs handleMove(nsecs_t when, nsecs_t readTime,
- const Gesture& gesture);
+ [[nodiscard]] std::list<NotifyArgs> handleMove(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
+ const Gesture& gesture);
[[nodiscard]] std::list<NotifyArgs> handleButtonsChange(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
[[nodiscard]] std::list<NotifyArgs> releaseAllButtons(nsecs_t when, nsecs_t readTime);
[[nodiscard]] std::list<NotifyArgs> handleScroll(nsecs_t when, nsecs_t readTime,
const Gesture& gesture);
[[nodiscard]] std::list<NotifyArgs> handleFling(nsecs_t when, nsecs_t readTime,
+ nsecs_t gestureStartTime,
const Gesture& gesture);
[[nodiscard]] NotifyMotionArgs endScroll(nsecs_t when, nsecs_t readTime);
@@ -82,7 +92,9 @@
const PointerCoords* pointerCoords, float xCursorPosition,
float yCursorPosition);
- void enableTapToClick();
+ void enableTapToClick(nsecs_t when);
+ bool mIsHoverCancelled{false};
+ nsecs_t mWhenToEnableTapToClick{0};
const int32_t mDeviceId;
InputReaderContext& mReaderContext;
diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.h b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
index e9d93af..fb2db06 100644
--- a/services/inputflinger/tests/FakeInputDispatcherPolicy.h
+++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
@@ -63,7 +63,7 @@
void interceptKeyBeforeQueueing(const KeyEvent&, uint32_t&) override {}
- void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
+ void interceptMotionBeforeQueueing(int32_t, uint32_t, int32_t, nsecs_t, uint32_t&) override {}
nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override {
return 0;
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index d2b68dd..69772af 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -41,10 +41,14 @@
const auto TOUCHPAD_PALM_REJECTION =
ACONFIG_FLAG(input_flags, enable_touchpad_typing_palm_rejection);
+const auto TOUCHPAD_PALM_REJECTION_V2 =
+ ACONFIG_FLAG(input_flags, enable_v2_touchpad_typing_palm_rejection);
} // namespace
using testing::AllOf;
+using testing::ElementsAre;
+using testing::VariantWith;
class GestureConverterTestBase : public testing::Test {
protected:
@@ -107,14 +111,14 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
}
@@ -126,14 +130,14 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X + 10, POINTER_Y + 5), WithRelativeMotion(10, 5),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X + 10, POINTER_Y + 5), WithRelativeMotion(10, 5),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X + 10, POINTER_Y + 5));
}
@@ -147,67 +151,69 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
- AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
- AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
+ AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
+ AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Then release the left button
Gesture leftUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, leftUpGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, leftUpGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Finally release the right button
Gesture rightUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_RIGHT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, rightUpGesture);
- ASSERT_EQ(3u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, rightUpGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, DragWithButton) {
@@ -219,32 +225,33 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT, /* up= */ GESTURES_BUTTON_NONE,
/* is_tap= */ false);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Move
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
@@ -252,24 +259,27 @@
Gesture upGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, upGesture);
- ASSERT_EQ(3u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, upGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithButtonState(0),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Scroll) {
@@ -279,50 +289,52 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDownTime(downTime),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithCoords(POINTER_X, POINTER_Y - 10),
- WithGestureScrollDistance(0, 10, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(POINTER_X, POINTER_Y - 10),
+ WithGestureScrollDistance(0, 10, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithCoords(POINTER_X, POINTER_Y - 15),
- WithGestureScrollDistance(0, 5, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(POINTER_X, POINTER_Y - 15),
+ WithGestureScrollDistance(0, 5, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithCoords(POINTER_X, POINTER_Y - 15),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y - 15),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Scroll_Rotated) {
@@ -333,43 +345,47 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDownTime(downTime),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithCoords(POINTER_X - 10, POINTER_Y),
- WithGestureScrollDistance(0, 10, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(POINTER_X - 10, POINTER_Y),
+ WithGestureScrollDistance(0, 10, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithCoords(POINTER_X - 15, POINTER_Y),
- WithGestureScrollDistance(0, 5, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
-
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(POINTER_X - 15, POINTER_Y),
+ WithGestureScrollDistance(0, 5, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithCoords(POINTER_X - 15, POINTER_Y),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X - 15, POINTER_Y),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Scroll_ClearsClassificationAfterGesture) {
@@ -378,21 +394,22 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionClassification(MotionClassification::NONE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionClassification(MotionClassification::NONE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Scroll_ClearsScrollDistanceAfterGesture) {
@@ -401,20 +418,21 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like pinch.
Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, pinchGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGestureScrollDistance(0, 0, EPSILON));
}
@@ -426,17 +444,19 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/0);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/-5,
/*dy=*/10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- WithMotionClassification(MotionClassification::NONE));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionClassification(MotionClassification::NONE))));
}
TEST_F(GestureConverterTest, ThreeFingerSwipe_ClearsGestureAxesAfterGesture) {
@@ -446,16 +466,17 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/5,
/*dy=*/5);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like pinch.
Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, pinchGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(0)));
@@ -472,7 +493,8 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(4u, args.size());
// Three fake fingers should be created. We don't actually care where they are, so long as they
@@ -523,7 +545,7 @@
Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 0, /* dy= */ 5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -540,30 +562,36 @@
EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY() - 15);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) {
@@ -574,7 +602,8 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(4u, args.size());
// Three fake fingers should be created. We don't actually care where they are, so long as they
@@ -616,7 +645,7 @@
Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 0, /* dy= */ 5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -631,23 +660,24 @@
EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithPointerCount(1u), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) {
@@ -657,7 +687,8 @@
Gesture startGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 10, /* dy= */ 0);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(5u, args.size());
// Four fake fingers should be created. We don't actually care where they are, so long as they
@@ -720,7 +751,7 @@
Gesture continueGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 5, /* dy= */ 0);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -739,38 +770,46 @@
EXPECT_EQ(arg.pointerCoords[3].getY(), finger3Start.getY());
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(4u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Pinch_Inwards) {
@@ -780,51 +819,57 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON),
- WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON),
- WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithCoords(POINTER_X - 100, POINTER_Y),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCoords(1, POINTER_X + 100, POINTER_Y),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 0.8, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(0.8f, EPSILON),
- WithPointerCoords(0, POINTER_X - 80, POINTER_Y),
- WithPointerCoords(1, POINTER_X + 80, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(0.8f, EPSILON),
+ WithPointerCoords(0, POINTER_X - 80, POINTER_Y),
+ WithPointerCoords(1, POINTER_X + 80, POINTER_Y), WithPointerCount(2u),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Pinch_Outwards) {
@@ -834,51 +879,57 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON),
- WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON),
- WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithCoords(POINTER_X - 100, POINTER_Y),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCoords(1, POINTER_X + 100, POINTER_Y),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 1.2, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.2f, EPSILON),
- WithPointerCoords(0, POINTER_X - 120, POINTER_Y),
- WithPointerCoords(1, POINTER_X + 120, POINTER_Y), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.2f, EPSILON),
+ WithPointerCoords(0, POINTER_X - 120, POINTER_Y),
+ WithPointerCoords(1, POINTER_X + 120, POINTER_Y),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Pinch_ClearsClassificationAfterGesture) {
@@ -888,21 +939,22 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*dz=*/1.2, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- WithMotionClassification(MotionClassification::NONE));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionClassification(MotionClassification::NONE))));
}
TEST_F(GestureConverterTest, Pinch_ClearsScaleFactorAfterGesture) {
@@ -912,21 +964,22 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*dz=*/1.2, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like scroll.
Gesture scrollGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/1,
/*dy=*/0);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, scrollGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, scrollGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGesturePinchScaleFactor(0, EPSILON));
}
@@ -939,28 +992,28 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
/*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(3u, args.size());
-
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, ResetDuringScroll) {
@@ -969,18 +1022,18 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithCoords(POINTER_X, POINTER_Y - 10),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y - 10),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, ResetDuringThreeFingerSwipe) {
@@ -990,31 +1043,35 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/10);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(3u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, ResetDuringPinch) {
@@ -1024,22 +1081,24 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(2u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, FlingTapDown) {
@@ -1049,7 +1108,8 @@
Gesture tapDownGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*vx=*/0.f, /*vy=*/0.f, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapDownGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapDownGesture);
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
@@ -1069,52 +1129,57 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapGesture);
- ASSERT_EQ(5u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTest, Click) {
@@ -1125,62 +1190,71 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonDownGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonUpGesture);
-
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabled,
- REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) {
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION),
+ REQUIRES_FLAGS_DISABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
+
// Tap should be ignored when disabled
mReader->getContext()->setPreventingTouchpadTaps(true);
@@ -1188,9 +1262,45 @@
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
- Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
+ Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
+
+ Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ // no events should be generated
+ ASSERT_EQ(0u, args.size());
+
+ // Future taps should be re-enabled
+ ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
+}
+
+TEST_F_WITH_FLAGS(GestureConverterTest, TapWithTapToClickDisabledWithDelay,
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
+
+ // Tap should be ignored when disabled
+ mReader->getContext()->setPreventingTouchpadTaps(true);
+
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
+
+ Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
ASSERT_EQ(1u, args.size());
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
@@ -1198,18 +1308,73 @@
WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
+ Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapGesture);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
// no events should be generated
ASSERT_EQ(0u, args.size());
// Future taps should be re-enabled
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
+
+ // taps before the threshold should still be ignored
+ currentTime += TAP_ENABLE_DELAY_NANOS.count();
+ flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
+
+ tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ // no events should be generated
+ ASSERT_EQ(0u, args.size());
+
+ // taps after the threshold should be recognised
+ currentTime += 1;
+ flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
+
+ tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ ASSERT_EQ(5u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithRelativeMotion(0.f, 0.f),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(1),
+ WithRelativeMotion(0.f, 0.f)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
+ WithRelativeMotion(0.f, 0.f)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithRelativeMotion(0.f, 0.f),
+ WithButtonState(0)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0),
+ WithButtonState(0)));
}
TEST_F_WITH_FLAGS(GestureConverterTest, ClickWithTapToClickDisabled,
@@ -1223,58 +1388,64 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonDownGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
- WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonUpGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(POINTER_X, POINTER_Y),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X, POINTER_Y), WithRelativeMotion(0, 0),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X, POINTER_Y),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Future taps should be re-enabled
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
@@ -1290,14 +1461,14 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
- WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(0.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)))));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
@@ -1305,6 +1476,45 @@
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
}
+TEST_F_WITH_FLAGS(GestureConverterTest, KeypressCancelsHoverMove,
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ const nsecs_t gestureStartTime = 1000;
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
+
+ // Start a move gesture at gestureStartTime
+ Gesture moveGesture(kGestureMove, gestureStartTime, gestureStartTime, -5, 10);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(gestureStartTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
+
+ // Key presses with IME connection should cancel ongoing move gesture
+ nsecs_t currentTime = gestureStartTime + 100;
+ mFakePolicy->setIsInputMethodConnectionActive(true);
+ mReader->getContext()->setLastKeyDownTimestamp(currentTime);
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT))));
+
+ // any updates in existing move gesture should be ignored
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_EQ(0u, args.size());
+
+ // New gesture should not be affected
+ currentTime += 100;
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, currentTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
+}
+
// TODO(b/311416205): De-duplicate the test cases after the refactoring is complete and the flagging
// logic can be removed.
class GestureConverterTestWithChoreographer : public GestureConverterTestBase {
@@ -1321,13 +1531,14 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Move_Rotated) {
@@ -1337,13 +1548,14 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(10, 5), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(10, 5), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, ButtonsChange) {
@@ -1355,65 +1567,64 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
- ASSERT_EQ(3u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
- AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
- AMOTION_EVENT_BUTTON_SECONDARY),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
+ AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
+ AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Then release the left button
Gesture leftUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, leftUpGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(0, 0),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, leftUpGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Finally release the right button
Gesture rightUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_RIGHT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, rightUpGesture);
- ASSERT_EQ(3u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, rightUpGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, DragWithButton) {
@@ -1425,53 +1636,53 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT, /* up= */ GESTURES_BUTTON_NONE,
/* is_tap= */ false);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Move
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, 0),
- WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Release the button
Gesture upGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE, /* up= */ GESTURES_BUTTON_LEFT,
/* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, upGesture);
- ASSERT_EQ(3u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, upGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Scroll) {
@@ -1481,47 +1692,50 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(0, 0),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDownTime(downTime),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, -10),
- WithGestureScrollDistance(0, 10, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(0, 0),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(0, -10),
+ WithGestureScrollDistance(0, 10, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, -15),
- WithGestureScrollDistance(0, 5, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(0, -15),
+ WithGestureScrollDistance(0, 5, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, 0 - 15),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, 0 - 15),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Scroll_Rotated) {
@@ -1532,40 +1746,46 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(downTime, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
-
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(0, 0),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDownTime(downTime),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(-10, 0),
- WithGestureScrollDistance(0, 10, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(downTime, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(0, 0),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithCoords(-10, 0),
+ WithGestureScrollDistance(0, 10, EPSILON),
+ WithMotionClassification(
+ MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(-15, 0),
- WithGestureScrollDistance(0, 5, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithCoords(-15, 0),
+ WithGestureScrollDistance(0, 5, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(-15, 0),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(-15, 0),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Scroll_ClearsClassificationAfterGesture) {
@@ -1574,21 +1794,22 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionClassification(MotionClassification::NONE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionClassification(MotionClassification::NONE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Scroll_ClearsScrollDistanceAfterGesture) {
@@ -1597,20 +1818,21 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like pinch.
Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, pinchGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGestureScrollDistance(0, 0, EPSILON));
}
@@ -1622,17 +1844,18 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/0);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/-5,
/*dy=*/10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- WithMotionClassification(MotionClassification::NONE));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionClassification(MotionClassification::NONE))));
}
TEST_F(GestureConverterTestWithChoreographer, ThreeFingerSwipe_ClearsGestureAxesAfterGesture) {
@@ -1642,16 +1865,17 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/5,
/*dy=*/5);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like pinch.
Gesture pinchGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, pinchGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, pinchGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(0)));
@@ -1668,7 +1892,8 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(4u, args.size());
// Three fake fingers should be created. We don't actually care where they are, so long as they
@@ -1719,7 +1944,7 @@
Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 0, /* dy= */ 5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -1736,30 +1961,36 @@
EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY() - 15);
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithGestureSwipeFingerCount(3),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(3),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, ThreeFingerSwipe_Rotated) {
@@ -1770,7 +2001,8 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0,
/* dy= */ 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(4u, args.size());
// Three fake fingers should be created. We don't actually care where they are, so long as they
@@ -1812,7 +2044,7 @@
Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 0, /* dy= */ 5);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -1827,23 +2059,24 @@
EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY());
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithPointerCount(1u), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, FourFingerSwipe_Horizontal) {
@@ -1853,7 +2086,8 @@
Gesture startGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 10, /* dy= */ 0);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
ASSERT_EQ(5u, args.size());
// Four fake fingers should be created. We don't actually care where they are, so long as they
@@ -1916,7 +2150,7 @@
Gesture continueGesture(kGestureFourFingerSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dx= */ 5, /* dy= */ 0);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, continueGesture);
ASSERT_EQ(1u, args.size());
arg = std::get<NotifyMotionArgs>(args.front());
ASSERT_THAT(arg,
@@ -1935,38 +2169,46 @@
EXPECT_EQ(arg.pointerCoords[3].getY(), finger3Start.getY());
Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture);
- ASSERT_EQ(4u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON), WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithGestureSwipeFingerCount(4),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, liftGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(4u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithGestureSwipeFingerCount(4),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Pinch_Inwards) {
@@ -1976,50 +2218,56 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithCoords(-100, 0),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCoords(1, 100, 0),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithCoords(-100, 0), WithPointerCount(1u),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCoords(1, 100, 0), WithPointerCount(2u),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 0.8, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(0.8f, EPSILON), WithPointerCoords(0, -80, 0),
- WithPointerCoords(1, 80, 0), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(0.8f, EPSILON),
+ WithPointerCoords(0, -80, 0), WithPointerCoords(1, 80, 0),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Pinch_Outwards) {
@@ -2029,50 +2277,56 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithCoords(-100, 0),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCoords(1, 100, 0),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithCoords(-100, 0), WithPointerCount(1u),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCoords(1, 100, 0), WithPointerCount(2u),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 1.1, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.1f, EPSILON), WithPointerCoords(0, -110, 0),
- WithPointerCoords(1, 110, 0), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.1f, EPSILON),
+ WithPointerCoords(0, -110, 0), WithPointerCoords(1, 110, 0),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Pinch_ClearsClassificationAfterGesture) {
@@ -2082,21 +2336,22 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*dz=*/1.2, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- WithMotionClassification(MotionClassification::NONE));
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionClassification(MotionClassification::NONE))));
}
TEST_F(GestureConverterTestWithChoreographer, Pinch_ClearsScaleFactorAfterGesture) {
@@ -2106,21 +2361,22 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*dz=*/1.2, GESTURES_ZOOM_UPDATE);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, updateGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, updateGesture);
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_END);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, endGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, endGesture);
// Move gestures don't use the fake finger array, so to test that gesture axes are cleared we
// need to use another gesture type, like scroll.
Gesture scrollGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/1,
/*dy=*/0);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, scrollGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, scrollGesture);
ASSERT_FALSE(args.empty());
EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()), WithGesturePinchScaleFactor(0, EPSILON));
}
@@ -2133,27 +2389,27 @@
Gesture downGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*down=*/GESTURES_BUTTON_LEFT | GESTURES_BUTTON_RIGHT,
/*up=*/GESTURES_BUTTON_NONE, /*is_tap=*/false);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, downGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, downGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(3u, args.size());
-
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY), WithCoords(0, 0),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
- WithCoords(0, 0), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithCoords(0, 0), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithButtonState(0), WithCoords(0, 0),
+ WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, ResetDuringScroll) {
@@ -2162,17 +2418,17 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture startGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -10);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, -10),
- WithGestureScrollDistance(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(ToolType::FINGER),
- WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, -10),
+ WithGestureScrollDistance(0, 0, EPSILON),
+ WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
+ WithToolType(ToolType::FINGER),
+ WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, ResetDuringThreeFingerSwipe) {
@@ -2182,31 +2438,35 @@
Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dx=*/0,
/*dy=*/10);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(3u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
- WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(ToolType::FINGER),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(3u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithGestureOffset(0, 0, EPSILON),
+ WithMotionClassification(
+ MotionClassification::MULTI_FINGER_SWIPE),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, ResetDuringPinch) {
@@ -2216,22 +2476,24 @@
Gesture startGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /*dz=*/1,
GESTURES_ZOOM_START);
- (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture);
+ (void)converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, startGesture);
std::list<NotifyArgs> args = converter.reset(ARBITRARY_TIME);
- ASSERT_EQ(2u, args.size());
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP |
- 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- EXPECT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithMotionClassification(MotionClassification::PINCH),
- WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(1u),
- WithToolType(ToolType::FINGER), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(2u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithMotionClassification(MotionClassification::PINCH),
+ WithGesturePinchScaleFactor(1.0f, EPSILON),
+ WithPointerCount(1u), WithToolType(ToolType::FINGER),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, FlingTapDown) {
@@ -2241,7 +2503,8 @@
Gesture tapDownGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/*vx=*/0.f, /*vy=*/0.f, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapDownGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapDownGesture);
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
@@ -2257,50 +2520,54 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, tapGesture);
- ASSERT_EQ(5u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(0, 0), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F(GestureConverterTestWithChoreographer, Click) {
@@ -2311,7 +2578,8 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
ASSERT_EQ(1u, args.size());
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
@@ -2322,49 +2590,56 @@
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonDownGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
- ASSERT_EQ(2u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonUpGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(0, 0), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
}
TEST_F_WITH_FLAGS(GestureConverterTestWithChoreographer, TapWithTapToClickDisabled,
- REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) {
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION),
+ REQUIRES_FLAGS_DISABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
+
// Tap should be ignored when disabled
mReader->getContext()->setPreventingTouchpadTaps(true);
@@ -2372,21 +2647,22 @@
GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
- Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
+ Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
- Gesture tapGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
+ Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, tapGesture);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
// no events should be generated
ASSERT_EQ(0u, args.size());
@@ -2395,6 +2671,96 @@
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
}
+TEST_F_WITH_FLAGS(GestureConverterTestWithChoreographer, TapWithTapToClickDisabledWithDelay,
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ nsecs_t currentTime = ARBITRARY_GESTURE_TIME;
+
+ // Tap should be ignored when disabled
+ mReader->getContext()->setPreventingTouchpadTaps(true);
+
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
+
+ Gesture flingGesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+
+ Gesture tapGesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ // no events should be generated
+ ASSERT_EQ(0u, args.size());
+
+ // Future taps should be re-enabled
+ ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
+
+ // taps before the threshold should still be ignored
+ currentTime += TAP_ENABLE_DELAY_NANOS.count();
+ flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
+
+ tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ // no events should be generated
+ ASSERT_EQ(0u, args.size());
+
+ // taps after the threshold should be recognised
+ currentTime += 1;
+ flingGesture = Gesture(kGestureFling, currentTime, currentTime, /* vx= */ 0,
+ /* vy= */ 0, GESTURES_FLING_TAP_DOWN);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, flingGesture);
+
+ ASSERT_EQ(1u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0)));
+
+ tapGesture = Gesture(kGestureButtonsChange, currentTime, currentTime,
+ /* down= */ GESTURES_BUTTON_LEFT,
+ /* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ true);
+ args = converter.handleGesture(currentTime, currentTime, currentTime, tapGesture);
+
+ ASSERT_EQ(5u, args.size());
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithRelativeMotion(0.f, 0.f),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(1),
+ WithRelativeMotion(0.f, 0.f)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
+ WithRelativeMotion(0.f, 0.f)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithRelativeMotion(0.f, 0.f),
+ WithButtonState(0)));
+ args.pop_front();
+ ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithRelativeMotion(0, 0),
+ WithButtonState(0)));
+}
+
TEST_F_WITH_FLAGS(GestureConverterTestWithChoreographer, ClickWithTapToClickDisabled,
REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION)) {
// Click should still produce button press/release events
@@ -2406,56 +2772,62 @@
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* vx= */ 0,
/* vy= */ 0, GESTURES_FLING_TAP_DOWN);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, flingGesture);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, flingGesture);
- ASSERT_EQ(1u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonDownGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_LEFT,
/* up= */ GESTURES_BUTTON_NONE, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonDownGesture);
- ASSERT_EQ(2u, args.size());
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonDownGesture);
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER),
+ WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithPressure(1.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
Gesture buttonUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* down= */ GESTURES_BUTTON_NONE,
/* up= */ GESTURES_BUTTON_LEFT, /* is_tap= */ false);
- args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, buttonUpGesture);
+ args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, buttonUpGesture);
- ASSERT_EQ(3u, args.size());
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
- WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
- WithToolType(ToolType::FINGER), WithButtonState(0), WithPressure(1.0f),
- WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithCoords(0, 0),
- WithRelativeMotion(0.f, 0.f), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
- args.pop_front();
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(0, 0), WithToolType(ToolType::FINGER), WithButtonState(0),
- WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
+ WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
+ WithButtonState(0), WithCoords(0, 0),
+ WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(1.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
+ WithCoords(0, 0), WithRelativeMotion(0.f, 0.f),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT))),
+ VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
+ WithCoords(0, 0), WithRelativeMotion(0, 0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
+ WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Future taps should be re-enabled
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
@@ -2471,16 +2843,57 @@
converter.setDisplayId(ADISPLAY_ID_DEFAULT);
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
- std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, moveGesture);
- ASSERT_EQ(1u, args.size());
+ std::list<NotifyArgs> args =
+ converter.handleGesture(ARBITRARY_TIME, READ_TIME, ARBITRARY_TIME, moveGesture);
- ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
- AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
- WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
- WithButtonState(0), WithPressure(0.0f), WithDisplayId(ADISPLAY_ID_DEFAULT)));
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE), WithCoords(0, 0),
+ WithRelativeMotion(-5, 10), WithToolType(ToolType::FINGER),
+ WithButtonState(0), WithPressure(0.0f),
+ WithDisplayId(ADISPLAY_ID_DEFAULT)))));
// Future taps should be re-enabled
ASSERT_FALSE(mReader->getContext()->isPreventingTouchpadTaps());
}
+TEST_F_WITH_FLAGS(GestureConverterTestWithChoreographer, KeypressCancelsHoverMove,
+ REQUIRES_FLAGS_ENABLED(TOUCHPAD_PALM_REJECTION_V2)) {
+ const nsecs_t gestureStartTime = 1000;
+ InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID);
+ GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID);
+ converter.setDisplayId(ADISPLAY_ID_DEFAULT);
+
+ // Start a move gesture at gestureStartTime
+ Gesture moveGesture(kGestureMove, gestureStartTime, gestureStartTime, -5, 10);
+ std::list<NotifyArgs> args =
+ converter.handleGesture(gestureStartTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
+
+ // Key presses with IME connection should cancel ongoing move gesture
+ nsecs_t currentTime = gestureStartTime + 100;
+ mFakePolicy->setIsInputMethodConnectionActive(true);
+ mReader->getContext()->setLastKeyDownTimestamp(currentTime);
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT))));
+
+ // any updates in existing move gesture should be ignored
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, gestureStartTime, moveGesture);
+ ASSERT_EQ(0u, args.size());
+
+ // New gesture should not be affected
+ currentTime += 100;
+ moveGesture = Gesture(kGestureMove, currentTime, currentTime, -5, 10);
+ args = converter.handleGesture(currentTime, READ_TIME, currentTime, moveGesture);
+ ASSERT_THAT(args,
+ ElementsAre(VariantWith<NotifyMotionArgs>(
+ WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))));
+}
+
} // namespace android
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 5002391..a880a4c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -549,7 +549,7 @@
}
}
- void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
+ void interceptMotionBeforeQueueing(int32_t, uint32_t, int32_t, nsecs_t, uint32_t&) override {}
nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent&, uint32_t) override {
nsecs_t delay = std::chrono::nanoseconds(mInterceptKeyTimeout).count();
@@ -572,7 +572,8 @@
/** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
* essentially a passthrough for notifySwitch.
*/
- mLastNotifySwitch = NotifySwitchArgs(/*id=*/1, when, policyFlags, switchValues, switchMask);
+ mLastNotifySwitch =
+ NotifySwitchArgs(InputEvent::nextId(), when, policyFlags, switchValues, switchMask);
}
void pokeUserActivity(nsecs_t, int32_t, int32_t) override {
@@ -836,7 +837,8 @@
}
TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
- NotifySwitchArgs args(/*id=*/10, /*eventTime=*/20, /*policyFlags=*/0, /*switchValues=*/1,
+ NotifySwitchArgs args(InputEvent::nextId(), /*eventTime=*/20, /*policyFlags=*/0,
+ /*switchValues=*/1,
/*switchMask=*/2);
mDispatcher->notifySwitch(args);
@@ -1182,6 +1184,11 @@
mInfo.setInputConfig(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY, disableUserActivity);
}
+ void setGlobalStylusBlocksTouch(bool shouldGlobalStylusBlockTouch) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH,
+ shouldGlobalStylusBlockTouch);
+ }
+
void setAlpha(float alpha) { mInfo.alpha = alpha; }
void setTouchOcclusionMode(TouchOcclusionMode mode) { mInfo.touchOcclusionMode = mode; }
@@ -1221,31 +1228,27 @@
void setWindowOffset(float offsetX, float offsetY) { mInfo.transform.set(offsetX, offsetY); }
- KeyEvent* consumeKey(bool handled = true) {
- InputEvent* event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED, handled);
- if (event == nullptr) {
- ADD_FAILURE() << "Consume failed : no event";
- return nullptr;
+ const KeyEvent& consumeKey(bool handled = true) {
+ const InputEvent& event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED, handled);
+ if (event.getType() != InputEventType::KEY) {
+ LOG(FATAL) << "Instead of key event, got " << event;
}
- if (event->getType() != InputEventType::KEY) {
- ADD_FAILURE() << "Instead of key event, got " << *event;
- return nullptr;
- }
- return static_cast<KeyEvent*>(event);
+ return static_cast<const KeyEvent&>(event);
}
void consumeKeyEvent(const ::testing::Matcher<KeyEvent>& matcher) {
- KeyEvent* keyEvent = consumeKey();
- ASSERT_NE(nullptr, keyEvent) << "Did not get a key event, but expected " << matcher;
- ASSERT_THAT(*keyEvent, matcher);
+ const KeyEvent& keyEvent = consumeKey();
+ ASSERT_THAT(keyEvent, matcher);
}
void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
- consumeEvent(InputEventType::KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId, expectedFlags);
+ consumeKeyEvent(AllOf(WithKeyAction(ACTION_DOWN), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags)));
}
void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
- consumeEvent(InputEventType::KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
+ consumeKeyEvent(AllOf(WithKeyAction(ACTION_UP), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags)));
}
void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
@@ -1267,44 +1270,46 @@
void consumeAnyMotionDown(std::optional<int32_t> expectedDisplayId = std::nullopt,
std::optional<int32_t> expectedFlags = std::nullopt) {
- consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
- expectedFlags);
+ consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_DOWN),
+ testing::Conditional(expectedDisplayId.has_value(),
+ WithDisplayId(*expectedDisplayId), testing::_),
+ testing::Conditional(expectedFlags.has_value(), WithFlags(*expectedFlags),
+ testing::_)));
}
void consumeMotionPointerDown(int32_t pointerIdx,
int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN |
+ const int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN |
(pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- consumeEvent(InputEventType::MOTION, action, expectedDisplayId, expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(action), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags)));
}
void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
+ const int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
(pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- consumeEvent(InputEventType::MOTION, action, expectedDisplayId, expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(action), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags)));
}
void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
- expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDisplayId(expectedDisplayId),
+ WithFlags(expectedFlags)));
}
void consumeMotionOutside(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
int32_t expectedFlags = 0) {
- consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_OUTSIDE, expectedDisplayId,
- expectedFlags);
+ consumeMotionEvent(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_OUTSIDE),
+ WithDisplayId(expectedDisplayId), WithFlags(expectedFlags)));
}
- void consumeMotionOutsideWithZeroedCoords(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
- int32_t expectedFlags = 0) {
- MotionEvent* motionEvent = consumeMotion();
- ASSERT_NE(nullptr, motionEvent);
- EXPECT_EQ(AMOTION_EVENT_ACTION_OUTSIDE, motionEvent->getActionMasked());
- EXPECT_EQ(0.f, motionEvent->getRawPointerCoords(0)->getX());
- EXPECT_EQ(0.f, motionEvent->getRawPointerCoords(0)->getY());
+ void consumeMotionOutsideWithZeroedCoords() {
+ consumeMotionEvent(
+ AllOf(WithMotionAction(AMOTION_EVENT_ACTION_OUTSIDE), WithRawCoords(0, 0)));
}
void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
@@ -1319,21 +1324,15 @@
mInputReceiver->consumeCaptureEvent(hasCapture);
}
- const MotionEvent& consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) {
- MotionEvent* motionEvent = consumeMotion();
- if (nullptr == motionEvent) {
- LOG(FATAL) << "Did not get a motion event, but expected " << matcher;
+ const MotionEvent& consumeMotionEvent(
+ const ::testing::Matcher<MotionEvent>& matcher = testing::_) {
+ const InputEvent& event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
+ if (event.getType() != InputEventType::MOTION) {
+ LOG(FATAL) << "Instead of motion event, got " << event;
}
- EXPECT_THAT(*motionEvent, matcher);
- return *motionEvent;
- }
-
- void consumeEvent(InputEventType expectedEventType, int32_t expectedAction,
- std::optional<int32_t> expectedDisplayId,
- std::optional<int32_t> expectedFlags) {
- ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
- mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
- expectedFlags);
+ const auto& motionEvent = static_cast<const MotionEvent&>(event);
+ EXPECT_THAT(motionEvent, matcher);
+ return motionEvent;
}
void consumeDragEvent(bool isExiting, float x, float y) {
@@ -1364,26 +1363,6 @@
mInputReceiver->sendTimeline(inputEventId, timeline);
}
- InputEvent* consume(std::chrono::milliseconds timeout, bool handled = true) {
- if (mInputReceiver == nullptr) {
- return nullptr;
- }
- return mInputReceiver->consume(timeout, handled);
- }
-
- MotionEvent* consumeMotion() {
- InputEvent* event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
- if (event == nullptr) {
- ADD_FAILURE() << "Consume failed : no event";
- return nullptr;
- }
- if (event->getType() != InputEventType::MOTION) {
- ADD_FAILURE() << "Instead of motion event, got " << *event;
- return nullptr;
- }
- return static_cast<MotionEvent*>(event);
- }
-
void assertNoEvents() {
if (mInputReceiver == nullptr &&
mInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
@@ -1415,6 +1394,17 @@
std::shared_ptr<FakeInputReceiver> mInputReceiver;
static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
friend class sp<FakeWindowHandle>;
+
+ const InputEvent& consume(std::chrono::milliseconds timeout, bool handled = true) {
+ if (mInputReceiver == nullptr) {
+ LOG(FATAL) << "Cannot consume event from a window with no input event receiver";
+ }
+ InputEvent* event = mInputReceiver->consume(timeout, handled);
+ if (event == nullptr) {
+ LOG(FATAL) << "Consume failed: no event";
+ }
+ return *event;
+ }
};
std::atomic<int32_t> FakeWindowHandle::sId{1};
@@ -1579,9 +1569,9 @@
static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid key event.
- NotifyKeyArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
- displayId, POLICY_FLAG_PASS_TO_USER, action, /*flags=*/0, AKEYCODE_A, KEY_A,
- AMETA_NONE, currentTime);
+ NotifyKeyArgs args(InputEvent::nextId(), currentTime, /*readTime=*/0, DEVICE_ID,
+ AINPUT_SOURCE_KEYBOARD, displayId, POLICY_FLAG_PASS_TO_USER, action,
+ /*flags=*/0, AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
return args;
}
@@ -1590,9 +1580,9 @@
int32_t displayId = ADISPLAY_ID_NONE) {
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid key event.
- NotifyKeyArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
- displayId, 0, action, /*flags=*/0, AKEYCODE_C, KEY_C, AMETA_META_ON,
- currentTime);
+ NotifyKeyArgs args(InputEvent::nextId(), currentTime, /*readTime=*/0, DEVICE_ID,
+ AINPUT_SOURCE_KEYBOARD, displayId, 0, action, /*flags=*/0, AKEYCODE_C, KEY_C,
+ AMETA_META_ON, currentTime);
return args;
}
@@ -1601,9 +1591,9 @@
int32_t displayId = ADISPLAY_ID_NONE) {
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid key event.
- NotifyKeyArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
- displayId, 0, action, /*flags=*/0, AKEYCODE_ASSIST, KEY_ASSISTANT,
- AMETA_NONE, currentTime);
+ NotifyKeyArgs args(InputEvent::nextId(), currentTime, /*readTime=*/0, DEVICE_ID,
+ AINPUT_SOURCE_KEYBOARD, displayId, 0, action, /*flags=*/0, AKEYCODE_ASSIST,
+ KEY_ASSISTANT, AMETA_NONE, currentTime);
return args;
}
@@ -1631,9 +1621,9 @@
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid motion event.
- NotifyMotionArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, source, displayId,
- POLICY_FLAG_PASS_TO_USER, action, /*actionButton=*/0, /*flags=*/0,
- AMETA_NONE, /*buttonState=*/0, MotionClassification::NONE,
+ NotifyMotionArgs args(InputEvent::nextId(), currentTime, /*readTime=*/0, DEVICE_ID, source,
+ displayId, POLICY_FLAG_PASS_TO_USER, action, /*actionButton=*/0,
+ /*flags=*/0, AMETA_NONE, /*buttonState=*/0, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
pointerCoords, /*xPrecision=*/0, /*yPrecision=*/0,
AMOTION_EVENT_INVALID_CURSOR_POSITION,
@@ -1652,7 +1642,8 @@
static NotifyPointerCaptureChangedArgs generatePointerCaptureChangedArgs(
const PointerCaptureRequest& request) {
- return NotifyPointerCaptureChangedArgs(/*id=*/0, systemTime(SYSTEM_TIME_MONOTONIC), request);
+ return NotifyPointerCaptureChangedArgs(InputEvent::nextId(), systemTime(SYSTEM_TIME_MONOTONIC),
+ request);
}
} // namespace
@@ -3355,6 +3346,150 @@
}
/**
+ * If stylus is down anywhere on the screen, then touches should not be delivered to windows that
+ * have InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH.
+ *
+ * Two windows: one on the left and one on the right.
+ * The window on the right has GLOBAL_STYLUS_BLOCKS_TOUCH config.
+ * Stylus down on the left window, and then touch down on the right window.
+ * Check that the right window doesn't get touches while the stylus is down on the left window.
+ */
+TEST_F(InputDispatcherMultiDeviceTest, GlobalStylusDownBlocksTouch) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> leftWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Left window",
+ ADISPLAY_ID_DEFAULT);
+ leftWindow->setFrame(Rect(0, 0, 100, 100));
+
+ sp<FakeWindowHandle> sbtRightWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher,
+ "Stylus blocks touch (right) window", ADISPLAY_ID_DEFAULT);
+ sbtRightWindow->setFrame(Rect(100, 100, 200, 200));
+ sbtRightWindow->setGlobalStylusBlocksTouch(true);
+
+ mDispatcher->onWindowInfosChanged(
+ {{*leftWindow->getInfo(), *sbtRightWindow->getInfo()}, {}, 0, 0});
+
+ const int32_t stylusDeviceId = 5;
+ const int32_t touchDeviceId = 4;
+
+ // Stylus down in the left window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(52))
+ .deviceId(stylusDeviceId)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(stylusDeviceId)));
+
+ // Finger tap on the right window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(151))
+ .deviceId(touchDeviceId)
+ .build());
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(151))
+ .deviceId(touchDeviceId)
+ .build());
+
+ // The touch should be blocked, because stylus is down somewhere else on screen!
+ sbtRightWindow->assertNoEvents();
+
+ // Continue stylus motion, and ensure it's not impacted.
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(51).y(53))
+ .deviceId(stylusDeviceId)
+ .build());
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(51).y(53))
+ .deviceId(stylusDeviceId)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_MOVE), WithDeviceId(stylusDeviceId)));
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_UP), WithDeviceId(stylusDeviceId)));
+
+ // Now that the stylus gesture is done, touches should be getting delivered correctly.
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(153))
+ .deviceId(touchDeviceId)
+ .build());
+ sbtRightWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId)));
+}
+
+/**
+ * If stylus is hovering anywhere on the screen, then touches should not be delivered to windows
+ * that have InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH.
+ *
+ * Two windows: one on the left and one on the right.
+ * The window on the right has GLOBAL_STYLUS_BLOCKS_TOUCH config.
+ * Stylus hover on the left window, and then touch down on the right window.
+ * Check that the right window doesn't get touches while the stylus is hovering on the left window.
+ */
+TEST_F(InputDispatcherMultiDeviceTest, GlobalStylusHoverBlocksTouch) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> leftWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Left window",
+ ADISPLAY_ID_DEFAULT);
+ leftWindow->setFrame(Rect(0, 0, 100, 100));
+
+ sp<FakeWindowHandle> sbtRightWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher,
+ "Stylus blocks touch (right) window", ADISPLAY_ID_DEFAULT);
+ sbtRightWindow->setFrame(Rect(100, 100, 200, 200));
+ sbtRightWindow->setGlobalStylusBlocksTouch(true);
+
+ mDispatcher->onWindowInfosChanged(
+ {{*leftWindow->getInfo(), *sbtRightWindow->getInfo()}, {}, 0, 0});
+
+ const int32_t stylusDeviceId = 5;
+ const int32_t touchDeviceId = 4;
+
+ // Stylus hover in the left window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(52))
+ .deviceId(stylusDeviceId)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(stylusDeviceId)));
+
+ // Finger tap on the right window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(151))
+ .deviceId(touchDeviceId)
+ .build());
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(151))
+ .deviceId(touchDeviceId)
+ .build());
+
+ // The touch should be blocked, because stylus is hovering somewhere else on screen!
+ sbtRightWindow->assertNoEvents();
+
+ // Continue stylus motion, and ensure it's not impacted.
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(51).y(53))
+ .deviceId(stylusDeviceId)
+ .build());
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(51).y(53))
+ .deviceId(stylusDeviceId)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_HOVER_MOVE), WithDeviceId(stylusDeviceId)));
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_HOVER_EXIT), WithDeviceId(stylusDeviceId)));
+
+ // Now that the stylus gesture is done, touches should be getting delivered correctly.
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(151).y(153))
+ .deviceId(touchDeviceId)
+ .build());
+ sbtRightWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId)));
+}
+
+/**
* A spy window above a window with no input channel.
* Start hovering with a stylus device, and then tap with it.
* Ensure spy window receives the entire sequence.
@@ -3625,20 +3760,18 @@
mDispatcher->waitForIdle();
- MotionEvent* motionEvent1 = window1->consumeMotion();
- ASSERT_NE(motionEvent1, nullptr);
+ const MotionEvent& motionEvent1 = window1->consumeMotionEvent();
window2->assertNoEvents();
- nsecs_t downTimeForWindow1 = motionEvent1->getDownTime();
- ASSERT_EQ(motionEvent1->getDownTime(), motionEvent1->getEventTime());
+ nsecs_t downTimeForWindow1 = motionEvent1.getDownTime();
+ ASSERT_EQ(motionEvent1.getDownTime(), motionEvent1.getEventTime());
// Now touch down on the window with another pointer
mDispatcher->notifyMotion(generateTouchArgs(POINTER_1_DOWN, {{50, 50}, {150, 50}}));
mDispatcher->waitForIdle();
- MotionEvent* motionEvent2 = window2->consumeMotion();
- ASSERT_NE(motionEvent2, nullptr);
- nsecs_t downTimeForWindow2 = motionEvent2->getDownTime();
+ const MotionEvent& motionEvent2 = window2->consumeMotionEvent();
+ nsecs_t downTimeForWindow2 = motionEvent2.getDownTime();
ASSERT_NE(downTimeForWindow1, downTimeForWindow2);
- ASSERT_EQ(motionEvent2->getDownTime(), motionEvent2->getEventTime());
+ ASSERT_EQ(motionEvent2.getDownTime(), motionEvent2.getEventTime());
// Now move the pointer on the second window
mDispatcher->notifyMotion(generateTouchArgs(AMOTION_EVENT_ACTION_MOVE, {{50, 50}, {151, 51}}));
@@ -4233,8 +4366,7 @@
// When device reset happens, that key stream should be terminated with FLAG_CANCELED
// on the app side.
mDispatcher->notifyDeviceReset({/*id=*/10, /*eventTime=*/20, DEVICE_ID});
- window->consumeEvent(InputEventType::KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
- AKEY_EVENT_FLAG_CANCELED);
+ window->consumeKeyUp(ADISPLAY_ID_DEFAULT, AKEY_EVENT_FLAG_CANCELED);
}
TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
@@ -4473,12 +4605,12 @@
InputEventInjectionSync::WAIT_FOR_RESULT))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
- const MotionEvent* event = window->consumeMotion();
- EXPECT_EQ(POINTER_1_DOWN, event->getAction());
- EXPECT_EQ(70, event->getX(0)); // 50 + 20
- EXPECT_EQ(90, event->getY(0)); // 50 + 40
- EXPECT_EQ(-10, event->getX(1)); // -30 + 20
- EXPECT_EQ(-10, event->getY(1)); // -50 + 40
+ const MotionEvent& event = window->consumeMotionEvent();
+ EXPECT_EQ(POINTER_1_DOWN, event.getAction());
+ EXPECT_EQ(70, event.getX(0)); // 50 + 20
+ EXPECT_EQ(90, event.getY(0)); // 50 + 40
+ EXPECT_EQ(-10, event.getX(1)); // -30 + 20
+ EXPECT_EQ(-10, event.getY(1)); // -50 + 40
}
/**
@@ -4744,15 +4876,15 @@
EXPECT_EQ(OK, mDispatcher->pilferPointers(spyWindowDefaultDisplay->getToken()));
// windowDefaultDisplay gets cancel
- MotionEvent* event = windowDefaultDisplay->consumeMotion();
- EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, event->getAction());
+ const MotionEvent& event = windowDefaultDisplay->consumeMotionEvent();
+ EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
// The cancel event is sent to windowDefaultDisplay of the ADISPLAY_ID_DEFAULT display, so the
// coordinates of the cancel are converted by windowDefaultDisplay's transform, the x and y
// coordinates are both 100, otherwise if the cancel event is sent to windowSecondDisplay of
// SECOND_DISPLAY_ID, the x and y coordinates are 200
- EXPECT_EQ(100, event->getX(0));
- EXPECT_EQ(100, event->getY(0));
+ EXPECT_EQ(100, event.getX(0));
+ EXPECT_EQ(100, event.getY(0));
}
/**
@@ -4882,19 +5014,18 @@
{PointF{150, 220}}));
firstWindow->assertNoEvents();
- const MotionEvent* event = secondWindow->consumeMotion();
- ASSERT_NE(nullptr, event);
- EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, event->getAction());
+ const MotionEvent& event = secondWindow->consumeMotionEvent();
+ EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, event.getAction());
// Ensure that the events from the "getRaw" API are in logical display coordinates.
- EXPECT_EQ(300, event->getRawX(0));
- EXPECT_EQ(880, event->getRawY(0));
+ EXPECT_EQ(300, event.getRawX(0));
+ EXPECT_EQ(880, event.getRawY(0));
// Ensure that the x and y values are in the window's coordinate space.
// The left-top of the second window is at (100, 200) in display space, which is (200, 800) in
// the logical display space. This will be the origin of the window space.
- EXPECT_EQ(100, event->getX(0));
- EXPECT_EQ(80, event->getY(0));
+ EXPECT_EQ(100, event.getX(0));
+ EXPECT_EQ(80, event.getY(0));
}
TEST_F(InputDispatcherDisplayProjectionTest, CancelMotionWithCorrectCoordinates) {
@@ -5968,8 +6099,7 @@
motionArgs.pointerCoords[0].getX() - 10);
mDispatcher->notifyMotion(motionArgs);
- window->consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
- /*expectedFlags=*/0);
+ window->consumeMotionMove(ADISPLAY_ID_DEFAULT, /*expectedFlags=*/0);
}
/**
@@ -6039,10 +6169,9 @@
const NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
mDispatcher->notifyKey(keyArgs);
- KeyEvent* event = window->consumeKey();
- ASSERT_NE(event, nullptr);
+ const KeyEvent& event = window->consumeKey();
- std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
+ std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(event);
ASSERT_NE(verified, nullptr);
ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
@@ -6083,10 +6212,9 @@
ADISPLAY_ID_DEFAULT);
mDispatcher->notifyMotion(motionArgs);
- MotionEvent* event = window->consumeMotion();
- ASSERT_NE(event, nullptr);
+ const MotionEvent& event = window->consumeMotionEvent();
- std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
+ std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(event);
ASSERT_NE(verified, nullptr);
ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
@@ -6664,9 +6792,8 @@
}
void consumeKey(bool handled, const ::testing::Matcher<KeyEvent>& matcher) {
- KeyEvent* event = mWindow->consumeKey(handled);
- ASSERT_NE(event, nullptr) << "Did not receive key event";
- ASSERT_THAT(*event, matcher);
+ const KeyEvent& event = mWindow->consumeKey(handled);
+ ASSERT_THAT(event, matcher);
}
};
@@ -6897,7 +7024,7 @@
mDispatcher->notifyKey(keyArgs);
// Window should receive key down event.
- mWindow->consumeEvent(InputEventType::KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
+ mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT,
/*expectedFlags=*/0);
}
};
@@ -6967,10 +7094,9 @@
GTEST_SKIP() << "Flaky test (b/270393106)";
sendAndConsumeKeyDown(/*deviceId=*/1);
for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
- KeyEvent* repeatEvent = mWindow->consumeKey();
- ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
+ const KeyEvent& repeatEvent = mWindow->consumeKey();
EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
- IdGenerator::getSource(repeatEvent->getId()));
+ IdGenerator::getSource(repeatEvent.getId()));
}
}
@@ -6980,9 +7106,8 @@
std::unordered_set<int32_t> idSet;
for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
- KeyEvent* repeatEvent = mWindow->consumeKey();
- ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
- int32_t id = repeatEvent->getId();
+ const KeyEvent& repeatEvent = mWindow->consumeKey();
+ int32_t id = repeatEvent.getId();
EXPECT_EQ(idSet.end(), idSet.find(id));
idSet.insert(id);
}
@@ -7071,8 +7196,7 @@
mDispatcher->onWindowInfosChanged({{*windowInPrimary->getInfo()}, {}, 0, 0});
// Old focus should receive a cancel event.
- windowInSecondary->consumeEvent(InputEventType::KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
- AKEY_EVENT_FLAG_CANCELED);
+ windowInSecondary->consumeKeyUp(ADISPLAY_ID_NONE, AKEY_EVENT_FLAG_CANCELED);
// Test inject a key down, should timeout because of no target window.
ASSERT_NO_FATAL_FAILURE(assertInjectedKeyTimesOut(*mDispatcher));
@@ -7550,24 +7674,21 @@
void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
const std::vector<PointF>& points) {
const std::string name = window->getName();
- MotionEvent* motionEvent = window->consumeMotion();
+ const MotionEvent& motionEvent =
+ window->consumeMotionEvent(WithMotionAction(expectedAction));
- ASSERT_NE(nullptr, motionEvent)
- << name.c_str() << ": consumer should have returned non-NULL event.";
-
- ASSERT_THAT(*motionEvent, WithMotionAction(expectedAction));
- ASSERT_EQ(points.size(), motionEvent->getPointerCount());
+ ASSERT_EQ(points.size(), motionEvent.getPointerCount());
for (size_t i = 0; i < points.size(); i++) {
float expectedX = points[i].x;
float expectedY = points[i].y;
- EXPECT_EQ(expectedX, motionEvent->getX(i))
+ EXPECT_EQ(expectedX, motionEvent.getX(i))
<< "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
- << ", got " << motionEvent->getX(i);
- EXPECT_EQ(expectedY, motionEvent->getY(i))
+ << ", got " << motionEvent.getX(i);
+ EXPECT_EQ(expectedY, motionEvent.getY(i))
<< "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
- << ", got " << motionEvent->getY(i);
+ << ", got " << motionEvent.getY(i);
}
}
@@ -8380,8 +8501,7 @@
.build()));
mFocusedWindow->consumeMotionDown();
mFocusedWindow->consumeMotionUp();
- mUnfocusedWindow->consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
- ADISPLAY_ID_DEFAULT, /*flags=*/0);
+ mUnfocusedWindow->consumeMotionOutside(ADISPLAY_ID_DEFAULT, /*flags=*/0);
// We consumed all events, so no ANR
ASSERT_TRUE(mDispatcher->waitForIdle());
mFakePolicy->assertNotifyAnrWasNotCalled();
@@ -8457,8 +8577,7 @@
// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
tapOnFocusedWindow();
- mUnfocusedWindow->consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
- ADISPLAY_ID_DEFAULT, /*flags=*/0);
+ mUnfocusedWindow->consumeMotionOutside(ADISPLAY_ID_DEFAULT, /*flags=*/0);
// Receive the events, but don't respond
std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
ASSERT_TRUE(downEventSequenceNum);
@@ -8590,8 +8709,7 @@
mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
{FOCUSED_WINDOW_LOCATION}));
- mUnfocusedWindow->consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
- ADISPLAY_ID_DEFAULT, /*flags=*/0);
+ mUnfocusedWindow->consumeMotionOutside(ADISPLAY_ID_DEFAULT, /*flags=*/0);
// Touch Window 2
mDispatcher->notifyMotion(
@@ -9723,7 +9841,7 @@
// Receives cancel for first pointer after next pointer down
mSpyWindow->consumeMotionEvent(WithMotionAction(ACTION_CANCEL));
- mSpyWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+ mSpyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithPointerIds({1})));
mDragWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
mSpyWindow->assertNoEvents();
@@ -9733,13 +9851,13 @@
mDragWindow->assertNoEvents();
const MotionEvent firstFingerMoveEvent =
- MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ MotionEventBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
.pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(60).y(60))
.pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(60).y(60))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionEvent(*mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
+ injectMotionEvent(*mDispatcher, firstFingerMoveEvent, INJECT_EVENT_TIMEOUT,
InputEventInjectionSync::WAIT_FOR_RESULT))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
@@ -9930,8 +10048,7 @@
.displayId(SECOND_DISPLAY_ID)
.pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
- windowInSecondary->consumeEvent(InputEventType::MOTION, AMOTION_EVENT_ACTION_DOWN,
- SECOND_DISPLAY_ID, /*expectedFlag=*/0);
+ windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID, /*expectedFlag=*/0);
// Update window again.
mDispatcher->onWindowInfosChanged(
{{*mDragWindow->getInfo(), *mSpyWindow->getInfo(), *mWindow->getInfo(),
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index e0a3e94..c6536de 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2894,9 +2894,9 @@
mapper.assertConfigureWasCalled();
mapper.assertResetWasNotCalled();
- RawEvent event{.deviceId = EVENTHUB_ID,
+ RawEvent event{.when = ARBITRARY_TIME,
.readTime = ARBITRARY_TIME,
- .when = ARBITRARY_TIME,
+ .deviceId = EVENTHUB_ID,
.type = EV_SYN,
.code = SYN_REPORT,
.value = 0};
@@ -10971,7 +10971,7 @@
ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
}
-TEST_F(MultiTouchInputMapperTest, ResetClearsTouchState) {
+TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(ui::ROTATION_0);
prepareAxes(POSITION | ID | SLOT | PRESSURE);
@@ -10994,36 +10994,25 @@
ASSERT_NO_FATAL_FAILURE(
mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
- // Reset the mapper. When the mapper is reset, the touch state is also cleared.
+ // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
+ // preserved. Resetting should cancel the ongoing gesture.
resetMapper(mapper, ARBITRARY_TIME);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
- // Move the second slot pointer, and ensure there are no events, because the touch state was
- // cleared and no slots should be in use.
+ // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
+ // the existing touch state to generate a down event.
processPosition(mapper, 301, 302);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-
- // Release both fingers.
- processId(mapper, INVALID_TRACKING_ID);
- processSlot(mapper, FIRST_SLOT);
- processId(mapper, INVALID_TRACKING_ID);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-
- // Start a new gesture, and ensure we get a DOWN event for it.
- processId(mapper, FIRST_TRACKING_ID);
- processPosition(mapper, 200, 300);
- processPressure(mapper, RAW_PRESSURE_MAX);
- processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
+ AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
-TEST_F(MultiTouchInputMapperTest, ResetClearsTouchStateWithNoPointersDown) {
+TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(ui::ROTATION_0);
prepareAxes(POSITION | ID | SLOT | PRESSURE);
@@ -11151,66 +11140,6 @@
ASSERT_FALSE(fakePointerController->isPointerShown());
}
-TEST_F(MultiTouchInputMapperTest, SimulateKernelBufferOverflow) {
- addConfigurationProperty("touch.deviceType", "touchScreen");
- prepareDisplay(ui::ROTATION_0);
- prepareAxes(POSITION | ID | SLOT | PRESSURE);
- MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
-
- // First finger down.
- processId(mapper, FIRST_TRACKING_ID);
- processPosition(mapper, 100, 200);
- processPressure(mapper, RAW_PRESSURE_MAX);
- processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
- WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
-
- // Assume the kernel buffer overflows, and we get a SYN_DROPPED event.
- // This will reset the mapper, and thus also reset the touch state.
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_DROPPED, 0);
- resetMapper(mapper, ARBITRARY_TIME);
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
- WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
-
- // Since the touch state was reset, it doesn't know which slots are active, so any movements
- // are ignored.
- processPosition(mapper, 101, 201);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-
- // Second finger goes down. This is the first active finger, so we get a DOWN event.
- processSlot(mapper, SECOND_SLOT);
- processId(mapper, SECOND_TRACKING_ID);
- processPosition(mapper, 400, 500);
- processPressure(mapper, RAW_PRESSURE_MAX);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
- WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
-
- // First slot is still ignored, only the second one is active.
- processSlot(mapper, FIRST_SLOT);
- processPosition(mapper, 102, 202);
- processSlot(mapper, SECOND_SLOT);
- processPosition(mapper, 401, 501);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
- WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
-
- // Both slots up, so we get the UP event for the active pointer.
- processSlot(mapper, FIRST_SLOT);
- processId(mapper, INVALID_TRACKING_ID);
- processSlot(mapper, SECOND_SLOT);
- processId(mapper, INVALID_TRACKING_ID);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(
- mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
// --- MultiTouchInputMapperTest_ExternalDevice ---
class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index 66fdaa4..8ba497a 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -464,6 +464,53 @@
return WithPointersMatcher(pointers);
}
+/// Pointer ids matcher
+class WithPointerIdsMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithPointerIdsMatcher(std::set<int32_t> pointerIds) : mPointerIds(pointerIds) {}
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
+ std::set<int32_t> actualPointerIds;
+ for (size_t pointerIndex = 0; pointerIndex < event.getPointerCount(); pointerIndex++) {
+ const PointerProperties* properties = event.getPointerProperties(pointerIndex);
+ actualPointerIds.insert(properties->id);
+ }
+
+ if (mPointerIds != actualPointerIds) {
+ *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
+ << dumpSet(actualPointerIds);
+ return false;
+ }
+ return true;
+ }
+
+ bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
+ std::set<int32_t> actualPointerIds;
+ for (const PointerProperties& properties : event.pointerProperties) {
+ actualPointerIds.insert(properties.id);
+ }
+
+ if (mPointerIds != actualPointerIds) {
+ *os << "expected pointer ids " << dumpSet(mPointerIds) << ", but got "
+ << dumpSet(actualPointerIds);
+ return false;
+ }
+ return true;
+ }
+
+ void DescribeTo(std::ostream* os) const { *os << "with pointer ids " << dumpSet(mPointerIds); }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer ids"; }
+
+private:
+ const std::set<int32_t> mPointerIds;
+};
+
+inline WithPointerIdsMatcher WithPointerIds(const std::set<int32_t /*id*/>& pointerIds) {
+ return WithPointerIdsMatcher(pointerIds);
+}
+
/// Key code
class WithKeyCodeMatcher {
public:
diff --git a/services/powermanager/WorkDuration.cpp b/services/powermanager/WorkDuration.cpp
index ef723c2..bd2b10a 100644
--- a/services/powermanager/WorkDuration.cpp
+++ b/services/powermanager/WorkDuration.cpp
@@ -25,8 +25,9 @@
WorkDuration::WorkDuration(int64_t startTimestampNanos, int64_t totalDurationNanos,
int64_t cpuDurationNanos, int64_t gpuDurationNanos)
- : workPeriodStartTimestampNanos(startTimestampNanos),
+ : timestampNanos(0),
actualTotalDurationNanos(totalDurationNanos),
+ workPeriodStartTimestampNanos(startTimestampNanos),
actualCpuDurationNanos(cpuDurationNanos),
actualGpuDurationNanos(gpuDurationNanos) {}
diff --git a/services/powermanager/include/android/WorkDuration.h b/services/powermanager/include/android/WorkDuration.h
index 99b5b8b..26a575f 100644
--- a/services/powermanager/include/android/WorkDuration.h
+++ b/services/powermanager/include/android/WorkDuration.h
@@ -61,11 +61,11 @@
return os;
}
- int64_t workPeriodStartTimestampNanos;
+ int64_t timestampNanos;
int64_t actualTotalDurationNanos;
+ int64_t workPeriodStartTimestampNanos;
int64_t actualCpuDurationNanos;
int64_t actualGpuDurationNanos;
- int64_t timestampNanos;
};
} // namespace android::os
diff --git a/services/powermanager/tests/PowerHalWrapperAidlTest.cpp b/services/powermanager/tests/PowerHalWrapperAidlTest.cpp
index 641ba9f..3d2cf29 100644
--- a/services/powermanager/tests/PowerHalWrapperAidlTest.cpp
+++ b/services/powermanager/tests/PowerHalWrapperAidlTest.cpp
@@ -29,9 +29,12 @@
#include <thread>
using aidl::android::hardware::power::Boost;
+using aidl::android::hardware::power::ChannelConfig;
using aidl::android::hardware::power::IPower;
using aidl::android::hardware::power::IPowerHintSession;
using aidl::android::hardware::power::Mode;
+using aidl::android::hardware::power::SessionConfig;
+using aidl::android::hardware::power::SessionTag;
using android::binder::Status;
using namespace android;
@@ -53,6 +56,14 @@
(int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
int64_t durationNanos, std::shared_ptr<IPowerHintSession>* session),
(override));
+ MOCK_METHOD(ndk::ScopedAStatus, createHintSessionWithConfig,
+ (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
+ int64_t durationNanos, SessionTag tag, SessionConfig* config,
+ std::shared_ptr<IPowerHintSession>* _aidl_return),
+ (override));
+ MOCK_METHOD(ndk::ScopedAStatus, getSessionChannel,
+ (int32_t tgid, int32_t uid, ChannelConfig* _aidl_return), (override));
+ MOCK_METHOD(ndk::ScopedAStatus, closeSessionChannel, (int32_t tgid, int32_t uid), (override));
MOCK_METHOD(ndk::ScopedAStatus, getHintSessionPreferredRate, (int64_t * rate), (override));
MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t * version), (override));
MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string * hash), (override));
diff --git a/services/sensorservice/senserservice_flags.aconfig b/services/sensorservice/senserservice_flags.aconfig
index 6b74f6f..a3bd0ee 100644
--- a/services/sensorservice/senserservice_flags.aconfig
+++ b/services/sensorservice/senserservice_flags.aconfig
@@ -5,4 +5,11 @@
namespace: "sensors"
description: "This flag controls if the dynamic sensor data will be clean up after HAL is disconnected."
bug: "307782607"
+}
+
+flag {
+ name: "sensor_device_on_dynamic_sensor_disconnected"
+ namespace: "sensors"
+ description: "This flag controls if the callback onDynamicSensorsDisconnected is implemented or not."
+ bug: "316958439"
}
\ No newline at end of file
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 5e84be1..c71c517 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -40,6 +40,9 @@
// True if the display is secure
virtual bool isSecure() const = 0;
+ // Sets the secure flag for the display
+ virtual void setSecure(bool secure) = 0;
+
// True if the display is virtual
virtual bool isVirtual() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index eac5d97..c53b461 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -74,6 +74,7 @@
void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
void createClientCompositionCache(uint32_t cacheSize) override;
void applyDisplayBrightness(const bool applyImmediately) override;
+ void setSecure(bool secure) override;
// Internal helpers used by chooseCompositionStrategy()
using ChangedTypes = android::HWComposer::DeviceRequestedChanges::ChangedTypes;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 7e99ec2..46cb95e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -33,6 +33,7 @@
MOCK_CONST_METHOD0(getId, DisplayId());
MOCK_CONST_METHOD0(isSecure, bool());
+ MOCK_METHOD1(setSecure, void(bool));
MOCK_CONST_METHOD0(isVirtual, bool());
MOCK_CONST_METHOD0(getPreferredBootHwcConfigId, int32_t());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 690d35f..d907bf5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -74,6 +74,10 @@
return getState().isSecure;
}
+void Display::setSecure(bool secure) {
+ editState().isSecure = secure;
+}
+
bool Display::isVirtual() const {
return VirtualDisplayId::tryCast(mId).has_value();
}
@@ -246,7 +250,6 @@
}
// Get any composition changes requested by the HWC device, and apply them.
- std::optional<android::HWComposer::DeviceRequestedChanges> changes;
auto& hwc = getCompositionEngine().getHwComposer();
const bool requiresClientComposition = anyLayersRequireClientComposition();
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
index a18397d..91cfe5d 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
@@ -56,7 +56,7 @@
}
// Do not unflatten if source crop is only moved.
- if (FlagManager::getInstance().cache_if_source_crop_layer_only_moved() &&
+ if (FlagManager::getInstance().cache_when_source_crop_layer_only_moved() &&
incomingLayers[i]->isSourceCropSizeEqual(*(existingLayers[i])) &&
incomingLayers[i]->getDifferingFields(*(existingLayers[i])) ==
LayerStateField::SourceCrop) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index bf7ed87..30ba9e4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -4094,7 +4094,11 @@
};
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
- mOutput.mState.isSecure = true;
+ if (FlagManager::getInstance().display_protected()) {
+ mOutput.mState.isProtected = true;
+ } else {
+ mOutput.mState.isSecure = true;
+ }
mLayer2.mLayerFEState.hasProtectedContent = false;
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
@@ -4108,7 +4112,11 @@
}
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
- mOutput.mState.isSecure = true;
+ if (FlagManager::getInstance().display_protected()) {
+ mOutput.mState.isProtected = true;
+ } else {
+ mOutput.mState.isSecure = true;
+ }
mLayer2.mLayerFEState.hasProtectedContent = true;
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
@@ -4130,7 +4138,11 @@
}
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
- mOutput.mState.isSecure = true;
+ if (FlagManager::getInstance().display_protected()) {
+ mOutput.mState.isProtected = true;
+ } else {
+ mOutput.mState.isSecure = true;
+ }
mLayer2.mLayerFEState.hasProtectedContent = true;
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
@@ -4143,7 +4155,11 @@
}
TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
- mOutput.mState.isSecure = true;
+ if (FlagManager::getInstance().display_protected()) {
+ mOutput.mState.isProtected = true;
+ } else {
+ mOutput.mState.isSecure = true;
+ }
mLayer2.mLayerFEState.hasProtectedContent = true;
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
@@ -4222,6 +4238,7 @@
GenerateClientCompositionRequestsTest() {
mOutput.mState.needsFiltering = false;
+ mOutput.mState.isProtected = true;
mOutput.setDisplayColorProfileForTest(
std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
@@ -4246,6 +4263,7 @@
mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
mOutput.mState.needsFiltering = false;
mOutput.mState.isSecure = false;
+ mOutput.mState.isProtected = true;
for (size_t i = 0; i < mLayers.size(); i++) {
mLayers[i].mOutputLayerState.clearClientTarget = false;
@@ -4708,7 +4726,7 @@
Region(kDisplayFrame),
false, /* needs filtering */
false, /* secure */
- true, /* supports protected content */
+ true, /* isProtected */
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4721,7 +4739,7 @@
Region(kDisplayFrame),
false, /* needs filtering */
false, /* secure */
- true, /* supports protected content */
+ true, /* isProtected */
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4734,7 +4752,7 @@
Region(kDisplayFrame),
false, /* needs filtering */
false, /* secure */
- true, /* supports protected content */
+ true, /* isProtected */
kDisplayViewport,
kDisplayDataspace,
true /* realContentIsVisible */,
@@ -4912,7 +4930,7 @@
Region(Rect(0, 0, 1000, 1000)),
false, /* needs filtering */
true, /* secure */
- true, /* supports protected content */
+ true, /* isProtected */
kPortraitViewport,
kOutputDataspace,
true /* realContentIsVisible */,
@@ -4931,7 +4949,7 @@
Region(Rect(1000, 0, 2000, 1000)),
false, /* needs filtering */
true, /* secure */
- true, /* supports protected content */
+ true, /* isProtected */
kPortraitViewport,
kOutputDataspace,
true /* realContentIsVisible */,
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
index 763b998..d2eff75 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
@@ -244,7 +244,7 @@
TEST_F(FlattenerTest, unflattenLayers_onlySourceCropMoved) {
SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::
- cache_if_source_crop_layer_only_moved,
+ cache_when_source_crop_layer_only_moved,
true);
auto& layerState1 = mTestLayers[0]->layerState;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 950b05e..799d62c 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -353,6 +353,10 @@
return mCompositionDisplay->isSecure();
}
+void DisplayDevice::setSecure(bool secure) {
+ mCompositionDisplay->setSecure(secure);
+}
+
const Rect DisplayDevice::getBounds() const {
return mCompositionDisplay->getState().displaySpace.getBoundsAsRect();
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index ac390cb..97b56a2 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -95,6 +95,7 @@
// isSecure indicates whether this display can be trusted to display
// secure surfaces.
bool isSecure() const;
+ void setSecure(bool secure);
int getWidth() const;
int getHeight() const;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 24a9e22..704ece5 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -165,8 +165,7 @@
auto intError = mComposer.getChangedCompositionTypes(
mId, &layerIds, &types);
uint32_t numElements = layerIds.size();
- auto error = static_cast<Error>(intError);
- error = static_cast<Error>(intError);
+ const auto error = static_cast<Error>(intError);
if (error != Error::NONE) {
return error;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 3ffd8ea..cf1c3c1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -77,6 +77,8 @@
using aidl::android::hardware::graphics::common::HdrConversionStrategy;
using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
+using aidl::android::hardware::graphics::composer3::VrrConfig;
+using namespace std::string_literals;
namespace hal = android::hardware::graphics::composer::hal;
namespace android {
@@ -89,7 +91,8 @@
: mComposer(std::move(composer)),
mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
mUpdateDeviceProductInfoOnHotplugReconnect(
- sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
+ sysprop::update_device_product_info_on_hotplug_reconnect(false)),
+ mEnableVrrTimeout(base::GetBoolProperty("debug.sf.vrr_timeout_hint_enabled"s, false)) {}
HWComposer::HWComposer(const std::string& composerServiceName)
: HWComposer(Hwc2::Composer::create(composerServiceName)) {}
@@ -299,6 +302,10 @@
hwcMode.dpiY = config.dpi->y;
}
+ if (!mEnableVrrTimeout) {
+ hwcMode.vrrConfig->notifyExpectedPresentConfig = {};
+ }
+
modes.push_back(hwcMode);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 4ca528a..fb32ff4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -491,6 +491,7 @@
private:
// For unit tests
friend TestableSurfaceFlinger;
+ friend HWComposerTest;
struct DisplayData {
std::unique_ptr<HWC2::Display> hwcDisplay;
@@ -542,6 +543,7 @@
const size_t mMaxVirtualDisplayDimension;
const bool mUpdateDeviceProductInfoOnHotplugReconnect;
+ bool mEnableVrrTimeout;
};
} // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/Hal.h b/services/surfaceflinger/DisplayHardware/Hal.h
index 31c2833..e3d9622 100644
--- a/services/surfaceflinger/DisplayHardware/Hal.h
+++ b/services/surfaceflinger/DisplayHardware/Hal.h
@@ -169,10 +169,8 @@
out << "}, ";
out << "notifyExpectedPresentConfig={";
if (vrrConfig->notifyExpectedPresentConfig) {
- out << "notifyExpectedPresentHeadsUpNs="
- << vrrConfig->notifyExpectedPresentConfig->notifyExpectedPresentHeadsUpNs
- << ", notifyExpectedPresentTimeoutNs="
- << vrrConfig->notifyExpectedPresentConfig->notifyExpectedPresentTimeoutNs;
+ out << "headsUpNs=" << vrrConfig->notifyExpectedPresentConfig->headsUpNs
+ << ", timeoutNs=" << vrrConfig->notifyExpectedPresentConfig->timeoutNs;
}
out << "}}";
return out.str();
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index dd228b4..a0c943b 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -31,10 +31,6 @@
#include <utils/Mutex.h>
#include <utils/Trace.h>
-#include <aidl/android/hardware/power/IPower.h>
-#include <aidl/android/hardware/power/IPowerHintSession.h>
-#include <aidl/android/hardware/power/WorkDuration.h>
-
#include <binder/IServiceManager.h>
#include "../SurfaceFlingerProperties.h"
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 0276e44..bbe51cc0 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -25,9 +25,14 @@
#include <ui/FenceTime.h>
#include <utils/Mutex.h>
+// FMQ library in IPower does questionable conversions
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
#include <aidl/android/hardware/power/IPower.h>
-#include <compositionengine/impl/OutputCompositionState.h>
#include <powermanager/PowerHalController.h>
+#pragma clang diagnostic pop
+
+#include <compositionengine/impl/OutputCompositionState.h>
#include <scheduler/Time.h>
#include <ui/DisplayIdentification.h>
#include "../Scheduler/OneShotTimer.h"
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 803299c..d0e2d7a 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -390,6 +390,22 @@
mGpuComposition = true;
}
+// TODO(b/316171339): migrate from perfetto side
+bool SurfaceFrame::isSelfJanky() const {
+ int32_t jankType = getJankType().value_or(JankType::None);
+
+ if (jankType == JankType::None) {
+ return false;
+ }
+
+ int32_t jankBitmask = JankType::AppDeadlineMissed | JankType::Unknown;
+ if (jankType & jankBitmask) {
+ return true;
+ }
+
+ return false;
+}
+
std::optional<int32_t> SurfaceFrame::getJankType() const {
std::scoped_lock lock(mMutex);
if (mPresentState == PresentState::Dropped) {
@@ -1113,20 +1129,23 @@
}
void FrameTimeline::DisplayFrame::addSkippedFrame(pid_t surfaceFlingerPid, nsecs_t monoBootOffset,
- nsecs_t previousActualPresentTime) const {
+ nsecs_t previousPredictionPresentTime) const {
nsecs_t skippedFrameStartTime = 0, skippedFramePresentTime = 0;
const constexpr float kThresh = 0.5f;
const constexpr float kRange = 1.5f;
for (auto& surfaceFrame : mSurfaceFrames) {
- if (previousActualPresentTime != 0 &&
- static_cast<float>(mSurfaceFlingerActuals.presentTime - previousActualPresentTime) >=
+ if (previousPredictionPresentTime != 0 &&
+ static_cast<float>(mSurfaceFlingerPredictions.presentTime -
+ previousPredictionPresentTime) >=
static_cast<float>(mRenderRate.getPeriodNsecs()) * kRange &&
static_cast<float>(surfaceFrame->getPredictions().presentTime) <=
- (static_cast<float>(mSurfaceFlingerActuals.presentTime) -
+ (static_cast<float>(mSurfaceFlingerPredictions.presentTime) -
kThresh * static_cast<float>(mRenderRate.getPeriodNsecs())) &&
static_cast<float>(surfaceFrame->getPredictions().presentTime) >=
- (static_cast<float>(previousActualPresentTime) -
- kThresh * static_cast<float>(mRenderRate.getPeriodNsecs()))) {
+ (static_cast<float>(previousPredictionPresentTime) -
+ kThresh * static_cast<float>(mRenderRate.getPeriodNsecs())) &&
+ // sf skipped frame is not considered if app is self janked
+ !surfaceFrame->isSelfJanky()) {
skippedFrameStartTime = surfaceFrame->getPredictions().endTime;
skippedFramePresentTime = surfaceFrame->getPredictions().presentTime;
break;
@@ -1215,18 +1234,18 @@
});
}
-void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset,
- nsecs_t previousActualPresentTime) const {
+nsecs_t FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset,
+ nsecs_t previousPredictionPresentTime) const {
if (mSurfaceFrames.empty()) {
// We don't want to trace display frames without any surface frames updates as this cannot
// be janky
- return;
+ return previousPredictionPresentTime;
}
if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) {
// DisplayFrame should not have an invalid token.
ALOGE("Cannot trace DisplayFrame with invalid token");
- return;
+ return previousPredictionPresentTime;
}
if (mPredictionState == PredictionState::Valid) {
@@ -1241,8 +1260,9 @@
}
if (FlagManager::getInstance().add_sf_skipped_frames_to_trace()) {
- addSkippedFrame(surfaceFlingerPid, monoBootOffset, previousActualPresentTime);
+ addSkippedFrame(surfaceFlingerPid, monoBootOffset, previousPredictionPresentTime);
}
+ return mSurfaceFlingerPredictions.presentTime;
}
float FrameTimeline::computeFps(const std::unordered_set<int32_t>& layerIds) {
@@ -1333,8 +1353,9 @@
const auto& pendingPresentFence = *mPendingPresentFences.begin();
const nsecs_t signalTime = Fence::SIGNAL_TIME_INVALID;
auto& displayFrame = pendingPresentFence.second;
- displayFrame->onPresent(signalTime, mPreviousPresentTime);
- displayFrame->trace(mSurfaceFlingerPid, monoBootOffset, mPreviousPresentTime);
+ displayFrame->onPresent(signalTime, mPreviousActualPresentTime);
+ mPreviousPredictionPresentTime = displayFrame->trace(mSurfaceFlingerPid, monoBootOffset,
+ mPreviousPredictionPresentTime);
mPendingPresentFences.erase(mPendingPresentFences.begin());
}
@@ -1349,9 +1370,10 @@
}
auto& displayFrame = pendingPresentFence.second;
- displayFrame->onPresent(signalTime, mPreviousPresentTime);
- displayFrame->trace(mSurfaceFlingerPid, monoBootOffset, mPreviousPresentTime);
- mPreviousPresentTime = signalTime;
+ displayFrame->onPresent(signalTime, mPreviousActualPresentTime);
+ mPreviousPredictionPresentTime = displayFrame->trace(mSurfaceFlingerPid, monoBootOffset,
+ mPreviousPredictionPresentTime);
+ mPreviousActualPresentTime = signalTime;
mPendingPresentFences.erase(mPendingPresentFences.begin() + static_cast<int>(i));
--i;
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index b5047a3..a76f7d4 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -165,6 +165,8 @@
TraceCookieCounter* traceCookieCounter, bool isBuffer, GameMode);
~SurfaceFrame() = default;
+ bool isSelfJanky() const;
+
// Returns std::nullopt if the frame hasn't been classified yet.
// Used by both SF and FrameTimeline.
std::optional<int32_t> getJankType() const;
@@ -381,8 +383,8 @@
// Emits a packet for perfetto tracing. The function body will be executed only if tracing
// is enabled. monoBootOffset is the difference between SYSTEM_TIME_BOOTTIME
// and SYSTEM_TIME_MONOTONIC.
- void trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset,
- nsecs_t previousActualPresentTime) const;
+ nsecs_t trace(pid_t surfaceFlingerPid, nsecs_t monoBootOffset,
+ nsecs_t previousPredictionPresentTime) const;
// Sets the token, vsyncPeriod, predictions and SF start time.
void onSfWakeUp(int64_t token, Fps refreshRate, Fps renderRate,
std::optional<TimelineItem> predictions, nsecs_t wakeUpTime);
@@ -508,7 +510,8 @@
uint32_t mMaxDisplayFrames;
std::shared_ptr<TimeStats> mTimeStats;
const pid_t mSurfaceFlingerPid;
- nsecs_t mPreviousPresentTime = 0;
+ nsecs_t mPreviousActualPresentTime = 0;
+ nsecs_t mPreviousPredictionPresentTime = 0;
const JankClassificationThresholds mJankClassificationThresholds;
static constexpr uint32_t kDefaultMaxDisplayFrames = 64;
// The initial container size for the vector<SurfaceFrames> inside display frame. Although
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
index 1e5a6fb..821ac0c 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
@@ -190,8 +190,12 @@
return outInvalidRelativeRoot != UNASSIGNED_LAYER_ID;
}
-LayerHierarchyBuilder::LayerHierarchyBuilder(
- const std::vector<std::unique_ptr<RequestedLayerState>>& layers) {
+void LayerHierarchyBuilder::init(const std::vector<std::unique_ptr<RequestedLayerState>>& layers) {
+ mLayerIdToHierarchy.clear();
+ mHierarchies.clear();
+ mRoot = nullptr;
+ mOffscreenRoot = nullptr;
+
mHierarchies.reserve(layers.size());
mLayerIdToHierarchy.reserve(layers.size());
for (auto& layer : layers) {
@@ -202,6 +206,7 @@
onLayerAdded(layer.get());
}
detachHierarchyFromRelativeParent(&mOffscreenRoot);
+ mInitialized = true;
}
void LayerHierarchyBuilder::attachToParent(LayerHierarchy* hierarchy) {
@@ -332,7 +337,7 @@
}
}
-void LayerHierarchyBuilder::update(
+void LayerHierarchyBuilder::doUpdate(
const std::vector<std::unique_ptr<RequestedLayerState>>& layers,
const std::vector<std::unique_ptr<RequestedLayerState>>& destroyedLayers) {
// rebuild map
@@ -381,6 +386,32 @@
attachHierarchyToRelativeParent(&mRoot);
}
+void LayerHierarchyBuilder::update(LayerLifecycleManager& layerLifecycleManager) {
+ if (!mInitialized) {
+ ATRACE_NAME("LayerHierarchyBuilder:init");
+ init(layerLifecycleManager.getLayers());
+ } else if (layerLifecycleManager.getGlobalChanges().test(
+ RequestedLayerState::Changes::Hierarchy)) {
+ ATRACE_NAME("LayerHierarchyBuilder:update");
+ doUpdate(layerLifecycleManager.getLayers(), layerLifecycleManager.getDestroyedLayers());
+ } else {
+ return; // nothing to do
+ }
+
+ uint32_t invalidRelativeRoot;
+ bool hasRelZLoop = mRoot.hasRelZLoop(invalidRelativeRoot);
+ while (hasRelZLoop) {
+ ATRACE_NAME("FixRelZLoop");
+ TransactionTraceWriter::getInstance().invoke("relz_loop_detected",
+ /*overwrite=*/false);
+ layerLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
+ // reinitialize the hierarchy with the updated layer data
+ init(layerLifecycleManager.getLayers());
+ // check if we have any remaining loops
+ hasRelZLoop = mRoot.hasRelZLoop(invalidRelativeRoot);
+ }
+}
+
const LayerHierarchy& LayerHierarchyBuilder::getHierarchy() const {
return mRoot;
}
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
index ba2e262..a1c73c3 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
@@ -17,6 +17,7 @@
#pragma once
#include "FrontEnd/LayerCreationArgs.h"
+#include "FrontEnd/LayerLifecycleManager.h"
#include "RequestedLayerState.h"
#include "ftl/small_vector.h"
@@ -197,9 +198,8 @@
// hierarchy from a list of RequestedLayerState and associated change flags.
class LayerHierarchyBuilder {
public:
- LayerHierarchyBuilder(const std::vector<std::unique_ptr<RequestedLayerState>>&);
- void update(const std::vector<std::unique_ptr<RequestedLayerState>>& layers,
- const std::vector<std::unique_ptr<RequestedLayerState>>& destroyedLayers);
+ LayerHierarchyBuilder() = default;
+ void update(LayerLifecycleManager& layerLifecycleManager);
LayerHierarchy getPartialHierarchy(uint32_t, bool childrenOnly) const;
const LayerHierarchy& getHierarchy() const;
const LayerHierarchy& getOffscreenHierarchy() const;
@@ -213,14 +213,18 @@
void detachFromRelativeParent(LayerHierarchy*);
void attachHierarchyToRelativeParent(LayerHierarchy*);
void detachHierarchyFromRelativeParent(LayerHierarchy*);
-
+ void init(const std::vector<std::unique_ptr<RequestedLayerState>>&);
+ void doUpdate(const std::vector<std::unique_ptr<RequestedLayerState>>& layers,
+ const std::vector<std::unique_ptr<RequestedLayerState>>& destroyedLayers);
void onLayerDestroyed(RequestedLayerState* layer);
void updateMirrorLayer(RequestedLayerState* layer);
LayerHierarchy* getHierarchyFromId(uint32_t layerId, bool crashOnFailure = true);
+
std::unordered_map<uint32_t, LayerHierarchy*> mLayerIdToHierarchy;
std::vector<std::unique_ptr<LayerHierarchy>> mHierarchies;
LayerHierarchy mRoot{nullptr};
LayerHierarchy mOffscreenRoot{nullptr};
+ bool mInitialized = false;
};
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 693a357..6e862b4 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -100,6 +100,11 @@
case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
to_string(event.header.displayId).c_str(), event.modeChange.modeId);
+ case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ return StringPrintf("HdcpLevelsChange{displayId=%s, connectedLevel=%d, maxLevel=%d}",
+ to_string(event.header.displayId).c_str(),
+ event.hdcpLevelsChange.connectedLevel,
+ event.hdcpLevelsChange.maxLevel);
default:
return "Event{}";
}
@@ -170,6 +175,20 @@
}};
}
+DisplayEventReceiver::Event makeHdcpLevelsChange(PhysicalDisplayId displayId,
+ int32_t connectedLevel, int32_t maxLevel) {
+ return DisplayEventReceiver::Event{
+ .header =
+ DisplayEventReceiver::Event::Header{
+ .type = DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE,
+ .displayId = displayId,
+ .timestamp = systemTime(),
+ },
+ .hdcpLevelsChange.connectedLevel = connectedLevel,
+ .hdcpLevelsChange.maxLevel = maxLevel,
+ };
+}
+
} // namespace
EventThreadConnection::EventThreadConnection(EventThread* eventThread, uid_t callingUid,
@@ -301,7 +320,7 @@
mVsyncRegistration.update({.workDuration = mWorkDuration.get().count(),
.readyDuration = mReadyDuration.count(),
- .earliestVsync = mLastVsyncCallbackTime.ns()});
+ .lastVsync = mLastVsyncCallbackTime.ns()});
}
sp<EventThreadConnection> EventThread::createEventConnection(
@@ -442,6 +461,14 @@
mCondition.notify_all();
}
+void EventThread::onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ mPendingEvents.push_back(makeHdcpLevelsChange(displayId, connectedLevel, maxLevel));
+ mCondition.notify_all();
+}
+
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
@@ -501,7 +528,7 @@
const auto scheduleResult =
mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
.readyDuration = mReadyDuration.count(),
- .earliestVsync = mLastVsyncCallbackTime.ns()});
+ .lastVsync = mLastVsyncCallbackTime.ns()});
LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");
} else {
mVsyncRegistration.cancel();
@@ -757,7 +784,7 @@
if (reschedule) {
mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
.readyDuration = mReadyDuration.count(),
- .earliestVsync = mLastVsyncCallbackTime.ns()});
+ .lastVsync = mLastVsyncCallbackTime.ns()});
}
return oldRegistration;
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 7842318..8970103 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -131,6 +131,9 @@
const sp<EventThreadConnection>& connection) const = 0;
virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;
+
+ virtual void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) = 0;
};
struct IEventThreadCallback {
@@ -177,6 +180,9 @@
void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex);
+ void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
+ int32_t maxLevel) override;
+
private:
friend EventThreadTest;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 18c0a69..cf8b3bf 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -125,7 +125,7 @@
mVsync.scheduledFrameTime =
mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
- .earliestVsync = mVsync.lastCallbackTime.ns()});
+ .lastVsync = mVsync.lastCallbackTime.ns()});
}
return oldRegistration;
}
@@ -143,7 +143,7 @@
mVsync.scheduledFrameTime =
mVsync.registration->update({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
- .earliestVsync = mVsync.lastCallbackTime.ns()});
+ .lastVsync = mVsync.lastCallbackTime.ns()});
}
void MessageQueue::waitMessage() {
@@ -196,7 +196,7 @@
mVsync.scheduledFrameTime =
mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
- .earliestVsync = mVsync.lastCallbackTime.ns()});
+ .lastVsync = mVsync.lastCallbackTime.ns()});
}
auto MessageQueue::getScheduledFrameTime() const -> std::optional<Clock::time_point> {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index ce59a04..bfc47e6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -412,6 +412,17 @@
thread->onFrameRateOverridesChanged(displayId, std::move(overrides));
}
+void Scheduler::onHdcpLevelsChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
+ int32_t connectedLevel, int32_t maxLevel) {
+ android::EventThread* thread;
+ {
+ std::lock_guard<std::mutex> lock(mConnectionsLock);
+ RETURN_IF_INVALID_HANDLE(handle);
+ thread = mConnections[handle].thread.get();
+ }
+ thread->onHdcpLevelsChanged(displayId, connectedLevel, maxLevel);
+}
+
void Scheduler::onPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
{
std::lock_guard<std::mutex> lock(mPolicyLock);
@@ -600,8 +611,10 @@
const Display& display = *displayOpt;
const nsecs_t threshold =
display.selectorPtr->getActiveMode().modePtr->getVsyncRate().getPeriodNsecs() / 2;
- const nsecs_t nextVsyncTime = display.schedulePtr->getTracker().nextAnticipatedVSyncTimeFrom(
- currentExpectedPresentTime.ns() + threshold);
+ const nsecs_t nextVsyncTime =
+ display.schedulePtr->getTracker()
+ .nextAnticipatedVSyncTimeFrom(currentExpectedPresentTime.ns() + threshold,
+ currentExpectedPresentTime.ns());
return Fps::fromPeriodNsecs(nextVsyncTime - currentExpectedPresentTime.ns());
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ce585c6..a29d153 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -173,6 +173,8 @@
void onFrameRateOverridesChanged(ConnectionHandle, PhysicalDisplayId)
EXCLUDES(mConnectionsLock);
+ void onHdcpLevelsChanged(ConnectionHandle, PhysicalDisplayId, int32_t, int32_t);
+
// Modifies work duration in the event thread.
void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration);
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatch.h b/services/surfaceflinger/Scheduler/VSyncDispatch.h
index c3a952f..f978016 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatch.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatch.h
@@ -84,8 +84,8 @@
* able to provide the ready-by time (deadline) on the callback.
* For internal clients, we don't need to add additional padding, so
* readyDuration will typically be 0.
- * @earliestVsync: The targeted display time. This will be snapped to the closest
- * predicted vsync time after earliestVsync.
+ * @lastVsync: The targeted display time. This will be snapped to the closest
+ * predicted vsync time after lastVsync.
*
* callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync
* event.
@@ -93,11 +93,11 @@
struct ScheduleTiming {
nsecs_t workDuration = 0;
nsecs_t readyDuration = 0;
- nsecs_t earliestVsync = 0;
+ nsecs_t lastVsync = 0;
bool operator==(const ScheduleTiming& other) const {
return workDuration == other.workDuration && readyDuration == other.readyDuration &&
- earliestVsync == other.earliestVsync;
+ lastVsync == other.lastVsync;
}
bool operator!=(const ScheduleTiming& other) const { return !(*this == other); }
@@ -109,12 +109,12 @@
* The callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync
* event.
*
- * The caller designates the earliest vsync event that should be targeted by the earliestVsync
+ * The caller designates the earliest vsync event that should be targeted by the lastVsync
* parameter.
* The callback will be scheduled at (workDuration + readyDuration - predictedVsync), where
- * predictedVsync is the first vsync event time where ( predictedVsync >= earliestVsync ).
+ * predictedVsync is the first vsync event time where ( predictedVsync >= lastVsync ).
*
- * If (workDuration + readyDuration - earliestVsync) is in the past, or if a callback has
+ * If (workDuration + readyDuration - lastVsync) is in the past, or if a callback has
* already been dispatched for the predictedVsync, an error will be returned.
*
* It is valid to reschedule a callback to a different time.
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index ef30887..5cb0ffb 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -45,8 +45,11 @@
nsecs_t getExpectedCallbackTime(VSyncTracker& tracker, nsecs_t now,
const VSyncDispatch::ScheduleTiming& timing) {
- const auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
- std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
+ const auto nextVsyncTime =
+ tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
+ now + timing.workDuration +
+ timing.readyDuration),
+ timing.lastVsync);
return getExpectedCallbackTime(nextVsyncTime, timing);
}
@@ -93,8 +96,11 @@
ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
VSyncTracker& tracker, nsecs_t now) {
- auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
- std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
+ auto nextVsyncTime =
+ tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
+ now + timing.workDuration +
+ timing.readyDuration),
+ timing.lastVsync);
auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
bool const wouldSkipAVsyncTarget =
@@ -139,11 +145,13 @@
bool const nextVsyncTooClose = mLastDispatchTime &&
(nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod;
if (alreadyDispatchedForVsync) {
- return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance);
+ return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance,
+ *mLastDispatchTime);
}
if (nextVsyncTooClose) {
- return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod);
+ return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod,
+ *mLastDispatchTime + currentPeriod);
}
return nextVsyncTime;
@@ -160,11 +168,12 @@
}
const auto earliestReadyBy = now + mScheduleTiming.workDuration + mScheduleTiming.readyDuration;
- const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.earliestVsync);
+ const auto earliestVsync = std::max(earliestReadyBy, mScheduleTiming.lastVsync);
const auto nextVsyncTime =
adjustVsyncIfNeeded(tracker, /*nextVsyncTime*/
- tracker.nextAnticipatedVSyncTimeFrom(earliestVsync));
+ tracker.nextAnticipatedVSyncTimeFrom(earliestVsync,
+ mScheduleTiming.lastVsync));
const auto nextReadyTime = nextVsyncTime - mScheduleTiming.readyDuration;
const auto nextWakeupTime = nextReadyTime - mScheduleTiming.workDuration;
@@ -214,10 +223,10 @@
StringAppendF(&result, "\t\t%s: %s %s\n", mName.c_str(),
mRunning ? "(in callback function)" : "", armedInfo.c_str());
StringAppendF(&result,
- "\t\t\tworkDuration: %.2fms readyDuration: %.2fms earliestVsync: %.2fms relative "
+ "\t\t\tworkDuration: %.2fms readyDuration: %.2fms lastVsync: %.2fms relative "
"to now\n",
mScheduleTiming.workDuration / 1e6f, mScheduleTiming.readyDuration / 1e6f,
- (mScheduleTiming.earliestVsync - systemTime()) / 1e6f);
+ (mScheduleTiming.lastVsync - systemTime()) / 1e6f);
if (mLastDispatchTime) {
StringAppendF(&result, "\t\t\tmLastDispatchTime: %.2fms ago\n",
@@ -237,6 +246,7 @@
VSyncDispatchTimerQueue::~VSyncDispatchTimerQueue() {
std::lock_guard lock(mMutex);
+ mRunning = false;
cancelTimer();
for (auto& [_, entry] : mCallbacks) {
ALOGE("Forgot to unregister a callback on VSyncDispatch!");
@@ -305,6 +315,10 @@
std::vector<Invocation> invocations;
{
std::lock_guard lock(mMutex);
+ if (!mRunning) {
+ ALOGD("TimerQueue is not running. Skipping callback.");
+ return;
+ }
auto const now = mTimeKeeper->now();
mLastTimerCallback = now;
for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
index e0fb8f9..3d08410 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
@@ -148,6 +148,10 @@
std::mutex mutable mMutex;
+ // During VSyncDispatchTimerQueue deconstruction, skip timerCallback to
+ // avoid crash
+ bool mRunning = true;
+
static constexpr nsecs_t kInvalidTime = std::numeric_limits<int64_t>::max();
std::unique_ptr<TimeKeeper> const mTimeKeeper;
VsyncSchedule::TrackerPtr mTracker;
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 0d79a39..28e35de 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -253,7 +253,7 @@
}
auto VSyncPredictor::getVsyncSequenceLocked(nsecs_t timestamp) const -> VsyncSequence {
- const auto vsync = nextAnticipatedVSyncTimeFromLocked(timestamp);
+ const auto vsync = snapToVsync(timestamp);
if (!mLastVsyncSequence) return {vsync, 0};
const auto [slope, _] = getVSyncPredictionModelLocked();
@@ -263,7 +263,7 @@
return {vsync, vsyncSequence};
}
-nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFromLocked(nsecs_t timePoint) const {
+nsecs_t VSyncPredictor::snapToVsync(nsecs_t timePoint) const {
auto const [slope, intercept] = getVSyncPredictionModelLocked();
if (mTimestamps.empty()) {
@@ -299,9 +299,29 @@
return prediction;
}
-nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const {
+nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint,
+ std::optional<nsecs_t> lastVsyncOpt) const {
+ ATRACE_CALL();
std::lock_guard lock(mMutex);
+ const auto currentPeriod = mRateMap.find(idealPeriod())->second.slope;
+ const auto threshold = currentPeriod / 2;
+ const auto minFramePeriod = minFramePeriodLocked().ns();
+ const auto lastFrameMissed =
+ lastVsyncOpt && std::abs(*lastVsyncOpt - mLastMissedVsync.ns()) < threshold;
+ const nsecs_t baseTime =
+ FlagManager::getInstance().vrr_config() && !lastFrameMissed && lastVsyncOpt
+ ? std::max(timePoint, *lastVsyncOpt + minFramePeriod - threshold)
+ : timePoint;
+ const auto vsyncTime = snapToVsyncAlignedWithRenderRate(baseTime);
+ if (FlagManager::getInstance().vrr_config()) {
+ const auto vsyncTimePoint = TimePoint::fromNs(vsyncTime);
+ const Fps renderRate = mRenderRateOpt ? *mRenderRateOpt : mDisplayModePtr->getPeakFps();
+ mVsyncTrackerCallback.onVsyncGenerated(vsyncTimePoint, mDisplayModePtr, renderRate);
+ }
+ return vsyncTime;
+}
+nsecs_t VSyncPredictor::snapToVsyncAlignedWithRenderRate(nsecs_t timePoint) const {
// update the mLastVsyncSequence for reference point
mLastVsyncSequence = getVsyncSequenceLocked(timePoint);
@@ -325,30 +345,12 @@
}();
if (renderRatePhase == 0) {
- const auto vsyncTime = mLastVsyncSequence->vsyncTime;
- if (FlagManager::getInstance().vrr_config()) {
- const auto vsyncTimePoint = TimePoint::fromNs(vsyncTime);
- ATRACE_FORMAT("%s InPhase vsyncIn %.2fms", __func__,
- ticks<std::milli, float>(vsyncTimePoint - TimePoint::now()));
- const Fps renderRate = mRenderRateOpt ? *mRenderRateOpt : mDisplayModePtr->getPeakFps();
- mVsyncTrackerCallback.onVsyncGenerated(vsyncTimePoint, mDisplayModePtr, renderRate);
- }
- return vsyncTime;
+ return mLastVsyncSequence->vsyncTime;
}
auto const [slope, intercept] = getVSyncPredictionModelLocked();
const auto approximateNextVsync = mLastVsyncSequence->vsyncTime + slope * renderRatePhase;
- const auto nextAnticipatedVsyncTime =
- nextAnticipatedVSyncTimeFromLocked(approximateNextVsync - slope / 2);
- if (FlagManager::getInstance().vrr_config()) {
- const auto nextAnticipatedVsyncTimePoint = TimePoint::fromNs(nextAnticipatedVsyncTime);
- ATRACE_FORMAT("%s outOfPhase vsyncIn %.2fms", __func__,
- ticks<std::milli, float>(nextAnticipatedVsyncTimePoint - TimePoint::now()));
- const Fps renderRate = mRenderRateOpt ? *mRenderRateOpt : mDisplayModePtr->getPeakFps();
- mVsyncTrackerCallback.onVsyncGenerated(nextAnticipatedVsyncTimePoint, mDisplayModePtr,
- renderRate);
- }
- return nextAnticipatedVsyncTime;
+ return snapToVsync(approximateNextVsync - slope / 2);
}
/*
@@ -403,7 +405,7 @@
: std::nullopt;
ALOGV("%s %s: DisplayMode %s notifyExpectedPresentTimeout %s", __func__, to_string(mId).c_str(),
to_string(*modePtr).c_str(),
- timeout ? std::to_string(timeout->notifyExpectedPresentTimeoutNs).c_str() : "N/A");
+ timeout ? std::to_string(timeout->timeoutNs).c_str() : "N/A");
std::lock_guard lock(mMutex);
mDisplayModePtr = modePtr;
@@ -451,6 +453,7 @@
if (mLastVsyncSequence) {
mLastVsyncSequence->vsyncTime += phase.ns();
}
+ mPastExpectedPresentTimes.clear();
}
}
}
@@ -468,23 +471,17 @@
lastConfirmedPresentTime.ns()) /
1e6f);
}
- mPastExpectedPresentTimes.push_back(expectedPresentTime);
-
const auto currentPeriod = mRateMap.find(idealPeriod())->second.slope;
const auto threshold = currentPeriod / 2;
+ mPastExpectedPresentTimes.push_back(expectedPresentTime);
- const auto minFramePeriod = minFramePeriodLocked().ns();
while (!mPastExpectedPresentTimes.empty()) {
const auto front = mPastExpectedPresentTimes.front().ns();
- const bool frontIsLastConfirmed =
- std::abs(front - lastConfirmedPresentTime.ns()) < threshold;
- const bool frontIsBeforeConfirmed =
- front < lastConfirmedPresentTime.ns() - minFramePeriod + threshold;
- if (frontIsLastConfirmed || frontIsBeforeConfirmed) {
+ const bool frontIsBeforeConfirmed = front < lastConfirmedPresentTime.ns() + threshold;
+ if (frontIsBeforeConfirmed) {
if (CC_UNLIKELY(mTraceOn)) {
ATRACE_FORMAT_INSTANT("Discarding old vsync - %.2f before last signaled fence",
- static_cast<float>(lastConfirmedPresentTime.ns() -
- mPastExpectedPresentTimes.front().ns()) /
+ static_cast<float>(lastConfirmedPresentTime.ns() - front) /
1e6f);
}
mPastExpectedPresentTimes.pop_front();
@@ -508,6 +505,7 @@
TimePoint::fromNs(expectedPresentTime.ns() + currentPeriod);
ensureMinFrameDurationIsKept(expectedPresentTime, lastConfirmedPresentTime);
+ mLastMissedVsync = expectedPresentTime;
}
VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModel() const {
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index 72a3431..9191003 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -45,7 +45,9 @@
~VSyncPredictor();
bool addVsyncTimestamp(nsecs_t timestamp) final EXCLUDES(mMutex);
- nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final EXCLUDES(mMutex);
+ nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint,
+ std::optional<nsecs_t> lastVsyncOpt = {}) const final
+ EXCLUDES(mMutex);
nsecs_t currentPeriod() const final EXCLUDES(mMutex);
Period minFramePeriod() const final EXCLUDES(mMutex);
void resetModel() final EXCLUDES(mMutex);
@@ -87,7 +89,8 @@
size_t next(size_t i) const REQUIRES(mMutex);
bool validate(nsecs_t timestamp) const REQUIRES(mMutex);
Model getVSyncPredictionModelLocked() const REQUIRES(mMutex);
- nsecs_t nextAnticipatedVSyncTimeFromLocked(nsecs_t timePoint) const REQUIRES(mMutex);
+ nsecs_t snapToVsync(nsecs_t timePoint) const REQUIRES(mMutex);
+ nsecs_t snapToVsyncAlignedWithRenderRate(nsecs_t timePoint) const REQUIRES(mMutex);
bool isVSyncInPhaseLocked(nsecs_t timePoint, unsigned divisor) const REQUIRES(mMutex);
Period minFramePeriodLocked() const REQUIRES(mMutex);
void ensureMinFrameDurationIsKept(TimePoint, TimePoint) REQUIRES(mMutex);
@@ -120,6 +123,8 @@
mutable std::optional<VsyncSequence> mLastVsyncSequence GUARDED_BY(mMutex);
std::deque<TimePoint> mPastExpectedPresentTimes GUARDED_BY(mMutex);
+
+ TimePoint mLastMissedVsync GUARDED_BY(mMutex);
};
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 1ed863c..417163f 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -57,9 +57,13 @@
* is updated.
*
* \param [in] timePoint The point in time after which to estimate a vsync event.
+ * \param [in] lastVsyncOpt The last vsync time used by the client. If provided, the tracker
+ * should use that as a reference point when generating the new vsync
+ * and avoid crossing the minimal frame period of a VRR display.
* \return A prediction of the timestamp of a vsync event.
*/
- virtual nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const = 0;
+ virtual nsecs_t nextAnticipatedVSyncTimeFrom(
+ nsecs_t timePoint, std::optional<nsecs_t> lastVsyncOpt = {}) const = 0;
/*
* The current period of the vsync signal.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2769e5d..2503efc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -551,6 +551,12 @@
base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, true);
mLegacyFrontEndEnabled = !mLayerLifecycleManagerEnabled ||
base::GetBoolProperty("persist.debug.sf.enable_legacy_frontend"s, false);
+
+ // These are set by the HWC implementation to indicate that they will use the workarounds.
+ mIsHotplugErrViaNegVsync =
+ base::GetBoolProperty("debug.sf.hwc_hotplug_error_via_neg_vsync"s, false);
+
+ mIsHdcpViaNegVsync = base::GetBoolProperty("debug.sf.hwc_hdcp_via_neg_vsync"s, false);
}
LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
@@ -2130,15 +2136,28 @@
void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp,
std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
- if (FlagManager::getInstance().connected_display()) {
+ if (FlagManager::getInstance().connected_display() && timestamp < 0 &&
+ vsyncPeriod.has_value()) {
// use ~0 instead of -1 as AidlComposerHal.cpp passes the param as unsigned int32
- if (mIsHotplugErrViaNegVsync && timestamp < 0 && vsyncPeriod.has_value() &&
- vsyncPeriod.value() == ~0) {
- int hotplugErrorCode = static_cast<int32_t>(-timestamp);
- ALOGD("SurfaceFlinger got hotplugErrorCode=%d", hotplugErrorCode);
+ if (mIsHotplugErrViaNegVsync && vsyncPeriod.value() == ~0) {
+ const int32_t hotplugErrorCode = static_cast<int32_t>(-timestamp);
+ ALOGD("SurfaceFlinger got hotplugErrorCode=%d for display %" PRIu64, hotplugErrorCode,
+ hwcDisplayId);
mScheduler->onHotplugConnectionError(mAppConnectionHandle, hotplugErrorCode);
return;
}
+
+ if (mIsHdcpViaNegVsync && vsyncPeriod.value() == ~1) {
+ const int32_t value = static_cast<int32_t>(-timestamp);
+ // one byte is good enough to encode android.hardware.drm.HdcpLevel
+ const int32_t maxLevel = (value >> 8) & 0xFF;
+ const int32_t connectedLevel = value & 0xFF;
+ ALOGD("SurfaceFlinger got HDCP level changed: connected=%d, max=%d for "
+ "display=%" PRIu64,
+ connectedLevel, maxLevel, hwcDisplayId);
+ updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel);
+ return;
+ }
}
ATRACE_NAME(vsyncPeriod
@@ -2372,11 +2391,7 @@
mLegacyLayers[layer->sequence] = layer;
}
}
- if (mLayerLifecycleManager.getGlobalChanges().test(Changes::Hierarchy)) {
- ATRACE_NAME("LayerHierarchyBuilder:update");
- mLayerHierarchyBuilder.update(mLayerLifecycleManager.getLayers(),
- mLayerLifecycleManager.getDestroyedLayers());
- }
+ mLayerHierarchyBuilder.update(mLayerLifecycleManager);
}
bool mustComposite = false;
@@ -3432,9 +3447,10 @@
}
const sp<IBinder> token = sp<BBinder>::make();
+ const ui::DisplayConnectionType connectionType =
+ getHwComposer().getDisplayConnectionType(displayId);
- mPhysicalDisplays.try_emplace(displayId, token, displayId,
- getHwComposer().getDisplayConnectionType(displayId),
+ mPhysicalDisplays.try_emplace(displayId, token, displayId, connectionType,
std::move(displayModes), std::move(colorModes),
std::move(info.deviceProductInfo));
@@ -3442,7 +3458,7 @@
state.physical = {.id = displayId,
.hwcDisplayId = hwcDisplayId,
.activeMode = std::move(activeMode)};
- state.isSecure = true; // All physical displays are currently considered secure.
+ state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
state.isProtected = true;
state.displayName = std::move(info.name);
@@ -4126,7 +4142,7 @@
const auto notifyExpectedPresentConfig =
modePtr->getVrrConfig()->notifyExpectedPresentConfig;
if (!notifyExpectedPresentConfig) return std::nullopt;
- return Period::fromNs(notifyExpectedPresentConfig->notifyExpectedPresentTimeoutNs);
+ return Period::fromNs(notifyExpectedPresentConfig->timeoutNs);
}();
notifyExpectedPresentIfRequired(modePtr->getPhysicalDisplayId(), vsyncPeriod,
@@ -4248,9 +4264,6 @@
sp<RegionSamplingThread>::make(*this,
RegionSamplingThread::EnvironmentTimingTunables());
mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline, *this);
-
- mIsHotplugErrViaNegVsync =
- base::GetBoolProperty("debug.sf.hwc_hotplug_error_via_neg_vsync"s, false);
}
void SurfaceFlinger::updatePhaseConfiguration(Fps refreshRate) {
@@ -8752,6 +8765,40 @@
return NO_ERROR;
}
+void SurfaceFlinger::updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel,
+ int32_t maxLevel) {
+ if (!FlagManager::getInstance().connected_display()) {
+ return;
+ }
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto idOpt = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
+ if (!idOpt) {
+ ALOGE("No display found for HDCP level changed event: connected=%d, max=%d for "
+ "display=%" PRIu64,
+ connectedLevel, maxLevel, hwcDisplayId);
+ return;
+ }
+
+ const bool isInternalDisplay =
+ mPhysicalDisplays.get(*idOpt).transform(&PhysicalDisplay::isInternal).value_or(false);
+ if (isInternalDisplay) {
+ ALOGW("Unexpected HDCP level changed for internal display: connected=%d, max=%d for "
+ "display=%" PRIu64,
+ connectedLevel, maxLevel, hwcDisplayId);
+ return;
+ }
+
+ static_cast<void>(mScheduler->schedule([this, displayId = *idOpt, connectedLevel, maxLevel]() {
+ if (const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayId))) {
+ Mutex::Autolock lock(mStateLock);
+ display->setSecure(connectedLevel >= 2 /* HDCP_V1 */);
+ }
+ mScheduler->onHdcpLevelsChanged(mAppConnectionHandle, displayId, connectedLevel, maxLevel);
+ }));
+}
+
std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextureFromBufferData(
BufferData& bufferData, const char* layerName, uint64_t transactionId) {
if (bufferData.buffer &&
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6b44401..72003cd 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -654,6 +654,8 @@
status_t getStalledTransactionInfo(
int pid, std::optional<TransactionHandler::StalledTransactionInfo>& result);
+ void updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel, int32_t maxLevel);
+
// Implements IBinder::DeathRecipient.
void binderDied(const wp<IBinder>& who) override;
@@ -1276,6 +1278,7 @@
hal::Connection connection = hal::Connection::INVALID;
};
+ bool mIsHdcpViaNegVsync = false;
bool mIsHotplugErrViaNegVsync = false;
std::mutex mHotplugMutex;
@@ -1469,7 +1472,7 @@
bool mLegacyFrontEndEnabled = true;
frontend::LayerLifecycleManager mLayerLifecycleManager;
- frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
+ frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
frontend::LayerSnapshotBuilder mLayerSnapshotBuilder;
std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles;
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.h b/services/surfaceflinger/Tracing/TransactionTracing.h
index ddbf3e4..6a66fff 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.h
+++ b/services/surfaceflinger/Tracing/TransactionTracing.h
@@ -218,6 +218,13 @@
friend class Singleton<TransactionTracing>;
std::function<void(const std::string& prefix, bool overwrite)> mWriterFunction =
[](const std::string&, bool) {};
+ std::atomic<bool> mEnabled{true};
+
+ void doInvoke(const std::string& filename, bool overwrite) {
+ if (mEnabled) {
+ mWriterFunction(filename, overwrite);
+ }
+ };
public:
void setWriterFunction(
@@ -225,12 +232,15 @@
mWriterFunction = std::move(function);
}
void invoke(const std::string& prefix, bool overwrite) {
- mWriterFunction(TransactionTracing::getFilePath(prefix), overwrite);
+ doInvoke(TransactionTracing::getFilePath(prefix), overwrite);
}
/* pass in a complete file path for testing */
void invokeForTest(const std::string& filename, bool overwrite) {
- mWriterFunction(filename, overwrite);
+ doInvoke(filename, overwrite);
}
+ /* hacky way to avoid generating traces when converting transaction trace to layers trace. */
+ void disable() { mEnabled.store(false); }
+ void enable() { mEnabled.store(true); }
};
} // namespace android
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index c2d1954..617ea2c 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -40,9 +40,24 @@
namespace android {
using namespace ftl::flag_operators;
+namespace {
+class ScopedTraceDisabler {
+public:
+ ScopedTraceDisabler() { TransactionTraceWriter::getInstance().disable(); }
+ ~ScopedTraceDisabler() { TransactionTraceWriter::getInstance().enable(); }
+};
+} // namespace
+
bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& traceFile,
std::uint32_t traceFlags, LayerTracing& layerTracing,
bool onlyLastEntry) {
+ // We are generating the layers trace by replaying back a set of transactions. If the
+ // transactions have unexpected states, we may generate a transaction trace to debug
+ // the unexpected state. This is silly. So we disable it by poking the
+ // TransactionTraceWriter. This is really a hack since we should manage our depenecies a
+ // little better.
+ ScopedTraceDisabler fatalErrorTraceDisabler;
+
if (traceFile.entry_size() == 0) {
ALOGD("Trace file is empty");
return false;
@@ -52,7 +67,7 @@
// frontend
frontend::LayerLifecycleManager lifecycleManager;
- frontend::LayerHierarchyBuilder hierarchyBuilder{{}};
+ frontend::LayerHierarchyBuilder hierarchyBuilder;
frontend::LayerSnapshotBuilder snapshotBuilder;
ui::DisplayMap<ui::LayerStack, frontend::DisplayInfo> displayInfos;
@@ -119,12 +134,10 @@
lifecycleManager.applyTransactions(transactions, /*ignoreUnknownHandles=*/true);
lifecycleManager.onHandlesDestroyed(destroyedHandles, /*ignoreUnknownHandles=*/true);
- if (lifecycleManager.getGlobalChanges().test(
- frontend::RequestedLayerState::Changes::Hierarchy)) {
- hierarchyBuilder.update(lifecycleManager.getLayers(),
- lifecycleManager.getDestroyedLayers());
- }
+ // update hierarchy
+ hierarchyBuilder.update(lifecycleManager);
+ // update snapshots
frontend::LayerSnapshotBuilder::Args args{.root = hierarchyBuilder.getHierarchy(),
.layerLifecycleManager = lifecycleManager,
.displays = displayInfos,
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index cb1faee..a27e100 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -122,7 +122,7 @@
DUMP_READ_ONLY_FLAG(multithreaded_present);
DUMP_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace);
DUMP_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency);
- DUMP_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved);
+ DUMP_READ_ONLY_FLAG(cache_when_source_crop_layer_only_moved);
DUMP_READ_ONLY_FLAG(enable_fro_dependent_features);
DUMP_READ_ONLY_FLAG(display_protected);
DUMP_READ_ONLY_FLAG(fp16_client_target);
@@ -195,7 +195,7 @@
FLAG_MANAGER_READ_ONLY_FLAG(multithreaded_present, "debug.sf.multithreaded_present")
FLAG_MANAGER_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace, "")
FLAG_MANAGER_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency, "")
-FLAG_MANAGER_READ_ONLY_FLAG(cache_if_source_crop_layer_only_moved,
+FLAG_MANAGER_READ_ONLY_FLAG(cache_when_source_crop_layer_only_moved,
"debug.sf.cache_source_crop_only_moved")
FLAG_MANAGER_READ_ONLY_FLAG(enable_fro_dependent_features, "")
FLAG_MANAGER_READ_ONLY_FLAG(display_protected, "")
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 2e1d6ae..2f2895c 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -61,7 +61,7 @@
bool multithreaded_present() const;
bool add_sf_skipped_frames_to_trace() const;
bool use_known_refresh_rate_for_fps_consistency() const;
- bool cache_if_source_crop_layer_only_moved() const;
+ bool cache_when_source_crop_layer_only_moved() const;
bool enable_fro_dependent_features() const;
bool display_protected() const;
bool fp16_client_target() const;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index b690d8d..649ad25 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -134,13 +134,13 @@
dispatch->schedule(tmp,
{.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
.readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
- .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
+ .lastVsync = mFdp.ConsumeIntegral<nsecs_t>()});
},
"o.o");
dispatch->schedule(tmp,
{.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
.readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
- .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
+ .lastVsync = mFdp.ConsumeIntegral<nsecs_t>()});
dispatch->unregisterCallback(tmp);
dispatch->cancel(tmp);
}
@@ -162,20 +162,20 @@
entry.update(*stubTracker, 0);
entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
.readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
- .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()},
+ .lastVsync = mFdp.ConsumeIntegral<nsecs_t>()},
*stubTracker, 0);
entry.disarm();
entry.ensureNotRunning();
entry.schedule({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
.readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
- .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()},
+ .lastVsync = mFdp.ConsumeIntegral<nsecs_t>()},
*stubTracker, 0);
auto const wakeup = entry.wakeupTime();
auto const ready = entry.readyTime();
entry.callback(entry.executing(), *wakeup, *ready);
entry.addPendingWorkloadUpdate({.workDuration = mFdp.ConsumeIntegral<nsecs_t>(),
.readyDuration = mFdp.ConsumeIntegral<nsecs_t>(),
- .earliestVsync = mFdp.ConsumeIntegral<nsecs_t>()});
+ .lastVsync = mFdp.ConsumeIntegral<nsecs_t>()});
dump<scheduler::VSyncDispatchTimerQueueEntry>(&entry, &mFdp);
}
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index fa307e9..114f3b0 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -86,7 +86,10 @@
bool addVsyncTimestamp(nsecs_t /* timestamp */) override { return true; }
- nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t /* timePoint */) const override { return 1; }
+ nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t /* timePoint */,
+ std::optional<nsecs_t>) const override {
+ return 1;
+ }
nsecs_t currentPeriod() const override { return 1; }
Period minFramePeriod() const override { return Period::fromNs(currentPeriod()); }
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
index 1a28b81..b65a2b3 100644
--- a/services/surfaceflinger/surfaceflinger_flags.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -100,8 +100,18 @@
bug: "299201319"
}
+# This flag is broken.
+# See alternative one: cache_when_source_crop_layer_only_moved
+# flag {
+# name: "cache_if_source_crop_layer_only_moved"
+# namespace: "core_graphics"
+# description: "do not flatten layers if source crop is only moved"
+# bug: "305718400"
+# is_fixed_read_only: true
+# }
+
flag {
- name: "cache_if_source_crop_layer_only_moved"
+ name: "cache_when_source_crop_layer_only_moved"
namespace: "core_graphics"
description: "do not flatten layers if source crop is only moved"
bug: "305718400"
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index ee12276..6671414 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -481,14 +481,17 @@
constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
-template <typename PhysicalDisplay, int width, int height>
+template <typename PhysicalDisplay, int width, int height,
+ Secure secure = (PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal)
+ ? Secure::TRUE
+ : Secure::FALSE>
struct PhysicalDisplayVariant
- : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE,
- Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
+ : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE, secure,
+ PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
PHYSICAL_DISPLAY_FLAGS>,
HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height,
- Async::FALSE, Secure::TRUE, PhysicalDisplay::PRIMARY,
+ Async::FALSE, secure, PhysicalDisplay::PRIMARY,
GRALLOC_USAGE_PHYSICAL_DISPLAY, PHYSICAL_DISPLAY_FLAGS>,
PhysicalDisplay> {};
@@ -515,6 +518,7 @@
};
struct TertiaryDisplay {
+ static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
static constexpr Primary PRIMARY = Primary::FALSE;
static constexpr uint8_t PORT = 253;
static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 8891c06..4e8a609 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -471,7 +471,7 @@
mock::VSyncTracker& mockTracker =
*static_cast<mock::VSyncTracker*>(&mVsyncSchedule->getTracker());
- EXPECT_CALL(mockTracker, nextAnticipatedVSyncTimeFrom(_))
+ EXPECT_CALL(mockTracker, nextAnticipatedVSyncTimeFrom(_, _))
.WillOnce(Return(preferredExpectedPresentationTime));
VsyncEventData vsyncEventData = mThread->getLatestVsyncEventData(mConnection);
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index 6edecff..a5c0657 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -21,6 +21,7 @@
#undef LOG_TAG
#define LOG_TAG "LibSurfaceFlingerUnittests"
+#include <optional>
#include <vector>
// StrictMock<T> derives from T and is not marked final, so the destructor of T is expected to be
@@ -82,6 +83,8 @@
EXPECT_CALL(*mHal, setVsyncEnabled(hwcDisplayId, Hwc2::IComposerClient::Vsync::DISABLE));
EXPECT_CALL(*mHal, onHotplugConnect(hwcDisplayId));
}
+
+ void setVrrTimeoutHint(bool status) { mHwc.mEnableVrrTimeout = status; }
};
TEST_F(HWComposerTest, isHeadless) {
@@ -323,6 +326,7 @@
EXPECT_TRUE(mHwc.getModes(info->id, kMaxFrameIntervalNs).empty());
}
{
+ setVrrTimeoutHint(true);
constexpr int32_t kWidth = 480;
constexpr int32_t kHeight = 720;
constexpr int32_t kConfigGroup = 1;
@@ -330,10 +334,8 @@
const hal::VrrConfig vrrConfig =
hal::VrrConfig{.minFrameIntervalNs = static_cast<Fps>(120_Hz).getPeriodNsecs(),
.notifyExpectedPresentConfig = hal::VrrConfig::
- NotifyExpectedPresentConfig{.notifyExpectedPresentHeadsUpNs =
- ms2ns(30),
- .notifyExpectedPresentTimeoutNs =
- ms2ns(30)}};
+ NotifyExpectedPresentConfig{.headsUpNs = ms2ns(30),
+ .timeoutNs = ms2ns(30)}};
hal::DisplayConfiguration displayConfiguration{.configId = kConfigId,
.width = kWidth,
.height = kHeight,
@@ -363,9 +365,9 @@
displayConfiguration.dpi = {kDpi, kDpi};
EXPECT_CALL(*mHal, getDisplayConfigurations(kHwcDisplayId, _, _))
- .WillOnce(DoAll(SetArgPointee<2>(std::vector<hal::DisplayConfiguration>{
- displayConfiguration}),
- Return(HalError::NONE)));
+ .WillRepeatedly(DoAll(SetArgPointee<2>(std::vector<hal::DisplayConfiguration>{
+ displayConfiguration}),
+ Return(HalError::NONE)));
modes = mHwc.getModes(info->id, kMaxFrameIntervalNs);
EXPECT_EQ(modes.size(), size_t{1});
@@ -377,6 +379,10 @@
EXPECT_EQ(modes.front().vrrConfig, vrrConfig);
EXPECT_EQ(modes.front().dpiX, kDpi);
EXPECT_EQ(modes.front().dpiY, kDpi);
+
+ setVrrTimeoutHint(false);
+ modes = mHwc.getModes(info->id, kMaxFrameIntervalNs);
+ EXPECT_EQ(modes.front().vrrConfig->notifyExpectedPresentConfig, std::nullopt);
}
}
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
index 95f1940..2b333f4 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.cpp
@@ -45,7 +45,8 @@
// reparenting tests
TEST_F(LayerHierarchyTest, addLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 12, 121, 122, 1221, 13, 2};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -64,7 +65,8 @@
}
TEST_F(LayerHierarchyTest, reparentLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(2, 11);
reparentLayer(111, 12);
reparentLayer(1221, 1);
@@ -79,7 +81,8 @@
}
TEST_F(LayerHierarchyTest, reparentLayerToNull) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(2, UNASSIGNED_LAYER_ID);
reparentLayer(11, UNASSIGNED_LAYER_ID);
@@ -96,7 +99,8 @@
}
TEST_F(LayerHierarchyTest, reparentLayerToNullAndDestroyHandles) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(2, UNASSIGNED_LAYER_ID);
reparentLayer(11, UNASSIGNED_LAYER_ID);
reparentLayer(1221, UNASSIGNED_LAYER_ID);
@@ -115,7 +119,8 @@
}
TEST_F(LayerHierarchyTest, destroyHandleThenDestroyParentLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
destroyLayerHandle(111);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -139,7 +144,8 @@
}
TEST_F(LayerHierarchyTest, layerSurvivesTemporaryReparentToNull) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(11, UNASSIGNED_LAYER_ID);
reparentLayer(11, 1);
@@ -154,7 +160,8 @@
// offscreen tests
TEST_F(LayerHierarchyTest, layerMovesOnscreen) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(11, UNASSIGNED_LAYER_ID);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -170,7 +177,8 @@
}
TEST_F(LayerHierarchyTest, addLayerToOffscreenParent) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(11, UNASSIGNED_LAYER_ID);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -187,7 +195,8 @@
// rel-z tests
TEST_F(LayerHierarchyTest, setRelativeParent) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -200,7 +209,8 @@
}
TEST_F(LayerHierarchyTest, reparentFromRelativeParentWithSetLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -216,7 +226,8 @@
}
TEST_F(LayerHierarchyTest, reparentToRelativeParent) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -231,7 +242,8 @@
}
TEST_F(LayerHierarchyTest, setParentAsRelativeParent) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -246,7 +258,8 @@
}
TEST_F(LayerHierarchyTest, relativeChildMovesOffscreenIsNotTraversable) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -262,7 +275,8 @@
}
TEST_F(LayerHierarchyTest, reparentRelativeLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -294,7 +308,8 @@
// mirror tests
TEST_F(LayerHierarchyTest, canTraverseMirrorLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -308,7 +323,8 @@
}
TEST_F(LayerHierarchyTest, canMirrorOffscreenLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(11, UNASSIGNED_LAYER_ID);
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
@@ -324,7 +340,8 @@
TEST_F(LayerHierarchyTest, newChildLayerIsUpdatedInMirrorHierarchy) {
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
createLayer(1111, 111);
createLayer(112, 11);
@@ -340,7 +357,8 @@
// mirror & relatives tests
TEST_F(LayerHierarchyTest, mirrorWithRelativeOutsideMirrorHierarchy) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(111, 12);
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
@@ -371,7 +389,8 @@
}
TEST_F(LayerHierarchyTest, mirrorWithRelativeInsideMirrorHierarchy) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(1221, 12);
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 12);
@@ -401,7 +420,8 @@
}
TEST_F(LayerHierarchyTest, childMovesOffscreenWhenRelativeParentDies) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(11, 2);
reparentLayer(2, UNASSIGNED_LAYER_ID);
@@ -427,7 +447,8 @@
}
TEST_F(LayerHierarchyTest, offscreenLayerCannotBeRelativeToOnscreenLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentRelativeLayer(1221, 2);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -462,7 +483,8 @@
}
TEST_F(LayerHierarchyTest, backgroundLayersAreBehindParentLayer) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
updateBackgroundColor(1, 0.5);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -485,7 +507,8 @@
createLayer(11, 1);
reparentLayer(1, 11);
mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
std::vector<uint32_t> expectedTraversalPath = {};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -502,17 +525,11 @@
createLayer(11, 1);
reparentRelativeLayer(11, 2);
reparentRelativeLayer(2, 11);
- mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
-
- // fix loop
- uint32_t invalidRelativeRoot;
- bool hasRelZLoop = hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot);
- EXPECT_TRUE(hasRelZLoop);
- mLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
- hierarchyBuilder.update(mLifecycleManager.getLayers(), mLifecycleManager.getDestroyedLayers());
- EXPECT_EQ(invalidRelativeRoot, 11u);
- EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot));
+ LayerHierarchyBuilder hierarchyBuilder;
+ // this call is expected to fix the loop!
+ hierarchyBuilder.update(mLifecycleManager);
+ uint32_t unused;
+ EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(unused));
std::vector<uint32_t> expectedTraversalPath = {1, 11, 2, 2};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -534,16 +551,11 @@
createLayer(221, 22);
reparentRelativeLayer(22, 111);
reparentRelativeLayer(11, 221);
- mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
-
- // fix loop
- uint32_t invalidRelativeRoot;
- bool hasRelZLoop = hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot);
- EXPECT_TRUE(hasRelZLoop);
- mLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
- hierarchyBuilder.update(mLifecycleManager.getLayers(), mLifecycleManager.getDestroyedLayers());
- EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(invalidRelativeRoot));
+ LayerHierarchyBuilder hierarchyBuilder;
+ // this call is expected to fix the loop!
+ hierarchyBuilder.update(mLifecycleManager);
+ uint32_t unused;
+ EXPECT_FALSE(hierarchyBuilder.getHierarchy().hasRelZLoop(unused));
std::vector<uint32_t> expectedTraversalPath = {1, 11, 111, 22, 221, 2, 21, 22, 221};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -554,7 +566,8 @@
}
TEST_F(LayerHierarchyTest, ReparentRootLayerToNull) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(1, UNASSIGNED_LAYER_ID);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -568,7 +581,8 @@
TEST_F(LayerHierarchyTest, AddRemoveLayerInSameTransaction) {
// remove default hierarchy
mLifecycleManager = LayerLifecycleManager();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
createRootLayer(1);
destroyLayerHandle(1);
UPDATE_AND_VERIFY(hierarchyBuilder);
@@ -582,7 +596,8 @@
// traversal path test
TEST_F(LayerHierarchyTest, traversalPathId) {
setZ(122, -1);
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
auto checkTraversalPathIdVisitor =
[](const LayerHierarchy& hierarchy,
const LayerHierarchy::TraversalPath& traversalPath) -> bool {
@@ -605,7 +620,8 @@
createLayer(53, 5);
mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
UPDATE_AND_VERIFY(hierarchyBuilder);
std::vector<uint32_t> expectedTraversalPath = {1, 11, 2, 4, 5, 51, 53};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -639,7 +655,8 @@
setZ(13, 1);
mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
UPDATE_AND_VERIFY(hierarchyBuilder);
std::vector<uint32_t> expectedTraversalPath = {1, 11, 13, 12};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -661,7 +678,8 @@
setLayerStack(2, 10);
mLifecycleManager.commitChanges();
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
UPDATE_AND_VERIFY(hierarchyBuilder);
std::vector<uint32_t> expectedTraversalPath = {2, 21, 1, 11};
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()), expectedTraversalPath);
@@ -672,7 +690,8 @@
}
TEST_F(LayerHierarchyTest, canMirrorDisplay) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
setLayerStack(3, 1);
@@ -687,7 +706,8 @@
}
TEST_F(LayerHierarchyTest, mirrorNonExistingDisplay) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(5));
setLayerStack(3, 1);
@@ -701,7 +721,8 @@
}
TEST_F(LayerHierarchyTest, newRootLayerIsMirrored) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
setLayerStack(3, 1);
@@ -719,7 +740,8 @@
}
TEST_F(LayerHierarchyTest, removedRootLayerIsNoLongerMirrored) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
setFlags(12, layer_state_t::eLayerSkipScreenshot, layer_state_t::eLayerSkipScreenshot);
createDisplayMirrorLayer(3, ui::LayerStack::fromValue(0));
setLayerStack(3, 1);
@@ -737,7 +759,8 @@
}
TEST_F(LayerHierarchyTest, canMirrorDisplayWithMirrors) {
- LayerHierarchyBuilder hierarchyBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder hierarchyBuilder;
+ hierarchyBuilder.update(mLifecycleManager);
reparentLayer(12, UNASSIGNED_LAYER_ID);
mirrorLayer(/*layer*/ 14, /*parent*/ 1, /*layerToMirror*/ 11);
UPDATE_AND_VERIFY(hierarchyBuilder);
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 7e9abce..67e6249 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -176,14 +176,12 @@
void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({{id, "test"}}); }
void updateAndVerify(LayerHierarchyBuilder& hierarchyBuilder) {
- if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
- hierarchyBuilder.update(mLifecycleManager.getLayers(),
- mLifecycleManager.getDestroyedLayers());
- }
+ hierarchyBuilder.update(mLifecycleManager);
mLifecycleManager.commitChanges();
// rebuild layer hierarchy from scratch and verify that it matches the updated state.
- LayerHierarchyBuilder newBuilder(mLifecycleManager.getLayers());
+ LayerHierarchyBuilder newBuilder;
+ newBuilder.update(mLifecycleManager);
EXPECT_EQ(getTraversalPath(hierarchyBuilder.getHierarchy()),
getTraversalPath(newBuilder.getHierarchy()));
EXPECT_EQ(getTraversalPathInZOrder(hierarchyBuilder.getHierarchy()),
@@ -512,10 +510,7 @@
}
void update(LayerSnapshotBuilder& snapshotBuilder) {
- if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
- mHierarchyBuilder.update(mLifecycleManager.getLayers(),
- mLifecycleManager.getDestroyedLayers());
- }
+ mHierarchyBuilder.update(mLifecycleManager);
LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
.layerLifecycleManager = mLifecycleManager,
.includeMetadata = false,
@@ -530,7 +525,7 @@
mLifecycleManager.commitChanges();
}
- LayerHierarchyBuilder mHierarchyBuilder{{}};
+ LayerHierarchyBuilder mHierarchyBuilder;
DisplayInfos mFrontEndDisplayInfos;
bool mHasDisplayChanges = false;
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
index 787fa1c..e9d2319 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
@@ -56,7 +56,7 @@
LayerHistoryIntegrationTest() : LayerSnapshotTestBase() {
mFlinger.resetScheduler(mScheduler);
mLifecycleManager = {};
- mHierarchyBuilder = {{}};
+ mHierarchyBuilder = {};
}
void updateLayerSnapshotsAndLayerHistory(nsecs_t now) {
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 50cd784..ba32c68 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -58,8 +58,7 @@
void update(LayerSnapshotBuilder& actualBuilder, LayerSnapshotBuilder::Args& args) {
if (mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy)) {
- mHierarchyBuilder.update(mLifecycleManager.getLayers(),
- mLifecycleManager.getDestroyedLayers());
+ mHierarchyBuilder.update(mLifecycleManager);
}
args.root = mHierarchyBuilder.getHierarchy();
actualBuilder.update(args);
diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
index 9aa089f..e9c4d80 100644
--- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
@@ -91,7 +91,7 @@
TEST_F(MessageQueueTest, commit) {
const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
- .earliestVsync = 0};
+ .lastVsync = 0};
EXPECT_FALSE(mEventQueue.getScheduledFrameTime());
EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
@@ -105,7 +105,7 @@
InSequence s;
const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
- .earliestVsync = 0};
+ .lastVsync = 0};
EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
@@ -124,7 +124,7 @@
InSequence s;
const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
- .earliestVsync = 0};
+ .lastVsync = 0};
EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(1234));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
@@ -151,7 +151,7 @@
const auto timingAfterCallback =
scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
- .earliestVsync = kPresentTime.ns()};
+ .lastVsync = kPresentTime.ns()};
EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback)).WillOnce(Return(0));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
@@ -163,7 +163,7 @@
const auto timing =
scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDifferentDuration.ns(),
.readyDuration = 0,
- .earliestVsync = 0};
+ .lastVsync = 0};
EXPECT_CALL(*mVSyncDispatch, schedule(mCallbackToken, timing)).WillOnce(Return(0));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index e515895..7fdca71 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -98,7 +98,7 @@
mock::VsyncTrackerCallback mVsyncTrackerCallback;
TestableScheduler* mScheduler =
new TestableScheduler{mSelector, mSchedulerCallback, mVsyncTrackerCallback};
- surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
+ surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
ConnectionHandle mConnectionHandle;
MockEventThread* mEventThread;
@@ -584,17 +584,17 @@
scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
vrrTracker->addVsyncTimestamp(0);
- // Next frame at refresh rate as no previous frame
- EXPECT_EQ(refreshRate,
- scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(), TimePoint::fromNs(0)));
-
EXPECT_EQ(Fps::fromPeriodNsecs(1000),
scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
- TimePoint::fromNs(500)));
+ TimePoint::fromNs(1000)));
EXPECT_EQ(Fps::fromPeriodNsecs(1000),
scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
- TimePoint::fromNs(1500)));
+ TimePoint::fromNs(2000)));
+ // Not crossing the min frame period
+ EXPECT_EQ(Fps::fromPeriodNsecs(1500),
+ scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
+ TimePoint::fromNs(2500)));
// Change render rate
frameRate = Fps::fromPeriodNsecs(2000);
vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
@@ -602,10 +602,10 @@
EXPECT_EQ(Fps::fromPeriodNsecs(2000),
scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
- TimePoint::fromNs(2500)));
+ TimePoint::fromNs(2000)));
EXPECT_EQ(Fps::fromPeriodNsecs(2000),
scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
- TimePoint::fromNs(4500)));
+ TimePoint::fromNs(4000)));
}
TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 7ad97a2..8b16a8a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -53,7 +53,7 @@
auto vsyncController = std::make_unique<mock::VsyncController>();
auto vsyncTracker = std::make_shared<mock::VSyncTracker>();
- EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
.WillRepeatedly(Return(
TestableSurfaceFlinger::FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
@@ -138,14 +138,14 @@
auto vsyncController = std::make_unique<mock::VsyncController>();
auto vsyncTracker = std::make_shared<mock::VSyncTracker>();
- EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
.WillRepeatedly(
Return(TestableSurfaceFlinger::FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
EXPECT_CALL(*vsyncTracker, minFramePeriod())
.WillRepeatedly(Return(Period::fromNs(
TestableSurfaceFlinger::FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)));
- EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker),
std::move(eventThread), std::move(sfEventThread),
std::move(selectorPtr),
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
index fc5f2b0..1583f64 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
@@ -46,7 +46,7 @@
EXPECT_CALL(static_cast<mock::VSyncTracker&>(
mFlinger.scheduler()->getVsyncSchedule()->getTracker()),
- nextAnticipatedVSyncTimeFrom(_))
+ nextAnticipatedVSyncTimeFrom(_, _))
.WillRepeatedly(Return(0));
// --------------------------------------------------------------------
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 22cb24b..27030d1 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -303,13 +303,13 @@
auto vsyncController = makeMock<mock::VsyncController>(options.useNiceMock);
auto vsyncTracker = makeSharedMock<mock::VSyncTracker>(options.useNiceMock);
- EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*vsyncTracker, currentPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
EXPECT_CALL(*vsyncTracker, minFramePeriod())
.WillRepeatedly(
Return(Period::fromNs(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)));
- EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_, _)).WillRepeatedly(Return(0));
setupScheduler(std::move(vsyncController), std::move(vsyncTracker), std::move(eventThread),
std::move(sfEventThread), DefaultDisplayMode{options.displayId},
SchedulerCallbackImpl::kNoOp, VsyncTrackerCallbackImpl::kNoOp,
diff --git a/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
index 4a83d44..d071ce9 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
@@ -105,4 +105,16 @@
verifyTraceFile();
}
+// Check we cannot write to file if the trace write is disabled.
+TEST_F(TransactionTraceWriterTest, canDisableTraceWriter) {
+ TransactionTraceWriter::getInstance().disable();
+ TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
+ EXPECT_NE(access(mFilename.c_str(), F_OK), 0);
+
+ TransactionTraceWriter::getInstance().enable();
+ TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
+ EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
+ verifyTraceFile();
+}
+
} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 6a56353..d891008 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -64,7 +64,7 @@
public:
FixedRateIdealStubTracker() : StubTracker{toNs(3ms)} {}
- nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final {
+ nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint, std::optional<nsecs_t>) const final {
auto const floor = timePoint % mPeriod;
if (floor == 0) {
return timePoint;
@@ -77,7 +77,7 @@
public:
VRRStubTracker(nsecs_t period) : StubTracker(period) {}
- nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t time_point) const final {
+ nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t time_point, std::optional<nsecs_t>) const final {
std::lock_guard lock(mMutex);
auto const normalized_to_base = time_point - mBase;
auto const floor = (normalized_to_base) % mPeriod;
@@ -117,7 +117,7 @@
mCallback.schedule(
{.workDuration = mWorkload,
.readyDuration = mReadyDuration,
- .earliestVsync = systemTime(SYSTEM_TIME_MONOTONIC) + mWorkload + mReadyDuration});
+ .lastVsync = systemTime(SYSTEM_TIME_MONOTONIC) + mWorkload + mReadyDuration});
for (auto i = 0u; i < iterations - 1; i++) {
std::unique_lock lock(mMutex);
@@ -130,7 +130,7 @@
mCallback.schedule({.workDuration = mWorkload,
.readyDuration = mReadyDuration,
- .earliestVsync = last + mWorkload + mReadyDuration});
+ .lastVsync = last + mWorkload + mReadyDuration});
}
// wait for the last callback.
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index 2047018..4bf58de 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -46,14 +46,14 @@
class MockVSyncTracker : public mock::VSyncTracker {
public:
MockVSyncTracker(nsecs_t period) : mPeriod{period} {
- ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_))
+ ON_CALL(*this, nextAnticipatedVSyncTimeFrom(_, _))
.WillByDefault(Invoke(this, &MockVSyncTracker::nextVSyncTime));
ON_CALL(*this, addVsyncTimestamp(_)).WillByDefault(Return(true));
ON_CALL(*this, currentPeriod())
.WillByDefault(Invoke(this, &MockVSyncTracker::getCurrentPeriod));
}
- nsecs_t nextVSyncTime(nsecs_t timePoint) const {
+ nsecs_t nextVSyncTime(nsecs_t timePoint, std::optional<nsecs_t>) const {
if (timePoint % mPeriod == 0) {
return timePoint;
}
@@ -243,10 +243,9 @@
mDispatchGroupThreshold,
mVsyncMoveThreshold);
CountingCallback cb(mDispatch);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = 1000});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
}
@@ -257,10 +256,9 @@
EXPECT_CALL(mMockClock, alarmAt(_, 900));
CountingCallback cb(mDispatch);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = intended});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
@@ -277,16 +275,14 @@
EXPECT_CALL(mMockClock, alarmAt(_, 700)).InSequence(seq);
CountingCallback cb(mDispatch);
- auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = intended});
+ auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
result =
- mDispatch->update(cb,
- {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
+ mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(700, *result);
@@ -303,17 +299,18 @@
CountingCallback cb(mDispatch);
const auto result =
- mDispatch->update(cb,
- {.workDuration = 300, .readyDuration = 0, .earliestVsync = intended});
+ mDispatch->update(cb, {.workDuration = 300, .readyDuration = 0, .lastVsync = intended});
EXPECT_FALSE(result.has_value());
}
TEST_F(VSyncDispatchTimerQueueTest, basicAlarmSettingFutureWithAdjustmentToTrueVsync) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000)).WillOnce(Return(1150));
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(mPeriod)))
+ .WillOnce(Return(1150));
EXPECT_CALL(mMockClock, alarmAt(_, 1050));
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
@@ -324,7 +321,8 @@
auto const now = 234;
mMockClock.advanceBy(234);
auto const workDuration = 10 * mPeriod;
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + workDuration))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(now + workDuration, std::optional<nsecs_t>(mPeriod)))
.WillOnce(Return(mPeriod * 11));
EXPECT_CALL(mMockClock, alarmAt(_, mPeriod));
@@ -332,7 +330,7 @@
const auto result = mDispatch->schedule(cb,
{.workDuration = workDuration,
.readyDuration = 0,
- .earliestVsync = mPeriod});
+ .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod, *result);
}
@@ -342,10 +340,9 @@
EXPECT_CALL(mMockClock, alarmCancel());
CountingCallback cb(mDispatch);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = mPeriod});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod - 100, *result);
EXPECT_EQ(mDispatch->cancel(cb), CancelResult::Cancelled);
@@ -356,10 +353,9 @@
EXPECT_CALL(mMockClock, alarmCancel());
CountingCallback cb(mDispatch);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = mPeriod});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod - 100, *result);
mMockClock.advanceBy(950);
@@ -371,10 +367,9 @@
EXPECT_CALL(mMockClock, alarmCancel());
PausingCallback cb(mDispatch, std::chrono::duration_cast<std::chrono::milliseconds>(1s));
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = mPeriod});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod - 100, *result);
@@ -393,10 +388,9 @@
PausingCallback cb(mDispatch, 50ms);
cb.stashResource(resource);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = mPeriod});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod - 100, *result);
@@ -413,7 +407,8 @@
}
TEST_F(VSyncDispatchTimerQueueTest, basicTwoAlarmSetting) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
.Times(4)
.WillOnce(Return(1055))
.WillOnce(Return(1063))
@@ -428,8 +423,8 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod});
- mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
+ mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod});
+ mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
advanceToNextCallback();
advanceToNextCallback();
@@ -441,7 +436,7 @@
}
TEST_F(VSyncDispatchTimerQueueTest, noCloseCallbacksAfterPeriodChange) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
.Times(4)
.WillOnce(Return(1000))
.WillOnce(Return(2000))
@@ -455,21 +450,21 @@
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 0});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 0});
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(1));
EXPECT_THAT(cb.mCalls[0], Eq(1000));
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
ASSERT_THAT(cb.mCalls.size(), Eq(2));
EXPECT_THAT(cb.mCalls[1], Eq(2000));
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
advanceToNextCallback();
@@ -478,7 +473,7 @@
}
TEST_F(VSyncDispatchTimerQueueTest, rearmsFaroutTimeoutWhenCancellingCloseOne) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
.Times(4)
.WillOnce(Return(10000))
.WillOnce(Return(1000))
@@ -493,9 +488,8 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = mPeriod * 10});
- mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .earliestVsync = mPeriod});
+ mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = mPeriod * 10});
+ mDispatch->schedule(cb1, {.workDuration = 250, .readyDuration = 0, .lastVsync = mPeriod});
mDispatch->cancel(cb1);
}
@@ -507,9 +501,9 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 300, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
}
@@ -522,9 +516,9 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
}
@@ -542,10 +536,9 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1,
- {.workDuration = closeOffset, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = closeOffset, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
ASSERT_THAT(cb0.mCalls.size(), Eq(1));
@@ -553,11 +546,9 @@
ASSERT_THAT(cb1.mCalls.size(), Eq(1));
EXPECT_THAT(cb1.mCalls[0], Eq(mPeriod));
- mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 2000});
+ mDispatch->schedule(cb0, {.workDuration = 400, .readyDuration = 0, .lastVsync = 2000});
mDispatch->schedule(cb1,
- {.workDuration = notCloseOffset,
- .readyDuration = 0,
- .earliestVsync = 2000});
+ {.workDuration = notCloseOffset, .readyDuration = 0, .lastVsync = 2000});
advanceToNextCallback();
ASSERT_THAT(cb1.mCalls.size(), Eq(2));
EXPECT_THAT(cb1.mCalls[1], Eq(2000));
@@ -577,32 +568,32 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 200, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
EXPECT_EQ(mDispatch->cancel(cb0), CancelResult::Cancelled);
}
TEST_F(VSyncDispatchTimerQueueTest, setAlarmCallsAtCorrectTimeWithChangingVsync) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
.Times(3)
.WillOnce(Return(950))
.WillOnce(Return(1975))
.WillOnce(Return(2950));
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 920});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 920});
mMockClock.advanceBy(850);
EXPECT_THAT(cb.mCalls.size(), Eq(1));
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1900});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1900});
mMockClock.advanceBy(900);
EXPECT_THAT(cb.mCalls.size(), Eq(1));
mMockClock.advanceBy(125);
EXPECT_THAT(cb.mCalls.size(), Eq(2));
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2900});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2900});
mMockClock.advanceBy(975);
EXPECT_THAT(cb.mCalls.size(), Eq(3));
}
@@ -616,13 +607,11 @@
tmp = mDispatch->registerCallback(
[&](auto, auto, auto) {
mDispatch->schedule(tmp,
- {.workDuration = 100,
- .readyDuration = 0,
- .earliestVsync = 2000});
+ {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
},
"o.o");
- mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(tmp, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
}
@@ -631,30 +620,29 @@
std::optional<nsecs_t> lastTarget;
tmp = mDispatch->registerCallback(
[&](auto timestamp, auto, auto) {
- auto result =
- mDispatch->schedule(tmp,
- {.workDuration = 400,
- .readyDuration = 0,
- .earliestVsync = timestamp - mVsyncMoveThreshold});
+ auto result = mDispatch->schedule(tmp,
+ {.workDuration = 400,
+ .readyDuration = 0,
+ .lastVsync = timestamp - mVsyncMoveThreshold});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod + timestamp - 400, *result);
result = mDispatch->schedule(tmp,
{.workDuration = 400,
.readyDuration = 0,
- .earliestVsync = timestamp});
+ .lastVsync = timestamp});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod + timestamp - 400, *result);
result = mDispatch->schedule(tmp,
{.workDuration = 400,
.readyDuration = 0,
- .earliestVsync = timestamp + mVsyncMoveThreshold});
+ .lastVsync = timestamp + mVsyncMoveThreshold});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(mPeriod + timestamp - 400, *result);
lastTarget = timestamp;
},
"oo");
- mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(tmp, {.workDuration = 999, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
EXPECT_THAT(lastTarget, Eq(1000));
@@ -670,16 +658,16 @@
EXPECT_CALL(mMockClock, alarmAt(_, 1900)).InSequence(seq);
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 0, .readyDuration = 0, .lastVsync = 1000});
mMockClock.advanceBy(750);
- mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
- mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .earliestVsync = 2000});
+ mDispatch->schedule(cb, {.workDuration = 50, .readyDuration = 0, .lastVsync = 2000});
mMockClock.advanceBy(800);
- mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+ mDispatch->schedule(cb, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
}
TEST_F(VSyncDispatchTimerQueueTest, lateModifications) {
@@ -692,12 +680,12 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
- mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .earliestVsync = 2000});
- mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 200, .readyDuration = 0, .lastVsync = 2000});
+ mDispatch->schedule(cb1, {.workDuration = 150, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
advanceToNextCallback();
@@ -709,8 +697,8 @@
CountingCallback cb0(mDispatch);
CountingCallback cb1(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 20000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 500, .readyDuration = 0, .lastVsync = 20000});
}
TEST_F(VSyncDispatchTimerQueueTest, setsTimerAfterCancellation) {
@@ -720,17 +708,15 @@
EXPECT_CALL(mMockClock, alarmAt(_, 900)).InSequence(seq);
CountingCallback cb0(mDispatch);
- mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
mDispatch->cancel(cb0);
- mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
}
TEST_F(VSyncDispatchTimerQueueTest, makingUpIdsError) {
VSyncDispatch::CallbackToken token(100);
EXPECT_FALSE(
- mDispatch
- ->schedule(token,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000})
+ mDispatch->schedule(token, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000})
.has_value());
EXPECT_THAT(mDispatch->cancel(token), Eq(CancelResult::Error));
}
@@ -738,12 +724,10 @@
TEST_F(VSyncDispatchTimerQueueTest, canMoveCallbackBackwardsInTime) {
CountingCallback cb0(mDispatch);
auto result =
- mDispatch->schedule(cb0,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
- result = mDispatch->schedule(cb0,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb0, {.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
}
@@ -755,14 +739,12 @@
EXPECT_CALL(mMockClock, alarmAt(_, 500));
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
mMockClock.advanceBy(400);
- result = mDispatch->schedule(cb,
- {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1200, *result);
@@ -779,14 +761,12 @@
EXPECT_CALL(mMockClock, alarmAt(_, 400)).InSequence(seq);
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
mMockClock.advanceBy(400);
- result = mDispatch->schedule(cb,
- {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(400, *result);
@@ -795,19 +775,18 @@
}
TEST_F(VSyncDispatchTimerQueueTest, targetOffsetMovingBackALittleCanStillSchedule) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
.Times(2)
.WillOnce(Return(1000))
.WillOnce(Return(1002));
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
mMockClock.advanceBy(400);
- result = mDispatch->schedule(cb,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(602, *result);
}
@@ -815,13 +794,12 @@
TEST_F(VSyncDispatchTimerQueueTest, canScheduleNegativeOffsetAgainstDifferentPeriods) {
CountingCallback cb0(mDispatch);
auto result =
- mDispatch->schedule(cb0,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
advanceToNextCallback();
- result = mDispatch->schedule(cb0,
- {.workDuration = 1100, .readyDuration = 0, .earliestVsync = 2000});
+ result =
+ mDispatch->schedule(cb0, {.workDuration = 1100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
}
@@ -832,13 +810,12 @@
EXPECT_CALL(mMockClock, alarmAt(_, 1100)).InSequence(seq);
CountingCallback cb0(mDispatch);
auto result =
- mDispatch->schedule(cb0,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb0, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
advanceToNextCallback();
- result = mDispatch->schedule(cb0,
- {.workDuration = 1900, .readyDuration = 0, .earliestVsync = 2000});
+ result =
+ mDispatch->schedule(cb0, {.workDuration = 1900, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1100, *result);
}
@@ -850,13 +827,11 @@
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
- result = mDispatch->schedule(cb,
- {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
@@ -872,13 +847,11 @@
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
- result = mDispatch->schedule(cb,
- {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(0, *result);
@@ -892,10 +865,10 @@
VSyncCallbackRegistration cb(
mDispatch, [](auto, auto, auto) {}, "");
VSyncCallbackRegistration cb1(std::move(cb));
- cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
cb.cancel();
- cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
cb1.cancel();
}
@@ -908,10 +881,10 @@
VSyncCallbackRegistration cb1(
mDispatch, [](auto, auto, auto) {}, "");
cb1 = std::move(cb);
- cb.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 1000});
+ cb.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 1000});
cb.cancel();
- cb1.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ cb1.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
cb1.cancel();
}
@@ -924,16 +897,14 @@
CountingCallback cb2(mDispatch);
auto result =
- mDispatch->schedule(cb1,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
mMockClock.setLag(100);
mMockClock.advanceBy(620);
- result = mDispatch->schedule(cb2,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+ result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1900, *result);
mMockClock.advanceBy(80);
@@ -952,16 +923,14 @@
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
mMockClock.setLag(100);
mMockClock.advanceBy(620);
- result = mDispatch->schedule(cb,
- {.workDuration = 370, .readyDuration = 0, .earliestVsync = 2000});
+ result = mDispatch->schedule(cb, {.workDuration = 370, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1630, *result);
mMockClock.advanceBy(80);
@@ -978,12 +947,10 @@
CountingCallback cb2(mDispatch);
auto result =
- mDispatch->schedule(cb1,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
- result = mDispatch->schedule(cb2,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+ result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1900, *result);
@@ -1007,12 +974,10 @@
CountingCallback cb2(mDispatch);
auto result =
- mDispatch->schedule(cb1,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
- result = mDispatch->schedule(cb2,
- {.workDuration = 100, .readyDuration = 0, .earliestVsync = 2000});
+ result = mDispatch->schedule(cb2, {.workDuration = 100, .readyDuration = 0, .lastVsync = 2000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1900, *result);
@@ -1034,21 +999,21 @@
CountingCallback cb2(mDispatch);
Sequence seq;
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
.InSequence(seq)
.WillOnce(Return(1000));
EXPECT_CALL(mMockClock, alarmAt(_, 600)).InSequence(seq);
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000, std::optional<nsecs_t>(1000)))
.InSequence(seq)
.WillOnce(Return(1000));
auto result =
- mDispatch->schedule(cb1,
- {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb1, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(600, *result);
- result = mDispatch->schedule(cb2,
- {.workDuration = 390, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb2, {.workDuration = 390, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(610, *result);
@@ -1070,10 +1035,9 @@
EXPECT_CALL(mMockClock, alarmAt(_, 900));
CountingCallback cb(mDispatch);
- const auto result = mDispatch->schedule(cb,
- {.workDuration = 70,
- .readyDuration = 30,
- .earliestVsync = intended});
+ const auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 70, .readyDuration = 30, .lastVsync = intended});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(900, *result);
advanceToNextCallback();
@@ -1094,8 +1058,8 @@
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
@@ -1118,8 +1082,8 @@
CountingCallback cb(mDispatch);
- mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .earliestVsync = 1000});
- mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 400, .readyDuration = 0, .lastVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 1400, .readyDuration = 0, .lastVsync = 1000});
advanceToNextCallback();
@@ -1139,14 +1103,12 @@
EXPECT_CALL(mMockClock, alarmAt(_, 500));
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
mMockClock.advanceBy(300);
- result = mDispatch->schedule(cb,
- {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(1200, *result);
@@ -1162,14 +1124,12 @@
EXPECT_CALL(mMockClock, alarmAt(_, 300)).InSequence(seq);
CountingCallback cb(mDispatch);
auto result =
- mDispatch->schedule(cb,
- {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ mDispatch->schedule(cb, {.workDuration = 500, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(500, *result);
mMockClock.advanceBy(300);
- result = mDispatch->schedule(cb,
- {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ result = mDispatch->schedule(cb, {.workDuration = 800, .readyDuration = 0, .lastVsync = 1000});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(300, *result);
@@ -1204,7 +1164,7 @@
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
auto const wakeup = entry.wakeupTime();
@@ -1219,14 +1179,15 @@
auto const duration = 500;
auto const now = 8750;
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(now + duration))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(now + duration, std::optional<nsecs_t>(994)))
.Times(1)
.WillOnce(Return(10000));
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .earliestVsync = 994},
+ EXPECT_TRUE(entry.schedule({.workDuration = 500, .readyDuration = 0, .lastVsync = 994},
*mStubTracker.get(), now)
.has_value());
auto const wakeup = entry.wakeupTime();
@@ -1249,7 +1210,7 @@
},
mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
auto const wakeup = entry.wakeupTime();
@@ -1272,7 +1233,7 @@
}
TEST_F(VSyncDispatchTimerQueueEntryTest, updateCallback) {
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(_, _))
.Times(2)
.WillOnce(Return(1000))
.WillOnce(Return(1020));
@@ -1284,7 +1245,7 @@
entry.update(*mStubTracker.get(), 0);
EXPECT_FALSE(entry.wakeupTime());
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
auto wakeup = entry.wakeupTime();
@@ -1300,7 +1261,7 @@
TEST_F(VSyncDispatchTimerQueueEntryTest, skipsUpdateIfJustScheduled) {
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
entry.update(*mStubTracker.get(), 0);
@@ -1313,24 +1274,24 @@
TEST_F(VSyncDispatchTimerQueueEntryTest, willSnapToNextTargettableVSync) {
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
entry.executing(); // 1000 is executing
// had 1000 not been executing, this could have been scheduled for time 800.
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
EXPECT_THAT(*entry.readyTime(), Eq(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
EXPECT_THAT(*entry.wakeupTime(), Eq(1950));
EXPECT_THAT(*entry.readyTime(), Eq(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 1001},
+ EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 1001},
*mStubTracker.get(), 0)
.has_value());
EXPECT_THAT(*entry.wakeupTime(), Eq(1800));
@@ -1343,23 +1304,25 @@
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
Sequence seq;
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
.InSequence(seq)
.WillOnce(Return(1000));
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500))
+ EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(500, std::optional<nsecs_t>(500)))
.InSequence(seq)
.WillOnce(Return(1000));
- EXPECT_CALL(*mStubTracker.get(), nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold))
+ EXPECT_CALL(*mStubTracker.get(),
+ nextAnticipatedVSyncTimeFrom(1000 + mVsyncMoveThreshold,
+ std::optional<nsecs_t>(1000)))
.InSequence(seq)
.WillOnce(Return(2000));
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
entry.executing(); // 1000 is executing
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
}
@@ -1367,16 +1330,16 @@
TEST_F(VSyncDispatchTimerQueueEntryTest, reportsScheduledIfStillTime) {
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 100, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
- EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 200, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
- EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 50, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
- EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 1200, .readyDuration = 0, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
}
@@ -1386,9 +1349,9 @@
VSyncDispatchTimerQueueEntry entry(
"test", [](auto, auto, auto) {}, mVsyncMoveThreshold);
EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
- entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .earliestVsync = 400});
+ entry.addPendingWorkloadUpdate({.workDuration = 100, .readyDuration = 0, .lastVsync = 400});
entry.addPendingWorkloadUpdate(
- {.workDuration = effectualOffset, .readyDuration = 0, .earliestVsync = 400});
+ {.workDuration = effectualOffset, .readyDuration = 0, .lastVsync = 400});
EXPECT_TRUE(entry.hasPendingWorkloadUpdate());
entry.update(*mStubTracker.get(), 0);
EXPECT_FALSE(entry.hasPendingWorkloadUpdate());
@@ -1410,7 +1373,7 @@
},
mVsyncMoveThreshold);
- EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .earliestVsync = 500},
+ EXPECT_TRUE(entry.schedule({.workDuration = 70, .readyDuration = 30, .lastVsync = 500},
*mStubTracker.get(), 0)
.has_value());
auto const wakeup = entry.wakeupTime();
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 7a498c9..961ba57 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -662,7 +662,7 @@
const auto refreshRate = Fps::fromPeriodNsecs(mPeriod);
NotifyExpectedPresentConfig notifyExpectedPresentConfig;
- notifyExpectedPresentConfig.notifyExpectedPresentTimeoutNs = Period::fromNs(30).ns();
+ notifyExpectedPresentConfig.timeoutNs = Period::fromNs(30).ns();
hal::VrrConfig vrrConfig;
vrrConfig.notifyExpectedPresentConfig = notifyExpectedPresentConfig;
@@ -720,15 +720,17 @@
vrrTracker.setRenderRate(minFrameRate);
vrrTracker.addVsyncTimestamp(0);
EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
- EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1300));
+ EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000));
vrrTracker.onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500));
- EXPECT_EQ(1500, vrrTracker.nextAnticipatedVSyncTimeFrom(1300));
- EXPECT_EQ(2500, vrrTracker.nextAnticipatedVSyncTimeFrom(2300));
+ EXPECT_EQ(3500, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 2000));
+ EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(3500, 3500));
- vrrTracker.onFrameMissed(TimePoint::fromNs(2500));
- EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2300));
- EXPECT_EQ(4000, vrrTracker.nextAnticipatedVSyncTimeFrom(3300));
+ // Miss when starting 4500 and expect the next vsync will be at 5000 (next one)
+ vrrTracker.onFrameBegin(TimePoint::fromNs(3500), TimePoint::fromNs(2500));
+ vrrTracker.onFrameMissed(TimePoint::fromNs(4500));
+ EXPECT_EQ(5000, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500));
+ EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000));
}
} // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPower.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPower.h
index a088aab..ed1405b 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPower.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPower.h
@@ -18,12 +18,21 @@
#include "binder/Status.h"
+// FMQ library in IPower does questionable conversions
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
#include <aidl/android/hardware/power/IPower.h>
+#pragma clang diagnostic pop
+
#include <gmock/gmock.h>
using aidl::android::hardware::power::Boost;
+using aidl::android::hardware::power::ChannelConfig;
using aidl::android::hardware::power::IPower;
using aidl::android::hardware::power::IPowerHintSession;
+using aidl::android::hardware::power::SessionConfig;
+using aidl::android::hardware::power::SessionTag;
+
using aidl::android::hardware::power::Mode;
using android::binder::Status;
@@ -42,6 +51,14 @@
int64_t durationNanos, std::shared_ptr<IPowerHintSession>* session),
(override));
MOCK_METHOD(ndk::ScopedAStatus, getHintSessionPreferredRate, (int64_t * rate), (override));
+ MOCK_METHOD(ndk::ScopedAStatus, createHintSessionWithConfig,
+ (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
+ int64_t durationNanos, SessionTag tag, SessionConfig* config,
+ std::shared_ptr<IPowerHintSession>* _aidl_return),
+ (override));
+ MOCK_METHOD(ndk::ScopedAStatus, getSessionChannel,
+ (int32_t tgid, int32_t uid, ChannelConfig* _aidl_return), (override));
+ MOCK_METHOD(ndk::ScopedAStatus, closeSessionChannel, (int32_t tgid, int32_t uid), (override));
MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t * version), (override));
MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string * hash), (override));
MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPowerHintSession.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPowerHintSession.h
index 364618d..27564b2 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPowerHintSession.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockIPowerHintSession.h
@@ -18,10 +18,15 @@
#include "binder/Status.h"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
#include <aidl/android/hardware/power/IPower.h>
+#pragma clang diagnostic pop
+
#include <gmock/gmock.h>
using aidl::android::hardware::power::IPowerHintSession;
+using aidl::android::hardware::power::SessionConfig;
using aidl::android::hardware::power::SessionHint;
using aidl::android::hardware::power::SessionMode;
using android::binder::Status;
@@ -47,6 +52,7 @@
MOCK_METHOD(ndk::ScopedAStatus, sendHint, (SessionHint), (override));
MOCK_METHOD(ndk::ScopedAStatus, setThreads, (const ::std::vector<int32_t>&), (override));
MOCK_METHOD(ndk::ScopedAStatus, setMode, (SessionMode, bool), (override));
+ MOCK_METHOD(ndk::ScopedAStatus, getSessionConfig, (SessionConfig * _aidl_return), (override));
};
} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h
index 68fe3c5..b17c8ad 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h
@@ -19,7 +19,10 @@
#include <gmock/gmock.h>
#include <scheduler/Time.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
#include <powermanager/PowerHalController.h>
+#pragma clang diagnostic pop
namespace android {
namespace hardware {
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 866af3b..e2b0ed1 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -59,6 +59,9 @@
MOCK_METHOD(void, requestLatestConfig, (const sp<android::EventThreadConnection>&));
MOCK_METHOD(void, pauseVsyncCallback, (bool));
MOCK_METHOD(void, onNewVsyncSchedule, (std::shared_ptr<scheduler::VsyncSchedule>), (override));
+ MOCK_METHOD(void, onHdcpLevelsChanged,
+ (PhysicalDisplayId displayId, int32_t connectedLevel, int32_t maxLevel),
+ (override));
};
} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index e588bb9..3870983 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -28,7 +28,8 @@
~VSyncTracker() override;
MOCK_METHOD(bool, addVsyncTimestamp, (nsecs_t), (override));
- MOCK_METHOD(nsecs_t, nextAnticipatedVSyncTimeFrom, (nsecs_t), (const, override));
+ MOCK_METHOD(nsecs_t, nextAnticipatedVSyncTimeFrom, (nsecs_t, std::optional<nsecs_t>),
+ (const, override));
MOCK_METHOD(nsecs_t, currentPeriod, (), (const, override));
MOCK_METHOD(Period, minFramePeriod, (), (const, override));
MOCK_METHOD(void, resetModel, (), (override));