Merge "Strengthen dataspace guarantees in SurfaceFlinger." into udc-dev
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index aa0ef25..1c4e63e 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -38,6 +38,7 @@
],
init_rc: ["atrace.rc"],
+ required: ["ftrace_synthetic_events.conf"],
product_variables: {
debuggable: {
@@ -45,3 +46,8 @@
},
},
}
+
+prebuilt_etc {
+ name: "ftrace_synthetic_events.conf",
+ src: "ftrace_synthetic_events.conf",
+}
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index e66cc41..92b1677 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -291,12 +291,10 @@
# Setup synthetic events
chmod 0666 /sys/kernel/tracing/synthetic_events
chmod 0666 /sys/kernel/debug/tracing/synthetic_events
+ copy /system/etc/ftrace_synthetic_events.conf /sys/kernel/tracing/synthetic_events
+ copy /system/etc/ftrace_synthetic_events.conf /sys/kernel/debug/tracing/synthetic_events
- # rss_stat_throttled
- write /sys/kernel/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size"
- write /sys/kernel/debug/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size"
-
- # allow creating event triggers
+ # allow creating rss_stat event triggers
chmod 0666 /sys/kernel/tracing/events/kmem/rss_stat/trigger
chmod 0666 /sys/kernel/debug/tracing/events/kmem/rss_stat/trigger
@@ -304,6 +302,14 @@
chmod 0666 /sys/kernel/tracing/events/synthetic/rss_stat_throttled/enable
chmod 0666 /sys/kernel/debug/tracing/events/synthetic/rss_stat_throttled/enable
+ # allow creating suspend_resume triggers
+ chmod 0666 /sys/kernel/tracing/events/power/suspend_resume/trigger
+ chmod 0666 /sys/kernel/debug/tracing/events/power/suspend_resume/trigger
+
+ # allow enabling suspend_resume_minimal
+ chmod 0666 /sys/kernel/tracing/events/synthetic/suspend_resume_minimal/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/synthetic/suspend_resume_minimal/enable
+
on late-init && property:ro.boot.fastboot.boottrace=enabled
setprop debug.atrace.tags.enableflags 802922
setprop persist.traced.enable 0
diff --git a/cmds/atrace/ftrace_synthetic_events.conf b/cmds/atrace/ftrace_synthetic_events.conf
new file mode 100644
index 0000000..e2257fe
--- /dev/null
+++ b/cmds/atrace/ftrace_synthetic_events.conf
@@ -0,0 +1,2 @@
+rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size
+suspend_resume_minimal bool start
diff --git a/cmds/cmd/fuzzer/Android.bp b/cmds/cmd/fuzzer/Android.bp
index a65f6de..faf461a 100644
--- a/cmds/cmd/fuzzer/Android.bp
+++ b/cmds/cmd/fuzzer/Android.bp
@@ -42,5 +42,13 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 155276,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libcmd",
+ vector: "local_no_privileges_required",
+ service_privilege: "constrained",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index baf8e42..043a7f1 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2236,8 +2236,7 @@
const uint64_t start = Nanotime();
const int ret = dump_backtrace_to_file_timeout(
- pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace,
- is_java_process ? 5 : 20, fd);
+ pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace, 3, fd);
if (ret == -1) {
// For consistency, the header and footer to this message match those
@@ -2816,6 +2815,7 @@
options->do_screenshot = false;
break;
case Dumpstate::BugreportMode::BUGREPORT_WEAR:
+ options->do_vibrate = false;
options->do_progress_updates = true;
options->do_screenshot = is_screenshot_requested;
break;
@@ -3361,8 +3361,7 @@
"WMShell", "protolog", "save-for-bugreport"},
CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());
- // Currently WindowManagerService and InputMethodManagerSerivice support WinScope protocol.
- for (const auto& service : {"input_method", "window"}) {
+ for (const auto& service : {"input_method", "window", "window shell"}) {
RunCommand(
// Empty name because it's not intended to be classified as a bugreport section.
// Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport.
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index aa5219b..93d8cdf 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -286,8 +286,8 @@
// Other options retain default values
- EXPECT_TRUE(options_.do_vibrate);
EXPECT_FALSE(options_.progress_updates_to_socket);
+ EXPECT_FALSE(options_.do_vibrate);
EXPECT_FALSE(options_.show_header_only);
EXPECT_FALSE(options_.is_remote_mode);
EXPECT_FALSE(options_.stream_to_socket);
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 1386660..d73a30b 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -72,6 +72,7 @@
cc_test {
name: "servicemanager_test",
+ host_supported: true,
test_suites: ["device-tests"],
defaults: ["servicemanager_defaults"],
srcs: [
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index d4ce466..cc8ac0a 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -337,26 +337,26 @@
auto ctx = mAccess->getCallingContext();
if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services");
+ return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services.");
}
if (!mAccess->canAdd(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
if (binder == nullptr) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder");
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder.");
}
if (!isValidServiceName(name)) {
ALOGE("Invalid service name: %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name");
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name.");
}
#ifndef VENDORSERVICEMANAGER
if (!meetsDeclarationRequirements(binder, name)) {
// already logged
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error");
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error.");
}
#endif // !VENDORSERVICEMANAGER
@@ -368,7 +368,7 @@
if (binder->remoteBinder() != nullptr &&
binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
ALOGE("Could not linkToDeath when adding %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "linkToDeath failure");
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Couldn't linkToDeath.");
}
auto it = mNameToService.find(name);
@@ -422,7 +422,7 @@
Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
if (!mAccess->canList(mAccess->getCallingContext())) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
size_t toReserve = 0;
@@ -466,18 +466,18 @@
if (!isValidServiceName(name)) {
ALOGE("Invalid service name: %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name.");
}
if (callback == nullptr) {
- return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Null callback.");
}
if (OK !=
IInterface::asBinder(callback)->linkToDeath(
sp<ServiceManager>::fromExisting(this))) {
ALOGE("Could not linkToDeath when adding %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Couldn't link to death.");
}
mNameToRegistrationCallback[name].push_back(callback);
@@ -497,7 +497,7 @@
auto ctx = mAccess->getCallingContext();
if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
bool found = false;
@@ -509,7 +509,7 @@
if (!found) {
ALOGE("Trying to unregister callback, but none exists %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Nothing to unregister.");
}
return Status::ok();
@@ -519,7 +519,7 @@
auto ctx = mAccess->getCallingContext();
if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
*outReturn = false;
@@ -547,7 +547,7 @@
}
if (outReturn->size() == 0 && allInstances.size() != 0) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
return Status::ok();
@@ -558,7 +558,7 @@
auto ctx = mAccess->getCallingContext();
if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
*outReturn = std::nullopt;
@@ -587,7 +587,7 @@
}
if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
return Status::ok();
@@ -598,7 +598,7 @@
auto ctx = mAccess->getCallingContext();
if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
*outReturn = std::nullopt;
@@ -667,36 +667,37 @@
Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
const sp<IClientCallback>& cb) {
if (cb == nullptr) {
- return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Callback null.");
}
auto ctx = mAccess->getCallingContext();
if (!mAccess->canAdd(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
auto serviceIt = mNameToService.find(name);
if (serviceIt == mNameToService.end()) {
ALOGE("Could not add callback for nonexistent service: %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Service doesn't exist.");
}
if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
ALOGW("Only a server can register for client callbacks (for %s)", name.c_str());
- return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ "Only service can register client callback for itself.");
}
if (serviceIt->second.binder != service) {
ALOGW("Tried to register client callback for %s but a different service is registered "
"under this name.",
name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Service mismatch.");
}
if (OK !=
IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
ALOGE("Could not linkToDeath when adding client callback for %s", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Couldn't linkToDeath.");
}
mNameToClientCallback[name].push_back(cb);
@@ -810,24 +811,25 @@
Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
if (binder == nullptr) {
- return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+ return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Null service.");
}
auto ctx = mAccess->getCallingContext();
if (!mAccess->canAdd(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
auto serviceIt = mNameToService.find(name);
if (serviceIt == mNameToService.end()) {
ALOGW("Tried to unregister %s, but that service wasn't registered to begin with.",
name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Service not registered.");
}
if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
ALOGW("Only a server can unregister itself (for %s)", name.c_str());
- return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
+ return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
+ "Service can only unregister itself.");
}
sp<IBinder> storedBinder = serviceIt->second.binder;
@@ -835,14 +837,16 @@
if (binder != storedBinder) {
ALOGW("Tried to unregister %s, but a different service is registered under this name.",
name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE,
+ "Different service registered under this name.");
}
// important because we don't have timer-based guarantees, we don't want to clear
// this
if (serviceIt->second.guaranteeClient) {
ALOGI("Tried to unregister %s, but there is about to be a client.", name.c_str());
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE,
+ "Can't unregister, pending client.");
}
// - kernel driver will hold onto one refcount (during this transaction)
@@ -857,7 +861,8 @@
// help reduce thrashing, but we should be able to remove it.
serviceIt->second.guaranteeClient = true;
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE,
+ "Can't unregister, known client.");
}
ALOGI("Unregistering %s", name.c_str());
@@ -868,7 +873,7 @@
Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
if (!mAccess->canList(mAccess->getCallingContext())) {
- return Status::fromExceptionCode(Status::EX_SECURITY);
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
}
outReturn->reserve(mNameToService.size());
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index d4ba321..f8fb256 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -831,6 +831,14 @@
AKEYCODE_STYLUS_BUTTON_TAIL = 311,
/** Key to open recent apps (a.k.a. Overview) */
AKEYCODE_RECENT_APPS = 312,
+ /** User customizable key #1. */
+ AKEYCODE_MACRO_1 = 313,
+ /** User customizable key #2. */
+ AKEYCODE_MACRO_2 = 314,
+ /** User customizable key #3. */
+ AKEYCODE_MACRO_3 = 315,
+ /** User customizable key #4. */
+ AKEYCODE_MACRO_4 = 316,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/input/Input.h b/include/input/Input.h
index e8af5f7..a033535 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -216,7 +216,21 @@
bool isFromSource(uint32_t source, uint32_t test);
-bool isStylusToolType(uint32_t toolType);
+/**
+ * The pointer tool type.
+ */
+enum class ToolType {
+ UNKNOWN = AMOTION_EVENT_TOOL_TYPE_UNKNOWN,
+ FINGER = AMOTION_EVENT_TOOL_TYPE_FINGER,
+ STYLUS = AMOTION_EVENT_TOOL_TYPE_STYLUS,
+ MOUSE = AMOTION_EVENT_TOOL_TYPE_MOUSE,
+ ERASER = AMOTION_EVENT_TOOL_TYPE_ERASER,
+ PALM = AMOTION_EVENT_TOOL_TYPE_PALM,
+ ftl_first = UNKNOWN,
+ ftl_last = PALM,
+};
+
+bool isStylusToolType(ToolType toolType);
/*
* Flags that flow alongside events in the input dispatch system to help with certain
@@ -320,8 +334,6 @@
*/
const char* motionClassificationToString(MotionClassification classification);
-const char* motionToolTypeToString(int32_t toolType);
-
/**
* Portion of FrameMetrics timeline of interest to input code.
*/
@@ -448,11 +460,11 @@
int32_t id;
// The pointer tool type.
- int32_t toolType;
+ ToolType toolType;
inline void clear() {
id = -1;
- toolType = 0;
+ toolType = ToolType::UNKNOWN;
}
bool operator==(const PointerProperties& other) const;
@@ -638,7 +650,7 @@
return mPointerProperties[pointerIndex].id;
}
- inline int32_t getToolType(size_t pointerIndex) const {
+ inline ToolType getToolType(size_t pointerIndex) const {
return mPointerProperties[pointerIndex].toolType;
}
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index a1be542..4f53c36 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -669,7 +669,6 @@
static void addSample(MotionEvent* event, const InputMessage* msg);
static bool canAddSample(const Batch& batch, const InputMessage* msg);
static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
- static bool shouldResampleTool(int32_t toolType);
static bool isTouchResamplingEnabled();
};
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 08169f5..ebdaa4c 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -131,6 +131,53 @@
*outResult = reply.readInt32();
return NO_ERROR;
}
+
+ virtual status_t logFgsApiBegin(int32_t apiType, int32_t appUid, int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
+
+ virtual status_t logFgsApiEnd(int32_t apiType, int32_t appUid, int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_END_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
+
+ virtual status_t logFgsApiStateChanged(int32_t apiType, int32_t state, int32_t appUid,
+ int32_t appPid) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
+ data.writeInt32(apiType);
+ data.writeInt32(state);
+ data.writeInt32(appUid);
+ data.writeInt32(appPid);
+ status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply);
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ ALOGD("FGS Logger Transaction failed");
+ ALOGD("%d", err);
+ return err;
+ }
+ return NO_ERROR;
+ }
};
// ------------------------------------------------------------------------------------
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 0d06e9e..851b407 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -295,7 +295,8 @@
bool RpcServer::shutdown() {
RpcMutexUniqueLock _l(mLock);
if (mShutdownTrigger == nullptr) {
- LOG_RPC_DETAIL("Cannot shutdown. No shutdown trigger installed (already shutdown?)");
+ LOG_RPC_DETAIL("Cannot shutdown. No shutdown trigger installed (already shutdown, or not "
+ "joined yet?)");
return false;
}
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 07b38d7..41707d4 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -79,6 +79,12 @@
},
{
"name": "rustBinderSerializationTest"
+ },
+ {
+ "name": "libbinder_ndk_bindgen_test"
+ },
+ {
+ "name": "libbinder_rpc_unstable_bindgen_test"
}
],
"presubmit-large": [
diff --git a/libs/binder/include_activitymanager/binder/IActivityManager.h b/libs/binder/include_activitymanager/binder/IActivityManager.h
index 4632b2e..20d12ae 100644
--- a/libs/binder/include_activitymanager/binder/IActivityManager.h
+++ b/libs/binder/include_activitymanager/binder/IActivityManager.h
@@ -42,6 +42,10 @@
const pid_t pid,
const uid_t uid,
int32_t* outResult) = 0;
+ virtual status_t logFgsApiBegin(int32_t apiType, int32_t appUid, int32_t appPid) = 0;
+ virtual status_t logFgsApiEnd(int32_t apiType, int32_t appUid, int32_t appPid) = 0;
+ virtual status_t logFgsApiStateChanged(int32_t apiType, int32_t state, int32_t appUid,
+ int32_t appPid) = 0;
enum {
OPEN_CONTENT_URI_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
@@ -50,6 +54,9 @@
IS_UID_ACTIVE_TRANSACTION,
GET_UID_PROCESS_STATE_TRANSACTION,
CHECK_PERMISSION_TRANSACTION,
+ LOG_FGS_API_BEGIN_TRANSACTION,
+ LOG_FGS_API_END_TRANSACTION,
+ LOG_FGS_API_STATE_CHANGED_TRANSACTION
};
};
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 61a047b..873e955 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -238,6 +238,13 @@
"binderRpcUniversalTests.cpp",
],
+ // This test uses a lot of resources and takes a long time. Due to
+ // design of several tests, it is also very sensitive to resource
+ // contention on the device. b/276820894
+ test_options: {
+ unit_test: false,
+ },
+
test_suites: ["general-tests"],
require_root: true,
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 8d1def1..504b3ce 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -382,9 +382,16 @@
status = session->setupPreconnectedClient({}, [=]() {
#ifdef BINDER_RPC_TO_TRUSTY_TEST
auto port = trustyIpcPort(serverVersion);
- int tipcFd = tipc_connect(kTrustyIpcDevice, port.c_str());
- return tipcFd >= 0 ? android::base::unique_fd(tipcFd)
- : android::base::unique_fd();
+ for (size_t i = 0; i < 5; i++) {
+ // Try to connect several times,
+ // in case the service is slow to start
+ int tipcFd = tipc_connect(kTrustyIpcDevice, port.c_str());
+ if (tipcFd >= 0) {
+ return android::base::unique_fd(tipcFd);
+ }
+ usleep(50000);
+ }
+ return android::base::unique_fd();
#else
LOG_ALWAYS_FATAL("Tried to connect to Trusty outside of vendor");
return android::base::unique_fd();
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 6da7a5b..46d387c 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -374,7 +374,8 @@
parcelables::GenericDataParcelable genericDataParcelable;
status_t status = genericDataParcelable.readFromParcel(&p);
FUZZ_LOG() << " status: " << status;
- FUZZ_LOG() << " toString() result: " << genericDataParcelable.toString();
+ std::string toString = genericDataParcelable.toString();
+ FUZZ_LOG() << " toString() result: " << toString;
},
};
// clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index 08eb27a..3a1471e 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -198,6 +198,8 @@
aidl::parcelables::GenericDataParcelable genericDataParcelable;
binder_status_t status = genericDataParcelable.readFromParcel(p.aParcel());
FUZZ_LOG() << "status: " << status;
+ std::string toString = genericDataParcelable.toString();
+ FUZZ_LOG() << "toString() result: " << toString;
},
[](const NdkParcelAdapter& p, FuzzedDataProvider& provider) {
FUZZ_LOG() << "about to marshal AParcel";
diff --git a/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
index 01e6999..dd08f72 100644
--- a/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
+++ b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
@@ -16,6 +16,14 @@
package parcelables;
parcelable GenericDataParcelable {
+ enum JustSomeEnum {
+ SOME_ENUMERATOR,
+ ANOTHER_ENUMERATOR,
+ MAYBE_ONE_MORE_ENUMERATOR,
+ }
+
+ const int COOL_CONSTANT = 0x1234;
+
int data;
float majorVersion;
float minorVersion;
@@ -25,4 +33,6 @@
String greatString;
@utf8InCpp
String greaterString;
+ @nullable String nullableString;
+ JustSomeEnum gretEnum = JustSomeEnum.ANOTHER_ENUMERATOR;
}
diff --git a/libs/binder/trusty/RpcServerTrusty.cpp b/libs/binder/trusty/RpcServerTrusty.cpp
index 109da75..3a99606 100644
--- a/libs/binder/trusty/RpcServerTrusty.cpp
+++ b/libs/binder/trusty/RpcServerTrusty.cpp
@@ -154,8 +154,18 @@
return NO_ERROR;
}
-void RpcServerTrusty::handleDisconnect(const tipc_port* /*port*/, handle_t /*chan*/,
- void* /*ctx*/) {}
+void RpcServerTrusty::handleDisconnect(const tipc_port* /*port*/, handle_t /*chan*/, void* ctx) {
+ auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
+ if (channelContext == nullptr) {
+ // Connections marked "incoming" (outgoing from the server's side)
+ // do not have a valid channel context because joinFn does not get
+ // called for them. We ignore them here.
+ return;
+ }
+
+ auto& session = channelContext->session;
+ (void)session->shutdownAndWait(false);
+}
void RpcServerTrusty::handleChannelCleanup(void* ctx) {
auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
diff --git a/libs/binder/trusty/binderRpcTest/rules.mk b/libs/binder/trusty/binderRpcTest/rules.mk
index ae39492..975f689 100644
--- a/libs/binder/trusty/binderRpcTest/rules.mk
+++ b/libs/binder/trusty/binderRpcTest/rules.mk
@@ -32,4 +32,8 @@
trusty/user/base/lib/googletest \
trusty/user/base/lib/libstdc++-trusty \
+# TEST_P tests from binderRpcUniversalTests.cpp don't get linked in
+# unless we pass in --whole-archive to the linker (b/275620340).
+MODULE_USE_WHOLE_ARCHIVE := true
+
include make/trusted_app.mk
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index b391337..fee91a4 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -190,8 +190,8 @@
}
SAFE_PARCEL(output.writeParcelable, trustedPresentationThresholds);
SAFE_PARCEL(output.writeParcelable, trustedPresentationListener);
- SAFE_PARCEL(output.writeFloat, currentSdrHdrRatio);
- SAFE_PARCEL(output.writeFloat, desiredSdrHdrRatio);
+ SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
+ SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint))
return NO_ERROR;
}
@@ -335,9 +335,9 @@
SAFE_PARCEL(input.readParcelable, &trustedPresentationListener);
SAFE_PARCEL(input.readFloat, &tmpFloat);
- currentSdrHdrRatio = tmpFloat;
+ currentHdrSdrRatio = tmpFloat;
SAFE_PARCEL(input.readFloat, &tmpFloat);
- desiredSdrHdrRatio = tmpFloat;
+ desiredHdrSdrRatio = tmpFloat;
int32_t tmpInt32;
SAFE_PARCEL(input.readInt32, &tmpInt32);
@@ -592,8 +592,8 @@
}
if (other.what & eExtendedRangeBrightnessChanged) {
what |= eExtendedRangeBrightnessChanged;
- desiredSdrHdrRatio = other.desiredSdrHdrRatio;
- currentSdrHdrRatio = other.currentSdrHdrRatio;
+ desiredHdrSdrRatio = other.desiredHdrSdrRatio;
+ currentHdrSdrRatio = other.currentHdrSdrRatio;
}
if (other.what & eCachingHintChanged) {
what |= eCachingHintChanged;
@@ -747,8 +747,8 @@
CHECK_DIFF(diff, eCropChanged, other, crop);
if (other.what & eBufferChanged) diff |= eBufferChanged;
CHECK_DIFF(diff, eDataspaceChanged, other, dataspace);
- CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentSdrHdrRatio,
- desiredSdrHdrRatio);
+ CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentHdrSdrRatio,
+ desiredHdrSdrRatio);
CHECK_DIFF(diff, eCachingHintChanged, other, cachingHint);
CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata);
if (other.what & eSurfaceDamageRegionChanged &&
@@ -897,6 +897,11 @@
SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace));
SAFE_PARCEL(output->writeBool, allowProtected);
SAFE_PARCEL(output->writeBool, grayscale);
+
+ SAFE_PARCEL(output->writeInt32, excludeHandles.size());
+ for (auto& excludeHandle : excludeHandles) {
+ SAFE_PARCEL(output->writeStrongBinder, excludeHandle);
+ }
return NO_ERROR;
}
@@ -913,6 +918,15 @@
dataspace = static_cast<ui::Dataspace>(value);
SAFE_PARCEL(input->readBool, &allowProtected);
SAFE_PARCEL(input->readBool, &grayscale);
+
+ int32_t numExcludeHandles = 0;
+ SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
+ excludeHandles.reserve(numExcludeHandles);
+ for (int i = 0; i < numExcludeHandles; i++) {
+ sp<IBinder> binder;
+ SAFE_PARCEL(input->readStrongBinder, &binder);
+ excludeHandles.emplace(binder);
+ }
return NO_ERROR;
}
@@ -940,10 +954,6 @@
SAFE_PARCEL(CaptureArgs::writeToParcel, output);
SAFE_PARCEL(output->writeStrongBinder, layerHandle);
- SAFE_PARCEL(output->writeInt32, excludeHandles.size());
- for (auto el : excludeHandles) {
- SAFE_PARCEL(output->writeStrongBinder, el);
- }
SAFE_PARCEL(output->writeBool, childrenOnly);
return NO_ERROR;
}
@@ -953,15 +963,6 @@
SAFE_PARCEL(input->readStrongBinder, &layerHandle);
- int32_t numExcludeHandles = 0;
- SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
- excludeHandles.reserve(numExcludeHandles);
- for (int i = 0; i < numExcludeHandles; i++) {
- sp<IBinder> binder;
- SAFE_PARCEL(input->readStrongBinder, &binder);
- excludeHandles.emplace(binder);
- }
-
SAFE_PARCEL(input->readBool, &childrenOnly);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2f5830d..7700aa4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1723,8 +1723,8 @@
return *this;
}
s->what |= layer_state_t::eExtendedRangeBrightnessChanged;
- s->currentSdrHdrRatio = currentBufferRatio;
- s->desiredSdrHdrRatio = desiredRatio;
+ s->currentHdrSdrRatio = currentBufferRatio;
+ s->desiredHdrSdrRatio = desiredRatio;
registerSurfaceControlForCallback(sc);
return *this;
diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp
index 804ce4f..6df9ff1 100644
--- a/libs/gui/WindowInfo.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -125,6 +125,7 @@
parcel->writeBool(replaceTouchableRegionWithCrop) ?:
parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
parcel->writeStrongBinder(windowToken);
+ parcel->writeStrongBinder(focusTransferTarget);
// clang-format on
return status;
}
@@ -175,7 +176,9 @@
parcel->read(touchableRegion) ?:
parcel->readBool(&replaceTouchableRegionWithCrop) ?:
parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
- parcel->readNullableStrongBinder(&windowToken);
+ parcel->readNullableStrongBinder(&windowToken) ?:
+ parcel->readNullableStrongBinder(&focusTransferTarget);
+
// clang-format on
if (status != OK) {
diff --git a/libs/gui/android/gui/FocusRequest.aidl b/libs/gui/android/gui/FocusRequest.aidl
index b13c600..62d1b68 100644
--- a/libs/gui/android/gui/FocusRequest.aidl
+++ b/libs/gui/android/gui/FocusRequest.aidl
@@ -24,15 +24,6 @@
@nullable IBinder token;
@utf8InCpp String windowName;
/**
- * The token that the caller expects currently to be focused. If the
- * specified token does not match the currently focused window, this request will be dropped.
- * If the specified focused token matches the currently focused window, the call will succeed.
- * Set this to "null" if this call should succeed no matter what the currently focused token
- * is.
- */
- @nullable IBinder focusedToken;
- @utf8InCpp String focusedWindowName;
- /**
* SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm) when requesting the focus
* change. This determines which request gets precedence if there is a focus change request
* from another source such as pointer down.
diff --git a/libs/gui/include/gui/DisplayCaptureArgs.h b/libs/gui/include/gui/DisplayCaptureArgs.h
index c826c17..5c794ae 100644
--- a/libs/gui/include/gui/DisplayCaptureArgs.h
+++ b/libs/gui/include/gui/DisplayCaptureArgs.h
@@ -22,9 +22,11 @@
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
+#include <gui/SpHash.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
+#include <unordered_set>
namespace android::gui {
@@ -55,6 +57,8 @@
bool grayscale = false;
+ std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
+
virtual status_t writeToParcel(Parcel* output) const;
virtual status_t readFromParcel(const Parcel* input);
};
diff --git a/libs/gui/include/gui/LayerCaptureArgs.h b/libs/gui/include/gui/LayerCaptureArgs.h
index 05ff9d5..fae2bcc 100644
--- a/libs/gui/include/gui/LayerCaptureArgs.h
+++ b/libs/gui/include/gui/LayerCaptureArgs.h
@@ -20,14 +20,11 @@
#include <sys/types.h>
#include <gui/DisplayCaptureArgs.h>
-#include <gui/SpHash.h>
-#include <unordered_set>
namespace android::gui {
struct LayerCaptureArgs : CaptureArgs {
sp<IBinder> layerHandle;
- std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
bool childrenOnly{false};
status_t writeToParcel(Parcel* output) const override;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 6e3be5c..5c88a07 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -389,8 +389,8 @@
gui::DropInputMode dropInputMode;
bool dimmingEnabled;
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index b01a3db..70b2ee8 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -236,6 +236,11 @@
Type layoutParamsType = Type::UNKNOWN;
ftl::Flags<Flag> layoutParamsFlags;
+ // The input token for the window to which focus should be transferred when this input window
+ // can be successfully focused. If null, this input window will not transfer its focus to
+ // any other window.
+ sp<IBinder> focusTransferTarget;
+
void setInputConfig(ftl::Flags<InputConfig> config, bool value);
void addTouchableRegion(const Rect& region);
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 5f80c16..9e8c65c 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -272,8 +272,6 @@
FocusRequest request;
request.token = mInputInfo.token;
request.windowName = mInputInfo.name;
- request.focusedToken = nullptr;
- request.focusedWindowName = "";
request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
request.displayId = displayId;
t.setFocusedWindow(request);
diff --git a/libs/gui/tests/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp
index c51b244..11b87ef 100644
--- a/libs/gui/tests/WindowInfo_test.cpp
+++ b/libs/gui/tests/WindowInfo_test.cpp
@@ -71,6 +71,7 @@
i.applicationInfo.name = "ApplicationFooBar";
i.applicationInfo.token = new BBinder();
i.applicationInfo.dispatchingTimeoutMillis = 0x12345678ABCD;
+ i.focusTransferTarget = new BBinder();
Parcel p;
i.writeToParcel(&p);
@@ -101,6 +102,7 @@
ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop);
ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
ASSERT_EQ(i.applicationInfo, i2.applicationInfo);
+ ASSERT_EQ(i.focusTransferTarget, i2.focusTransferTarget);
}
TEST(InputApplicationInfo, Parcelling) {
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 53b22cb..4dbf575 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -79,25 +79,6 @@
}
}
-const char* motionToolTypeToString(int32_t toolType) {
- switch (toolType) {
- case AMOTION_EVENT_TOOL_TYPE_UNKNOWN:
- return "UNKNOWN";
- case AMOTION_EVENT_TOOL_TYPE_FINGER:
- return "FINGER";
- case AMOTION_EVENT_TOOL_TYPE_STYLUS:
- return "STYLUS";
- case AMOTION_EVENT_TOOL_TYPE_MOUSE:
- return "MOUSE";
- case AMOTION_EVENT_TOOL_TYPE_ERASER:
- return "ERASER";
- case AMOTION_EVENT_TOOL_TYPE_PALM:
- return "PALM";
- default:
- return "INVALID";
- }
-}
-
// --- IdGenerator ---
#if defined(__ANDROID__)
[[maybe_unused]]
@@ -256,8 +237,8 @@
return (source & test) == test;
}
-bool isStylusToolType(uint32_t toolType) {
- return toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS || toolType == AMOTION_EVENT_TOOL_TYPE_ERASER;
+bool isStylusToolType(ToolType toolType) {
+ return toolType == ToolType::STYLUS || toolType == ToolType::ERASER;
}
VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
@@ -810,7 +791,7 @@
mPointerProperties.push_back({});
PointerProperties& properties = mPointerProperties.back();
properties.id = parcel->readInt32();
- properties.toolType = parcel->readInt32();
+ properties.toolType = static_cast<ToolType>(parcel->readInt32());
}
while (sampleCount > 0) {
@@ -866,7 +847,7 @@
for (size_t i = 0; i < pointerCount; i++) {
const PointerProperties& properties = mPointerProperties[i];
parcel->writeInt32(properties.id);
- parcel->writeInt32(properties.toolType);
+ parcel->writeInt32(static_cast<int32_t>(properties.toolType));
}
const PointerCoords* pc = mSamplePointerCoords.data();
@@ -1030,9 +1011,9 @@
out << ", x[" << i << "]=" << x;
out << ", y[" << i << "]=" << y;
}
- int toolType = event.getToolType(i);
- if (toolType != AMOTION_EVENT_TOOL_TYPE_FINGER) {
- out << ", toolType[" << i << "]=" << toolType;
+ ToolType toolType = event.getToolType(i);
+ if (toolType != ToolType::FINGER) {
+ out << ", toolType[" << i << "]=" << ftl::enum_string(toolType);
}
}
if (event.getButtonState() != 0) {
diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp
index 4a19227..f99a7d6 100644
--- a/libs/input/InputEventLabels.cpp
+++ b/libs/input/InputEventLabels.cpp
@@ -343,7 +343,11 @@
DEFINE_KEYCODE(STYLUS_BUTTON_SECONDARY), \
DEFINE_KEYCODE(STYLUS_BUTTON_TERTIARY), \
DEFINE_KEYCODE(STYLUS_BUTTON_TAIL), \
- DEFINE_KEYCODE(RECENT_APPS)
+ DEFINE_KEYCODE(RECENT_APPS), \
+ DEFINE_KEYCODE(MACRO_1), \
+ DEFINE_KEYCODE(MACRO_2), \
+ DEFINE_KEYCODE(MACRO_3), \
+ DEFINE_KEYCODE(MACRO_4)
// NOTE: If you add a new axis here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 311b244..f6b4648 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -145,6 +145,10 @@
return value ? "true" : "false";
}
+static bool shouldResampleTool(ToolType toolType) {
+ return toolType == ToolType::FINGER || toolType == ToolType::UNKNOWN;
+}
+
// --- InputMessage ---
bool InputMessage::isValid(size_t actualSize) const {
@@ -1274,11 +1278,6 @@
event->addSample(sampleTime, touchState.lastResample.pointers);
}
-bool InputConsumer::shouldResampleTool(int32_t toolType) {
- return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
- || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
"channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
diff --git a/libs/input/MotionPredictor.cpp b/libs/input/MotionPredictor.cpp
index b4151c6..3037573 100644
--- a/libs/input/MotionPredictor.cpp
+++ b/libs/input/MotionPredictor.cpp
@@ -30,6 +30,7 @@
#include <log/log.h>
#include <attestation/HmacKeyManager.h>
+#include <ftl/enum.h>
#include <input/TfLiteMotionPredictor.h>
namespace android {
@@ -108,10 +109,10 @@
return {};
}
- const int32_t toolType = event.getPointerProperties(0)->toolType;
- if (toolType != AMOTION_EVENT_TOOL_TYPE_STYLUS) {
+ const ToolType toolType = event.getPointerProperties(0)->toolType;
+ if (toolType != ToolType::STYLUS) {
ALOGD_IF(isDebug(), "Prediction not supported for non-stylus tool: %s",
- motionToolTypeToString(toolType));
+ ftl::enum_string(toolType).c_str());
return {};
}
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 2132dc1..59125dd 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -259,10 +259,10 @@
mPointerProperties[0].clear();
mPointerProperties[0].id = 1;
- mPointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerProperties[0].toolType = ToolType::FINGER;
mPointerProperties[1].clear();
mPointerProperties[1].id = 2;
- mPointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mPointerProperties[1].toolType = ToolType::STYLUS;
mSamples[0].pointerCoords[0].clear();
mSamples[0].pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
@@ -366,9 +366,9 @@
ASSERT_EQ(2U, event->getPointerCount());
ASSERT_EQ(1, event->getPointerId(0));
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
+ ASSERT_EQ(ToolType::FINGER, event->getToolType(0));
ASSERT_EQ(2, event->getPointerId(1));
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
+ ASSERT_EQ(ToolType::STYLUS, event->getToolType(1));
ASSERT_EQ(2U, event->getHistorySize());
@@ -692,7 +692,7 @@
MotionEvent createMotionEvent(int32_t source, uint32_t action, float x, float y, float dx, float dy,
const ui::Transform& transform, const ui::Transform& rawTransform) {
std::vector<PointerProperties> pointerProperties;
- pointerProperties.push_back(PointerProperties{/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER});
+ pointerProperties.push_back(PointerProperties{/*id=*/0, ToolType::FINGER});
std::vector<PointerCoords> pointerCoords;
pointerCoords.emplace_back().clear();
pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, x);
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index 5d8b970..965fda7 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -172,7 +172,7 @@
for (size_t i = 0; i < pointerCount; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = (i + 2) % pointerCount;
- pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[i].toolType = ToolType::FINGER;
pointerCoords[i].clear();
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
diff --git a/libs/input/tests/MotionPredictor_test.cpp b/libs/input/tests/MotionPredictor_test.cpp
index c61efbf..7a62f5e 100644
--- a/libs/input/tests/MotionPredictor_test.cpp
+++ b/libs/input/tests/MotionPredictor_test.cpp
@@ -45,7 +45,7 @@
PointerProperties properties;
properties.clear();
properties.id = i;
- properties.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ properties.toolType = ToolType::STYLUS;
pointerProperties.push_back(properties);
PointerCoords coords;
coords.clear();
diff --git a/libs/input/tests/TouchResampling_test.cpp b/libs/input/tests/TouchResampling_test.cpp
index 7cb9526..655de80 100644
--- a/libs/input/tests/TouchResampling_test.cpp
+++ b/libs/input/tests/TouchResampling_test.cpp
@@ -99,7 +99,7 @@
properties.push_back({});
properties.back().clear();
properties.back().id = pointer.id;
- properties.back().toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ properties.back().toolType = ToolType::FINGER;
coords.push_back({});
coords.back().clear();
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 0277579..ae72109 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -212,7 +212,7 @@
coords[pointerIndex].isResampled = position.isResampled;
properties[pointerIndex].id = pointerId;
- properties[pointerIndex].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ properties[pointerIndex].toolType = ToolType::FINGER;
pointerIndex++;
}
EXPECT_EQ(pointerIndex, pointerCount);
diff --git a/libs/jpegrecoverymap/Android.bp b/libs/jpegrecoverymap/Android.bp
index b470f35..a1b0e19 100644
--- a/libs/jpegrecoverymap/Android.bp
+++ b/libs/jpegrecoverymap/Android.bp
@@ -24,7 +24,7 @@
cc_library {
name: "libjpegrecoverymap",
host_supported: true,
-
+ vendor_available: true,
export_include_dirs: ["include"],
local_include_dirs: ["include"],
@@ -49,10 +49,12 @@
cc_library {
name: "libjpegencoder",
host_supported: true,
+ vendor_available: true,
shared_libs: [
"libjpeg",
"liblog",
+ "libutils",
],
export_include_dirs: ["include"],
@@ -65,10 +67,12 @@
cc_library {
name: "libjpegdecoder",
host_supported: true,
+ vendor_available: true,
shared_libs: [
"libjpeg",
"liblog",
+ "libutils",
],
export_include_dirs: ["include"],
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
index dd06fa2..09f4165 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegrutils.h
@@ -105,14 +105,16 @@
* xmlns:Item="http://ns.google.com/photos/1.0/container/item/">
* <Container:Directory>
* <rdf:Seq>
- * <rdf:li>
+ * <rdf:li
+ * rdf:parseType="Resource">
* <Container:Item
* Item:Semantic="Primary"
* Item:Mime="image/jpeg"/>
* </rdf:li>
- * <rdf:li>
+ * <rdf:li
+ * rdf:parseType="Resource">
* <Container:Item
- * Item:Semantic="RecoveryMap"
+ * Item:Semantic="GainMap"
* Item:Mime="image/jpeg"
* Item:Length="1000"/>
* </rdf:li>
@@ -142,14 +144,14 @@
* <rdf:Description
* xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/"
* hdrgm:Version="1"
- * hdrgm:GainMapMin="0.5"
- * hdrgm:GainMapMax="8.5"
+ * hdrgm:GainMapMin="-1"
+ * hdrgm:GainMapMax="3"
* hdrgm:Gamma="1"
* hdrgm:OffsetSDR="0"
* hdrgm:OffsetHDR="0"
- * hdrgm:HDRCapacityMin="0.5"
- * hdrgm:HDRCapacityMax="8.5"
- * hdrgm:BaseRendition="SDR"/>
+ * hdrgm:HDRCapacityMin="0"
+ * hdrgm:HDRCapacityMax="3"
+ * hdrgm:BaseRenditionIsHDR="False"/>
* </rdf:RDF>
* </x:xmpmeta>
*
diff --git a/libs/jpegrecoverymap/jpegrutils.cpp b/libs/jpegrecoverymap/jpegrutils.cpp
index ff96447..cde0ceb 100644
--- a/libs/jpegrecoverymap/jpegrutils.cpp
+++ b/libs/jpegrecoverymap/jpegrutils.cpp
@@ -15,14 +15,17 @@
*/
#include <jpegrecoverymap/jpegrutils.h>
-#include <utils/Log.h>
+
+#include <algorithm>
+#include <cmath>
+
#include <image_io/xml/xml_reader.h>
#include <image_io/xml/xml_writer.h>
#include <image_io/base/message_handler.h>
#include <image_io/xml/xml_element_rules.h>
#include <image_io/xml/xml_handler.h>
#include <image_io/xml/xml_rule.h>
-#include <cmath>
+#include <utils/Log.h>
using namespace photos_editing_formats::image_io;
using namespace std;
@@ -230,26 +233,26 @@
const string kItemSemantic = Name(kItemPrefix, "Semantic");
// Item XMP constants - element and attribute values
-const string kSemanticPrimary = "Primary";
-const string kSemanticRecoveryMap = "RecoveryMap";
-const string kMimeImageJpeg = "image/jpeg";
+const string kSemanticPrimary = "Primary";
+const string kSemanticGainMap = "GainMap";
+const string kMimeImageJpeg = "image/jpeg";
-// RecoveryMap XMP constants - URI and namespace prefix
-const string kRecoveryMapUri = "http://ns.adobe.com/hdr-gain-map/1.0/";
-const string kRecoveryMapPrefix = "hdrgm";
+// GainMap XMP constants - URI and namespace prefix
+const string kGainMapUri = "http://ns.adobe.com/hdr-gain-map/1.0/";
+const string kGainMapPrefix = "hdrgm";
-// RecoveryMap XMP constants - element and attribute names
-const string kMapVersion = Name(kRecoveryMapPrefix, "Version");
-const string kMapGainMapMin = Name(kRecoveryMapPrefix, "GainMapMin");
-const string kMapGainMapMax = Name(kRecoveryMapPrefix, "GainMapMax");
-const string kMapGamma = Name(kRecoveryMapPrefix, "Gamma");
-const string kMapOffsetSdr = Name(kRecoveryMapPrefix, "OffsetSDR");
-const string kMapOffsetHdr = Name(kRecoveryMapPrefix, "OffsetHDR");
-const string kMapHDRCapacityMin = Name(kRecoveryMapPrefix, "HDRCapacityMin");
-const string kMapHDRCapacityMax = Name(kRecoveryMapPrefix, "HDRCapacityMax");
-const string kMapBaseRendition = Name(kRecoveryMapPrefix, "BaseRendition");
+// GainMap XMP constants - element and attribute names
+const string kMapVersion = Name(kGainMapPrefix, "Version");
+const string kMapGainMapMin = Name(kGainMapPrefix, "GainMapMin");
+const string kMapGainMapMax = Name(kGainMapPrefix, "GainMapMax");
+const string kMapGamma = Name(kGainMapPrefix, "Gamma");
+const string kMapOffsetSdr = Name(kGainMapPrefix, "OffsetSDR");
+const string kMapOffsetHdr = Name(kGainMapPrefix, "OffsetHDR");
+const string kMapHDRCapacityMin = Name(kGainMapPrefix, "HDRCapacityMin");
+const string kMapHDRCapacityMax = Name(kGainMapPrefix, "HDRCapacityMax");
+const string kMapBaseRenditionIsHDR = Name(kGainMapPrefix, "BaseRenditionIsHDR");
-// RecoveryMap XMP constants - names for XMP handlers
+// GainMap XMP constants - names for XMP handlers
const string XMPXmlHandler::minContentBoostAttrName = kMapGainMapMin;
const string XMPXmlHandler::maxContentBoostAttrName = kMapGainMapMax;
@@ -313,15 +316,23 @@
writer.StartWritingElement("rdf:Description");
writer.WriteXmlns(kContainerPrefix, kContainerUri);
writer.WriteXmlns(kItemPrefix, kItemUri);
+
writer.StartWritingElements(kConDirSeq);
- size_t item_depth = writer.StartWritingElements(kLiItem);
+
+ size_t item_depth = writer.StartWritingElement("rdf:li");
+ writer.WriteAttributeNameAndValue("rdf:parseType", "Resource");
+ writer.StartWritingElement(kConItem);
writer.WriteAttributeNameAndValue(kItemSemantic, kSemanticPrimary);
writer.WriteAttributeNameAndValue(kItemMime, kMimeImageJpeg);
writer.FinishWritingElementsToDepth(item_depth);
- writer.StartWritingElements(kLiItem);
- writer.WriteAttributeNameAndValue(kItemSemantic, kSemanticRecoveryMap);
+
+ writer.StartWritingElement("rdf:li");
+ writer.WriteAttributeNameAndValue("rdf:parseType", "Resource");
+ writer.StartWritingElement(kConItem);
+ writer.WriteAttributeNameAndValue(kItemSemantic, kSemanticGainMap);
writer.WriteAttributeNameAndValue(kItemMime, kMimeImageJpeg);
writer.WriteAttributeNameAndValue(kItemLength, secondary_image_length);
+
writer.FinishWriting();
return ss.str();
@@ -329,7 +340,6 @@
string generateXmpForSecondaryImage(jpegr_metadata_struct& metadata) {
const vector<string> kConDirSeq({kConDirectory, string("rdf:Seq")});
- const vector<string> kLiItem({string("rdf:li"), kConItem});
std::stringstream ss;
photos_editing_formats::image_io::XmlWriter writer(ss);
@@ -339,16 +349,17 @@
writer.StartWritingElement("rdf:RDF");
writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
writer.StartWritingElement("rdf:Description");
- writer.WriteXmlns(kRecoveryMapPrefix, kRecoveryMapUri);
+ writer.WriteXmlns(kGainMapPrefix, kGainMapUri);
writer.WriteAttributeNameAndValue(kMapVersion, metadata.version);
writer.WriteAttributeNameAndValue(kMapGainMapMin, log2(metadata.minContentBoost));
writer.WriteAttributeNameAndValue(kMapGainMapMax, log2(metadata.maxContentBoost));
writer.WriteAttributeNameAndValue(kMapGamma, "1");
writer.WriteAttributeNameAndValue(kMapOffsetSdr, "0");
writer.WriteAttributeNameAndValue(kMapOffsetHdr, "0");
- writer.WriteAttributeNameAndValue(kMapHDRCapacityMin, "0");
- writer.WriteAttributeNameAndValue(kMapHDRCapacityMax, "2.3");
- writer.WriteAttributeNameAndValue(kMapBaseRendition, "SDR");
+ writer.WriteAttributeNameAndValue(
+ kMapHDRCapacityMin, std::max(log2(metadata.minContentBoost), 0.0f));
+ writer.WriteAttributeNameAndValue(kMapHDRCapacityMax, log2(metadata.maxContentBoost));
+ writer.WriteAttributeNameAndValue(kMapBaseRenditionIsHDR, "False");
writer.FinishWriting();
return ss.str();
diff --git a/libs/jpegrecoverymap/tests/jpegr_test.cpp b/libs/jpegrecoverymap/tests/jpegr_test.cpp
index df90f53..7c669ab 100644
--- a/libs/jpegrecoverymap/tests/jpegr_test.cpp
+++ b/libs/jpegrecoverymap/tests/jpegr_test.cpp
@@ -192,8 +192,8 @@
jpegr_metadata_struct metadata_read;
EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
- ASSERT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
- ASSERT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
+ EXPECT_FLOAT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
+ EXPECT_FLOAT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
}
/* Test Encode API-0 and decode */
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index e393fb2..8256dd8 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -264,14 +264,11 @@
SkAndroidFrameworkTraceUtil::setEnableTracing(tracingEnabled);
}
-SkiaRenderEngine::SkiaRenderEngine(
- RenderEngineType type,
- PixelFormat pixelFormat,
- bool useColorManagement,
- bool supportsBackgroundBlur) :
- RenderEngine(type),
- mDefaultPixelFormat(pixelFormat),
- mUseColorManagement(useColorManagement) {
+SkiaRenderEngine::SkiaRenderEngine(RenderEngineType type, PixelFormat pixelFormat,
+ bool useColorManagement, bool supportsBackgroundBlur)
+ : RenderEngine(type),
+ mDefaultPixelFormat(pixelFormat),
+ mUseColorManagement(useColorManagement) {
if (supportsBackgroundBlur) {
ALOGD("Background Blurs Enabled");
mBlurFilter = new KawaseBlurFilter();
@@ -507,15 +504,9 @@
}
if (parameters.requiresLinearEffect) {
- const ui::Dataspace inputDataspace = mUseColorManagement ? parameters.layer.sourceDataspace
- : ui::Dataspace::V0_SRGB_LINEAR;
- const ui::Dataspace outputDataspace = mUseColorManagement
- ? parameters.display.outputDataspace
- : ui::Dataspace::V0_SRGB_LINEAR;
-
auto effect =
- shaders::LinearEffect{.inputDataspace = inputDataspace,
- .outputDataspace = outputDataspace,
+ shaders::LinearEffect{.inputDataspace = parameters.layer.sourceDataspace,
+ .outputDataspace = parameters.outputDataSpace,
.undoPremultipliedAlpha = parameters.undoPremultipliedAlpha};
auto effectIter = mRuntimeEffects.find(effect);
@@ -678,9 +669,8 @@
// wait on the buffer to be ready to use prior to using it
waitFence(grContext, bufferFence);
- const ui::Dataspace dstDataspace =
- mUseColorManagement ? display.outputDataspace : ui::Dataspace::V0_SRGB_LINEAR;
- sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
+ sk_sp<SkSurface> dstSurface =
+ surfaceTextureRef->getOrCreateSurface(display.outputDataspace, grContext);
SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
if (dstCanvas == nullptr) {
@@ -888,10 +878,31 @@
const bool dimInLinearSpace = display.dimmingStage !=
aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF;
+ const bool isExtendedHdr = (layer.sourceDataspace & ui::Dataspace::RANGE_MASK) ==
+ static_cast<int32_t>(ui::Dataspace::RANGE_EXTENDED) &&
+ (display.outputDataspace & ui::Dataspace::TRANSFER_MASK) ==
+ static_cast<int32_t>(ui::Dataspace::TRANSFER_SRGB);
+
+ const ui::Dataspace runtimeEffectDataspace = !dimInLinearSpace && isExtendedHdr
+ ? static_cast<ui::Dataspace>(
+ (display.outputDataspace & ui::Dataspace::STANDARD_MASK) |
+ ui::Dataspace::TRANSFER_GAMMA2_2 |
+ (display.outputDataspace & ui::Dataspace::RANGE_MASK))
+ : display.outputDataspace;
+
+ // If the input dataspace is range extended, the output dataspace transfer is sRGB
+ // and dimmingStage is GAMMA_OETF, dim in linear space instead, and
+ // set the output dataspace's transfer to be GAMMA2_2.
+ // This allows DPU side to use oetf_gamma_2p2 for extended HDR layer
+ // to avoid tone shift.
+ // The reason of tone shift here is because HDR layers manage white point
+ // luminance in linear space, which color pipelines request GAMMA_OETF break
+ // without a gamma 2.2 fixup.
const bool requiresLinearEffect = layer.colorTransform != mat4() ||
(mUseColorManagement &&
needsToneMapping(layer.sourceDataspace, display.outputDataspace)) ||
- (dimInLinearSpace && !equalsWithinMargin(1.f, layerDimmingRatio));
+ (dimInLinearSpace && !equalsWithinMargin(1.f, layerDimmingRatio)) ||
+ (!dimInLinearSpace && isExtendedHdr);
// quick abort from drawing the remaining portion of the layer
if (layer.skipContentDraw ||
@@ -904,7 +915,7 @@
// image with the same colorspace as the destination surface so that Skia's color
// management is a no-op.
const ui::Dataspace layerDataspace = (!mUseColorManagement || requiresLinearEffect)
- ? dstDataspace
+ ? display.outputDataspace
: layer.sourceDataspace;
SkPaint paint;
@@ -985,7 +996,8 @@
.requiresLinearEffect = requiresLinearEffect,
.layerDimmingRatio = dimInLinearSpace
? layerDimmingRatio
- : 1.f}));
+ : 1.f,
+ .outputDataSpace = runtimeEffectDataspace}));
// Turn on dithering when dimming beyond this (arbitrary) threshold...
static constexpr float kDimmingThreshold = 0.2f;
@@ -1048,7 +1060,8 @@
.display = display,
.undoPremultipliedAlpha = false,
.requiresLinearEffect = requiresLinearEffect,
- .layerDimmingRatio = layerDimmingRatio}));
+ .layerDimmingRatio = layerDimmingRatio,
+ .outputDataSpace = runtimeEffectDataspace}));
}
if (layer.disableBlending) {
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index e4406b4..6457bfa 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -156,6 +156,7 @@
bool undoPremultipliedAlpha;
bool requiresLinearEffect;
float layerDimmingRatio;
+ const ui::Dataspace outputDataSpace;
};
sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&);
diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
index 514b45f..2106839 100644
--- a/libs/ui/Gralloc5.cpp
+++ b/libs/ui/Gralloc5.cpp
@@ -352,14 +352,12 @@
}
}
{
- (void)stride;
- // TODO(b/261856851): Add StandardMetadataType::STRIDE && enable this
- // auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper,
- // bufferHandle); if (static_cast<BufferUsage>(usage) != value) {
- // ALOGW("Layer count didn't match, expected %" PRIu64 " got %" PRId64, usage,
- // static_cast<int64_t>(value.value_or(BufferUsage::CPU_READ_NEVER)));
- // return BAD_VALUE;
- // }
+ auto value = getStandardMetadata<StandardMetadataType::STRIDE>(mMapper, bufferHandle);
+ if (stride != value) {
+ ALOGW("Stride didn't match, expected %" PRIu32 " got %" PRId32, stride,
+ value.value_or(-1));
+ return BAD_VALUE;
+ }
}
return OK;
}
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 49e1cba..16de390 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -205,6 +205,7 @@
srcs: [
"EGL/BlobCache.cpp",
"EGL/BlobCache_test.cpp",
+ "EGL/FileBlobCache.cpp",
"EGL/MultifileBlobCache.cpp",
"EGL/MultifileBlobCache_test.cpp",
],
diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp
index 3f7ae7e..1026842 100644
--- a/opengl/libs/EGL/FileBlobCache.cpp
+++ b/opengl/libs/EGL/FileBlobCache.cpp
@@ -31,7 +31,7 @@
namespace android {
-static uint32_t crc32c(const uint8_t* buf, size_t len) {
+uint32_t crc32c(const uint8_t* buf, size_t len) {
const uint32_t polyBits = 0x82F63B78;
uint32_t r = 0;
for (size_t i = 0; i < len; i++) {
diff --git a/opengl/libs/EGL/FileBlobCache.h b/opengl/libs/EGL/FileBlobCache.h
index 8220723..f083b0d 100644
--- a/opengl/libs/EGL/FileBlobCache.h
+++ b/opengl/libs/EGL/FileBlobCache.h
@@ -22,6 +22,8 @@
namespace android {
+uint32_t crc32c(const uint8_t* buf, size_t len);
+
class FileBlobCache : public BlobCache {
public:
// FileBlobCache attempts to load the saved cache contents from disk into
diff --git a/opengl/libs/EGL/MultifileBlobCache.cpp b/opengl/libs/EGL/MultifileBlobCache.cpp
index 99af299..7ffdac7 100644
--- a/opengl/libs/EGL/MultifileBlobCache.cpp
+++ b/opengl/libs/EGL/MultifileBlobCache.cpp
@@ -39,22 +39,11 @@
using namespace std::literals;
+constexpr uint32_t kMultifileMagic = 'MFB$';
+constexpr uint32_t kCrcPlaceholder = 0;
+
namespace {
-// Open the file and determine the size of the value it contains
-size_t getValueSizeFromFile(int fd, const std::string& entryPath) {
- // Read the beginning of the file to get header
- android::MultifileHeader header;
- size_t result = read(fd, static_cast<void*>(&header), sizeof(android::MultifileHeader));
- if (result != sizeof(android::MultifileHeader)) {
- ALOGE("Error reading MultifileHeader from cache entry (%s): %s", entryPath.c_str(),
- std::strerror(errno));
- return 0;
- }
-
- return header.valueSize;
-}
-
// Helper function to close entries or free them
void freeHotCacheEntry(android::MultifileHotCache& entry) {
if (entry.entryFd != -1) {
@@ -73,12 +62,14 @@
namespace android {
-MultifileBlobCache::MultifileBlobCache(size_t maxTotalSize, size_t maxHotCacheSize,
+MultifileBlobCache::MultifileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
const std::string& baseDir)
: mInitialized(false),
+ mMaxKeySize(maxKeySize),
+ mMaxValueSize(maxValueSize),
mMaxTotalSize(maxTotalSize),
mTotalCacheSize(0),
- mHotCacheLimit(maxHotCacheSize),
+ mHotCacheLimit(0),
mHotCacheSize(0),
mWorkerThreadIdle(true) {
if (baseDir.empty()) {
@@ -89,9 +80,9 @@
// Establish the name of our multifile directory
mMultifileDirName = baseDir + ".multifile";
- // Set a limit for max key and value, ensuring at least one entry can always fit in hot cache
- mMaxKeySize = mHotCacheLimit / 4;
- mMaxValueSize = mHotCacheLimit / 2;
+ // Set the hotcache limit to be large enough to contain one max entry
+ // This ensure the hot cache is always large enough for single entry
+ mHotCacheLimit = mMaxKeySize + mMaxValueSize + sizeof(MultifileHeader);
ALOGV("INIT: Initializing multifile blobcache with maxKeySize=%zu and maxValueSize=%zu",
mMaxKeySize, mMaxValueSize);
@@ -129,6 +120,15 @@
return;
}
+ // If the cache entry is damaged or no good, remove it
+ if (st.st_size <= 0 || st.st_atime <= 0) {
+ ALOGE("INIT: Entry %u has invalid stats! Removing.", entryHash);
+ if (remove(fullPath.c_str()) != 0) {
+ ALOGE("Error removing %s: %s", fullPath.c_str(), std::strerror(errno));
+ }
+ continue;
+ }
+
// Open the file so we can read its header
int fd = open(fullPath.c_str(), O_RDONLY);
if (fd == -1) {
@@ -137,13 +137,51 @@
return;
}
- // Look up the details we track about each file
- size_t valueSize = getValueSizeFromFile(fd, fullPath);
+ // Read the beginning of the file to get header
+ MultifileHeader header;
+ size_t result = read(fd, static_cast<void*>(&header), sizeof(MultifileHeader));
+ if (result != sizeof(MultifileHeader)) {
+ ALOGE("Error reading MultifileHeader from cache entry (%s): %s",
+ fullPath.c_str(), std::strerror(errno));
+ return;
+ }
+
+ // Verify header magic
+ if (header.magic != kMultifileMagic) {
+ ALOGE("INIT: Entry %u has bad magic (%u)! Removing.", entryHash, header.magic);
+ if (remove(fullPath.c_str()) != 0) {
+ ALOGE("Error removing %s: %s", fullPath.c_str(), std::strerror(errno));
+ }
+ continue;
+ }
+
+ // Note: Converting from off_t (signed) to size_t (unsigned)
+ size_t fileSize = static_cast<size_t>(st.st_size);
+
+ // Memory map the file
+ uint8_t* mappedEntry = reinterpret_cast<uint8_t*>(
+ mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
+ if (mappedEntry == MAP_FAILED) {
+ ALOGE("Failed to mmap cacheEntry, error: %s", std::strerror(errno));
+ return;
+ }
+
+ // Ensure we have a good CRC
+ if (header.crc !=
+ crc32c(mappedEntry + sizeof(MultifileHeader),
+ fileSize - sizeof(MultifileHeader))) {
+ ALOGE("INIT: Entry %u failed CRC check! Removing.", entryHash);
+ if (remove(fullPath.c_str()) != 0) {
+ ALOGE("Error removing %s: %s", fullPath.c_str(), std::strerror(errno));
+ }
+ continue;
+ }
// If the cache entry is damaged or no good, remove it
- // TODO: Perform any other checks
- if (valueSize <= 0 || st.st_size <= 0 || st.st_atime <= 0) {
- ALOGV("INIT: Entry %u has a problem! Removing.", entryHash);
+ if (header.keySize <= 0 || header.valueSize <= 0) {
+ ALOGE("INIT: Entry %u has a bad header keySize (%lu) or valueSize (%lu), "
+ "removing.",
+ entryHash, header.keySize, header.valueSize);
if (remove(fullPath.c_str()) != 0) {
ALOGE("Error removing %s: %s", fullPath.c_str(), std::strerror(errno));
}
@@ -152,25 +190,14 @@
ALOGV("INIT: Entry %u is good, tracking it now.", entryHash);
- // Note: Converting from off_t (signed) to size_t (unsigned)
- size_t fileSize = static_cast<size_t>(st.st_size);
- time_t accessTime = st.st_atime;
-
// Track details for rapid lookup later
- trackEntry(entryHash, valueSize, fileSize, accessTime);
+ trackEntry(entryHash, header.valueSize, fileSize, st.st_atime);
// Track the total size
increaseTotalCacheSize(fileSize);
// Preload the entry for fast retrieval
if ((mHotCacheSize + fileSize) < mHotCacheLimit) {
- // Memory map the file
- uint8_t* mappedEntry = reinterpret_cast<uint8_t*>(
- mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd, 0));
- if (mappedEntry == MAP_FAILED) {
- ALOGE("Failed to mmap cacheEntry, error: %s", std::strerror(errno));
- }
-
ALOGV("INIT: Populating hot cache with fd = %i, cacheEntry = %p for "
"entryHash %u",
fd, mappedEntry, entryHash);
@@ -183,6 +210,8 @@
return;
}
} else {
+ // If we're not keeping it in hot cache, unmap it now
+ munmap(mappedEntry, fileSize);
close(fd);
}
}
@@ -227,7 +256,7 @@
// Ensure key and value are under their limits
if (keySize > mMaxKeySize || valueSize > mMaxValueSize) {
- ALOGV("SET: keySize (%lu vs %zu) or valueSize (%lu vs %zu) too large", keySize, mMaxKeySize,
+ ALOGW("SET: keySize (%lu vs %zu) or valueSize (%lu vs %zu) too large", keySize, mMaxKeySize,
valueSize, mMaxValueSize);
return;
}
@@ -240,17 +269,18 @@
// If we're going to be over the cache limit, kick off a trim to clear space
if (getTotalSize() + fileSize > mMaxTotalSize) {
ALOGV("SET: Cache is full, calling trimCache to clear space");
- trimCache(mMaxTotalSize);
+ trimCache();
}
ALOGV("SET: Add %u to cache", entryHash);
uint8_t* buffer = new uint8_t[fileSize];
- // Write the key and value after the header
- android::MultifileHeader header = {keySize, valueSize};
+ // Write placeholders for magic and CRC until deferred thread completes the write
+ android::MultifileHeader header = {kMultifileMagic, kCrcPlaceholder, keySize, valueSize};
memcpy(static_cast<void*>(buffer), static_cast<const void*>(&header),
sizeof(android::MultifileHeader));
+ // Write the key and value after the header
memcpy(static_cast<void*>(buffer + sizeof(MultifileHeader)), static_cast<const void*>(key),
keySize);
memcpy(static_cast<void*>(buffer + sizeof(MultifileHeader) + keySize),
@@ -269,13 +299,18 @@
// Sending -1 as the fd indicates we don't have an fd for this
if (!addToHotCache(entryHash, -1, buffer, fileSize)) {
- ALOGE("GET: Failed to add %u to hot cache", entryHash);
+ ALOGE("SET: Failed to add %u to hot cache", entryHash);
+ delete[] buffer;
return;
}
// Track that we're creating a pending write for this entry
// Include the buffer to handle the case when multiple writes are pending for an entry
- mDeferredWrites.insert(std::make_pair(entryHash, buffer));
+ {
+ // Synchronize access to deferred write status
+ std::lock_guard<std::mutex> lock(mDeferredWriteStatusMutex);
+ mDeferredWrites.insert(std::make_pair(entryHash, buffer));
+ }
// Create deferred task to write to storage
ALOGV("SET: Adding task to queue.");
@@ -293,7 +328,7 @@
// Ensure key and value are under their limits
if (keySize > mMaxKeySize || valueSize > mMaxValueSize) {
- ALOGV("GET: keySize (%lu vs %zu) or valueSize (%lu vs %zu) too large", keySize, mMaxKeySize,
+ ALOGW("GET: keySize (%lu vs %zu) or valueSize (%lu vs %zu) too large", keySize, mMaxKeySize,
valueSize, mMaxValueSize);
return 0;
}
@@ -342,8 +377,15 @@
} else {
ALOGV("GET: HotCache MISS for entry: %u", entryHash);
- if (mDeferredWrites.find(entryHash) != mDeferredWrites.end()) {
- // Wait for writes to complete if there is an outstanding write for this entry
+ // Wait for writes to complete if there is an outstanding write for this entry
+ bool wait = false;
+ {
+ // Synchronize access to deferred write status
+ std::lock_guard<std::mutex> lock(mDeferredWriteStatusMutex);
+ wait = mDeferredWrites.find(entryHash) != mDeferredWrites.end();
+ }
+
+ if (wait) {
ALOGV("GET: Waiting for write to complete for %u", entryHash);
waitForWorkComplete();
}
@@ -455,6 +497,7 @@
mHotCacheSize, newEntrySize, mHotCacheLimit, newEntryHash);
// Wait for all the files to complete writing so our hot cache is accurate
+ ALOGV("HOTCACHE(ADD): Waiting for work to complete for %u", newEntryHash);
waitForWorkComplete();
// Free up old entries until under the limit
@@ -491,6 +534,7 @@
ALOGV("HOTCACHE(REMOVE): Removing %u from hot cache", entryHash);
// Wait for all the files to complete writing so our hot cache is accurate
+ ALOGV("HOTCACHE(REMOVE): Waiting for work to complete for %u", entryHash);
waitForWorkComplete();
ALOGV("HOTCACHE(REMOVE): Closing hot cache entry for %u", entryHash);
@@ -547,7 +591,7 @@
}
}
- ALOGV("LRU: Cache is emptry");
+ ALOGV("LRU: Cache is empty");
return false;
}
@@ -556,23 +600,15 @@
constexpr uint32_t kCacheLimitDivisor = 2;
// Calculate the cache size and remove old entries until under the limit
-void MultifileBlobCache::trimCache(size_t cacheByteLimit) {
- // Start with the value provided by egl_cache
- size_t limit = cacheByteLimit;
-
+void MultifileBlobCache::trimCache() {
// Wait for all deferred writes to complete
+ ALOGV("TRIM: Waiting for work to complete.");
waitForWorkComplete();
- size_t size = getTotalSize();
-
- // If size is larger than the threshold, remove files using LRU
- if (size > limit) {
- ALOGV("TRIM: Multifile cache size is larger than %zu, removing old entries",
- cacheByteLimit);
- if (!applyLRU(limit / kCacheLimitDivisor)) {
- ALOGE("Error when clearing multifile shader cache");
- return;
- }
+ ALOGV("TRIM: Reducing multifile cache size to %zu", mMaxTotalSize / kCacheLimitDivisor);
+ if (!applyLRU(mMaxTotalSize / kCacheLimitDivisor)) {
+ ALOGE("Error when clearing multifile shader cache");
+ return;
}
}
@@ -600,6 +636,11 @@
ALOGV("DEFERRED: Opened fd %i from %s", fd, fullPath.c_str());
+ // Add CRC check to the header (always do this last!)
+ MultifileHeader* header = reinterpret_cast<MultifileHeader*>(buffer);
+ header->crc =
+ crc32c(buffer + sizeof(MultifileHeader), bufferSize - sizeof(MultifileHeader));
+
ssize_t result = write(fd, buffer, bufferSize);
if (result != bufferSize) {
ALOGE("Error writing fileSize to cache entry (%s): %s", fullPath.c_str(),
@@ -612,13 +653,18 @@
// Erase the entry from mDeferredWrites
// Since there could be multiple outstanding writes for an entry, find the matching one
- typedef std::multimap<uint32_t, uint8_t*>::iterator entryIter;
- std::pair<entryIter, entryIter> iterPair = mDeferredWrites.equal_range(entryHash);
- for (entryIter it = iterPair.first; it != iterPair.second; ++it) {
- if (it->second == buffer) {
- ALOGV("DEFERRED: Marking write complete for %u at %p", it->first, it->second);
- mDeferredWrites.erase(it);
- break;
+ {
+ // Synchronize access to deferred write status
+ std::lock_guard<std::mutex> lock(mDeferredWriteStatusMutex);
+ typedef std::multimap<uint32_t, uint8_t*>::iterator entryIter;
+ std::pair<entryIter, entryIter> iterPair = mDeferredWrites.equal_range(entryHash);
+ for (entryIter it = iterPair.first; it != iterPair.second; ++it) {
+ if (it->second == buffer) {
+ ALOGV("DEFERRED: Marking write complete for %u at %p", it->first,
+ it->second);
+ mDeferredWrites.erase(it);
+ break;
+ }
}
}
@@ -686,4 +732,4 @@
mWorkerIdleCondition.wait(lock, [this] { return (mTasks.empty() && mWorkerThreadIdle); });
}
-}; // namespace android
\ No newline at end of file
+}; // namespace android
diff --git a/opengl/libs/EGL/MultifileBlobCache.h b/opengl/libs/EGL/MultifileBlobCache.h
index c0cc9dc..5e527dc 100644
--- a/opengl/libs/EGL/MultifileBlobCache.h
+++ b/opengl/libs/EGL/MultifileBlobCache.h
@@ -20,6 +20,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <android-base/thread_annotations.h>
#include <future>
#include <map>
#include <queue>
@@ -28,9 +29,13 @@
#include <unordered_map>
#include <unordered_set>
+#include "FileBlobCache.h"
+
namespace android {
struct MultifileHeader {
+ uint32_t magic;
+ uint32_t crc;
EGLsizeiANDROID keySize;
EGLsizeiANDROID valueSize;
};
@@ -86,7 +91,8 @@
class MultifileBlobCache {
public:
- MultifileBlobCache(size_t maxTotalSize, size_t maxHotCacheSize, const std::string& baseDir);
+ MultifileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
+ const std::string& baseDir);
~MultifileBlobCache();
void set(const void* key, EGLsizeiANDROID keySize, const void* value,
@@ -114,7 +120,7 @@
bool addToHotCache(uint32_t entryHash, int fd, uint8_t* entryBufer, size_t entrySize);
bool removeFromHotCache(uint32_t entryHash);
- void trimCache(size_t cacheByteLimit);
+ void trimCache();
bool applyLRU(size_t cacheLimit);
bool mInitialized;
@@ -135,7 +141,8 @@
// Below are the components used for deferred writes
// Track whether we have pending writes for an entry
- std::multimap<uint32_t, uint8_t*> mDeferredWrites;
+ std::mutex mDeferredWriteStatusMutex;
+ std::multimap<uint32_t, uint8_t*> mDeferredWrites GUARDED_BY(mDeferredWriteStatusMutex);
// Functions to work through tasks in the queue
void processTasks();
diff --git a/opengl/libs/EGL/MultifileBlobCache_test.cpp b/opengl/libs/EGL/MultifileBlobCache_test.cpp
index 1a55a4f..dbee13b 100644
--- a/opengl/libs/EGL/MultifileBlobCache_test.cpp
+++ b/opengl/libs/EGL/MultifileBlobCache_test.cpp
@@ -28,17 +28,16 @@
template <typename T>
using sp = std::shared_ptr<T>;
+constexpr size_t kMaxKeySize = 2 * 1024;
+constexpr size_t kMaxValueSize = 6 * 1024;
constexpr size_t kMaxTotalSize = 32 * 1024;
-constexpr size_t kMaxPreloadSize = 8 * 1024;
-
-constexpr size_t kMaxKeySize = kMaxPreloadSize / 4;
-constexpr size_t kMaxValueSize = kMaxPreloadSize / 2;
class MultifileBlobCacheTest : public ::testing::Test {
protected:
virtual void SetUp() {
mTempFile.reset(new TemporaryFile());
- mMBC.reset(new MultifileBlobCache(kMaxTotalSize, kMaxPreloadSize, &mTempFile->path[0]));
+ mMBC.reset(new MultifileBlobCache(kMaxKeySize, kMaxValueSize, kMaxTotalSize,
+ &mTempFile->path[0]));
}
virtual void TearDown() { mMBC.reset(); }
@@ -190,6 +189,26 @@
}
}
+TEST_F(MultifileBlobCacheTest, CacheMaxKeyAndValueSizeSucceeds) {
+ char key[kMaxKeySize];
+ for (int i = 0; i < kMaxKeySize; i++) {
+ key[i] = 'a';
+ }
+ char buf[kMaxValueSize];
+ for (int i = 0; i < kMaxValueSize; i++) {
+ buf[i] = 'b';
+ }
+ mMBC->set(key, kMaxKeySize, buf, kMaxValueSize);
+ for (int i = 0; i < kMaxValueSize; i++) {
+ buf[i] = 0xee;
+ }
+ mMBC->get(key, kMaxKeySize, buf, kMaxValueSize);
+ for (int i = 0; i < kMaxValueSize; i++) {
+ SCOPED_TRACE(i);
+ ASSERT_EQ('b', buf[i]);
+ }
+}
+
TEST_F(MultifileBlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
unsigned char buf[1] = {0xee};
mMBC->set("x", 1, "y", 1);
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 3dc93ee..1b68344 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -38,8 +38,9 @@
static const unsigned int kDeferredMonolithicSaveDelay = 4;
// Multifile cache size limits
-constexpr uint32_t kMultifileHotCacheLimit = 8 * 1024 * 1024;
-constexpr uint32_t kMultifileCacheByteLimit = 32 * 1024 * 1024;
+constexpr uint32_t kMaxMultifileKeySize = 1 * 1024 * 1024;
+constexpr uint32_t kMaxMultifileValueSize = 8 * 1024 * 1024;
+constexpr uint32_t kMaxMultifileTotalSize = 32 * 1024 * 1024;
namespace android {
@@ -250,7 +251,7 @@
if (mMultifileMode) {
mCacheByteLimit = static_cast<size_t>(
base::GetUintProperty<uint32_t>("ro.egl.blobcache.multifile_limit",
- kMultifileCacheByteLimit));
+ kMaxMultifileTotalSize));
// Check for a debug value
int debugCacheSize = base::GetIntProperty("debug.egl.blobcache.multifile_limit", -1);
@@ -274,8 +275,9 @@
MultifileBlobCache* egl_cache_t::getMultifileBlobCacheLocked() {
if (mMultifileBlobCache == nullptr) {
- mMultifileBlobCache.reset(
- new MultifileBlobCache(mCacheByteLimit, kMultifileHotCacheLimit, mFilename));
+ mMultifileBlobCache.reset(new MultifileBlobCache(kMaxMultifileKeySize,
+ kMaxMultifileValueSize, mCacheByteLimit,
+ mFilename));
}
return mMultifileBlobCache.get();
}
diff --git a/opengl/libs/EGL/fuzzer/Android.bp b/opengl/libs/EGL/fuzzer/Android.bp
new file mode 100644
index 0000000..022a2a3
--- /dev/null
+++ b/opengl/libs/EGL/fuzzer/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_fuzz {
+ name: "MultifileBlobCache_fuzzer",
+
+ fuzz_config: {
+ cc: ["cnorthrop@google.com"],
+ libfuzzer_options: ["len_control=0"],
+ },
+
+ static_libs: [
+ "libbase",
+ "libEGL_blobCache",
+ "liblog",
+ "libutils",
+ ],
+
+ srcs: [
+ "MultifileBlobCache_fuzzer.cpp",
+ ],
+}
diff --git a/opengl/libs/EGL/fuzzer/MultifileBlobCache_fuzzer.cpp b/opengl/libs/EGL/fuzzer/MultifileBlobCache_fuzzer.cpp
new file mode 100644
index 0000000..633cc9c
--- /dev/null
+++ b/opengl/libs/EGL/fuzzer/MultifileBlobCache_fuzzer.cpp
@@ -0,0 +1,158 @@
+/*
+ ** Copyright 2023, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include "MultifileBlobCache.h"
+
+#include <android-base/test_utils.h>
+#include <fcntl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+namespace android {
+
+constexpr size_t kMaxKeySize = 2 * 1024;
+constexpr size_t kMaxValueSize = 6 * 1024;
+constexpr size_t kMaxTotalSize = 32 * 1024;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ // To fuzz this, we're going to create a key/value pair from data
+ // and use them with MultifileBlobCache in a random order
+ // - Use the first entry in data to determine keySize
+ // - Use the second entry in data to determine valueSize
+ // - Mod each of them against half the remaining size, ensuring both fit
+ // - Create key and value using sizes from data
+ // - Use remaining data to switch between GET and SET while
+ // tweaking the keys slightly
+ // - Ensure two cache cleaning scenarios are hit at the end
+
+ // Ensure we have enough data to create interesting key/value pairs
+ size_t kMinInputLength = 128;
+ if (size < kMinInputLength) {
+ return 0;
+ }
+
+ // Need non-zero sizes for interesting results
+ if (data[0] == 0 || data[1] == 0) {
+ return 0;
+ }
+
+ // We need to divide the data up into buffers and sizes
+ FuzzedDataProvider fdp(data, size);
+
+ // Pull two values from data for key and value size
+ EGLsizeiANDROID keySize = static_cast<EGLsizeiANDROID>(fdp.ConsumeIntegral<uint8_t>());
+ EGLsizeiANDROID valueSize = static_cast<EGLsizeiANDROID>(fdp.ConsumeIntegral<uint8_t>());
+ size -= 2 * sizeof(uint8_t);
+
+ // Ensure key and value fit in the remaining space (cap them at half data size)
+ keySize = keySize % (size >> 1);
+ valueSize = valueSize % (size >> 1);
+
+ // If either size ended up zero, just move on to save time
+ if (keySize == 0 || valueSize == 0) {
+ return 0;
+ }
+
+ // Create key and value from remaining data
+ std::vector<uint8_t> key;
+ std::vector<uint8_t> value;
+ key = fdp.ConsumeBytes<uint8_t>(keySize);
+ value = fdp.ConsumeBytes<uint8_t>(valueSize);
+
+ // Create a tempfile and a cache
+ std::unique_ptr<TemporaryFile> tempFile;
+ std::unique_ptr<MultifileBlobCache> mbc;
+
+ tempFile.reset(new TemporaryFile());
+ mbc.reset(
+ new MultifileBlobCache(kMaxKeySize, kMaxValueSize, kMaxTotalSize, &tempFile->path[0]));
+ // With remaining data, select different paths below
+ int loopCount = 1;
+ uint8_t bumpCount = 0;
+ while (fdp.remaining_bytes() > 0) {
+ // Bounce back and forth between gets and sets
+ if (fdp.ConsumeBool()) {
+ mbc->set(key.data(), keySize, value.data(), valueSize);
+ } else {
+ uint8_t* buffer = new uint8_t[valueSize];
+ mbc->get(key.data(), keySize, buffer, valueSize);
+ delete[] buffer;
+ }
+
+ // Bump the key and values periodically, causing different hits/misses
+ if (fdp.ConsumeBool()) {
+ key[0]++;
+ value[0]++;
+ bumpCount++;
+ }
+
+ // Reset the key and value periodically to hit old entries
+ if (fdp.ConsumeBool()) {
+ key[0] -= bumpCount;
+ value[0] -= bumpCount;
+ bumpCount = 0;
+ }
+
+ loopCount++;
+ }
+ mbc->finish();
+
+ // Fill 2 keys and 2 values to max size with unique values
+ std::vector<uint8_t> maxKey1, maxKey2, maxValue1, maxValue2;
+ maxKey1.resize(kMaxKeySize, 0);
+ maxKey2.resize(kMaxKeySize, 0);
+ maxValue1.resize(kMaxValueSize, 0);
+ maxValue2.resize(kMaxValueSize, 0);
+ for (int i = 0; i < keySize && i < kMaxKeySize; ++i) {
+ maxKey1[i] = key[i];
+ maxKey2[i] = key[i] - 1;
+ }
+ for (int i = 0; i < valueSize && i < kMaxValueSize; ++i) {
+ maxValue1[i] = value[i];
+ maxValue2[i] = value[i] - 1;
+ }
+
+ // Trigger hot cache trimming
+ // Place the maxKey/maxValue twice
+ // The first will fit, the second will trigger hot cache trimming
+ tempFile.reset(new TemporaryFile());
+ mbc.reset(
+ new MultifileBlobCache(kMaxKeySize, kMaxValueSize, kMaxTotalSize, &tempFile->path[0]));
+ uint8_t* buffer = new uint8_t[kMaxValueSize];
+ mbc->set(maxKey1.data(), kMaxKeySize, maxValue1.data(), kMaxValueSize);
+ mbc->set(maxKey2.data(), kMaxKeySize, maxValue2.data(), kMaxValueSize);
+ mbc->get(maxKey1.data(), kMaxKeySize, buffer, kMaxValueSize);
+ mbc->finish();
+
+ // Trigger cold cache trimming
+ // Create a total size small enough only one entry fits
+ // Since the cache will add a header, 2 * key + value will only hold one value, the second will
+ // overflow
+ tempFile.reset(new TemporaryFile());
+ mbc.reset(new MultifileBlobCache(kMaxKeySize, kMaxValueSize, 2 * (kMaxKeySize + kMaxValueSize),
+ &tempFile->path[0]));
+ mbc->set(maxKey1.data(), kMaxKeySize, maxValue1.data(), kMaxValueSize);
+ mbc->set(maxKey2.data(), kMaxKeySize, maxValue2.data(), kMaxValueSize);
+ mbc->get(maxKey1.data(), kMaxKeySize, buffer, kMaxValueSize);
+ mbc->finish();
+
+ delete[] buffer;
+ return 0;
+}
+
+} // namespace android
diff --git a/opengl/tests/EGLTest/egl_cache_test.cpp b/opengl/tests/EGLTest/egl_cache_test.cpp
index 2b3e3a4..f81c68f 100644
--- a/opengl/tests/EGLTest/egl_cache_test.cpp
+++ b/opengl/tests/EGLTest/egl_cache_test.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "EGL_test"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <gtest/gtest.h>
@@ -27,6 +27,7 @@
#include "MultifileBlobCache.h"
#include "egl_display.h"
+#include <fstream>
#include <memory>
using namespace std::literals;
@@ -144,7 +145,7 @@
return cachefileName;
}
-TEST_P(EGLCacheTest, ModifiedCacheMisses) {
+TEST_P(EGLCacheTest, ModifiedCacheBeginMisses) {
// Skip if not in multifile mode
if (mCacheMode == egl_cache_t::EGLCacheMode::Monolithic) {
GTEST_SKIP() << "Skipping test designed for multifile";
@@ -168,11 +169,12 @@
ASSERT_TRUE(cachefileName.length() > 0);
// Stomp on the beginning of the cache file, breaking the key match
- const long stomp = 0xbadf00d;
- FILE *file = fopen(cachefileName.c_str(), "w");
- fprintf(file, "%ld", stomp);
- fflush(file);
- fclose(file);
+ const char* stomp = "BADF00D";
+ std::fstream fs(cachefileName);
+ fs.seekp(0, std::ios_base::beg);
+ fs.write(stomp, strlen(stomp));
+ fs.flush();
+ fs.close();
// Ensure no cache hit
mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
@@ -185,6 +187,56 @@
ASSERT_EQ(0xee, buf2[3]);
}
+TEST_P(EGLCacheTest, ModifiedCacheEndMisses) {
+ // Skip if not in multifile mode
+ if (mCacheMode == egl_cache_t::EGLCacheMode::Monolithic) {
+ GTEST_SKIP() << "Skipping test designed for multifile";
+ }
+
+ uint8_t buf[16] = { 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee };
+
+ mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
+
+ mCache->setBlob("abcdefghij", 10, "klmnopqrstuvwxyz", 16);
+ ASSERT_EQ(16, mCache->getBlob("abcdefghij", 10, buf, 16));
+ ASSERT_EQ('w', buf[12]);
+ ASSERT_EQ('x', buf[13]);
+ ASSERT_EQ('y', buf[14]);
+ ASSERT_EQ('z', buf[15]);
+
+ // Ensure the cache file is written to disk
+ mCache->terminate();
+
+ // Depending on the cache mode, the file will be in different locations
+ std::string cachefileName = getCachefileName();
+ ASSERT_TRUE(cachefileName.length() > 0);
+
+ // Stomp on the END of the cache file, modifying its contents
+ const char* stomp = "BADF00D";
+ std::fstream fs(cachefileName);
+ fs.seekp(-strlen(stomp), std::ios_base::end);
+ fs.write(stomp, strlen(stomp));
+ fs.flush();
+ fs.close();
+
+ // Ensure no cache hit
+ mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
+ uint8_t buf2[16] = { 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee,
+ 0xee, 0xee, 0xee, 0xee };
+
+ // getBlob may return junk for required size, but should not return a cache hit
+ mCache->getBlob("abcdefghij", 10, buf2, 16);
+ ASSERT_EQ(0xee, buf2[0]);
+ ASSERT_EQ(0xee, buf2[1]);
+ ASSERT_EQ(0xee, buf2[2]);
+ ASSERT_EQ(0xee, buf2[3]);
+}
+
TEST_P(EGLCacheTest, TerminatedCacheBelowCacheLimit) {
uint8_t buf[4] = { 0xee, 0xee, 0xee, 0xee };
mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
@@ -213,11 +265,68 @@
// Cache should contain both the key and the value
// So 8 bytes per entry, at least 24 bytes
ASSERT_GE(mCache->getCacheSize(), 24);
- mCache->setCacheLimit(4);
+
+ // Set the new limit and initialize cache
mCache->terminate();
+ mCache->setCacheLimit(4);
+ mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
+
+ // Ensure the new limit is respected
ASSERT_LE(mCache->getCacheSize(), 4);
}
+TEST_P(EGLCacheTest, TrimCacheOnOverflow) {
+ // Skip if not in multifile mode
+ if (mCacheMode == egl_cache_t::EGLCacheMode::Monolithic) {
+ GTEST_SKIP() << "Skipping test designed for multifile";
+ }
+
+ uint8_t buf[4] = { 0xee, 0xee, 0xee, 0xee };
+ mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
+
+ // Set one value in the cache
+ mCache->setBlob("abcd", 4, "efgh", 4);
+ ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4));
+ ASSERT_EQ('e', buf[0]);
+ ASSERT_EQ('f', buf[1]);
+ ASSERT_EQ('g', buf[2]);
+ ASSERT_EQ('h', buf[3]);
+
+ // Get the size of cache with a single entry
+ size_t cacheEntrySize = mCache->getCacheSize();
+
+ // Now reinitialize the cache, using max size equal to a single entry
+ mCache->terminate();
+ mCache->setCacheLimit(cacheEntrySize);
+ mCache->initialize(egl_display_t::get(EGL_DEFAULT_DISPLAY));
+
+ // Ensure our cache still has original value
+ ASSERT_EQ(4, mCache->getBlob("abcd", 4, buf, 4));
+ ASSERT_EQ('e', buf[0]);
+ ASSERT_EQ('f', buf[1]);
+ ASSERT_EQ('g', buf[2]);
+ ASSERT_EQ('h', buf[3]);
+
+ // Set another value, which should overflow the cache and trim
+ mCache->setBlob("ijkl", 4, "mnop", 4);
+ ASSERT_EQ(4, mCache->getBlob("ijkl", 4, buf, 4));
+ ASSERT_EQ('m', buf[0]);
+ ASSERT_EQ('n', buf[1]);
+ ASSERT_EQ('o', buf[2]);
+ ASSERT_EQ('p', buf[3]);
+
+ // The cache should still be under the limit
+ ASSERT_TRUE(mCache->getCacheSize() == cacheEntrySize);
+
+ // And no cache hit on trimmed entry
+ uint8_t buf2[4] = { 0xee, 0xee, 0xee, 0xee };
+ mCache->getBlob("abcd", 4, buf2, 4);
+ ASSERT_EQ(0xee, buf2[0]);
+ ASSERT_EQ(0xee, buf2[1]);
+ ASSERT_EQ(0xee, buf2[2]);
+ ASSERT_EQ(0xee, buf2[3]);
+}
+
INSTANTIATE_TEST_CASE_P(MonolithicCacheTests,
EGLCacheTest, ::testing::Values(egl_cache_t::EGLCacheMode::Monolithic));
INSTANTIATE_TEST_CASE_P(MultifileCacheTests,
diff --git a/services/gpuservice/vts/Android.bp b/services/gpuservice/vts/Android.bp
index f4ea440..a24822a 100644
--- a/services/gpuservice/vts/Android.bp
+++ b/services/gpuservice/vts/Android.bp
@@ -21,7 +21,6 @@
srcs: ["src/**/*.java"],
libs: [
"tradefed",
- "vts-core-tradefed-harness",
"compatibility-host-util",
],
test_suites: [
diff --git a/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
index 290a646..6c16335 100644
--- a/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
+++ b/services/gpuservice/vts/src/com/android/tests/gpuservice/GpuWorkTracepointTest.java
@@ -27,7 +27,7 @@
import com.android.tradefed.util.CommandStatus;
import com.android.compatibility.common.util.PropertyUtil;
-import com.android.compatibility.common.util.GmsTest;
+import com.android.compatibility.common.util.VsrTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -62,7 +62,7 @@
commandResult.getStatus(), CommandStatus.SUCCESS);
}
- @GmsTest(requirement = "VSR-3.3-004")
+ @VsrTest(requirements={"VSR-3.3-004"})
@RestrictedBuildTest
@Test
public void testGpuWorkPeriodTracepointFormat() throws Exception {
diff --git a/services/inputflinger/InputCommonConverter.cpp b/services/inputflinger/InputCommonConverter.cpp
index 0c93f5c..2437d0f 100644
--- a/services/inputflinger/InputCommonConverter.cpp
+++ b/services/inputflinger/InputCommonConverter.cpp
@@ -200,17 +200,12 @@
return static_cast<common::Button>(buttonState);
}
-static common::ToolType getToolType(int32_t toolType) {
- static_assert(static_cast<common::ToolType>(AMOTION_EVENT_TOOL_TYPE_UNKNOWN) ==
- common::ToolType::UNKNOWN);
- static_assert(static_cast<common::ToolType>(AMOTION_EVENT_TOOL_TYPE_FINGER) ==
- common::ToolType::FINGER);
- static_assert(static_cast<common::ToolType>(AMOTION_EVENT_TOOL_TYPE_STYLUS) ==
- common::ToolType::STYLUS);
- static_assert(static_cast<common::ToolType>(AMOTION_EVENT_TOOL_TYPE_MOUSE) ==
- common::ToolType::MOUSE);
- static_assert(static_cast<common::ToolType>(AMOTION_EVENT_TOOL_TYPE_ERASER) ==
- common::ToolType::ERASER);
+static common::ToolType getToolType(ToolType toolType) {
+ static_assert(static_cast<common::ToolType>(ToolType::UNKNOWN) == common::ToolType::UNKNOWN);
+ static_assert(static_cast<common::ToolType>(ToolType::FINGER) == common::ToolType::FINGER);
+ static_assert(static_cast<common::ToolType>(ToolType::STYLUS) == common::ToolType::STYLUS);
+ static_assert(static_cast<common::ToolType>(ToolType::MOUSE) == common::ToolType::MOUSE);
+ static_assert(static_cast<common::ToolType>(ToolType::ERASER) == common::ToolType::ERASER);
return static_cast<common::ToolType>(toolType);
}
diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp
index b192ad7..5f2a22f 100644
--- a/services/inputflinger/NotifyArgs.cpp
+++ b/services/inputflinger/NotifyArgs.cpp
@@ -161,9 +161,9 @@
StringPrintf("id=%" PRIu32 " x=%.1f y=%.1f pressure=%.1f", pointerProperties[i].id,
pointerCoords[i].getX(), pointerCoords[i].getY(),
pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
- const int32_t toolType = pointerProperties[i].toolType;
- if (toolType != AMOTION_EVENT_TOOL_TYPE_FINGER) {
- coords += StringPrintf(" toolType=%s", motionToolTypeToString(toolType));
+ const ToolType toolType = pointerProperties[i].toolType;
+ if (toolType != ToolType::FINGER) {
+ coords += StringPrintf(" toolType=%s", ftl::enum_string(toolType).c_str());
}
const float major = pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
const float minor = pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
diff --git a/services/inputflinger/PreferStylusOverTouchBlocker.cpp b/services/inputflinger/PreferStylusOverTouchBlocker.cpp
index ddd5146..fbd296c 100644
--- a/services/inputflinger/PreferStylusOverTouchBlocker.cpp
+++ b/services/inputflinger/PreferStylusOverTouchBlocker.cpp
@@ -24,11 +24,11 @@
bool hasTouch = false;
for (size_t i = 0; i < args.pointerCount; i++) {
// Make sure we are canceling stylus pointers
- const int32_t toolType = args.pointerProperties[i].toolType;
+ const ToolType toolType = args.pointerProperties[i].toolType;
if (isStylusToolType(toolType)) {
hasStylus = true;
}
- if (toolType == AMOTION_EVENT_TOOL_TYPE_FINGER) {
+ if (toolType == ToolType::FINGER) {
hasTouch = true;
}
}
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index c170b81..ae20f86 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -18,6 +18,7 @@
#include "UnwantedInteractionBlocker.h"
#include <android-base/stringprintf.h>
+#include <ftl/enum.h>
#include <input/PrintTools.h>
#include <inttypes.h>
#include <linux/input-event-codes.h>
@@ -98,18 +99,21 @@
return false;
}
-static int getLinuxToolCode(int toolType) {
+static int getLinuxToolCode(ToolType toolType) {
switch (toolType) {
- case AMOTION_EVENT_TOOL_TYPE_STYLUS:
+ case ToolType::STYLUS:
return BTN_TOOL_PEN;
- case AMOTION_EVENT_TOOL_TYPE_ERASER:
+ case ToolType::ERASER:
return BTN_TOOL_RUBBER;
- case AMOTION_EVENT_TOOL_TYPE_FINGER:
+ case ToolType::FINGER:
return BTN_TOOL_FINGER;
- default:
- ALOGW("Got tool type %" PRId32 ", converting to BTN_TOOL_FINGER", toolType);
- return BTN_TOOL_FINGER;
+ case ToolType::UNKNOWN:
+ case ToolType::MOUSE:
+ case ToolType::PALM:
+ break;
}
+ ALOGW("Got tool type %s, converting to BTN_TOOL_FINGER", ftl::enum_string(toolType).c_str());
+ return BTN_TOOL_FINGER;
}
static int32_t getActionUpForPointerId(const NotifyMotionArgs& args, int32_t pointerId) {
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index f03c837..58324c4 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -207,7 +207,7 @@
pointerProperties[0].clear();
pointerProperties[0].id = 0;
- pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[0].toolType = ToolType::FINGER;
pointerCoords[0].clear();
pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
@@ -235,7 +235,7 @@
pointerProperties[0].clear();
pointerProperties[0].id = 0;
- pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[0].toolType = ToolType::FINGER;
pointerCoords[0].clear();
pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
diff --git a/services/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index 4da846b..0e4e79e 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <optional>
#define LOG_TAG "InputDispatcher"
#define ATRACE_TAG ATRACE_TAG_INPUT
@@ -25,6 +26,7 @@
#include <binder/Binder.h>
#include <ftl/enum.h>
#include <gui/WindowInfo.h>
+#include <unordered_set>
#include "DebugConfig.h"
#include "FocusResolver.h"
@@ -34,6 +36,11 @@
namespace android::inputdispatcher {
+template <typename T>
+struct SpHash {
+ size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); }
+};
+
sp<IBinder> FocusResolver::getFocusedWindowToken(int32_t displayId) const {
auto it = mFocusedWindowTokenByDisplay.find(displayId);
return it != mFocusedWindowTokenByDisplay.end() ? it->second.second : nullptr;
@@ -54,30 +61,30 @@
int32_t displayId, const std::vector<sp<WindowInfoHandle>>& windows) {
std::string removeFocusReason;
- // Check if the currently focused window is still focusable.
- const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
- if (currentFocus) {
- Focusability result = isTokenFocusable(currentFocus, windows);
- if (result == Focusability::OK) {
- return std::nullopt;
- }
- removeFocusReason = ftl::enum_string(result);
- }
-
- // We don't have a focused window or the currently focused window is no longer focusable. Check
- // to see if we can grant focus to the window that previously requested focus.
const std::optional<FocusRequest> request = getFocusRequest(displayId);
+ const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
+
+ // Find the next focused token based on the latest FocusRequest. If the requested focus window
+ // cannot be focused, focus will be removed.
if (request) {
sp<IBinder> requestedFocus = request->token;
- const Focusability result = isTokenFocusable(requestedFocus, windows);
+ sp<WindowInfoHandle> resolvedFocusWindow;
+ Focusability result = getResolvedFocusWindow(requestedFocus, windows, resolvedFocusWindow);
+ if (result == Focusability::OK && resolvedFocusWindow->getToken() == currentFocus) {
+ return std::nullopt;
+ }
const Focusability previousResult = mLastFocusResultByDisplay[displayId];
mLastFocusResultByDisplay[displayId] = result;
if (result == Focusability::OK) {
+ LOG_ALWAYS_FATAL_IF(!resolvedFocusWindow,
+ "Focused window should be non-null when result is OK!");
return updateFocusedWindow(displayId,
"Window became focusable. Previous reason: " +
ftl::enum_string(previousResult),
- requestedFocus, request->windowName);
+ resolvedFocusWindow->getToken(),
+ resolvedFocusWindow->getName());
}
+ removeFocusReason = ftl::enum_string(result);
}
// Focused window is no longer focusable and we don't have a suitable focus request to grant.
@@ -96,35 +103,18 @@
return std::nullopt;
}
- // Handle conditional focus requests, i.e. requests that have a focused token. These requests
- // are not persistent. If the window is no longer focusable, we expect focus to go back to the
- // previously focused window.
- if (request.focusedToken) {
- if (currentFocus != request.focusedToken) {
- ALOGW("setFocusedWindow %s on display %" PRId32
- " ignored, reason: focusedToken %s is not focused",
- request.windowName.c_str(), displayId, request.focusedWindowName.c_str());
- return std::nullopt;
- }
- Focusability result = isTokenFocusable(request.token, windows);
- if (result == Focusability::OK) {
- return updateFocusedWindow(displayId, "setFocusedWindow with focus check",
- request.token, request.windowName);
- }
- ALOGW("setFocusedWindow %s on display %" PRId32 " ignored, reason: %s",
- request.windowName.c_str(), displayId, ftl::enum_string(result).c_str());
- return std::nullopt;
- }
-
- Focusability result = isTokenFocusable(request.token, windows);
+ sp<WindowInfoHandle> resolvedFocusWindow;
+ Focusability result = getResolvedFocusWindow(request.token, windows, resolvedFocusWindow);
// Update focus request. The focus resolver will always try to handle this request if there is
// no focused window on the display.
mFocusRequestByDisplay[displayId] = request;
mLastFocusResultByDisplay[displayId] = result;
if (result == Focusability::OK) {
- return updateFocusedWindow(displayId, "setFocusedWindow", request.token,
- request.windowName);
+ LOG_ALWAYS_FATAL_IF(!resolvedFocusWindow,
+ "Focused window should be non-null when result is OK!");
+ return updateFocusedWindow(displayId, "setFocusedWindow", resolvedFocusWindow->getToken(),
+ resolvedFocusWindow->getName());
}
// The requested window is not currently focusable. Wait for the window to become focusable
@@ -134,11 +124,43 @@
nullptr);
}
+FocusResolver::Focusability FocusResolver::getResolvedFocusWindow(
+ const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows,
+ sp<WindowInfoHandle>& outFocusableWindow) {
+ sp<IBinder> curFocusCandidate = token;
+ bool focusedWindowFound = false;
+
+ // Keep track of all windows reached to prevent a cyclical transferFocus request.
+ std::unordered_set<sp<IBinder>, SpHash<IBinder>> tokensReached;
+
+ while (curFocusCandidate != nullptr && tokensReached.count(curFocusCandidate) == 0) {
+ tokensReached.emplace(curFocusCandidate);
+ Focusability result = isTokenFocusable(curFocusCandidate, windows, outFocusableWindow);
+ if (result == Focusability::OK) {
+ LOG_ALWAYS_FATAL_IF(!outFocusableWindow,
+ "Focused window should be non-null when result is OK!");
+ focusedWindowFound = true;
+ // outFocusableWindow has been updated by isTokenFocusable to contain
+ // the window info for curFocusCandidate. See if we can grant focus
+ // to the token that it wants to transfer its focus to.
+ curFocusCandidate = outFocusableWindow->getInfo()->focusTransferTarget;
+ }
+
+ // If the initial token is not focusable, return early with the failed result.
+ if (!focusedWindowFound) {
+ return result;
+ }
+ }
+
+ return focusedWindowFound ? Focusability::OK : Focusability::NO_WINDOW;
+}
+
FocusResolver::Focusability FocusResolver::isTokenFocusable(
- const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows) {
+ const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows,
+ sp<WindowInfoHandle>& outFocusableWindow) {
bool allWindowsAreFocusable = true;
- bool visibleWindowFound = false;
bool windowFound = false;
+ sp<WindowInfoHandle> visibleWindowHandle = nullptr;
for (const sp<WindowInfoHandle>& window : windows) {
if (window->getToken() != token) {
continue;
@@ -146,7 +168,7 @@
windowFound = true;
if (!window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)) {
// Check if at least a single window is visible.
- visibleWindowFound = true;
+ visibleWindowHandle = window;
}
if (window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE)) {
// Check if all windows with the window token are focusable.
@@ -161,10 +183,12 @@
if (!allWindowsAreFocusable) {
return Focusability::NOT_FOCUSABLE;
}
- if (!visibleWindowFound) {
+ if (!visibleWindowHandle) {
return Focusability::NOT_VISIBLE;
}
+ // Only set the outFoundWindow if the window can be focused
+ outFocusableWindow = visibleWindowHandle;
return Focusability::OK;
}
diff --git a/services/inputflinger/dispatcher/FocusResolver.h b/services/inputflinger/dispatcher/FocusResolver.h
index 6d11a77..5bb157b 100644
--- a/services/inputflinger/dispatcher/FocusResolver.h
+++ b/services/inputflinger/dispatcher/FocusResolver.h
@@ -92,7 +92,13 @@
//
static Focusability isTokenFocusable(
const sp<IBinder>& token,
- const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
+ const std::vector<sp<android::gui::WindowInfoHandle>>& windows,
+ sp<android::gui::WindowInfoHandle>& outFocusableWindow);
+
+ static FocusResolver::Focusability getResolvedFocusWindow(
+ const sp<IBinder>& token,
+ const std::vector<sp<android::gui::WindowInfoHandle>>& windows,
+ sp<android::gui::WindowInfoHandle>& outFocusableWindow);
// Focus tracking for keys, trackball, etc. A window token can be associated with one or
// more InputWindowHandles. If a window is mirrored, the window and its mirror will share
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index cd427f0..6e2f862 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -31,6 +31,7 @@
#endif
#include <input/InputDevice.h>
#include <input/PrintTools.h>
+#include <openssl/mem.h>
#include <powermanager/PowerManager.h>
#include <unistd.h>
#include <utils/Trace.h>
@@ -1862,11 +1863,12 @@
entry.yPrecision, entry.downTime);
for (uint32_t i = 0; i < entry.pointerCount; i++) {
- ALOGD(" Pointer %d: id=%d, toolType=%d, "
+ ALOGD(" Pointer %d: id=%d, toolType=%s, "
"x=%f, y=%f, pressure=%f, size=%f, "
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
- i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
+ i, entry.pointerProperties[i].id,
+ ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
@@ -4178,7 +4180,7 @@
ALOGD(" Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
i, args->pointerProperties[i].id,
- motionToolTypeToString(args->pointerProperties[i].toolType),
+ ftl::enum_string(args->pointerProperties[i].toolType).c_str(),
args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
@@ -4629,7 +4631,7 @@
if (calculatedHmac == INVALID_HMAC) {
return nullptr;
}
- if (calculatedHmac != event.getHmac()) {
+ if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
return nullptr;
}
return result;
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 841c914..1750c64 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -149,6 +149,9 @@
/* Get the Bluetooth address of an input device, if known. */
virtual std::optional<std::string> getBluetoothAddress(int32_t deviceId) const = 0;
+
+ /* Sysfs node change reported. Recreate device if required to incorporate the new sysfs nodes */
+ virtual void sysfsNodeChanged(const std::string& sysfsNodePath) = 0;
};
// --- InputReaderConfiguration ---
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index e65f3af..ee8dde1 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -1531,6 +1531,20 @@
return associatedDevice;
}
+bool EventHub::AssociatedDevice::isChanged() const {
+ std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos =
+ readBatteryConfiguration(sysfsRootPath);
+ std::unordered_map<int32_t, RawLightInfo> newLightInfos =
+ readLightsConfiguration(sysfsRootPath);
+ std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath);
+
+ if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos &&
+ newLayoutInfo == layoutInfo) {
+ return false;
+ }
+ return true;
+}
+
void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) {
std::scoped_lock _l(mLock);
Device* device = getDeviceLocked(deviceId);
@@ -2536,6 +2550,42 @@
return device->disable();
}
+// TODO(b/274755573): Shift to uevent handling on native side and remove this method
+// Currently using Java UEventObserver to trigger this which uses UEvent infrastructure that uses a
+// NETLINK socket to observe UEvents. We can create similar infrastructure on Eventhub side to
+// directly observe UEvents instead of triggering from Java side.
+void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
+ std::scoped_lock _l(mLock);
+
+ // Check in opening devices
+ for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) {
+ std::unique_ptr<Device>& device = *it;
+ if (device->associatedDevice &&
+ sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
+ std::string::npos &&
+ device->associatedDevice->isChanged()) {
+ it = mOpeningDevices.erase(it);
+ openDeviceLocked(device->path);
+ }
+ }
+
+ // Check in already added device
+ std::vector<Device*> devicesToReopen;
+ for (const auto& [id, device] : mDevices) {
+ if (device->associatedDevice &&
+ sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
+ std::string::npos &&
+ device->associatedDevice->isChanged()) {
+ devicesToReopen.push_back(device.get());
+ }
+ }
+ for (const auto& device : devicesToReopen) {
+ closeDeviceLocked(*device);
+ openDeviceLocked(device->path);
+ }
+ devicesToReopen.clear();
+}
+
void EventHub::createVirtualKeyboardLocked() {
InputDeviceIdentifier identifier;
identifier.name = "Virtual";
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index ddf6c87..eaed987 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -385,7 +385,7 @@
}
for_each_mapper([this, when, &config, changes, &out](InputMapper& mapper) {
- out += mapper.configure(when, config, changes);
+ out += mapper.reconfigure(when, config, changes);
mSources |= mapper.getSources();
});
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 9080cc1..81ac03b 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -928,6 +928,10 @@
return *associatedDisplayId == displayId;
}
+void InputReader::sysfsNodeChanged(const std::string& sysfsNodePath) {
+ mEventHub->sysfsNodeChanged(sysfsNodePath);
+}
+
void InputReader::dump(std::string& dump) {
std::scoped_lock _l(mLock);
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 0b15efe..20612c7 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -388,6 +388,10 @@
/* Disable an input device. Closes file descriptor to that device. */
virtual status_t disableDevice(int32_t deviceId) = 0;
+
+ /* Sysfs node changed. Reopen the Eventhub device if any new Peripheral like Light, Battery,
+ * etc. is detected. */
+ virtual void sysfsNodeChanged(const std::string& sysfsNodePath) = 0;
};
template <std::size_t BITS>
@@ -567,6 +571,8 @@
status_t disableDevice(int32_t deviceId) override final;
+ void sysfsNodeChanged(const std::string& sysfsNodePath) override final;
+
~EventHub() override;
private:
@@ -578,6 +584,7 @@
std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
std::optional<RawLayoutInfo> layoutInfo;
+ bool isChanged() const;
bool operator==(const AssociatedDevice&) const = default;
bool operator!=(const AssociatedDevice&) const = default;
std::string dump() const;
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index e9c989a..120e150 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -117,6 +117,8 @@
std::optional<std::string> getBluetoothAddress(int32_t deviceId) const override;
+ void sysfsNodeChanged(const std::string& sysfsNodePath) override;
+
protected:
// These members are protected so they can be instrumented by test cases.
virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t deviceId,
diff --git a/services/inputflinger/reader/include/StylusState.h b/services/inputflinger/reader/include/StylusState.h
index ff15e0c..d042784 100644
--- a/services/inputflinger/reader/include/StylusState.h
+++ b/services/inputflinger/reader/include/StylusState.h
@@ -33,8 +33,8 @@
std::optional<float> pressure{};
/* The state of the stylus buttons as a bitfield (e.g. AMOTION_EVENT_BUTTON_SECONDARY). */
uint32_t buttons{};
- /* Which tool type the stylus is currently using (e.g. AMOTION_EVENT_TOOL_TYPE_ERASER). */
- int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN};
+ /* Which tool type the stylus is currently using (e.g. ToolType::ERASER). */
+ ToolType toolType{ToolType::UNKNOWN};
void clear() { *this = StylusState{}; }
};
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 83cf287..d7dc2ae 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -133,10 +133,10 @@
dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
}
-std::list<NotifyArgs> CursorInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> CursorInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
if (!changes) { // first time only
mCursorScrollAccumulator.configure(getDeviceContext());
@@ -350,7 +350,7 @@
PointerProperties pointerProperties;
pointerProperties.clear();
pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
+ pointerProperties.toolType = ToolType::MOUSE;
PointerCoords pointerCoords;
pointerCoords.clear();
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 5f02203..987b9de 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -59,9 +59,9 @@
virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
index a44d15b..c5a3075 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
@@ -46,9 +46,9 @@
dumpStylusState(dump, mStylusState);
}
-std::list<NotifyArgs> ExternalStylusInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
+std::list<NotifyArgs> ExternalStylusInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPressureAxis);
mTouchButtonAccumulator.configure();
return {};
@@ -77,8 +77,8 @@
mStylusState.when = when;
mStylusState.toolType = mTouchButtonAccumulator.getToolType();
- if (mStylusState.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ if (mStylusState.toolType == ToolType::UNKNOWN) {
+ mStylusState.toolType = ToolType::STYLUS;
}
if (mRawPressureAxis.valid) {
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
index 11b5315..0df8cf7 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
@@ -32,9 +32,9 @@
uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index 9cf3696..9d1e9ce 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -35,8 +35,8 @@
void InputMapper::dump(std::string& dump) {}
-std::list<NotifyArgs> InputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
- uint32_t changes) {
+std::list<NotifyArgs> InputMapper::reconfigure(nsecs_t when, const InputReaderConfiguration* config,
+ uint32_t changes) {
return {};
}
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index 2722edd..bb15e4d 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -53,9 +53,9 @@
virtual uint32_t getSources() const = 0;
virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo);
virtual void dump(std::string& dump);
- [[nodiscard]] virtual std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes);
+ [[nodiscard]] virtual std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes);
[[nodiscard]] virtual std::list<NotifyArgs> reset(nsecs_t when);
[[nodiscard]] virtual std::list<NotifyArgs> process(const RawEvent* rawEvent) = 0;
[[nodiscard]] virtual std::list<NotifyArgs> timeoutExpired(nsecs_t when);
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index 7724cf7..f60035b 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -103,10 +103,10 @@
}
}
-std::list<NotifyArgs> JoystickInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> JoystickInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
if (!changes) { // first time only
// Collect all axes.
@@ -321,7 +321,7 @@
PointerProperties pointerProperties;
pointerProperties.clear();
pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+ pointerProperties.toolType = ToolType::UNKNOWN;
PointerCoords pointerCoords;
pointerCoords.clear();
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.h b/services/inputflinger/reader/mapper/JoystickInputMapper.h
index 9ca4176..9adb07f 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.h
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.h
@@ -28,9 +28,9 @@
virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 269c106..fc00c48 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -131,10 +131,10 @@
return std::nullopt;
}
-std::list<NotifyArgs> KeyboardInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> KeyboardInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
if (!changes) { // first time only
// Configure basic parameters.
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index 2fc82c3..52576c3 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -29,9 +29,9 @@
uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 33e72c7..e871288 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -77,7 +77,7 @@
continue;
}
- if (inSlot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM) {
+ if (inSlot.getToolType() == ToolType::PALM) {
std::optional<int32_t> id = getActiveBitId(inSlot);
if (id) {
outState->rawPointerData.canceledIdBits.markBit(id.value());
@@ -112,12 +112,12 @@
outPointer.tiltY = 0;
outPointer.toolType = inSlot.getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+ if (outPointer.toolType == ToolType::UNKNOWN) {
outPointer.toolType = mTouchButtonAccumulator.getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ if (outPointer.toolType == ToolType::UNKNOWN) {
+ outPointer.toolType = ToolType::FINGER;
}
- } else if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS && !mStylusMtToolSeen) {
+ } else if (outPointer.toolType == ToolType::STYLUS && !mStylusMtToolSeen) {
mStylusMtToolSeen = true;
// The multi-touch device produced a stylus event with MT_TOOL_PEN. Dynamically
// re-configure this input device so that we add SOURCE_STYLUS if we haven't already.
@@ -130,12 +130,11 @@
bumpGeneration();
}
}
- if (shouldSimulateStylusWithTouch() &&
- outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER) {
- outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ if (shouldSimulateStylusWithTouch() && outPointer.toolType == ToolType::FINGER) {
+ outPointer.toolType = ToolType::STYLUS;
}
- bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE &&
+ bool isHovering = mTouchButtonAccumulator.getToolType() != ToolType::MOUSE &&
(mTouchButtonAccumulator.isHovering() ||
(mRawPointerAxes.pressure.valid && inSlot.getPressure() <= 0));
outPointer.isHovering = isHovering;
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index 94cc145..5b7b295 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -63,10 +63,10 @@
toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel()));
}
-std::list<NotifyArgs> RotaryEncoderInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> RotaryEncoderInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
if (!changes) {
mRotaryEncoderScrollAccumulator.configure(getDeviceContext());
}
@@ -121,7 +121,7 @@
PointerProperties pointerProperties;
pointerProperties.clear();
pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+ pointerProperties.toolType = ToolType::UNKNOWN;
uint32_t policyFlags = 0;
if (getDeviceContext().isExternal()) {
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index a0516c4..639a987 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -31,9 +31,9 @@
virtual uint32_t getSources() const override;
virtual void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
virtual void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 60e6727..720fc69 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -116,10 +116,10 @@
}
}
-std::list<NotifyArgs> SensorInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> SensorInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
if (!changes) { // first time only
mDeviceEnabled = true;
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.h b/services/inputflinger/reader/mapper/SensorInputMapper.h
index 7f47df7..93cc244 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.h
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.h
@@ -33,9 +33,9 @@
uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
bool enableSensor(InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod,
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
index 13ad224..f13417a 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
@@ -41,7 +41,7 @@
outState->rawPointerData.pointerCount = 1;
outState->rawPointerData.idToIndex[0] = 0;
- bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE &&
+ bool isHovering = mTouchButtonAccumulator.getToolType() != ToolType::MOUSE &&
(mTouchButtonAccumulator.isHovering() ||
(mRawPointerAxes.pressure.valid &&
mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
@@ -61,8 +61,8 @@
outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
outPointer.toolType = mTouchButtonAccumulator.getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ if (outPointer.toolType == ToolType::UNKNOWN) {
+ outPointer.toolType = ToolType::FINGER;
}
outPointer.isHovering = isHovering;
}
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index df7ba49..eb99438 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -229,11 +229,12 @@
dump += StringPrintf(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
"touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
"orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
- "toolType=%d, isHovering=%s\n",
+ "toolType=%s, isHovering=%s\n",
i, pointer.id, pointer.x, pointer.y, pointer.pressure,
pointer.touchMajor, pointer.touchMinor, pointer.toolMajor,
pointer.toolMinor, pointer.orientation, pointer.tiltX, pointer.tiltY,
- pointer.distance, pointer.toolType, toString(pointer.isHovering));
+ pointer.distance, ftl::enum_string(pointer.toolType).c_str(),
+ toString(pointer.isHovering));
}
dump += StringPrintf(INDENT3 "Last Cooked Button State: 0x%08x\n",
@@ -248,7 +249,7 @@
"pressure=%0.3f, touchMajor=%0.3f, touchMinor=%0.3f, "
"toolMajor=%0.3f, toolMinor=%0.3f, "
"orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
- "toolType=%d, isHovering=%s\n",
+ "toolType=%s, isHovering=%s\n",
i, pointerProperties.id, pointerCoords.getX(), pointerCoords.getY(),
pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y),
@@ -260,7 +261,7 @@
pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
- pointerProperties.toolType,
+ ftl::enum_string(pointerProperties.toolType).c_str(),
toString(mLastCookedState.cookedPointerData.isHovering(i)));
}
@@ -286,10 +287,10 @@
}
}
-std::list<NotifyArgs> TouchInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
- std::list<NotifyArgs> out = InputMapper::configure(when, config, changes);
+std::list<NotifyArgs> TouchInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
+ std::list<NotifyArgs> out = InputMapper::reconfigure(when, config, changes);
mConfig = *config;
@@ -872,14 +873,26 @@
: ui::Transform();
// Step 4: Scale the raw coordinates to the display space.
- // - Here, we assume that the raw surface of the touch device maps perfectly to the surface
- // of the display panel. This is usually true for touchscreens.
+ // - In DIRECT mode, we assume that the raw surface of the touch device maps perfectly to
+ // the surface of the display panel. This is usually true for touchscreens.
+ // - In POINTER mode, we cannot assume that the display and the touch device have the same
+ // aspect ratio, since it is likely to be untrue for devices like external drawing tablets.
+ // In this case, we used a fixed scale so that 1) we use the same scale across both the x and
+ // y axes to ensure the mapping does not stretch gestures, and 2) the entire region of the
+ // display can be reached by the touch device.
// - From this point onward, we are no longer in the discrete space of the raw coordinates but
// are in the continuous space of the logical display.
ui::Transform scaleRawToDisplay;
const float xScale = static_cast<float>(mViewport.deviceWidth) / rotatedRawSize.width;
const float yScale = static_cast<float>(mViewport.deviceHeight) / rotatedRawSize.height;
- scaleRawToDisplay.set(xScale, 0, 0, yScale);
+ if (mDeviceMode == DeviceMode::DIRECT) {
+ scaleRawToDisplay.set(xScale, 0, 0, yScale);
+ } else if (mDeviceMode == DeviceMode::POINTER) {
+ const float fixedScale = std::max(xScale, yScale);
+ scaleRawToDisplay.set(fixedScale, 0, 0, fixedScale);
+ } else {
+ LOG_ALWAYS_FATAL("computeInputTransform can only be used for DIRECT and POINTER modes");
+ }
// Step 5: Undo the display rotation to bring us back to the un-rotated display coordinate space
// that InputReader uses.
@@ -1582,10 +1595,10 @@
mCurrentRawState.rawPointerData.pointerForId(id);
if (isStylusToolType(pointer.toolType)) {
mCurrentCookedState.stylusIdBits.markBit(id);
- } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER ||
- pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+ } else if (pointer.toolType == ToolType::FINGER ||
+ pointer.toolType == ToolType::UNKNOWN) {
mCurrentCookedState.fingerIdBits.markBit(id);
- } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
+ } else if (pointer.toolType == ToolType::MOUSE) {
mCurrentCookedState.mouseIdBits.markBit(id);
}
}
@@ -1704,7 +1717,7 @@
PointerCoords& coords = currentPointerData.editPointerCoordsWithId(*mFusedStylusPointerId);
coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
- if (mExternalStylusState.toolType != AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
+ if (mExternalStylusState.toolType != ToolType::UNKNOWN) {
PointerProperties& properties =
currentPointerData.editPointerPropertiesWithId(*mFusedStylusPointerId);
properties.toolType = mExternalStylusState.toolType;
@@ -2678,7 +2691,7 @@
PointerProperties pointerProperties;
pointerProperties.clear();
pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties.toolType = ToolType::FINGER;
PointerCoords pointerCoords;
pointerCoords.clear();
@@ -2887,7 +2900,7 @@
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
mPointerGesture.currentGestureProperties[0].clear();
mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerGesture.currentGestureProperties[0].toolType = ToolType::FINGER;
mPointerGesture.currentGestureCoords[0].clear();
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
@@ -2922,8 +2935,7 @@
mPointerGesture.currentGestureProperties[0].clear();
mPointerGesture.currentGestureProperties[0].id =
mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType =
- AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerGesture.currentGestureProperties[0].toolType = ToolType::FINGER;
mPointerGesture.currentGestureCoords[0].clear();
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
mPointerGesture.tapX);
@@ -3010,7 +3022,7 @@
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
mPointerGesture.currentGestureProperties[0].clear();
mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerGesture.currentGestureProperties[0].toolType = ToolType::FINGER;
mPointerGesture.currentGestureCoords[0].clear();
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
@@ -3040,9 +3052,10 @@
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
- ALOGD(" currentGesture[%d]: index=%d, toolType=%d, "
+ ALOGD(" currentGesture[%d]: index=%d, toolType=%s, "
"x=%0.3f, y=%0.3f, pressure=%0.3f",
- id, index, properties.toolType, coords.getAxisValue(AMOTION_EVENT_AXIS_X),
+ id, index, ftl::enum_string(properties.toolType).c_str(),
+ coords.getAxisValue(AMOTION_EVENT_AXIS_X),
coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
}
@@ -3051,9 +3064,10 @@
uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
- ALOGD(" lastGesture[%d]: index=%d, toolType=%d, "
+ ALOGD(" lastGesture[%d]: index=%d, toolType=%s, "
"x=%0.3f, y=%0.3f, pressure=%0.3f",
- id, index, properties.toolType, coords.getAxisValue(AMOTION_EVENT_AXIS_X),
+ id, index, ftl::enum_string(properties.toolType).c_str(),
+ coords.getAxisValue(AMOTION_EVENT_AXIS_X),
coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
}
@@ -3342,7 +3356,7 @@
mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
mPointerGesture.currentGestureProperties[0].clear();
mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerGesture.currentGestureProperties[0].toolType = ToolType::FINGER;
mPointerGesture.currentGestureCoords[0].clear();
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
mPointerGesture.referenceGestureX);
@@ -3435,7 +3449,7 @@
mPointerGesture.currentGestureProperties[i].clear();
mPointerGesture.currentGestureProperties[i].id = gestureId;
- mPointerGesture.currentGestureProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mPointerGesture.currentGestureProperties[i].toolType = ToolType::FINGER;
mPointerGesture.currentGestureCoords[i].clear();
mPointerGesture.currentGestureCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X,
mPointerGesture.referenceGestureX +
@@ -3477,14 +3491,19 @@
if (!mCurrentCookedState.stylusIdBits.isEmpty()) {
uint32_t id = mCurrentCookedState.stylusIdBits.firstMarkedBit();
uint32_t index = mCurrentCookedState.cookedPointerData.idToIndex[id];
- mPointerController
- ->setPosition(mCurrentCookedState.cookedPointerData.pointerCoords[index].getX(),
- mCurrentCookedState.cookedPointerData.pointerCoords[index].getY());
-
hovering = mCurrentCookedState.cookedPointerData.hoveringIdBits.hasBit(id);
down = !hovering;
- const auto [x, y] = mPointerController->getPosition();
+ float x = mCurrentCookedState.cookedPointerData.pointerCoords[index].getX();
+ float y = mCurrentCookedState.cookedPointerData.pointerCoords[index].getY();
+ // Styluses are configured specifically for one display. We only update the
+ // PointerController for this stylus if the PointerController is configured for
+ // the same display as this stylus,
+ if (getAssociatedDisplayId() == mViewport.displayId) {
+ mPointerController->setPosition(x, y);
+ std::tie(x, y) = mPointerController->getPosition();
+ }
+
mPointerSimple.currentCoords.copyFrom(
mCurrentCookedState.cookedPointerData.pointerCoords[index]);
mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
@@ -3497,7 +3516,7 @@
hovering = false;
}
- return dispatchPointerSimple(when, readTime, policyFlags, down, hovering);
+ return dispatchPointerSimple(when, readTime, policyFlags, down, hovering, mViewport.displayId);
}
std::list<NotifyArgs> TouchInputMapper::abortPointerStylus(nsecs_t when, nsecs_t readTime,
@@ -3540,7 +3559,8 @@
hovering = false;
}
- return dispatchPointerSimple(when, readTime, policyFlags, down, hovering);
+ const int32_t displayId = mPointerController->getDisplayId();
+ return dispatchPointerSimple(when, readTime, policyFlags, down, hovering, displayId);
}
std::list<NotifyArgs> TouchInputMapper::abortPointerMouse(nsecs_t when, nsecs_t readTime,
@@ -3554,7 +3574,7 @@
std::list<NotifyArgs> TouchInputMapper::dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags, bool down,
- bool hovering) {
+ bool hovering, int32_t displayId) {
LOG_ALWAYS_FATAL_IF(mDeviceMode != DeviceMode::POINTER,
"%s cannot be used when the device is not in POINTER mode.", __func__);
std::list<NotifyArgs> out;
@@ -3567,7 +3587,6 @@
} else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
}
- int32_t displayId = mPointerController->getDisplayId();
const auto [xCursorPosition, yCursorPosition] = mPointerController->getPosition();
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index ae7faa9..d98ae60 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -78,8 +78,8 @@
int32_t distance{};
int32_t tiltX{};
int32_t tiltY{};
- // A fully decoded AMOTION_EVENT_TOOL_TYPE constant.
- int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN};
+ // A fully decoded ToolType constant.
+ ToolType toolType{ToolType::UNKNOWN};
bool isHovering{false};
};
@@ -152,9 +152,9 @@
uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
@@ -789,7 +789,7 @@
[[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags, bool down,
- bool hovering);
+ bool hovering, int32_t displayId);
[[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
@@ -821,6 +821,7 @@
static void assignPointerIds(const RawState& last, RawState& current);
+ // Compute input transforms for DIRECT and POINTER modes.
void computeInputTransforms();
void configureDeviceType();
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 661461b..33f368e 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -219,9 +219,9 @@
dump += addLinePrefix(mPropertyProvider.dump(), INDENT4);
}
-std::list<NotifyArgs> TouchpadInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) {
+std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) {
if (!changes) {
// First time configuration
mPropertyProvider.loadPropertiesFromIdcFile(getDeviceContext().getConfiguration());
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.h b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
index fb36d92..6f152fa 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.h
@@ -44,9 +44,9 @@
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
- [[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
- const InputReaderConfiguration* config,
- uint32_t changes) override;
+ [[nodiscard]] std::list<NotifyArgs> reconfigure(nsecs_t when,
+ const InputReaderConfiguration* config,
+ uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
index f6a42bd..f70be72 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
@@ -154,18 +154,18 @@
// --- MultiTouchMotionAccumulator::Slot ---
-int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
+ToolType MultiTouchMotionAccumulator::Slot::getToolType() const {
if (mHaveAbsMtToolType) {
switch (mAbsMtToolType) {
case MT_TOOL_FINGER:
- return AMOTION_EVENT_TOOL_TYPE_FINGER;
+ return ToolType::FINGER;
case MT_TOOL_PEN:
- return AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ return ToolType::STYLUS;
case MT_TOOL_PALM:
- return AMOTION_EVENT_TOOL_TYPE_PALM;
+ return ToolType::PALM;
}
}
- return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+ return ToolType::UNKNOWN;
}
} // namespace android
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
index 3c1a2a9..943dde5 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
@@ -45,7 +45,7 @@
inline int32_t getTrackingId() const { return mAbsMtTrackingId; }
inline int32_t getPressure() const { return mAbsMtPressure; }
inline int32_t getDistance() const { return mAbsMtDistance; }
- int32_t getToolType() const;
+ ToolType getToolType() const;
private:
friend class MultiTouchMotionAccumulator;
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
index 6b84f32..8c4bed3 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
@@ -141,21 +141,21 @@
return result;
}
-int32_t TouchButtonAccumulator::getToolType() const {
+ToolType TouchButtonAccumulator::getToolType() const {
if (mBtnToolMouse || mBtnToolLens) {
- return AMOTION_EVENT_TOOL_TYPE_MOUSE;
+ return ToolType::MOUSE;
}
if (mBtnToolRubber) {
- return AMOTION_EVENT_TOOL_TYPE_ERASER;
+ return ToolType::ERASER;
}
if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
- return AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ return ToolType::STYLUS;
}
if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap ||
mBtnToolQuintTap) {
- return AMOTION_EVENT_TOOL_TYPE_FINGER;
+ return ToolType::FINGER;
}
- return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+ return ToolType::UNKNOWN;
}
bool TouchButtonAccumulator::isToolActive() const {
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
index c2aa2ad..c5fd5f5 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
@@ -36,7 +36,7 @@
void process(const RawEvent* rawEvent);
uint32_t getButtonState() const;
- int32_t getToolType() const;
+ ToolType getToolType() const;
bool isToolActive() const;
bool isHovering() const;
bool hasStylus() const;
diff --git a/services/inputflinger/reader/mapper/gestures/GestureConverter.h b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
index 2714d03..70e8fb7 100644
--- a/services/inputflinger/reader/mapper/gestures/GestureConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/GestureConverter.h
@@ -99,10 +99,10 @@
// We never need any PointerProperties other than the finger tool type, so we can just keep a
// const array of them.
const std::array<PointerProperties, MAX_FAKE_FINGERS> mFingerProps = {{
- {.id = 0, .toolType = AMOTION_EVENT_TOOL_TYPE_FINGER},
- {.id = 1, .toolType = AMOTION_EVENT_TOOL_TYPE_FINGER},
- {.id = 2, .toolType = AMOTION_EVENT_TOOL_TYPE_FINGER},
- {.id = 3, .toolType = AMOTION_EVENT_TOOL_TYPE_FINGER},
+ {.id = 0, .toolType = ToolType::FINGER},
+ {.id = 1, .toolType = ToolType::FINGER},
+ {.id = 2, .toolType = ToolType::FINGER},
+ {.id = 3, .toolType = ToolType::FINGER},
}};
std::array<PointerCoords, MAX_FAKE_FINGERS> mFakeFingerCoords = {};
diff --git a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
index c091a51..e89262a 100644
--- a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
+++ b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+// clang-format off
+#include "../Macros.h"
+// clang-format on
#include "gestures/HardwareStateConverter.h"
#include <chrono>
@@ -80,14 +83,9 @@
schs.fingers.clear();
for (size_t i = 0; i < mMotionAccumulator.getSlotCount(); i++) {
MultiTouchMotionAccumulator::Slot slot = mMotionAccumulator.getSlot(i);
- if (!slot.isInUse()) {
- continue;
- }
// Some touchpads continue to report contacts even after they've identified them as palms.
- // We want to exclude these contacts from the HardwareStates, but still need to report a
- // tracking ID of -1 if a finger turns into a palm.
- const bool isPalm = slot.getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM;
- if (isPalm && mFingerSlots.find(i) == mFingerSlots.end()) {
+ // We want to exclude these contacts from the HardwareStates.
+ if (!slot.isInUse() || slot.getToolType() == ToolType::PALM) {
continue;
}
@@ -101,12 +99,7 @@
fingerState.orientation = slot.getOrientation();
fingerState.position_x = slot.getX();
fingerState.position_y = slot.getY();
- fingerState.tracking_id = isPalm ? -1 : slot.getTrackingId();
- if (fingerState.tracking_id == -1) {
- mFingerSlots.erase(i);
- } else {
- mFingerSlots.insert(i);
- }
+ fingerState.tracking_id = slot.getTrackingId();
}
schs.state.fingers = schs.fingers.data();
schs.state.finger_cnt = schs.fingers.size();
@@ -117,7 +110,6 @@
void HardwareStateConverter::reset() {
mCursorButtonAccumulator.reset(mDeviceContext);
mTouchButtonAccumulator.reset();
- mFingerSlots.clear();
mMscTimestamp = 0;
}
diff --git a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
index d6787b7..c314b0d 100644
--- a/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
+++ b/services/inputflinger/reader/mapper/gestures/HardwareStateConverter.h
@@ -54,7 +54,6 @@
MultiTouchMotionAccumulator mMotionAccumulator;
TouchButtonAccumulator mTouchButtonAccumulator;
int32_t mMscTimestamp = 0;
- std::set<size_t> mFingerSlots;
};
} // namespace android
diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp
index ff6d584..4626f5a 100644
--- a/services/inputflinger/tests/FakeEventHub.cpp
+++ b/services/inputflinger/tests/FakeEventHub.cpp
@@ -594,4 +594,33 @@
return lightIt->second;
};
+void FakeEventHub::setSysfsRootPath(int32_t deviceId, std::string sysfsRootPath) const {
+ Device* device = getDevice(deviceId);
+ if (device == nullptr) {
+ return;
+ }
+ device->sysfsRootPath = sysfsRootPath;
+}
+
+void FakeEventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
+ int32_t foundDeviceId = -1;
+ Device* foundDevice = nullptr;
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ Device* d = mDevices.valueAt(i);
+ if (sysfsNodePath.find(d->sysfsRootPath) != std::string::npos) {
+ foundDeviceId = mDevices.keyAt(i);
+ foundDevice = d;
+ }
+ }
+ if (foundDevice == nullptr) {
+ return;
+ }
+ // If device sysfs changed -> reopen the device
+ if (!mRawLightInfos.empty() && !foundDevice->classes.test(InputDeviceClass::LIGHT)) {
+ removeDevice(foundDeviceId);
+ addDevice(foundDeviceId, foundDevice->identifier.name,
+ foundDevice->classes | InputDeviceClass::LIGHT, foundDevice->identifier.bus);
+ }
+}
+
} // namespace android
diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h
index e0a3f9e..8e06940 100644
--- a/services/inputflinger/tests/FakeEventHub.h
+++ b/services/inputflinger/tests/FakeEventHub.h
@@ -64,6 +64,7 @@
std::vector<VirtualKeyDefinition> virtualKeys;
bool enabled;
std::optional<RawLayoutInfo> layoutInfo;
+ std::string sysfsRootPath;
status_t enable() {
enabled = true;
@@ -152,6 +153,7 @@
void enqueueEvent(nsecs_t when, nsecs_t readTime, int32_t deviceId, int32_t type, int32_t code,
int32_t value);
void assertQueueIsEmpty();
+ void setSysfsRootPath(int32_t deviceId, std::string sysfsRootPath) const;
private:
Device* getDevice(int32_t deviceId) const;
@@ -212,7 +214,7 @@
std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override;
std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
int32_t deviceId, int32_t lightId) const override;
-
+ void sysfsNodeChanged(const std::string& sysfsNodePath) override;
void dump(std::string&) const override {}
void monitor() const override {}
void requestReopenDevices() override {}
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index ccdb37a..5440a98 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -237,7 +237,60 @@
ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ windowToken);
}
-TEST(FocusResolverTest, ConditionalFocusRequestsAreNotPersistent) {
+TEST(FocusResolverTest, FocusTransferTarget) {
+ sp<IBinder> hostWindowToken = sp<BBinder>::make();
+ std::vector<sp<WindowInfoHandle>> windows;
+
+ sp<FakeWindowHandle> hostWindow =
+ sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
+ /*visible=*/true);
+ windows.push_back(hostWindow);
+ sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
+ sp<FakeWindowHandle> embeddedWindow =
+ sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/false,
+ /*visible=*/true);
+ windows.push_back(embeddedWindow);
+
+ FocusRequest request;
+ request.displayId = 42;
+ request.token = hostWindowToken;
+
+ // Host wants to transfer touch to embedded.
+ hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
+
+ FocusResolver focusResolver;
+ std::optional<FocusResolver::FocusChanges> changes =
+ focusResolver.setFocusedWindow(request, windows);
+ // Embedded was not focusable so host gains focus.
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ hostWindowToken);
+
+ // Embedded is now focusable so will gain focus
+ embeddedWindow->setFocusable(true);
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
+
+ // Embedded is not visible so host will get focus
+ embeddedWindow->setVisible(false);
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
+
+ // Embedded is now visible so will get focus
+ embeddedWindow->setVisible(true);
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
+
+ // Remove focusTransferTarget from host. Host will gain focus.
+ hostWindow->editInfo()->focusTransferTarget = nullptr;
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
+
+ // Set invalid token for focusTransferTarget. Host will remain focus
+ hostWindow->editInfo()->focusTransferTarget = sp<BBinder>::make();
+ changes = focusResolver.setInputWindows(request.displayId, windows);
+ ASSERT_FALSE(changes);
+}
+
+TEST(FocusResolverTest, FocusTransferMultipleInChain) {
sp<IBinder> hostWindowToken = sp<BBinder>::make();
std::vector<sp<WindowInfoHandle>> windows;
@@ -251,43 +304,60 @@
/*visible=*/true);
windows.push_back(embeddedWindow);
+ sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
+ sp<FakeWindowHandle> embeddedWindow2 =
+ sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
+ /*visible=*/true);
+ windows.push_back(embeddedWindow2);
+
FocusRequest request;
request.displayId = 42;
request.token = hostWindowToken;
+
+ hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
+ embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
+
FocusResolver focusResolver;
std::optional<FocusResolver::FocusChanges> changes =
focusResolver.setFocusedWindow(request, windows);
- ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ hostWindowToken);
-
- request.focusedToken = hostWindow->getToken();
- request.token = embeddedWindowToken;
- changes = focusResolver.setFocusedWindow(request, windows);
- ASSERT_FOCUS_CHANGE(changes, /*from*/ hostWindowToken, /*to*/ embeddedWindowToken);
-
- embeddedWindow->setFocusable(false);
- changes = focusResolver.setInputWindows(request.displayId, windows);
- // The embedded window is no longer focusable, provide focus back to the original focused
- // window.
- ASSERT_FOCUS_CHANGE(changes, /*from*/ embeddedWindowToken, /*to*/ hostWindowToken);
-
- embeddedWindow->setFocusable(true);
- changes = focusResolver.setInputWindows(request.displayId, windows);
- // The embedded window is focusable again, but we it cannot gain focus unless there is another
- // focus request.
- ASSERT_FALSE(changes);
-
- embeddedWindow->setVisible(false);
- changes = focusResolver.setFocusedWindow(request, windows);
- // If the embedded window is not visible/focusable, then we do not grant it focus and the
- // request is dropped.
- ASSERT_FALSE(changes);
-
- embeddedWindow->setVisible(true);
- changes = focusResolver.setInputWindows(request.displayId, windows);
- // If the embedded window becomes visble/focusable, nothing changes since the request has been
- // dropped.
- ASSERT_FALSE(changes);
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
}
+
+TEST(FocusResolverTest, FocusTransferTargetCycle) {
+ sp<IBinder> hostWindowToken = sp<BBinder>::make();
+ std::vector<sp<WindowInfoHandle>> windows;
+
+ sp<FakeWindowHandle> hostWindow =
+ sp<FakeWindowHandle>::make("Host Window", hostWindowToken, /*focusable=*/true,
+ /*visible=*/true);
+ windows.push_back(hostWindow);
+ sp<IBinder> embeddedWindowToken = sp<BBinder>::make();
+ sp<FakeWindowHandle> embeddedWindow =
+ sp<FakeWindowHandle>::make("Embedded Window", embeddedWindowToken, /*focusable=*/true,
+ /*visible=*/true);
+ windows.push_back(embeddedWindow);
+
+ sp<IBinder> embeddedWindowToken2 = sp<BBinder>::make();
+ sp<FakeWindowHandle> embeddedWindow2 =
+ sp<FakeWindowHandle>::make("Embedded Window2", embeddedWindowToken2, /*focusable=*/true,
+ /*visible=*/true);
+ windows.push_back(embeddedWindow2);
+
+ FocusRequest request;
+ request.displayId = 42;
+ request.token = hostWindowToken;
+
+ hostWindow->editInfo()->focusTransferTarget = embeddedWindowToken;
+ embeddedWindow->editInfo()->focusTransferTarget = embeddedWindowToken2;
+ embeddedWindow2->editInfo()->focusTransferTarget = hostWindowToken;
+
+ FocusResolver focusResolver;
+ std::optional<FocusResolver::FocusChanges> changes =
+ focusResolver.setFocusedWindow(request, windows);
+ // Cycle will be detected and stop right before trying to transfer token to host again.
+ ASSERT_FOCUS_CHANGE(changes, /*from*/ nullptr, /*to*/ embeddedWindowToken2);
+}
+
TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
sp<IBinder> windowToken = sp<BBinder>::make();
std::vector<sp<WindowInfoHandle>> windows;
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index 33f404d..c6d541e 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -93,7 +93,7 @@
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(AMOTION_EVENT_TOOL_TYPE_FINGER), WithButtonState(0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
WithPressure(0.0f)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
@@ -111,7 +111,7 @@
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(AMOTION_EVENT_TOOL_TYPE_FINGER), WithButtonState(0),
+ WithToolType(ToolType::FINGER), WithButtonState(0),
WithPressure(0.0f)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X + 10, POINTER_Y + 5));
@@ -133,14 +133,14 @@
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
AMOTION_EVENT_BUTTON_SECONDARY),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
@@ -148,7 +148,7 @@
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY |
AMOTION_EVENT_BUTTON_SECONDARY),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
// Then release the left button
Gesture leftUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -162,7 +162,7 @@
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
// Finally release the right button
Gesture rightUpGesture(kGestureButtonsChange, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
@@ -175,12 +175,12 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_SECONDARY), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, DragWithButton) {
@@ -198,14 +198,14 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
// Move
Gesture moveGesture(kGestureMove, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, -5, 10);
@@ -215,7 +215,7 @@
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithCoords(POINTER_X - 5, POINTER_Y + 10), WithRelativeMotion(-5, 10),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithToolType(ToolType::FINGER),
WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY), WithPressure(1.0f)));
ASSERT_NO_FATAL_FAILURE(mFakePointerController->assertPosition(POINTER_X - 5, POINTER_Y + 10));
@@ -231,12 +231,12 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY), WithButtonState(0),
WithCoords(POINTER_X - 5, POINTER_Y + 10),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, Scroll) {
@@ -252,7 +252,7 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDownTime(downTime),
+ WithToolType(ToolType::FINGER), WithDownTime(downTime),
WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
@@ -260,7 +260,7 @@
WithCoords(POINTER_X, POINTER_Y - 10),
WithGestureScrollDistance(0, 10, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithToolType(ToolType::FINGER),
WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
@@ -271,7 +271,7 @@
WithCoords(POINTER_X, POINTER_Y - 15),
WithGestureScrollDistance(0, 5, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithToolType(ToolType::FINGER),
WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
@@ -283,7 +283,7 @@
WithCoords(POINTER_X, POINTER_Y - 15),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithToolType(ToolType::FINGER),
WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
}
@@ -301,14 +301,14 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithCoords(POINTER_X, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDownTime(downTime)));
+ WithToolType(ToolType::FINGER), WithDownTime(downTime)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture continueGesture(kGestureScroll, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 0, -5);
args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture);
@@ -318,7 +318,7 @@
WithCoords(POINTER_X - 15, POINTER_Y),
WithGestureScrollDistance(0, 5, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture flingGesture(kGestureFling, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, 1, 1,
GESTURES_FLING_START);
@@ -329,7 +329,7 @@
WithCoords(POINTER_X - 15, POINTER_Y),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, Scroll_ClearsClassificationAndOffsetsAfterGesture) {
@@ -393,7 +393,7 @@
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER)));
PointerCoords finger0Start = arg.pointerCoords[0];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -402,7 +402,7 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER)));
PointerCoords finger1Start = arg.pointerCoords[1];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -411,7 +411,7 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
PointerCoords finger2Start = arg.pointerCoords[2];
args.pop_front();
@@ -420,7 +420,7 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0, -0.01, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
@@ -437,7 +437,7 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0, -0.005, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX());
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX());
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX());
@@ -453,19 +453,19 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
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),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) {
@@ -560,7 +560,7 @@
ASSERT_THAT(arg,
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER)));
PointerCoords finger0Start = arg.pointerCoords[0];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -569,7 +569,7 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER)));
PointerCoords finger1Start = arg.pointerCoords[1];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -578,7 +578,7 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
PointerCoords finger2Start = arg.pointerCoords[2];
args.pop_front();
arg = std::get<NotifyMotionArgs>(args.front());
@@ -587,7 +587,7 @@
3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER)));
PointerCoords finger3Start = arg.pointerCoords[3];
args.pop_front();
@@ -596,7 +596,7 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0.01, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 10);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 10);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 10);
@@ -615,7 +615,7 @@
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithGestureOffset(0.005, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER)));
EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() + 15);
EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() + 15);
EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() + 15);
@@ -633,26 +633,26 @@
3 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(4u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(4u), WithToolType(ToolType::FINGER)));
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),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
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),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(2u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, Pinch_Inwards) {
@@ -668,7 +668,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
@@ -676,7 +676,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 0.8, GESTURES_ZOOM_UPDATE);
@@ -688,7 +688,7 @@
WithGesturePinchScaleFactor(0.8f, EPSILON),
WithPointerCoords(0, POINTER_X - 80, POINTER_Y),
WithPointerCoords(1, POINTER_X + 80, POINTER_Y), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
@@ -699,13 +699,13 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, Pinch_Outwards) {
@@ -721,7 +721,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithCoords(POINTER_X - 100, POINTER_Y), WithPointerCount(1u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN |
@@ -729,7 +729,7 @@
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON),
WithPointerCoords(1, POINTER_X + 100, POINTER_Y), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture updateGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME,
/* dz= */ 1.2, GESTURES_ZOOM_UPDATE);
@@ -741,7 +741,7 @@
WithGesturePinchScaleFactor(1.2f, EPSILON),
WithPointerCoords(0, POINTER_X - 120, POINTER_Y),
WithPointerCoords(1, POINTER_X + 120, POINTER_Y), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
Gesture endGesture(kGesturePinch, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dz= */ 1,
GESTURES_ZOOM_END);
@@ -752,13 +752,13 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, Pinch_ClearsClassificationAndScaleFactorAfterGesture) {
@@ -802,18 +802,18 @@
WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
WithButtonState(AMOTION_EVENT_BUTTON_SECONDARY),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
args.pop_front();
ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()),
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0),
WithCoords(POINTER_X, POINTER_Y),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, ResetDuringScroll) {
@@ -830,7 +830,7 @@
WithCoords(POINTER_X, POINTER_Y - 10),
WithGestureScrollDistance(0, 0, EPSILON),
WithMotionClassification(MotionClassification::TWO_FINGER_SWIPE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER),
+ WithToolType(ToolType::FINGER),
WithFlags(AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE)));
}
@@ -849,19 +849,19 @@
2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithGestureOffset(0, 0, EPSILON),
WithMotionClassification(MotionClassification::MULTI_FINGER_SWIPE),
- WithPointerCount(3u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(3u), WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(2u), WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithPointerCount(1u), WithToolType(ToolType::FINGER)));
}
TEST_F(GestureConverterTest, ResetDuringPinch) {
@@ -879,13 +879,13 @@
1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
WithMotionClassification(MotionClassification::PINCH),
WithGesturePinchScaleFactor(1.0f, EPSILON), WithPointerCount(2u),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
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(AMOTION_EVENT_TOOL_TYPE_FINGER)));
+ WithToolType(ToolType::FINGER)));
}
} // namespace android
diff --git a/services/inputflinger/tests/HardwareStateConverter_test.cpp b/services/inputflinger/tests/HardwareStateConverter_test.cpp
index 36b9bab..3e97241 100644
--- a/services/inputflinger/tests/HardwareStateConverter_test.cpp
+++ b/services/inputflinger/tests/HardwareStateConverter_test.cpp
@@ -231,8 +231,7 @@
schs = processSync(conv, time);
ASSERT_TRUE(schs.has_value());
- ASSERT_EQ(1, schs->state.finger_cnt);
- EXPECT_EQ(-1, schs->state.fingers[0].tracking_id);
+ ASSERT_EQ(0, schs->state.finger_cnt);
processAxis(conv, time, EV_ABS, ABS_MT_POSITION_X, 53);
processAxis(conv, time, EV_ABS, ABS_MT_POSITION_Y, 97);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index e299643..fb808eb 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -637,14 +637,10 @@
}
}
- void setFocusedWindow(const sp<WindowInfoHandle>& window,
- const sp<WindowInfoHandle>& focusedWindow = nullptr) {
+ void setFocusedWindow(const sp<WindowInfoHandle>& window) {
FocusRequest request;
request.token = window->getToken();
request.windowName = window->getName();
- if (focusedWindow) {
- request.focusedToken = focusedWindow->getToken();
- }
request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
request.displayId = window->getInfo()->displayId;
mDispatcher->setFocusedWindow(request);
@@ -1464,7 +1460,7 @@
class PointerBuilder {
public:
- PointerBuilder(int32_t id, int32_t toolType) {
+ PointerBuilder(int32_t id, ToolType toolType) {
mProperties.clear();
mProperties.id = id;
mProperties.toolType = toolType;
@@ -1722,7 +1718,7 @@
.eventTime(eventTime)
.rawXCursorPosition(cursorPosition.x)
.rawYCursorPosition(cursorPosition.y)
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER)
.x(position.x)
.y(position.y))
.build();
@@ -1767,7 +1763,7 @@
for (size_t i = 0; i < pointerCount; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = i;
- pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[i].toolType = ToolType::FINGER;
pointerCoords[i].clear();
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
@@ -1961,21 +1957,21 @@
// First touch pointer down on right window
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
// Second touch pointer down
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(110).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(110).y(100))
.build()));
// First touch pointer lifts. The second one remains down
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(110).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(110).y(100))
.build()));
window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
window->consumeMotionEvent(WithMotionAction(POINTER_1_DOWN));
@@ -2069,8 +2065,8 @@
const MotionEvent secondFingerDownEvent =
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(150))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -2085,8 +2081,8 @@
MotionEventBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(150))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT,
@@ -2102,7 +2098,7 @@
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
.pointer(PointerBuilder(/* id */ 1,
- AMOTION_EVENT_TOOL_TYPE_FINGER)
+ ToolType::FINGER)
.x(100)
.y(100))
.build(),
@@ -2154,8 +2150,8 @@
const MotionEvent secondFingerDownEvent =
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(300).y(100))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -2179,8 +2175,8 @@
const MotionEvent secondFingerMoveEvent =
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(310).y(110))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(310).y(110))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerMoveEvent, INJECT_EVENT_TIMEOUT,
@@ -2274,15 +2270,15 @@
args = MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
.policyFlags(DEFAULT_POLICY_FLAGS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
.policyFlags(DEFAULT_POLICY_FLAGS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(120).y(120))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
spyWindow->consumeMotionEvent(WithMotionAction(POINTER_1_DOWN));
@@ -2294,8 +2290,8 @@
args = MotionArgsBuilder(AMOTION_EVENT_ACTION_CANCEL, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
.policyFlags(0)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(120).y(120))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL));
@@ -2313,7 +2309,7 @@
args = MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
.policyFlags(DEFAULT_POLICY_FLAGS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_DOWN));
@@ -2358,7 +2354,7 @@
.deviceId(mouseDeviceId)
.downTime(baseTime + 10)
.eventTime(baseTime + 20)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(300)
.y(100))
.build()));
@@ -2372,7 +2368,7 @@
.deviceId(mouseDeviceId)
.downTime(baseTime + 10)
.eventTime(baseTime + 30)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(110)
.y(100))
.build()));
@@ -2386,7 +2382,7 @@
.deviceId(touchDeviceId)
.downTime(baseTime + 40)
.eventTime(baseTime + 40)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2401,7 +2397,7 @@
.deviceId(touchDeviceId)
.downTime(baseTime + 40)
.eventTime(baseTime + 50)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2415,7 +2411,7 @@
.deviceId(touchDeviceId)
.downTime(baseTime + 60)
.eventTime(baseTime + 60)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(300)
.y(100))
.build()));
@@ -2429,7 +2425,7 @@
.deviceId(touchDeviceId)
.downTime(baseTime + 60)
.eventTime(baseTime + 70)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(300)
.y(100))
.build()));
@@ -2467,7 +2463,7 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
leftWindow->consumeMotionEvent(
AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(mouseDeviceId)));
@@ -2477,7 +2473,7 @@
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
leftWindow->consumeMotionEvent(
@@ -2490,7 +2486,7 @@
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
leftWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -2498,7 +2494,7 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
.build()));
leftWindow->consumeMotionEvent(WithMotionAction(ACTION_CANCEL));
@@ -2508,8 +2504,8 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(100).y(100))
.build()));
leftWindow->consumeMotionEvent(
AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(touchDeviceId)));
@@ -2547,21 +2543,21 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
.build()));
// Second touch pointer down
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(350).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(350).y(100))
.build()));
// First touch pointer lifts. The second one remains down
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(350).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(350).y(100))
.build()));
window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
window->consumeMotionEvent(WithMotionAction(POINTER_1_DOWN));
@@ -2572,7 +2568,7 @@
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(320).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(320).y(100))
.build()));
window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDeviceId(touchDeviceId),
@@ -2584,7 +2580,7 @@
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(320).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(320).y(100))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -2592,8 +2588,8 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_0_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(350).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(350).y(100))
.build()));
// The pointer_down event should be ignored
window->assertNoEvents();
@@ -2619,7 +2615,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.deviceId(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(50)
.y(50))
.build()));
@@ -2631,7 +2627,7 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(300).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(300).y(100))
.build()));
window->consumeMotionEvent(
@@ -2673,7 +2669,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(50)
.y(50))
.build()));
@@ -2685,7 +2681,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2695,7 +2691,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_UP,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2709,7 +2705,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(300)
.y(100))
.build()));
@@ -2720,10 +2716,10 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(300)
.y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(1, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2756,7 +2752,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_STYLUS)
.deviceId(stylusDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS)
.x(50)
.y(50))
.build()));
@@ -2768,7 +2764,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2781,7 +2777,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_STYLUS)
.deviceId(stylusDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS)
.x(50)
.y(50))
.build()));
@@ -2794,7 +2790,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_UP,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(100)
.y(100))
.build()));
@@ -2806,7 +2802,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_STYLUS)
.deviceId(stylusDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS)
.x(50)
.y(50))
.build()));
@@ -2839,40 +2835,40 @@
// Start hovering with stylus
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
// Stop hovering
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
// Stylus touches down
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
// Stylus goes up
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_UP));
// Again hover
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
// Stop hovering
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_HOVER_EXIT, AINPUT_SOURCE_STYLUS)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
@@ -2908,7 +2904,7 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
spyWindow->consumeMotionEvent(
AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(mouseDeviceId)));
@@ -2919,7 +2915,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
@@ -2929,7 +2925,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(55).y(55))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(55).y(55))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
@@ -2941,7 +2937,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(60).y(60))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
@@ -2950,7 +2946,7 @@
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
spyWindow->consumeMotionEvent(
@@ -2964,7 +2960,7 @@
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(100))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -2974,7 +2970,7 @@
args = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(110).y(110))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(110).y(110))
.build()));
spyWindow->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
@@ -2983,7 +2979,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(65).y(65))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(65).y(65))
.build()));
// No more events
@@ -3129,9 +3125,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(900)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(900).y(400))
.build()));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
@@ -3140,9 +3134,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT));
windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
@@ -3152,9 +3144,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
windowLeft->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
windowLeft->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
@@ -3165,9 +3155,7 @@
AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -3177,9 +3165,7 @@
AINPUT_SOURCE_MOUSE)
.buttonState(0)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
windowLeft->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE));
@@ -3187,9 +3173,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
.buttonState(0)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
@@ -3198,9 +3182,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(900)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(900).y(400))
.build()));
windowRight->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
@@ -3230,14 +3212,14 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(100))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(120).y(120))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
.build()));
window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
window->consumeMotionEvent(WithMotionAction(POINTER_1_DOWN));
@@ -3247,7 +3229,7 @@
args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(300).y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(AllOf(WithMotionAction(ACTION_CANCEL), WithDeviceId(touchDeviceId),
WithPointerCount(2u)));
@@ -3258,7 +3240,7 @@
.deviceId(mouseDeviceId)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(300).y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -3267,8 +3249,8 @@
mDispatcher->notifyMotion(&(
args = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(101).y(101))
- .pointer(PointerBuilder(1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(121).y(121))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(101).y(101))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(121).y(121))
.build()));
window->assertNoEvents();
}
@@ -3293,7 +3275,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(100)
.y(100))
.build()));
@@ -3327,7 +3309,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(100)
.y(100))
.build()));
@@ -3337,7 +3319,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(110)
.y(110))
.build()));
@@ -3356,7 +3338,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(SECOND_DEVICE_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(200)
.y(200))
.build()));
@@ -3380,7 +3362,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_UP,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(SECOND_DEVICE_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(200)
.y(200))
.build()));
@@ -3397,7 +3379,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(SECOND_DEVICE_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(250)
.y(250))
.build()));
@@ -3412,7 +3394,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_UP,
AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(SECOND_DEVICE_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(0, ToolType::FINGER)
.x(250)
.y(250))
.build()));
@@ -3441,9 +3423,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER));
// Inject a series of mouse events for a mouse click
@@ -3451,9 +3431,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
@@ -3464,9 +3442,7 @@
AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS));
@@ -3476,9 +3452,7 @@
AINPUT_SOURCE_MOUSE)
.buttonState(0)
.actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionEvent(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE));
@@ -3486,9 +3460,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
.buttonState(0)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
@@ -3496,9 +3468,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
- .x(300)
- .y(400))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(300).y(400))
.build()));
window->assertNoEvents();
}
@@ -3521,7 +3491,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(300)
.y(400))
.build()));
@@ -3551,7 +3521,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE)
.deviceId(mouseDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE).x(10).y(10))
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(10).y(10))
.build()));
window->consumeMotionEvent(
AllOf(WithMotionAction(ACTION_HOVER_ENTER), WithDeviceId(mouseDeviceId)));
@@ -3560,7 +3530,7 @@
mDispatcher->notifyMotion(
&(args = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.deviceId(touchDeviceId)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
.build()));
window->consumeMotionEvent(
@@ -3633,7 +3603,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
.displayId(ADISPLAY_ID_DEFAULT)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(300)
.y(600))
.build()));
@@ -3654,7 +3624,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
.displayId(ADISPLAY_ID_DEFAULT)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE)
.x(400)
.y(700))
.build()));
@@ -3911,8 +3881,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(-30).y(-50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(-30).y(-50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -4033,7 +4003,7 @@
MotionEvent event = MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER)
.x(untransformedPoint.x)
.y(untransformedPoint.y))
.build();
@@ -5255,7 +5225,8 @@
setFocusedWindow(windowTop);
windowTop->consumeFocusEvent(true);
- setFocusedWindow(windowSecond, windowTop);
+ windowTop->editInfo()->focusTransferTarget = windowSecond->getToken();
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
windowSecond->consumeFocusEvent(true);
windowTop->consumeFocusEvent(false);
@@ -5266,7 +5237,7 @@
windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
}
-TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestFocusTokenNotFocused) {
+TEST_F(InputDispatcherTest, SetFocusedWindow_TransferFocusTokenNotFocusable) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> windowTop =
sp<FakeWindowHandle>::make(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
@@ -5275,15 +5246,17 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
windowTop->setFocusable(true);
- windowSecond->setFocusable(true);
+ windowSecond->setFocusable(false);
+ windowTop->editInfo()->focusTransferTarget = windowSecond->getToken();
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
- setFocusedWindow(windowSecond, windowTop);
+ setFocusedWindow(windowTop);
+ windowTop->consumeFocusEvent(true);
- ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
// Event should be dropped.
- windowTop->assertNoEvents();
+ windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
windowSecond->assertNoEvents();
}
@@ -6076,7 +6049,7 @@
const MotionEvent event =
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(20).y(20))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(20).y(20))
.addFlag(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE)
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectMotionEvent(mDispatcher, event))
@@ -7937,7 +7910,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_STYLUS)
.buttonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
+ .pointer(PointerBuilder(0, ToolType::STYLUS)
.x(50)
.y(50))
.build()));
@@ -7949,7 +7922,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.pointer(PointerBuilder(MOUSE_POINTER_ID,
- AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ ToolType::MOUSE)
.x(50)
.y(50))
.build()));
@@ -8038,8 +8011,8 @@
const MotionEvent secondFingerDownEvent =
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(60).y(60))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(60).y(60))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -8093,9 +8066,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_STYLUS)
.buttonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
- .x(50)
- .y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(50).y(50))
.build()))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
@@ -8107,9 +8078,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_STYLUS)
.buttonState(0)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
- .x(150)
- .y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50))
.build()))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
@@ -8122,9 +8091,7 @@
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_STYLUS)
.buttonState(0)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
- .x(150)
- .y(50))
+ .pointer(PointerBuilder(0, ToolType::STYLUS).x(150).y(50))
.build()))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
@@ -8182,8 +8149,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(75).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(75).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -8209,8 +8176,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -8225,8 +8192,8 @@
const MotionEvent secondFingerMoveEvent =
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerMoveEvent, INJECT_EVENT_TIMEOUT,
@@ -8239,8 +8206,8 @@
const MotionEvent secondFingerUpEvent =
MotionEventBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT,
@@ -8265,9 +8232,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
AINPUT_SOURCE_TOUCHSCREEN)
.displayId(SECOND_DISPLAY_ID)
- .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER)
- .x(100)
- .y(100))
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(100))
.build()));
windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
SECOND_DISPLAY_ID, /*expectedFlag=*/0);
@@ -8311,7 +8276,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.pointer(PointerBuilder(MOUSE_POINTER_ID,
- AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ ToolType::MOUSE)
.x(50)
.y(50))
.build()))
@@ -8326,7 +8291,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
.pointer(PointerBuilder(MOUSE_POINTER_ID,
- AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ ToolType::MOUSE)
.x(150)
.y(50))
.build()))
@@ -8341,7 +8306,7 @@
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
.buttonState(0)
.pointer(PointerBuilder(MOUSE_POINTER_ID,
- AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ ToolType::MOUSE)
.x(150)
.y(50))
.build()))
@@ -8813,8 +8778,8 @@
const MotionEvent secondFingerDownEvent =
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -8845,8 +8810,8 @@
const MotionEvent secondFingerDownEvent =
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -8884,8 +8849,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(200))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9007,8 +8972,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(200))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9022,9 +8987,9 @@
MotionEventBuilder(POINTER_2_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(100).y(200))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
- .pointer(PointerBuilder(/*id=*/2, AMOTION_EVENT_TOOL_TYPE_FINGER).x(-5).y(-5))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(100).y(200))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/2, ToolType::FINGER).x(-5).y(-5))
.build();
ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9058,8 +9023,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(150))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(10))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9073,9 +9038,9 @@
MotionEventBuilder(POINTER_2_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(150))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
- .pointer(PointerBuilder(/*id=*/2, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(10))
+ .pointer(PointerBuilder(/*id=*/2, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, thirdFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9119,8 +9084,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(10).y(10))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9166,8 +9131,8 @@
MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.displayId(ADISPLAY_ID_DEFAULT)
.eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
- .pointer(PointerBuilder(/*id=*/0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10))
- .pointer(PointerBuilder(/*id=*/1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(10).y(10))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(150).y(150))
.build();
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
@@ -9221,7 +9186,7 @@
NotifyMotionArgs motionArgs =
generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
ADISPLAY_ID_DEFAULT, {PointF{30, 40}});
- motionArgs.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ motionArgs.pointerProperties[0].toolType = ToolType::STYLUS;
mDispatcher->notifyMotion(&motionArgs);
}
};
diff --git a/services/inputflinger/tests/InputProcessorConverter_test.cpp b/services/inputflinger/tests/InputProcessorConverter_test.cpp
index 161a24f..4b42f4b 100644
--- a/services/inputflinger/tests/InputProcessorConverter_test.cpp
+++ b/services/inputflinger/tests/InputProcessorConverter_test.cpp
@@ -30,7 +30,7 @@
// Create a basic motion event for testing
PointerProperties properties;
properties.id = 0;
- properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ properties.toolType = ToolType::FINGER;
PointerCoords coords;
coords.clear();
diff --git a/services/inputflinger/tests/InputProcessor_test.cpp b/services/inputflinger/tests/InputProcessor_test.cpp
index b6deed8..0ffdef9 100644
--- a/services/inputflinger/tests/InputProcessor_test.cpp
+++ b/services/inputflinger/tests/InputProcessor_test.cpp
@@ -37,7 +37,7 @@
// Create a basic motion event for testing
PointerProperties properties;
properties.id = 0;
- properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ properties.toolType = ToolType::FINGER;
PointerCoords coords;
coords.clear();
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 853c5b0..2223b35 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -263,8 +263,8 @@
}
}
- std::list<NotifyArgs> configure(nsecs_t, const InputReaderConfiguration* config,
- uint32_t changes) override {
+ std::list<NotifyArgs> reconfigure(nsecs_t, const InputReaderConfiguration* config,
+ uint32_t changes) override {
std::scoped_lock<std::mutex> lock(mLock);
mConfigureWasCalled = true;
@@ -644,6 +644,30 @@
ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
}
+TEST_F(InputReaderTest, InputDeviceRecreatedOnSysfsNodeChanged) {
+ ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
+ mFakeEventHub->setSysfsRootPath(1, "xyz");
+
+ // Should also have received a notification describing the new input device.
+ ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
+ InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
+ ASSERT_EQ(0U, inputDevice.getLights().size());
+
+ RawLightInfo infoMonolight = {.id = 123,
+ .name = "mono_keyboard_backlight",
+ .maxBrightness = 255,
+ .flags = InputLightClass::BRIGHTNESS,
+ .path = ""};
+ mFakeEventHub->addRawLightInfo(/*rawId=*/123, std::move(infoMonolight));
+ mReader->sysfsNodeChanged("xyz");
+ mReader->loopOnce();
+
+ // Should also have received a notification describing the new recreated input device.
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
+ inputDevice = mFakePolicy->getInputDevices()[0];
+ ASSERT_EQ(1U, inputDevice.getLights().size());
+}
+
TEST_F(InputReaderTest, GetMergedInputDevices) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
@@ -1732,7 +1756,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
@@ -1751,7 +1775,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
+ WithToolType(ToolType::FINGER))));
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
@@ -1768,7 +1792,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
}
@@ -1864,12 +1888,12 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
WithDeviceId(touchscreenId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
WithDeviceId(touchscreenId))));
@@ -1877,11 +1901,11 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
// Release the stylus button.
@@ -1896,7 +1920,7 @@
const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
const auto stylusId = TestFixture::mStylusInfo.getId();
auto toolTypeDevice =
- AllOf(WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithDeviceId(touchscreenId));
+ AllOf(WithToolType(ToolType::STYLUS), WithDeviceId(touchscreenId));
// Press the stylus button.
TestFixture::mStylus->pressKey(BTN_STYLUS);
@@ -1980,7 +2004,7 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
// Press and release a stylus button. Each change in button state also generates a MOVE event.
@@ -1990,12 +2014,12 @@
WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
WithDeviceId(touchscreenId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
WithDeviceId(touchscreenId))));
@@ -2005,11 +2029,11 @@
WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
// Finish the stylus gesture.
@@ -2017,7 +2041,7 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
}
@@ -2039,7 +2063,7 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
// Press and release a stylus button. Each change only generates a MOVE motion event.
@@ -2050,7 +2074,7 @@
WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
TestFixture::mStylus->releaseKey(BTN_STYLUS);
@@ -2059,7 +2083,7 @@
WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
// Finish the stylus gesture.
@@ -2067,7 +2091,7 @@
TestFixture::mTouchscreen->sendSync();
ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId))));
}
@@ -2108,7 +2132,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId), WithPressure(100.f / RAW_PRESSURE_MAX))));
// Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
@@ -2116,7 +2140,7 @@
stylus->setPressure(200);
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
// The external stylus did not generate any events.
@@ -2162,7 +2186,7 @@
// it shows up as a finger pointer.
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDeviceId(touchscreenId),
+ WithToolType(ToolType::FINGER), WithDeviceId(touchscreenId),
WithPressure(1.f))));
// Change the pressure on the external stylus. Since the pressure was not present at the start
@@ -2175,7 +2199,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
+ WithToolType(ToolType::FINGER))));
// Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
mDevice->sendTrackingId(FIRST_TRACKING_ID);
@@ -2184,7 +2208,7 @@
mDevice->sendSync();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
+ WithToolType(ToolType::STYLUS), WithButtonState(0),
WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
// The external stylus did not generate any events.
@@ -2220,7 +2244,7 @@
mTestListener
->assertNotifyMotionWasCalled(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithToolType(
- AMOTION_EVENT_TOOL_TYPE_FINGER),
+ ToolType::FINGER),
WithButtonState(0),
WithDeviceId(touchscreenId),
WithPressure(1.f)),
@@ -3875,7 +3899,7 @@
ASSERT_EQ(0, args.edgeFlags);
ASSERT_EQ(uint32_t(1), args.pointerCount);
ASSERT_EQ(0, args.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
@@ -3893,7 +3917,7 @@
ASSERT_EQ(0, args.edgeFlags);
ASSERT_EQ(uint32_t(1), args.pointerCount);
ASSERT_EQ(0, args.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
@@ -3914,7 +3938,7 @@
ASSERT_EQ(0, args.edgeFlags);
ASSERT_EQ(uint32_t(1), args.pointerCount);
ASSERT_EQ(0, args.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
@@ -3932,7 +3956,7 @@
ASSERT_EQ(0, args.edgeFlags);
ASSERT_EQ(uint32_t(1), args.pointerCount);
ASSERT_EQ(0, args.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
@@ -5195,7 +5219,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5219,7 +5243,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5242,7 +5266,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5292,7 +5316,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5315,7 +5339,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5360,7 +5384,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
1, 0, 0, 0, 0, 0, 0, 0));
@@ -5387,7 +5411,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
1, 0, 0, 0, 0, 0, 0, 0));
@@ -5412,7 +5436,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
1, 0, 0, 0, 0, 0, 0, 0));
@@ -5455,7 +5479,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5480,7 +5504,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -5503,7 +5527,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -6151,14 +6175,14 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// eraser
processKey(mapper, BTN_TOOL_RUBBER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
// stylus
processKey(mapper, BTN_TOOL_RUBBER, 0);
@@ -6166,7 +6190,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// brush
processKey(mapper, BTN_TOOL_PEN, 0);
@@ -6174,7 +6198,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// pencil
processKey(mapper, BTN_TOOL_BRUSH, 0);
@@ -6182,7 +6206,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// air-brush
processKey(mapper, BTN_TOOL_PENCIL, 0);
@@ -6190,7 +6214,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// mouse
processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
@@ -6198,7 +6222,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// lens
processKey(mapper, BTN_TOOL_MOUSE, 0);
@@ -6206,7 +6230,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// double-tap
processKey(mapper, BTN_TOOL_LENS, 0);
@@ -6214,7 +6238,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// triple-tap
processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
@@ -6222,7 +6246,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// quad-tap
processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
@@ -6230,7 +6254,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// finger
processKey(mapper, BTN_TOOL_QUADTAP, 0);
@@ -6238,28 +6262,28 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// stylus trumps finger
processKey(mapper, BTN_TOOL_PEN, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// eraser trumps stylus
processKey(mapper, BTN_TOOL_RUBBER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
// mouse trumps eraser
processKey(mapper, BTN_TOOL_MOUSE, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// back to default tool type
processKey(mapper, BTN_TOOL_MOUSE, 0);
@@ -6269,7 +6293,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
}
TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
@@ -6659,7 +6683,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
ASSERT_TRUE(fakePointerController->isPointerShown());
ASSERT_NO_FATAL_FAILURE(
@@ -6683,7 +6707,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
ASSERT_FALSE(fakePointerController->isPointerShown());
}
@@ -7125,7 +7149,7 @@
mStylusState.when = ARBITRARY_TIME;
mStylusState.pressure = 0.f;
- mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mStylusState.toolType = ToolType::STYLUS;
mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
configureDevice(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
processExternalStylusState(mapper);
@@ -7149,7 +7173,7 @@
void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
auto toolTypeSource =
- AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
+ AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
// The first pointer is withheld.
processDown(mapper, 100, 200);
@@ -7184,7 +7208,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
mStylusState.pressure = 0.f;
processExternalStylusState(mapper);
@@ -7194,7 +7218,7 @@
void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
auto toolTypeSource =
- AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER));
+ AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::FINGER));
// The first pointer is withheld when an external stylus is connected,
// and a timeout is requested.
@@ -7252,7 +7276,7 @@
TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
auto toolTypeSource =
- AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
+ AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
// The external stylus reports pressure first. It is ignored for now.
mStylusState.pressure = 1.f;
@@ -7295,7 +7319,7 @@
TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
auto toolTypeSource =
- AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
+ AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
mStylusState.pressure = 0.8f;
processExternalStylusState(mapper);
@@ -7357,7 +7381,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
@@ -7368,17 +7392,17 @@
auto source = WithSource(EXPECTED_SOURCE);
mStylusState.pressure = 1.f;
- mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_ERASER;
+ mStylusState.toolType = ToolType::ERASER;
processExternalStylusState(mapper);
processDown(mapper, 100, 200);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_ERASER))));
+ WithToolType(ToolType::ERASER))));
ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
// The external stylus reports a tool change. We wait for some time for a touch event.
- mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mStylusState.toolType = ToolType::STYLUS;
processExternalStylusState(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
ASSERT_NO_FATAL_FAILURE(
@@ -7389,11 +7413,11 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
// There is another tool type change.
- mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ mStylusState.toolType = ToolType::FINGER;
processExternalStylusState(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
ASSERT_NO_FATAL_FAILURE(
@@ -7404,13 +7428,13 @@
handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
+ WithToolType(ToolType::FINGER))));
processUp(mapper);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
+ WithToolType(ToolType::FINGER))));
ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
@@ -7419,7 +7443,7 @@
TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
auto toolTypeSource =
- AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
+ AllOf(WithSource(EXPECTED_SOURCE), WithToolType(ToolType::STYLUS));
ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
@@ -7636,7 +7660,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -7655,9 +7679,9 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7686,9 +7710,9 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7715,9 +7739,9 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7738,7 +7762,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -7763,7 +7787,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -7790,9 +7814,9 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7819,9 +7843,9 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7842,7 +7866,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -7865,7 +7889,7 @@
ASSERT_EQ(0, motionArgs.edgeFlags);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
@@ -7953,7 +7977,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -7961,9 +7985,9 @@
ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -7983,9 +8007,9 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8002,9 +8026,9 @@
ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8014,7 +8038,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8029,7 +8053,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8047,9 +8071,9 @@
ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8066,9 +8090,9 @@
ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8078,7 +8102,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8090,7 +8114,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8123,7 +8147,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8131,9 +8155,9 @@
ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8151,9 +8175,9 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8171,9 +8195,9 @@
ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8183,7 +8207,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8196,7 +8220,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8212,9 +8236,9 @@
ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8232,9 +8256,9 @@
ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
@@ -8244,7 +8268,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8256,7 +8280,7 @@
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
@@ -8783,14 +8807,14 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// eraser
processKey(mapper, BTN_TOOL_RUBBER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
// stylus
processKey(mapper, BTN_TOOL_RUBBER, 0);
@@ -8798,7 +8822,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// brush
processKey(mapper, BTN_TOOL_PEN, 0);
@@ -8806,7 +8830,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// pencil
processKey(mapper, BTN_TOOL_BRUSH, 0);
@@ -8814,7 +8838,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// air-brush
processKey(mapper, BTN_TOOL_PENCIL, 0);
@@ -8822,7 +8846,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// mouse
processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
@@ -8830,7 +8854,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// lens
processKey(mapper, BTN_TOOL_MOUSE, 0);
@@ -8838,7 +8862,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// double-tap
processKey(mapper, BTN_TOOL_LENS, 0);
@@ -8846,7 +8870,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// triple-tap
processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
@@ -8854,7 +8878,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// quad-tap
processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
@@ -8862,7 +8886,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// finger
processKey(mapper, BTN_TOOL_QUADTAP, 0);
@@ -8870,42 +8894,42 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// stylus trumps finger
processKey(mapper, BTN_TOOL_PEN, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// eraser trumps stylus
processKey(mapper, BTN_TOOL_RUBBER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
// mouse trumps eraser
processKey(mapper, BTN_TOOL_MOUSE, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
// MT tool type trumps BTN tool types: MT_TOOL_FINGER
processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// MT tool type trumps BTN tool types: MT_TOOL_PEN
processToolType(mapper, MT_TOOL_PEN);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
// back to default tool type
processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
@@ -8916,7 +8940,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
}
TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
@@ -9531,7 +9555,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// finger move
processId(mapper, 1);
@@ -9539,14 +9563,14 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// finger up.
processId(mapper, -1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// new finger down
processId(mapper, 1);
@@ -9554,7 +9578,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
}
/**
@@ -9576,7 +9600,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// Tool changed to MT_TOOL_PALM expect sending the cancel event.
processToolType(mapper, MT_TOOL_PALM);
@@ -9602,7 +9626,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
}
/**
@@ -9624,7 +9648,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// Second finger down.
processSlot(mapper, SECOND_SLOT);
@@ -9633,7 +9657,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
// If the tool type of the first finger changes to MT_TOOL_PALM,
// we expect to receive ACTION_POINTER_UP with cancel flag.
@@ -9699,7 +9723,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// Second finger down.
processSlot(mapper, SECOND_SLOT);
@@ -9708,7 +9732,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// If the tool type of the first finger changes to MT_TOOL_PALM,
// we expect to receive ACTION_POINTER_UP with cancel flag.
@@ -9743,7 +9767,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
// third finger move
@@ -9797,7 +9821,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// Second finger down.
processSlot(mapper, SECOND_SLOT);
@@ -9806,7 +9830,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
// If the tool type of the second finger changes to MT_TOOL_PALM,
// we expect to receive ACTION_POINTER_UP with cancel flag.
@@ -10003,7 +10027,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
// Now that we know the device supports styluses, ensure that the device is re-configured with
// the stylus source.
@@ -10025,7 +10049,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
}
TEST_F(MultiTouchInputMapperTest, Process_WhenConfigEnabled_ShouldShowDirectStylusPointer) {
@@ -10048,7 +10072,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
ASSERT_TRUE(fakePointerController->isPointerShown());
ASSERT_NO_FATAL_FAILURE(
@@ -10075,7 +10099,7 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
+ WithToolType(ToolType::STYLUS),
WithPointerCoords(0, toDisplayX(100), toDisplayY(200)))));
ASSERT_FALSE(fakePointerController->isPointerShown());
}
@@ -10468,7 +10492,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
ASSERT_NO_FATAL_FAILURE(
assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
@@ -10490,7 +10514,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
movingDistance * mPointerMovementScale, 1, 0, 0, 0,
@@ -10528,7 +10552,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
ASSERT_NO_FATAL_FAILURE(
assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
@@ -10550,7 +10574,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
// New coordinate is the scaled relative coordinate from the initial coordinate.
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
@@ -10584,7 +10608,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
// One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
ASSERT_NO_FATAL_FAILURE(
@@ -10610,15 +10634,15 @@
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(1U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
ASSERT_EQ(2U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
// Two pointers' scaled relative coordinates from their initial centroid.
// Initial y coordinates are 0 as y1 and y2 have the same value.
@@ -10648,7 +10672,7 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(2U, motionArgs.pointerCount);
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
- ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
@@ -10718,12 +10742,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
// TODO(b/257078296): Pointer mode generates extra event.
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
// Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
@@ -10735,12 +10759,12 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
// TODO(b/257078296): Pointer mode generates extra event.
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
- WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
+ WithToolType(ToolType::STYLUS))));
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
diff --git a/services/inputflinger/tests/NotifyArgs_test.cpp b/services/inputflinger/tests/NotifyArgs_test.cpp
index 6715585..1536756 100644
--- a/services/inputflinger/tests/NotifyArgs_test.cpp
+++ b/services/inputflinger/tests/NotifyArgs_test.cpp
@@ -54,7 +54,7 @@
for (size_t i = 0; i < pointerCount; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = i;
- pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[i].toolType = ToolType::FINGER;
pointerCoords[i].clear();
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, x++);
diff --git a/services/inputflinger/tests/PreferStylusOverTouch_test.cpp b/services/inputflinger/tests/PreferStylusOverTouch_test.cpp
index 9014dfb..9818176 100644
--- a/services/inputflinger/tests/PreferStylusOverTouch_test.cpp
+++ b/services/inputflinger/tests/PreferStylusOverTouch_test.cpp
@@ -45,8 +45,8 @@
PointerCoords pointerCoords[pointerCount];
const int32_t deviceId = isFromSource(source, TOUCHSCREEN) ? TOUCH_DEVICE_ID : STYLUS_DEVICE_ID;
- const int32_t toolType = isFromSource(source, TOUCHSCREEN) ? AMOTION_EVENT_TOOL_TYPE_FINGER
- : AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ const ToolType toolType =
+ isFromSource(source, TOUCHSCREEN) ? ToolType::FINGER : ToolType::STYLUS;
for (size_t i = 0; i < pointerCount; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = i;
@@ -278,20 +278,20 @@
// Event from a stylus device, but with finger tool type
args = generateMotionArgs(/*downTime=*/1, /*eventTime=*/1, DOWN, {{1, 2}}, STYLUS);
// Keep source stylus, but make the tool type touch
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ args.pointerProperties[0].toolType = ToolType::FINGER;
assertNotBlocked(args);
// Second pointer (stylus pointer) goes down, from the same device
args = generateMotionArgs(/*downTime=*/1, /*eventTime=*/2, POINTER_1_DOWN, {{1, 2}, {10, 20}},
STYLUS);
// Keep source stylus, but make the tool type touch
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[0].toolType = ToolType::STYLUS;
assertNotBlocked(args);
// Second pointer (stylus pointer) goes down, from the same device
args = generateMotionArgs(/*downTime=*/1, /*eventTime=*/3, MOVE, {{2, 3}, {11, 21}}, STYLUS);
// Keep source stylus, but make the tool type touch
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ args.pointerProperties[0].toolType = ToolType::FINGER;
assertNotBlocked(args);
}
@@ -418,14 +418,14 @@
// Introduce a stylus pointer into the device 1 stream. It should be ignored.
args = generateMotionArgs(/*downTime=*/1, /*eventTime=*/3, POINTER_1_DOWN, {{1, 2}, {3, 4}},
TOUCHSCREEN);
- args.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[1].toolType = ToolType::STYLUS;
args.source = STYLUS;
assertDropped(args);
// Lift up touch from the mixed touch/stylus device
args = generateMotionArgs(/*downTime=*/1, /*eventTime=*/4, CANCEL, {{1, 2}, {3, 4}},
TOUCHSCREEN);
- args.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[1].toolType = ToolType::STYLUS;
args.source = STYLUS;
assertDropped(args);
diff --git a/services/inputflinger/tests/TestInputListenerMatchers.h b/services/inputflinger/tests/TestInputListenerMatchers.h
index 09f7ae8..338b747 100644
--- a/services/inputflinger/tests/TestInputListenerMatchers.h
+++ b/services/inputflinger/tests/TestInputListenerMatchers.h
@@ -138,8 +138,8 @@
MATCHER_P(WithToolType, toolType, "InputEvent with specified tool type") {
const auto argToolType = arg.pointerProperties[0].toolType;
- *result_listener << "expected tool type " << motionToolTypeToString(toolType) << ", but got "
- << motionToolTypeToString(argToolType);
+ *result_listener << "expected tool type " << ftl::enum_string(toolType) << ", but got "
+ << ftl::enum_string(argToolType);
return argToolType == toolType;
}
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 3f749b1..2a9ace0 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -79,7 +79,7 @@
for (size_t i = 0; i < pointerCount; i++) {
pointerProperties[i].clear();
pointerProperties[i].id = i;
- pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ pointerProperties[i].toolType = ToolType::FINGER;
pointerCoords[i].clear();
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
@@ -507,7 +507,7 @@
TEST_F(UnwantedInteractionBlockerTest, NoCrashWhenStylusSourceWithFingerToolIsReceived) {
mBlocker->notifyInputDevicesChanged({generateTestDeviceInfo()});
NotifyMotionArgs args = generateMotionArgs(/*downTime=*/0, /*eventTime=*/1, DOWN, {{1, 2, 3}});
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ args.pointerProperties[0].toolType = ToolType::FINGER;
args.source = AINPUT_SOURCE_STYLUS;
mBlocker->notifyMotion(&args);
}
@@ -548,15 +548,15 @@
// Now touch down stylus
args = generateMotionArgs(/*downTime=*/3, /*eventTime=*/3, DOWN, {{10, 20, 30}});
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[0].toolType = ToolType::STYLUS;
args.source |= AINPUT_SOURCE_STYLUS;
mBlocker->notifyMotion(&args);
args = generateMotionArgs(/*downTime=*/3, /*eventTime=*/4, MOVE, {{40, 50, 60}});
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[0].toolType = ToolType::STYLUS;
args.source |= AINPUT_SOURCE_STYLUS;
mBlocker->notifyMotion(&args);
args = generateMotionArgs(/*downTime=*/3, /*eventTime=*/5, UP, {{40, 50, 60}});
- args.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args.pointerProperties[0].toolType = ToolType::STYLUS;
args.source |= AINPUT_SOURCE_STYLUS;
mBlocker->notifyMotion(&args);
}
@@ -617,14 +617,14 @@
info.addSource(AINPUT_SOURCE_STYLUS);
mBlocker->notifyInputDevicesChanged({info});
NotifyMotionArgs args1 = generateMotionArgs(/*downTime=*/0, /*eventTime=*/0, DOWN, {{1, 2, 3}});
- args1.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args1.pointerProperties[0].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args1);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(DOWN));
// Move the stylus, setting large TOUCH_MAJOR/TOUCH_MINOR dimensions
NotifyMotionArgs args2 =
generateMotionArgs(/*downTime=*/0, RESAMPLE_PERIOD, MOVE, {{4, 5, 200}});
- args2.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args2.pointerProperties[0].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args2);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(MOVE));
@@ -632,7 +632,7 @@
// it's a palm.
NotifyMotionArgs args3 =
generateMotionArgs(/*downTime=*/0, 2 * RESAMPLE_PERIOD, UP, {{4, 5, 200}});
- args3.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args3.pointerProperties[0].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args3);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(UP));
}
@@ -655,21 +655,21 @@
// Stylus pointer down
NotifyMotionArgs args2 = generateMotionArgs(/*downTime=*/0, RESAMPLE_PERIOD, POINTER_1_DOWN,
{{1, 2, 3}, {10, 20, 30}});
- args2.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args2.pointerProperties[1].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args2);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(POINTER_1_DOWN));
// Large touch oval on the next finger move
NotifyMotionArgs args3 = generateMotionArgs(/*downTime=*/0, 2 * RESAMPLE_PERIOD, MOVE,
{{1, 2, 300}, {11, 21, 30}});
- args3.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args3.pointerProperties[1].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args3);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(MOVE));
// Lift up the finger pointer. It should be canceled due to the heuristic filter.
NotifyMotionArgs args4 = generateMotionArgs(/*downTime=*/0, 3 * RESAMPLE_PERIOD, POINTER_0_UP,
{{1, 2, 300}, {11, 21, 30}});
- args4.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args4.pointerProperties[1].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args4);
mTestListener.assertNotifyMotionWasCalled(
AllOf(WithMotionAction(POINTER_0_UP), WithFlags(FLAG_CANCELED)));
@@ -677,7 +677,7 @@
NotifyMotionArgs args5 =
generateMotionArgs(/*downTime=*/0, 4 * RESAMPLE_PERIOD, MOVE, {{12, 22, 30}});
args5.pointerProperties[0].id = args4.pointerProperties[1].id;
- args5.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args5.pointerProperties[0].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args5);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(MOVE));
@@ -685,7 +685,7 @@
NotifyMotionArgs args6 =
generateMotionArgs(/*downTime=*/0, 5 * RESAMPLE_PERIOD, UP, {{4, 5, 200}});
args6.pointerProperties[0].id = args4.pointerProperties[1].id;
- args6.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ args6.pointerProperties[0].toolType = ToolType::STYLUS;
mBlocker->notifyMotion(&args6);
mTestListener.assertNotifyMotionWasCalled(WithMotionAction(UP));
}
diff --git a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
index 9a19b97..0d5f30c 100644
--- a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
@@ -52,13 +52,13 @@
[&]() -> void { mapper.getSources(); },
[&]() -> void {
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
- fdp->ConsumeIntegral<int32_t>());
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<int32_t>());
},
[&]() -> void {
// Need to reconfigure with 0 or you risk a NPE.
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
InputDeviceInfo info;
mapper.populateDeviceInfo(info);
},
@@ -71,7 +71,7 @@
// Need to reconfigure with 0 or you risk a NPE.
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
fdp->ConsumeIntegral<nsecs_t>(),
fdp->ConsumeIntegral<int32_t>(),
@@ -90,7 +90,7 @@
[&]() -> void {
// Need to reconfigure with 0 or you risk a NPE.
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
mapper.getAssociatedDisplayId();
},
})();
diff --git a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
index 2909129..6617f65 100644
--- a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
@@ -28,7 +28,7 @@
// Create a basic motion event for testing
PointerProperties properties;
properties.id = 0;
- properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ properties.toolType = getFuzzedToolType(fdp);
PointerCoords coords;
coords.clear();
for (int32_t i = 0; i < fdp.ConsumeIntegralInRange<int32_t>(0, MAX_AXES); i++) {
diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
index 20242b1..baece3c 100644
--- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
@@ -165,6 +165,10 @@
return reader->getBluetoothAddress(deviceId);
}
+ void sysfsNodeChanged(const std::string& sysfsNodePath) {
+ reader->sysfsNodeChanged(sysfsNodePath);
+ }
+
private:
std::unique_ptr<InputReaderInterface> reader;
};
diff --git a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
index 33e7dbf..14cb8a5 100644
--- a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
@@ -64,8 +64,8 @@
[&]() -> void { mapper.getSources(); },
[&]() -> void {
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
- fdp->ConsumeIntegral<uint32_t>());
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
},
[&]() -> void {
std::list<NotifyArgs> unused = mapper.reset(fdp->ConsumeIntegral<nsecs_t>());
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index 2cb5cdf..9f4aa5c 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -66,6 +66,14 @@
namespace android {
+template<class Fdp>
+ToolType getFuzzedToolType(Fdp& fdp) {
+ const int32_t toolType = fdp.template ConsumeIntegralInRange<int32_t>(
+ static_cast<int32_t>(ToolType::ftl_first),
+ static_cast<int32_t>(ToolType::ftl_last));
+ return static_cast<ToolType>(toolType);
+}
+
class FuzzEventHub : public EventHubInterface {
InputDeviceIdentifier mIdentifier;
std::vector<TouchVideoFrame> mVideoFrames;
@@ -217,6 +225,7 @@
bool isDeviceEnabled(int32_t deviceId) const override { return mFdp->ConsumeBool(); }
status_t enableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
status_t disableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
+ void sysfsNodeChanged(const std::string& sysfsNodePath) override {}
};
class FuzzPointerController : public PointerControllerInterface {
diff --git a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
index 59cb94a..8352a90 100644
--- a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
@@ -79,8 +79,8 @@
[&]() -> void { mapper.getSources(); },
[&]() -> void {
std::list<NotifyArgs> unused =
- mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
- fdp->ConsumeIntegral<uint32_t>());
+ mapper.reconfigure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
},
[&]() -> void {
std::list<NotifyArgs> unused = mapper.reset(fdp->ConsumeIntegral<nsecs_t>());
@@ -127,8 +127,7 @@
[&]() -> void {
StylusState state{fdp->ConsumeIntegral<nsecs_t>(),
fdp->ConsumeFloatingPoint<float>(),
- fdp->ConsumeIntegral<uint32_t>(),
- fdp->ConsumeIntegral<int32_t>()};
+ fdp->ConsumeIntegral<uint32_t>(), getFuzzedToolType(*fdp)};
std::list<NotifyArgs> unused = mapper.updateExternalStylusState(state);
},
[&]() -> void { mapper.getAssociatedDisplayId(); },
diff --git a/services/powermanager/Android.bp b/services/powermanager/Android.bp
index 7fb33e5..b34e54f 100644
--- a/services/powermanager/Android.bp
+++ b/services/powermanager/Android.bp
@@ -43,6 +43,14 @@
"android.hardware.power-V4-cpp",
],
+ export_shared_lib_headers: [
+ "android.hardware.power@1.0",
+ "android.hardware.power@1.1",
+ "android.hardware.power@1.2",
+ "android.hardware.power@1.3",
+ "android.hardware.power-V4-cpp",
+ ],
+
cflags: [
"-Wall",
"-Werror",
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index b94b1c0..7a6b31d 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -55,14 +55,13 @@
SensorService::SensorEventConnection::~SensorEventConnection() {
ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
destroy();
- mService->cleanupConnection(this);
- if (mEventCache != nullptr) {
- delete[] mEventCache;
- }
+ delete[] mEventCache;
}
void SensorService::SensorEventConnection::destroy() {
- mDestroyed = true;
+ if (!mDestroyed.exchange(true)) {
+ mService->cleanupConnection(this);
+ }
}
void SensorService::SensorEventConnection::onFirstRef() {
diff --git a/services/stats/Android.bp b/services/stats/Android.bp
index 7d358e1..6b99627 100644
--- a/services/stats/Android.bp
+++ b/services/stats/Android.bp
@@ -21,6 +21,7 @@
"android.frameworks.stats@1.0",
"android.frameworks.stats-V2-ndk",
"libbinder_ndk",
+ "libexpresslog",
"libhidlbase",
"liblog",
"libstatslog",
diff --git a/services/stats/StatsAidl.cpp b/services/stats/StatsAidl.cpp
index 0f01507..b22f903 100644
--- a/services/stats/StatsAidl.cpp
+++ b/services/stats/StatsAidl.cpp
@@ -22,6 +22,7 @@
#include "StatsAidl.h"
+#include <Counter.h>
#include <log/log.h>
#include <stats_annotations.h>
#include <stats_event.h>
@@ -29,11 +30,18 @@
#include <unordered_map>
+namespace {
+ static const char* g_AtomErrorMetricName =
+ "statsd_errors.value_report_vendor_atom_errors_count";
+}
+
namespace aidl {
namespace android {
namespace frameworks {
namespace stats {
+using ::android::expresslog::Counter;
+
template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) noexcept {
return static_cast<typename std::underlying_type<E>::type>(e);
@@ -86,12 +94,14 @@
ndk::ScopedAStatus StatsHal::reportVendorAtom(const VendorAtom& vendorAtom) {
if (vendorAtom.atomId < 100000 || vendorAtom.atomId >= 200000) {
ALOGE("Atom ID %ld is not a valid vendor atom ID", (long)vendorAtom.atomId);
+ Counter::logIncrement(g_AtomErrorMetricName);
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-1, "Not a valid vendor atom ID");
}
if (vendorAtom.reverseDomainName.length() > 50) {
ALOGE("Vendor atom reverse domain name %s is too long.",
vendorAtom.reverseDomainName.c_str());
+ Counter::logIncrement(g_AtomErrorMetricName);
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-1, "Vendor atom reverse domain name is too long");
}
@@ -100,8 +110,9 @@
if (vendorAtom.atomAnnotations) {
if (!write_atom_annotations(event, *vendorAtom.atomAnnotations)) {
- ALOGE("Atom ID %ld has incompatible atom level annotation", (long)vendorAtom.atomId);
AStatsEvent_release(event);
+ ALOGE("Atom ID %ld has incompatible atom level annotation", (long)vendorAtom.atomId);
+ Counter::logIncrement(g_AtomErrorMetricName);
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-1, "invalid atom annotation");
}
@@ -222,6 +233,7 @@
default: {
AStatsEvent_release(event);
ALOGE("Atom ID %ld has invalid atomValue.getTag", (long)vendorAtom.atomId);
+ Counter::logIncrement(g_AtomErrorMetricName);
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-1, "invalid atomValue.getTag");
break;
@@ -235,9 +247,10 @@
VLOG("Atom ID %ld has %ld annotations for field #%ld", (long)vendorAtom.atomId,
(long)fieldAnnotations.size(), (long)atomValueIdx + 2);
if (!write_field_annotations(event, fieldAnnotations)) {
+ AStatsEvent_release(event);
ALOGE("Atom ID %ld has incompatible field level annotation for field #%ld",
(long)vendorAtom.atomId, (long)atomValueIdx + 2);
- AStatsEvent_release(event);
+ Counter::logIncrement(g_AtomErrorMetricName);
return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-1, "invalid atom field annotation");
}
@@ -249,6 +262,7 @@
AStatsEvent_release(event);
if (ret <= 0) {
ALOGE("Error writing Atom ID %ld. Result: %d", (long)vendorAtom.atomId, ret);
+ Counter::logIncrement(g_AtomErrorMetricName);
}
return ret <= 0 ? ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(ret,
"report atom failed")
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index fe7cff7..5683a92 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -47,8 +47,6 @@
"android.hardware.graphics.composer@2.2",
"android.hardware.graphics.composer@2.3",
"android.hardware.graphics.composer@2.4",
- "android.hardware.power@1.0",
- "android.hardware.power@1.3",
"android.hardware.power-V4-cpp",
"libbase",
"libbinder",
@@ -63,6 +61,7 @@
"liblayers_proto",
"liblog",
"libnativewindow",
+ "libpowermanager",
"libprocessgroup",
"libprotobuf-cpp-lite",
"libsync",
@@ -105,7 +104,7 @@
"android.hardware.graphics.composer@2.2",
"android.hardware.graphics.composer@2.3",
"android.hardware.graphics.composer@2.4",
- "android.hardware.power@1.3",
+ "libpowermanager",
"libhidlbase",
"libtimestats",
],
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
index a8322d8..d93e25e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
@@ -83,12 +83,9 @@
// If set, causes the dirty regions to flash with the delay
std::optional<std::chrono::microseconds> devOptFlashDirtyRegionsDelay;
- // The earliest time to send the present command to the HAL
- std::chrono::steady_clock::time_point earliestPresentTime;
-
- // The previous present fence. Used together with earliestPresentTime
- // to prevent an early presentation of a frame.
- std::shared_ptr<FenceTime> previousPresentFence;
+ // Optional.
+ // The earliest time to send the present command to the HAL.
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime;
// The expected time for the next present
nsecs_t expectedPresentTime{0};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index eae5871..35ca3a5 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -210,8 +210,8 @@
// The dimming flag
bool dimmingEnabled{true};
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
virtual ~LayerFECompositionState();
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index c291652..a3fda61 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -122,12 +122,9 @@
bool previousDeviceRequestedSuccess = false;
+ // Optional.
// The earliest time to send the present command to the HAL
- std::chrono::steady_clock::time_point earliestPresentTime;
-
- // The previous present fence. Used together with earliestPresentTime
- // to prevent an early presentation of a frame.
- std::shared_ptr<FenceTime> previousPresentFence;
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime;
// The expected time for the next present
nsecs_t expectedPresentTime{0};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index d5c488e..ce2b96f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -247,6 +247,10 @@
ui::Dataspace getDataspace() const { return mOutputDataspace.get(); }
+ float getHdrSdrRatio() const {
+ return getOutputLayer()->getLayerFE().getCompositionState()->currentHdrSdrRatio;
+ };
+
wp<GraphicBuffer> getBuffer() const { return mBuffer.get(); }
bool isProtected() const { return mIsProtected.get(); }
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index d50a768..85fc095 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -263,7 +263,6 @@
if (status_t result =
hwc.getDeviceCompositionChanges(*halDisplayId, requiresClientComposition,
getState().earliestPresentTime,
- getState().previousPresentFence,
getState().expectedPresentTime, outChanges);
result != NO_ERROR) {
ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
@@ -380,16 +379,11 @@
const TimePoint startTime = TimePoint::now();
- if (isPowerHintSessionEnabled()) {
- if (!getCompositionEngine().getHwComposer().getComposer()->isSupported(
- Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
- getState().previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
- mPowerAdvisor->setHwcPresentDelayedTime(mId, getState().earliestPresentTime);
- }
+ if (isPowerHintSessionEnabled() && getState().earliestPresentTime) {
+ mPowerAdvisor->setHwcPresentDelayedTime(mId, *getState().earliestPresentTime);
}
- hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime,
- getState().previousPresentFence);
+ hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime);
if (isPowerHintSessionEnabled()) {
mPowerAdvisor->setHwcPresentTiming(mId, startTime, TimePoint::now());
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 615d04b..426cc57 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -121,9 +121,9 @@
dumpVal(out, "dataspace", toString(dataspace), dataspace);
dumpVal(out, "hdr metadata types", hdrMetadata.validTypes);
dumpVal(out, "dimming enabled", dimmingEnabled);
- if (currentSdrHdrRatio > 1.01f || desiredSdrHdrRatio > 1.01f) {
- dumpVal(out, "current sdr/hdr ratio", currentSdrHdrRatio);
- dumpVal(out, "desired sdr/hdr ratio", desiredSdrHdrRatio);
+ if (currentHdrSdrRatio > 1.01f || desiredHdrSdrRatio > 1.01f) {
+ dumpVal(out, "current hdr/sdr ratio", currentHdrSdrRatio);
+ dumpVal(out, "desired hdr/sdr ratio", desiredHdrSdrRatio);
}
dumpVal(out, "colorTransform", colorTransform);
dumpVal(out, "caching hint", toString(cachingHint));
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 175dd1d..e720af5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -842,7 +842,6 @@
}
editState().earliestPresentTime = refreshArgs.earliestPresentTime;
- editState().previousPresentFence = refreshArgs.previousPresentFence;
editState().expectedPresentTime = refreshArgs.expectedPresentTime;
compositionengine::OutputLayer* peekThroughLayer = nullptr;
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 1b86cd3..0ac0ecb 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -344,8 +344,8 @@
// RANGE_EXTENDED can "self-promote" to HDR, but is still rendered for a particular
// range that we may need to re-adjust to the current display conditions
if ((state.dataspace & HAL_DATASPACE_RANGE_MASK) == HAL_DATASPACE_RANGE_EXTENDED &&
- layerFEState->currentSdrHdrRatio > 1.01f) {
- layerBrightnessNits *= layerFEState->currentSdrHdrRatio;
+ layerFEState->currentHdrSdrRatio > 1.01f) {
+ layerBrightnessNits *= layerFEState->currentHdrSdrRatio;
}
state.dimmingRatio =
std::clamp(layerBrightnessNits / getOutput().getState().displayBrightnessNits, 0.f,
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index a00ce57..8ced0ac 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -378,6 +378,10 @@
// to avoid flickering/color differences.
return true;
}
+ // TODO(b/274804887): temp fix of overdimming issue, skip caching if hsdr/sdr ratio > 1.01f
+ if (layer.getState()->getHdrSdrRatio() > 1.01f) {
+ return true;
+ }
return false;
});
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 0756c1b..9be6bc2 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -595,7 +595,7 @@
TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
EXPECT_CALL(mHwComposer,
- getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _, _, _, _))
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _, _, _))
.WillOnce(Return(INVALID_OPERATION));
chooseCompositionStrategy(mDisplay.get());
@@ -619,8 +619,8 @@
.WillOnce(Return(false));
EXPECT_CALL(mHwComposer,
- getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _, _))
- .WillOnce(testing::DoAll(testing::SetArgPointee<5>(mDeviceRequestedChanges),
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _))
+ .WillOnce(testing::DoAll(testing::SetArgPointee<4>(mDeviceRequestedChanges),
Return(NO_ERROR)));
EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(mDeviceRequestedChanges.changedTypes))
.Times(1);
@@ -672,8 +672,8 @@
.WillOnce(Return(false));
EXPECT_CALL(mHwComposer,
- getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _, _))
- .WillOnce(DoAll(SetArgPointee<5>(mDeviceRequestedChanges), Return(NO_ERROR)));
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _))
+ .WillOnce(DoAll(SetArgPointee<4>(mDeviceRequestedChanges), Return(NO_ERROR)));
EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(mDeviceRequestedChanges.changedTypes))
.Times(1);
EXPECT_CALL(*mDisplay, applyDisplayRequests(mDeviceRequestedChanges.displayRequests)).Times(1);
@@ -901,7 +901,7 @@
sp<Fence> layer1Fence = sp<Fence>::make();
sp<Fence> layer2Fence = sp<Fence>::make();
- EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID), _, _))
+ EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID), _))
.Times(1);
EXPECT_CALL(mHwComposer, getPresentFence(HalDisplayId(DEFAULT_DISPLAY_ID)))
.WillOnce(Return(presentFence));
@@ -1078,7 +1078,7 @@
mDisplay->editState().isEnabled = true;
- EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(_, _, _));
+ EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(_, _));
EXPECT_CALL(*mDisplaySurface, onFrameCommitted());
mDisplay->postFramebuffer();
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 1a56ab7..67b94ee 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -54,16 +54,14 @@
MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId));
- MOCK_METHOD6(getDeviceCompositionChanges,
- status_t(HalDisplayId, bool, std::chrono::steady_clock::time_point,
- const std::shared_ptr<FenceTime>&, nsecs_t,
- std::optional<android::HWComposer::DeviceRequestedChanges>*));
+ MOCK_METHOD5(getDeviceCompositionChanges,
+ status_t(HalDisplayId, bool, std::optional<std::chrono::steady_clock::time_point>,
+ nsecs_t, std::optional<android::HWComposer::DeviceRequestedChanges>*));
MOCK_METHOD5(setClientTarget,
status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
ui::Dataspace));
- MOCK_METHOD3(presentAndGetReleaseFences,
- status_t(HalDisplayId, std::chrono::steady_clock::time_point,
- const std::shared_ptr<FenceTime>&));
+ MOCK_METHOD2(presentAndGetReleaseFences,
+ status_t(HalDisplayId, std::optional<std::chrono::steady_clock::time_point>));
MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode));
MOCK_METHOD2(setActiveConfig, status_t(HalDisplayId, size_t));
MOCK_METHOD2(setColorTransform, status_t(HalDisplayId, const mat4&));
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index c555b39..961ec80 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -37,11 +37,10 @@
MOCK_METHOD(void, notifyDisplayUpdateImminentAndCpuReset, (), (override));
MOCK_METHOD(bool, usePowerHintSession, (), (override));
MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
- MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
- MOCK_METHOD(void, setTargetWorkDuration, (Duration targetDuration), (override));
- MOCK_METHOD(void, sendActualWorkDuration, (), (override));
- MOCK_METHOD(void, sendPredictedWorkDuration, (), (override));
- MOCK_METHOD(void, enablePowerHint, (bool enabled), (override));
+ MOCK_METHOD(bool, ensurePowerHintSessionRunning, (), (override));
+ MOCK_METHOD(void, updateTargetWorkDuration, (Duration targetDuration), (override));
+ MOCK_METHOD(void, reportActualWorkDuration, (), (override));
+ MOCK_METHOD(void, enablePowerHintSession, (bool enabled), (override));
MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
MOCK_METHOD(void, setGpuFenceTime,
(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index ca5ba69..bd030d0 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -662,6 +662,26 @@
EXPECT_FALSE(cachedSet.requiresHolePunch());
}
+TEST_F(CachedSetTest, holePunch_requiresNonHdrWithExtendedBrightness) {
+ const auto dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_DCI_P3 |
+ ui::Dataspace::TRANSFER_SRGB |
+ ui::Dataspace::RANGE_EXTENDED);
+ mTestLayers[0]->outputLayerCompositionState.dataspace = dataspace;
+ mTestLayers[0]->layerFECompositionState.currentHdrSdrRatio = 5.f;
+ mTestLayers[0]->layerState->update(&mTestLayers[0]->outputLayer);
+
+ CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
+ auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
+ layerFECompositionState.buffer = sp<GraphicBuffer>::make();
+ layerFECompositionState.blendMode = hal::BlendMode::NONE;
+ sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
+
+ CachedSet cachedSet(layer);
+ EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
+
+ EXPECT_FALSE(cachedSet.requiresHolePunch());
+}
+
TEST_F(CachedSetTest, holePunch_requiresNoBlending) {
CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index bd2680f..f28bfd4 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -1547,6 +1547,8 @@
}
bool AidlComposer::hasMultiThreadedPresentSupport(Display display) {
+#if 0
+ // TODO (b/259132483): Reenable
const auto displayId = translate<int64_t>(display);
std::vector<AidlDisplayCapability> capabilities;
const auto status = mAidlComposerClient->getDisplayCapabilities(displayId, &capabilities);
@@ -1556,6 +1558,10 @@
}
return std::find(capabilities.begin(), capabilities.end(),
AidlDisplayCapability::MULTI_THREADED_PRESENT) != capabilities.end();
+#else
+ (void) display;
+ return false;
+#endif
}
void AidlComposer::addReader(Display display) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 28148ac..f350eba 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -395,8 +395,8 @@
status_t HWComposer::getDeviceCompositionChanges(
HalDisplayId displayId, bool frameUsesClientComposition,
- std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence, nsecs_t expectedPresentTime,
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
+ nsecs_t expectedPresentTime,
std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
ATRACE_CALL();
@@ -426,14 +426,13 @@
// If composer supports getting the expected present time, we can skip
// as composer will make sure to prevent early presentation
- if (mComposer->isSupported(Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
+ if (!earliestPresentTime) {
return true;
}
// composer doesn't support getting the expected present time. We can only
// skip validate if we know that we are not going to present early.
- return std::chrono::steady_clock::now() >= earliestPresentTime ||
- previousPresentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING;
+ return std::chrono::steady_clock::now() >= *earliestPresentTime;
}();
displayData.validateWasSkipped = false;
@@ -508,8 +507,8 @@
}
status_t HWComposer::presentAndGetReleaseFences(
- HalDisplayId displayId, std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence) {
+ HalDisplayId displayId,
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) {
ATRACE_CALL();
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -525,13 +524,9 @@
return NO_ERROR;
}
- const bool waitForEarliestPresent =
- !mComposer->isSupported(Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
- previousPresentFence->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
-
- if (waitForEarliestPresent) {
+ if (earliestPresentTime) {
ATRACE_NAME("wait for earliest present time");
- std::this_thread::sleep_until(earliestPresentTime);
+ std::this_thread::sleep_until(*earliestPresentTime);
}
auto error = hwcDisplay->present(&displayData.lastPresentFence);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 7a3f41c..3702c62 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -143,17 +143,16 @@
// expected.
virtual status_t getDeviceCompositionChanges(
HalDisplayId, bool frameUsesClientComposition,
- std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence, nsecs_t expectedPresentTime,
- std::optional<DeviceRequestedChanges>* outChanges) = 0;
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
+ nsecs_t expectedPresentTime, std::optional<DeviceRequestedChanges>* outChanges) = 0;
virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
// Present layers to the display and read releaseFences.
virtual status_t presentAndGetReleaseFences(
- HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence) = 0;
+ HalDisplayId,
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) = 0;
// set power mode
virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
@@ -339,8 +338,8 @@
status_t getDeviceCompositionChanges(
HalDisplayId, bool frameUsesClientComposition,
- std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence, nsecs_t expectedPresentTime,
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
+ nsecs_t expectedPresentTime,
std::optional<DeviceRequestedChanges>* outChanges) override;
status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
@@ -348,8 +347,8 @@
// Present layers to the display and read releaseFences.
status_t presentAndGetReleaseFences(
- HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime,
- const std::shared_ptr<FenceTime>& previousPresentFence) override;
+ HalDisplayId,
+ std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) override;
// set power mode
status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index f05223c..37b68c8 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -31,7 +31,7 @@
#include <utils/Mutex.h>
#include <utils/Trace.h>
-#include <android/hardware/power/1.3/IPower.h>
+#include <android/hardware/power/IPower.h>
#include <android/hardware/power/IPowerHintSession.h>
#include <android/hardware/power/WorkDuration.h>
@@ -49,12 +49,7 @@
namespace impl {
-namespace V1_0 = android::hardware::power::V1_0;
-namespace V1_3 = android::hardware::power::V1_3;
-using V1_3::PowerHint;
-
using android::hardware::power::Boost;
-using android::hardware::power::IPower;
using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
using android::hardware::power::SessionHint;
@@ -80,7 +75,8 @@
} // namespace
-PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger) : mFlinger(flinger) {
+PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger)
+ : mPowerHal(std::make_unique<power::PowerHalController>()), mFlinger(flinger) {
if (getUpdateTimeout() > 0ms) {
mScreenUpdateTimer.emplace("UpdateImminentTimer", getUpdateTimeout(),
/* resetCallback */ nullptr,
@@ -117,6 +113,10 @@
}
void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expected) {
+ if (!mHasExpensiveRendering) {
+ ALOGV("Skipped sending EXPENSIVE_RENDERING because HAL doesn't support it");
+ return;
+ }
if (expected) {
mExpensiveDisplays.insert(displayId);
} else {
@@ -125,19 +125,16 @@
const bool expectsExpensiveRendering = !mExpensiveDisplays.empty();
if (mNotifiedExpensiveRendering != expectsExpensiveRendering) {
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- if (halWrapper == nullptr) {
- return;
- }
-
- if (!halWrapper->setExpensiveRendering(expectsExpensiveRendering)) {
- // The HAL has become unavailable; attempt to reconnect later
- mReconnectPowerHal = true;
+ auto ret = getPowerHal().setMode(Mode::EXPENSIVE_RENDERING, expectsExpensiveRendering);
+ if (!ret.isOk()) {
+ if (ret.isUnsupported()) {
+ mHasExpensiveRendering = false;
+ }
return;
}
mNotifiedExpensiveRendering = expectsExpensiveRendering;
+ traceExpensiveRendering(mNotifiedExpensiveRendering);
}
}
@@ -149,16 +146,22 @@
}
if (mSendUpdateImminent.exchange(false)) {
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- if (halWrapper == nullptr) {
- return;
+ ALOGV("AIDL notifyDisplayUpdateImminentAndCpuReset");
+ if (usePowerHintSession() && ensurePowerHintSessionRunning()) {
+ std::lock_guard lock(mHintSessionMutex);
+ auto ret = mHintSession->sendHint(SessionHint::CPU_LOAD_RESET);
+ if (!ret.isOk()) {
+ mHintSessionRunning = false;
+ }
}
- if (!halWrapper->notifyDisplayUpdateImminentAndCpuReset()) {
- // The HAL has become unavailable; attempt to reconnect later
- mReconnectPowerHal = true;
- return;
+ if (!mHasDisplayUpdateImminent) {
+ ALOGV("Skipped sending DISPLAY_UPDATE_IMMINENT because HAL doesn't support it");
+ } else {
+ auto ret = getPowerHal().setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 0);
+ if (ret.isUnsupported()) {
+ mHasDisplayUpdateImminent = false;
+ }
}
if (mScreenUpdateTimer) {
@@ -178,88 +181,123 @@
// checks both if it supports and if it's enabled
bool PowerAdvisor::usePowerHintSession() {
// uses cached value since the underlying support and flag are unlikely to change at runtime
- return mPowerHintEnabled.value_or(false) && supportsPowerHintSession();
+ return mHintSessionEnabled.value_or(false) && supportsPowerHintSession();
}
bool PowerAdvisor::supportsPowerHintSession() {
// cache to avoid needing lock every time
- if (!mSupportsPowerHint.has_value()) {
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- mSupportsPowerHint = halWrapper && halWrapper->supportsPowerHintSession();
+ if (!mSupportsHintSession.has_value()) {
+ mSupportsHintSession = getPowerHal().getHintSessionPreferredRate().isOk();
}
- return *mSupportsPowerHint;
+ return *mSupportsHintSession;
}
-bool PowerAdvisor::isPowerHintSessionRunning() {
- return mPowerHintSessionRunning;
+bool PowerAdvisor::ensurePowerHintSessionRunning() {
+ if (!mHintSessionRunning && !mHintSessionThreadIds.empty() && usePowerHintSession()) {
+ startPowerHintSession(mHintSessionThreadIds);
+ }
+ return mHintSessionRunning;
}
-void PowerAdvisor::setTargetWorkDuration(Duration targetDuration) {
+void PowerAdvisor::updateTargetWorkDuration(Duration targetDuration) {
if (!usePowerHintSession()) {
ALOGV("Power hint session target duration cannot be set, skipping");
return;
}
+ ATRACE_CALL();
{
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- if (halWrapper != nullptr) {
- halWrapper->setTargetWorkDuration(targetDuration);
+ mTargetDuration = targetDuration;
+ if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDuration.ns());
+ if (ensurePowerHintSessionRunning() && (targetDuration != mLastTargetDurationSent)) {
+ ALOGV("Sending target time: %" PRId64 "ns", targetDuration.ns());
+ mLastTargetDurationSent = targetDuration;
+ std::lock_guard lock(mHintSessionMutex);
+ auto ret = mHintSession->updateTargetWorkDuration(targetDuration.ns());
+ if (!ret.isOk()) {
+ ALOGW("Failed to set power hint target work duration with error: %s",
+ ret.exceptionMessage().c_str());
+ mHintSessionRunning = false;
+ }
}
}
}
-void PowerAdvisor::sendActualWorkDuration() {
+void PowerAdvisor::reportActualWorkDuration() {
if (!mBootFinished || !usePowerHintSession()) {
ALOGV("Actual work duration power hint cannot be sent, skipping");
return;
}
- const std::optional<Duration> actualDuration = estimateWorkDuration(false);
- if (actualDuration.has_value()) {
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- if (halWrapper != nullptr) {
- halWrapper->sendActualWorkDuration(*actualDuration + kTargetSafetyMargin,
- TimePoint::now());
- }
- }
-}
-
-void PowerAdvisor::sendPredictedWorkDuration() {
- if (!mBootFinished || !usePowerHintSession()) {
- ALOGV("Actual work duration power hint cannot be sent, skipping");
+ ATRACE_CALL();
+ std::optional<Duration> actualDuration = estimateWorkDuration();
+ if (!actualDuration.has_value() || actualDuration < 0ns || !ensurePowerHintSessionRunning()) {
+ ALOGV("Failed to send actual work duration, skipping");
return;
}
+ actualDuration = std::make_optional(*actualDuration + sTargetSafetyMargin);
+ mActualDuration = actualDuration;
+ WorkDuration duration;
+ duration.durationNanos = actualDuration->ns();
+ duration.timeStampNanos = TimePoint::now().ns();
+ mHintSessionQueue.push_back(duration);
- const std::optional<Duration> predictedDuration = estimateWorkDuration(true);
+ if (sTraceHintSessionData) {
+ ATRACE_INT64("Measured duration", actualDuration->ns());
+ ATRACE_INT64("Target error term", Duration{*actualDuration - mTargetDuration}.ns());
+ ATRACE_INT64("Reported duration", actualDuration->ns());
+ ATRACE_INT64("Reported target", mLastTargetDurationSent.ns());
+ ATRACE_INT64("Reported target error term",
+ Duration{*actualDuration - mLastTargetDurationSent}.ns());
+ }
- if (predictedDuration.has_value()) {
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* const halWrapper = getPowerHal();
- if (halWrapper != nullptr) {
- halWrapper->sendActualWorkDuration(*predictedDuration + kTargetSafetyMargin,
- TimePoint::now());
+ ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64
+ " with error: %" PRId64,
+ actualDuration->ns(), mLastTargetDurationSent.ns(),
+ Duration{*actualDuration - mLastTargetDurationSent}.ns());
+
+ {
+ std::lock_guard lock(mHintSessionMutex);
+ auto ret = mHintSession->reportActualWorkDuration(mHintSessionQueue);
+ if (!ret.isOk()) {
+ ALOGW("Failed to report actual work durations with error: %s",
+ ret.exceptionMessage().c_str());
+ mHintSessionRunning = false;
+ return;
}
}
+ mHintSessionQueue.clear();
}
-void PowerAdvisor::enablePowerHint(bool enabled) {
- mPowerHintEnabled = enabled;
+void PowerAdvisor::enablePowerHintSession(bool enabled) {
+ mHintSessionEnabled = enabled;
}
bool PowerAdvisor::startPowerHintSession(const std::vector<int32_t>& threadIds) {
- if (!usePowerHintSession()) {
- ALOGI("Power hint session cannot be started, skipping");
+ if (!mBootFinished.load()) {
+ return false;
}
+ if (!usePowerHintSession()) {
+ ALOGI("Cannot start power hint session: disabled or unsupported");
+ return false;
+ }
+ if (mHintSessionRunning) {
+ ALOGE("Cannot start power hint session: already running");
+ return false;
+ }
+ LOG_ALWAYS_FATAL_IF(threadIds.empty(), "No thread IDs provided to power hint session!");
{
- std::lock_guard lock(mPowerHalMutex);
- HalWrapper* halWrapper = getPowerHal();
- if (halWrapper != nullptr && usePowerHintSession()) {
- halWrapper->setPowerHintSessionThreadIds(threadIds);
- mPowerHintSessionRunning = halWrapper->startPowerHintSession();
+ std::lock_guard lock(mHintSessionMutex);
+ mHintSession = nullptr;
+ mHintSessionThreadIds = threadIds;
+
+ auto ret = getPowerHal().createHintSession(getpid(), static_cast<int32_t>(getuid()),
+ threadIds, mTargetDuration.ns());
+
+ if (ret.isOk()) {
+ mHintSessionRunning = true;
+ mHintSession = ret.value();
}
}
- return mPowerHintSessionRunning;
+ return mHintSessionRunning;
}
void PowerAdvisor::setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime) {
@@ -357,13 +395,13 @@
return sortedDisplays;
}
-std::optional<Duration> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
- if (earlyHint && (!mExpectedPresentTimes.isFull() || !mCommitStartTimes.isFull())) {
+std::optional<Duration> PowerAdvisor::estimateWorkDuration() {
+ if (!mExpectedPresentTimes.isFull() || !mCommitStartTimes.isFull()) {
return std::nullopt;
}
// Tracks when we finish presenting to hwc
- TimePoint estimatedEndTime = mCommitStartTimes[0];
+ TimePoint estimatedHwcEndTime = mCommitStartTimes[0];
// How long we spent this frame not doing anything, waiting for fences or vsync
Duration idleDuration = 0ns;
@@ -376,21 +414,11 @@
// used to accumulate gpu time as we iterate over the active displays
std::optional<TimePoint> estimatedGpuEndTime;
- // If we're predicting at the start of the frame, we use last frame as our reference point
- // If we're predicting at the end of the frame, we use the current frame as a reference point
- TimePoint referenceFrameStartTime = (earlyHint ? mCommitStartTimes[-1] : mCommitStartTimes[0]);
-
- // When the prior frame should be presenting to the display
- // If we're predicting at the start of the frame, we use last frame's expected present time
- // If we're predicting at the end of the frame, the present fence time is already known
- TimePoint lastFramePresentTime =
- (earlyHint ? mExpectedPresentTimes[-1] : mLastPresentFenceTime);
-
// The timing info for the previously calculated display, if there was one
- std::optional<DisplayTimeline> previousDisplayReferenceTiming;
+ std::optional<DisplayTimeline> previousDisplayTiming;
std::vector<DisplayId>&& displayIds =
getOrderedDisplayIds(&DisplayTimingData::hwcPresentStartTime);
- DisplayTimeline referenceTiming, estimatedTiming;
+ DisplayTimeline displayTiming;
// Iterate over the displays that use hwc in the same order they are presented
for (DisplayId displayId : displayIds) {
@@ -400,35 +428,26 @@
auto& displayData = mDisplayTimingData.at(displayId);
- // mLastPresentFenceTime should always be the time of the reference frame, since it will be
- // the previous frame's present fence if called at the start, and current frame's if called
- // at the end
- referenceTiming = displayData.calculateDisplayTimeline(mLastPresentFenceTime);
+ displayTiming = displayData.calculateDisplayTimeline(mLastPresentFenceTime);
// If this is the first display, include the duration before hwc present starts
- if (!previousDisplayReferenceTiming.has_value()) {
- estimatedEndTime += referenceTiming.hwcPresentStartTime - referenceFrameStartTime;
+ if (!previousDisplayTiming.has_value()) {
+ estimatedHwcEndTime += displayTiming.hwcPresentStartTime - mCommitStartTimes[0];
} else { // Otherwise add the time since last display's hwc present finished
- estimatedEndTime += referenceTiming.hwcPresentStartTime -
- previousDisplayReferenceTiming->hwcPresentEndTime;
+ estimatedHwcEndTime +=
+ displayTiming.hwcPresentStartTime - previousDisplayTiming->hwcPresentEndTime;
}
- // Late hint can re-use reference timing here since it's estimating its own reference frame
- estimatedTiming = earlyHint
- ? referenceTiming.estimateTimelineFromReference(lastFramePresentTime,
- estimatedEndTime)
- : referenceTiming;
-
// Update predicted present finish time with this display's present time
- estimatedEndTime = estimatedTiming.hwcPresentEndTime;
+ estimatedHwcEndTime = displayTiming.hwcPresentEndTime;
// Track how long we spent waiting for the fence, can be excluded from the timing estimate
- idleDuration += estimatedTiming.probablyWaitsForPresentFence
- ? lastFramePresentTime - estimatedTiming.presentFenceWaitStartTime
+ idleDuration += displayTiming.probablyWaitsForPresentFence
+ ? mLastPresentFenceTime - displayTiming.presentFenceWaitStartTime
: 0ns;
// Track how long we spent waiting to present, can be excluded from the timing estimate
- idleDuration += earlyHint ? 0ns : referenceTiming.hwcPresentDelayDuration;
+ idleDuration += displayTiming.hwcPresentDelayDuration;
// Estimate the reference frame's gpu timing
auto gpuTiming = displayData.estimateGpuTiming(previousValidGpuEndTime);
@@ -436,24 +455,24 @@
previousValidGpuEndTime = gpuTiming->startTime + gpuTiming->duration;
// Estimate the prediction frame's gpu end time from the reference frame
- estimatedGpuEndTime = std::max(estimatedTiming.hwcPresentStartTime,
+ estimatedGpuEndTime = std::max(displayTiming.hwcPresentStartTime,
estimatedGpuEndTime.value_or(TimePoint{0ns})) +
gpuTiming->duration;
}
- previousDisplayReferenceTiming = referenceTiming;
+ previousDisplayTiming = displayTiming;
}
ATRACE_INT64("Idle duration", idleDuration.ns());
- TimePoint estimatedFlingerEndTime = earlyHint ? estimatedEndTime : mLastSfPresentEndTime;
+ TimePoint estimatedFlingerEndTime = mLastSfPresentEndTime;
// Don't count time spent idly waiting in the estimate as we could do more work in that time
- estimatedEndTime -= idleDuration;
+ estimatedHwcEndTime -= idleDuration;
estimatedFlingerEndTime -= idleDuration;
// We finish the frame when both present and the gpu are done, so wait for the later of the two
// Also add the frame delay duration since the target did not move while we were delayed
Duration totalDuration = mFrameDelayDuration +
- std::max(estimatedEndTime, estimatedGpuEndTime.value_or(TimePoint{0ns})) -
+ std::max(estimatedHwcEndTime, estimatedGpuEndTime.value_or(TimePoint{0ns})) -
mCommitStartTimes[0];
// We finish SurfaceFlinger when post-composition finishes, so add that in here
@@ -468,10 +487,7 @@
Duration PowerAdvisor::combineTimingEstimates(Duration totalDuration, Duration flingerDuration) {
Duration targetDuration{0ns};
- {
- std::lock_guard lock(mPowerHalMutex);
- targetDuration = *getPowerHal()->getTargetWorkDuration();
- }
+ targetDuration = mTargetDuration;
if (!mTotalFrameTargetDuration.has_value()) return flingerDuration;
// Normalize total to the flinger target (vsync period) since that's how often we actually send
@@ -481,26 +497,6 @@
return std::max(flingerDuration, normalizedTotalDuration);
}
-PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimeline::estimateTimelineFromReference(
- TimePoint fenceTime, TimePoint displayStartTime) {
- DisplayTimeline estimated;
- estimated.hwcPresentStartTime = displayStartTime;
-
- // We don't predict waiting for vsync alignment yet
- estimated.hwcPresentDelayDuration = 0ns;
-
- // How long we expect to run before we start waiting for the fence
- // For now just re-use last frame's post-present duration and assume it will not change much
- // Excludes time spent waiting for vsync since that's not going to be consistent
- estimated.presentFenceWaitStartTime = estimated.hwcPresentStartTime +
- (presentFenceWaitStartTime - (hwcPresentStartTime + hwcPresentDelayDuration));
- estimated.probablyWaitsForPresentFence = fenceTime > estimated.presentFenceWaitStartTime;
- estimated.hwcPresentEndTime = postPresentFenceHwcPresentDuration +
- (estimated.probablyWaitsForPresentFence ? fenceTime
- : estimated.presentFenceWaitStartTime);
- return estimated;
-}
-
PowerAdvisor::DisplayTimeline PowerAdvisor::DisplayTimingData::calculateDisplayTimeline(
TimePoint fenceTime) {
DisplayTimeline timeline;
@@ -561,317 +557,17 @@
return GpuTimeline{.duration = gpuDuration, .startTime = latestGpuStartTime};
}
-class HidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
-public:
- HidlPowerHalWrapper(sp<V1_3::IPower> powerHal) : mPowerHal(std::move(powerHal)) {}
-
- ~HidlPowerHalWrapper() override = default;
-
- static std::unique_ptr<HalWrapper> connect() {
- // Power HAL 1.3 is not guaranteed to be available, thus we need to query
- // Power HAL 1.0 first and try to cast it to Power HAL 1.3.
- sp<V1_3::IPower> powerHal = nullptr;
- sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService();
- if (powerHal_1_0 != nullptr) {
- // Try to cast to Power HAL 1.3
- powerHal = V1_3::IPower::castFrom(powerHal_1_0);
- if (powerHal == nullptr) {
- ALOGW("No Power HAL 1.3 service in system, disabling PowerAdvisor");
- } else {
- ALOGI("Loaded Power HAL 1.3 service");
- }
- } else {
- ALOGW("No Power HAL found, disabling PowerAdvisor");
- }
-
- if (powerHal == nullptr) {
- return nullptr;
- }
-
- return std::make_unique<HidlPowerHalWrapper>(std::move(powerHal));
- }
-
- bool setExpensiveRendering(bool enabled) override {
- ALOGV("HIDL setExpensiveRendering %s", enabled ? "T" : "F");
- auto ret = mPowerHal->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, enabled);
- if (ret.isOk()) {
- traceExpensiveRendering(enabled);
- }
- return ret.isOk();
- }
-
- bool notifyDisplayUpdateImminentAndCpuReset() override {
- // Power HAL 1.x doesn't have a notification for this
- ALOGV("HIDL notifyUpdateImminent received but can't send");
- return true;
- }
-
- bool supportsPowerHintSession() override { return false; }
-
- bool isPowerHintSessionRunning() override { return false; }
-
- void restartPowerHintSession() override {}
-
- void setPowerHintSessionThreadIds(const std::vector<int32_t>&) override {}
-
- bool startPowerHintSession() override { return false; }
-
- void setTargetWorkDuration(Duration) override {}
-
- void sendActualWorkDuration(Duration, TimePoint) override {}
-
- bool shouldReconnectHAL() override { return false; }
-
- std::vector<int32_t> getPowerHintSessionThreadIds() override { return std::vector<int32_t>{}; }
-
- std::optional<Duration> getTargetWorkDuration() override { return std::nullopt; }
-
-private:
- const sp<V1_3::IPower> mPowerHal = nullptr;
-};
-
-AidlPowerHalWrapper::AidlPowerHalWrapper(sp<IPower> powerHal) : mPowerHal(std::move(powerHal)) {
- auto ret = mPowerHal->isModeSupported(Mode::EXPENSIVE_RENDERING, &mHasExpensiveRendering);
- if (!ret.isOk()) {
- mHasExpensiveRendering = false;
- }
-
- ret = mPowerHal->isBoostSupported(Boost::DISPLAY_UPDATE_IMMINENT, &mHasDisplayUpdateImminent);
- if (!ret.isOk()) {
- mHasDisplayUpdateImminent = false;
- }
-
- mSupportsPowerHint = checkPowerHintSessionSupported();
-}
-
-AidlPowerHalWrapper::~AidlPowerHalWrapper() {
- if (mPowerHintSession != nullptr) {
- mPowerHintSession->close();
- mPowerHintSession = nullptr;
- }
-}
-
-std::unique_ptr<PowerAdvisor::HalWrapper> AidlPowerHalWrapper::connect() {
- // This only waits if the service is actually declared
- sp<IPower> powerHal = waitForVintfService<IPower>();
- if (powerHal == nullptr) {
- return nullptr;
- }
- ALOGI("Loaded AIDL Power HAL service");
-
- return std::make_unique<AidlPowerHalWrapper>(std::move(powerHal));
-}
-
-bool AidlPowerHalWrapper::setExpensiveRendering(bool enabled) {
- ALOGV("AIDL setExpensiveRendering %s", enabled ? "T" : "F");
- if (!mHasExpensiveRendering) {
- ALOGV("Skipped sending EXPENSIVE_RENDERING because HAL doesn't support it");
- return true;
- }
-
- auto ret = mPowerHal->setMode(Mode::EXPENSIVE_RENDERING, enabled);
- if (ret.isOk()) {
- traceExpensiveRendering(enabled);
- }
- return ret.isOk();
-}
-
-bool AidlPowerHalWrapper::notifyDisplayUpdateImminentAndCpuReset() {
- ALOGV("AIDL notifyDisplayUpdateImminentAndCpuReset");
- if (isPowerHintSessionRunning()) {
- mPowerHintSession->sendHint(SessionHint::CPU_LOAD_RESET);
- }
-
- if (!mHasDisplayUpdateImminent) {
- ALOGV("Skipped sending DISPLAY_UPDATE_IMMINENT because HAL doesn't support it");
- return true;
- }
-
- auto ret = mPowerHal->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 0);
- return ret.isOk();
-}
-
-// Only version 2+ of the aidl supports power hint sessions, hidl has no support
-bool AidlPowerHalWrapper::supportsPowerHintSession() {
- return mSupportsPowerHint;
-}
-
-bool AidlPowerHalWrapper::checkPowerHintSessionSupported() {
- int64_t unused;
- // Try to get preferred rate to determine if hint sessions are supported
- // We check for isOk not EX_UNSUPPORTED_OPERATION to lump together errors
- return mPowerHal->getHintSessionPreferredRate(&unused).isOk();
-}
-
-bool AidlPowerHalWrapper::isPowerHintSessionRunning() {
- return mPowerHintSession != nullptr;
-}
-
-void AidlPowerHalWrapper::closePowerHintSession() {
- if (mPowerHintSession != nullptr) {
- mPowerHintSession->close();
- mPowerHintSession = nullptr;
- }
-}
-
-void AidlPowerHalWrapper::restartPowerHintSession() {
- closePowerHintSession();
- startPowerHintSession();
-}
-
-void AidlPowerHalWrapper::setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) {
- if (threadIds != mPowerHintThreadIds) {
- mPowerHintThreadIds = threadIds;
- if (isPowerHintSessionRunning()) {
- restartPowerHintSession();
- }
- }
-}
-
-bool AidlPowerHalWrapper::startPowerHintSession() {
- if (mPowerHintSession != nullptr || mPowerHintThreadIds.empty()) {
- ALOGV("Cannot start power hint session, skipping");
- return false;
- }
- auto ret = mPowerHal->createHintSession(getpid(), static_cast<int32_t>(getuid()),
- mPowerHintThreadIds, mTargetDuration.ns(),
- &mPowerHintSession);
- if (!ret.isOk()) {
- ALOGW("Failed to start power hint session with error: %s",
- ret.exceptionToString(ret.exceptionCode()).c_str());
- } else {
- mLastTargetDurationSent = mTargetDuration;
- }
- return isPowerHintSessionRunning();
-}
-
-void AidlPowerHalWrapper::setTargetWorkDuration(Duration targetDuration) {
- ATRACE_CALL();
- mTargetDuration = targetDuration;
- if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDuration.ns());
- if (isPowerHintSessionRunning() && (targetDuration != mLastTargetDurationSent)) {
- ALOGV("Sending target time: %" PRId64 "ns", targetDuration.ns());
- mLastTargetDurationSent = targetDuration;
- auto ret = mPowerHintSession->updateTargetWorkDuration(targetDuration.ns());
- if (!ret.isOk()) {
- ALOGW("Failed to set power hint target work duration with error: %s",
- ret.exceptionMessage().c_str());
- mShouldReconnectHal = true;
- }
- }
-}
-
-void AidlPowerHalWrapper::sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) {
- ATRACE_CALL();
- if (actualDuration < 0ns || !isPowerHintSessionRunning()) {
- ALOGV("Failed to send actual work duration, skipping");
- return;
- }
- mActualDuration = actualDuration;
- WorkDuration duration;
- duration.durationNanos = actualDuration.ns();
- duration.timeStampNanos = timestamp.ns();
- mPowerHintQueue.push_back(duration);
-
- if (sTraceHintSessionData) {
- ATRACE_INT64("Measured duration", actualDuration.ns());
- ATRACE_INT64("Target error term", Duration{actualDuration - mTargetDuration}.ns());
-
- ATRACE_INT64("Reported duration", actualDuration.ns());
- ATRACE_INT64("Reported target", mLastTargetDurationSent.ns());
- ATRACE_INT64("Reported target error term",
- Duration{actualDuration - mLastTargetDurationSent}.ns());
- }
-
- ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64
- " with error: %" PRId64,
- actualDuration.ns(), mLastTargetDurationSent.ns(),
- Duration{actualDuration - mLastTargetDurationSent}.ns());
-
- auto ret = mPowerHintSession->reportActualWorkDuration(mPowerHintQueue);
- if (!ret.isOk()) {
- ALOGW("Failed to report actual work durations with error: %s",
- ret.exceptionMessage().c_str());
- mShouldReconnectHal = true;
- }
- mPowerHintQueue.clear();
-}
-
-bool AidlPowerHalWrapper::shouldReconnectHAL() {
- return mShouldReconnectHal;
-}
-
-std::vector<int32_t> AidlPowerHalWrapper::getPowerHintSessionThreadIds() {
- return mPowerHintThreadIds;
-}
-
-std::optional<Duration> AidlPowerHalWrapper::getTargetWorkDuration() {
- return mTargetDuration;
-}
-
-const bool AidlPowerHalWrapper::sTraceHintSessionData =
+const bool PowerAdvisor::sTraceHintSessionData =
base::GetBoolProperty(std::string("debug.sf.trace_hint_sessions"), false);
-PowerAdvisor::HalWrapper* PowerAdvisor::getPowerHal() {
- if (!mHasHal) {
- return nullptr;
- }
+const Duration PowerAdvisor::sTargetSafetyMargin = std::chrono::microseconds(
+ base::GetIntProperty<int64_t>("debug.sf.hint_margin_us",
+ ticks<std::micro>(PowerAdvisor::kDefaultTargetSafetyMargin)));
- // Grab old hint session values before we destroy any existing wrapper
- std::vector<int32_t> oldPowerHintSessionThreadIds;
- std::optional<Duration> oldTargetWorkDuration;
-
- if (mHalWrapper != nullptr) {
- oldPowerHintSessionThreadIds = mHalWrapper->getPowerHintSessionThreadIds();
- oldTargetWorkDuration = mHalWrapper->getTargetWorkDuration();
- }
-
- // If we used to have a HAL, but it stopped responding, attempt to reconnect
- if (mReconnectPowerHal) {
- mHalWrapper = nullptr;
- mReconnectPowerHal = false;
- }
-
- if (mHalWrapper != nullptr) {
- auto wrapper = mHalWrapper.get();
- // If the wrapper is fine, return it, but if it indicates a reconnect, remake it
- if (!wrapper->shouldReconnectHAL()) {
- return wrapper;
- }
- ALOGD("Reconnecting Power HAL");
- mHalWrapper = nullptr;
- }
-
- // At this point, we know for sure there is no running session
- mPowerHintSessionRunning = false;
-
- // First attempt to connect to the AIDL Power HAL
- mHalWrapper = AidlPowerHalWrapper::connect();
-
- // If that didn't succeed, attempt to connect to the HIDL Power HAL
- if (mHalWrapper == nullptr) {
- mHalWrapper = HidlPowerHalWrapper::connect();
- } else {
- ALOGD("Successfully connecting AIDL Power HAL");
- // If AIDL, pass on any existing hint session values
- mHalWrapper->setPowerHintSessionThreadIds(oldPowerHintSessionThreadIds);
- // Only set duration and start if duration is defined
- if (oldTargetWorkDuration.has_value()) {
- mHalWrapper->setTargetWorkDuration(*oldTargetWorkDuration);
- // Only start if possible to run and both threadids and duration are defined
- if (usePowerHintSession() && !oldPowerHintSessionThreadIds.empty()) {
- mPowerHintSessionRunning = mHalWrapper->startPowerHintSession();
- }
- }
- }
-
- // If we make it to this point and still don't have a HAL, it's unlikely we
- // will, so stop trying
- if (mHalWrapper == nullptr) {
- mHasHal = false;
- }
-
- return mHalWrapper.get();
+power::PowerHalController& PowerAdvisor::getPowerHal() {
+ static std::once_flag halFlag;
+ std::call_once(halFlag, [this] { mPowerHal->init(); });
+ return *mPowerHal;
}
} // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index d45e7cb..7a0d426 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -27,6 +27,7 @@
#include <android/hardware/power/IPower.h>
#include <compositionengine/impl/OutputCompositionState.h>
+#include <powermanager/PowerHalController.h>
#include <scheduler/Time.h>
#include <ui/DisplayIdentification.h>
#include "../Scheduler/OneShotTimer.h"
@@ -52,15 +53,14 @@
// Checks both if it supports and if it's enabled
virtual bool usePowerHintSession() = 0;
virtual bool supportsPowerHintSession() = 0;
- virtual bool isPowerHintSessionRunning() = 0;
+
+ virtual bool ensurePowerHintSessionRunning() = 0;
// Sends a power hint that updates to the target work duration for the frame
- virtual void setTargetWorkDuration(Duration targetDuration) = 0;
+ virtual void updateTargetWorkDuration(Duration targetDuration) = 0;
// Sends a power hint for the actual known work duration at the end of the frame
- virtual void sendActualWorkDuration() = 0;
- // Sends a power hint for the upcoming frame predicted from previous frame timing
- virtual void sendPredictedWorkDuration() = 0;
+ virtual void reportActualWorkDuration() = 0;
// Sets whether the power hint session is enabled
- virtual void enablePowerHint(bool enabled) = 0;
+ virtual void enablePowerHintSession(bool enabled) = 0;
// Initializes the power hint session
virtual bool startPowerHintSession(const std::vector<int32_t>& threadIds) = 0;
// Provides PowerAdvisor with a copy of the gpu fence so it can determine the gpu end time
@@ -101,24 +101,6 @@
// full state of the system when sending out power hints to things like the GPU.
class PowerAdvisor final : public Hwc2::PowerAdvisor {
public:
- class HalWrapper {
- public:
- virtual ~HalWrapper() = default;
-
- virtual bool setExpensiveRendering(bool enabled) = 0;
- virtual bool notifyDisplayUpdateImminentAndCpuReset() = 0;
- virtual bool supportsPowerHintSession() = 0;
- virtual bool isPowerHintSessionRunning() = 0;
- virtual void restartPowerHintSession() = 0;
- virtual void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) = 0;
- virtual bool startPowerHintSession() = 0;
- virtual void setTargetWorkDuration(Duration targetDuration) = 0;
- virtual void sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) = 0;
- virtual bool shouldReconnectHAL() = 0;
- virtual std::vector<int32_t> getPowerHintSessionThreadIds() = 0;
- virtual std::optional<Duration> getTargetWorkDuration() = 0;
- };
-
PowerAdvisor(SurfaceFlinger& flinger);
~PowerAdvisor() override;
@@ -129,11 +111,10 @@
void notifyDisplayUpdateImminentAndCpuReset() override;
bool usePowerHintSession() override;
bool supportsPowerHintSession() override;
- bool isPowerHintSessionRunning() override;
- void setTargetWorkDuration(Duration targetDuration) override;
- void sendActualWorkDuration() override;
- void sendPredictedWorkDuration() override;
- void enablePowerHint(bool enabled) override;
+ bool ensurePowerHintSessionRunning() override;
+ void updateTargetWorkDuration(Duration targetDuration) override;
+ void reportActualWorkDuration() override;
+ void enablePowerHintSession(bool enabled) override;
bool startPowerHintSession(const std::vector<int32_t>& threadIds) override;
void setGpuFenceTime(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime);
void setHwcValidateTiming(DisplayId displayId, TimePoint validateStartTime,
@@ -155,15 +136,7 @@
private:
friend class PowerAdvisorTest;
- // Tracks if powerhal exists
- bool mHasHal = true;
- // Holds the hal wrapper for getPowerHal
- std::unique_ptr<HalWrapper> mHalWrapper GUARDED_BY(mPowerHalMutex) = nullptr;
-
- HalWrapper* getPowerHal() REQUIRES(mPowerHalMutex);
- bool mReconnectPowerHal GUARDED_BY(mPowerHalMutex) = false;
- std::mutex mPowerHalMutex;
-
+ std::unique_ptr<power::PowerHalController> mPowerHal;
std::atomic_bool mBootFinished = false;
std::unordered_set<DisplayId> mExpensiveDisplays;
@@ -189,9 +162,6 @@
Duration postPresentFenceHwcPresentDuration{0ns};
// Are we likely to have waited for the present fence during composition
bool probablyWaitsForPresentFence = false;
- // Estimate one frame's timeline from that of a previous frame
- DisplayTimeline estimateTimelineFromReference(TimePoint fenceTime,
- TimePoint displayStartTime);
};
struct GpuTimeline {
@@ -243,8 +213,7 @@
std::vector<DisplayId> getOrderedDisplayIds(
std::optional<TimePoint> DisplayTimingData::*sortBy);
// Estimates a frame's total work duration including gpu time.
- // Runs either at the beginning or end of a frame, using the most recent data available
- std::optional<Duration> estimateWorkDuration(bool earlyHint);
+ std::optional<Duration> estimateWorkDuration();
// There are two different targets and actual work durations we care about,
// this normalizes them together and takes the max of the two
Duration combineTimingEstimates(Duration totalDuration, Duration flingerDuration);
@@ -268,67 +237,41 @@
// Updated list of display IDs
std::vector<DisplayId> mDisplayIds;
- std::optional<bool> mPowerHintEnabled;
- std::optional<bool> mSupportsPowerHint;
- bool mPowerHintSessionRunning = false;
+ // Ensure powerhal connection is initialized
+ power::PowerHalController& getPowerHal();
- // An adjustable safety margin which pads the "actual" value sent to PowerHAL,
- // encouraging more aggressive boosting to give SurfaceFlinger a larger margin for error
- static constexpr const Duration kTargetSafetyMargin{1ms};
+ std::optional<bool> mHintSessionEnabled;
+ std::optional<bool> mSupportsHintSession;
+ bool mHintSessionRunning = false;
- // How long we expect hwc to run after the present call until it waits for the fence
- static constexpr const Duration kFenceWaitStartDelayValidated{150us};
- static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
-};
+ std::mutex mHintSessionMutex;
+ sp<hardware::power::IPowerHintSession> mHintSession GUARDED_BY(mHintSessionMutex) = nullptr;
-class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
-public:
- explicit AidlPowerHalWrapper(sp<hardware::power::IPower> powerHal);
- ~AidlPowerHalWrapper() override;
-
- static std::unique_ptr<HalWrapper> connect();
-
- bool setExpensiveRendering(bool enabled) override;
- bool notifyDisplayUpdateImminentAndCpuReset() override;
- bool supportsPowerHintSession() override;
- bool isPowerHintSessionRunning() override;
- void restartPowerHintSession() override;
- void setPowerHintSessionThreadIds(const std::vector<int32_t>& threadIds) override;
- bool startPowerHintSession() override;
- void setTargetWorkDuration(Duration targetDuration) override;
- void sendActualWorkDuration(Duration actualDuration, TimePoint timestamp) override;
- bool shouldReconnectHAL() override;
- std::vector<int32_t> getPowerHintSessionThreadIds() override;
- std::optional<Duration> getTargetWorkDuration() override;
-
-private:
- friend class AidlPowerHalWrapperTest;
-
- bool checkPowerHintSessionSupported();
- void closePowerHintSession();
-
- const sp<hardware::power::IPower> mPowerHal = nullptr;
- bool mHasExpensiveRendering = false;
- bool mHasDisplayUpdateImminent = false;
- // Used to indicate an error state and need for reconstruction
- bool mShouldReconnectHal = false;
-
- // Power hint session data
-
- // Concurrent access for this is protected by mPowerHalMutex
- sp<hardware::power::IPowerHintSession> mPowerHintSession = nullptr;
+ // Initialize to true so we try to call, to check if it's supported
+ bool mHasExpensiveRendering = true;
+ bool mHasDisplayUpdateImminent = true;
// Queue of actual durations saved to report
- std::vector<hardware::power::WorkDuration> mPowerHintQueue;
+ std::vector<hardware::power::WorkDuration> mHintSessionQueue;
// The latest values we have received for target and actual
Duration mTargetDuration = kDefaultTargetDuration;
std::optional<Duration> mActualDuration;
// The list of thread ids, stored so we can restart the session from this class if needed
- std::vector<int32_t> mPowerHintThreadIds;
- bool mSupportsPowerHint = false;
+ std::vector<int32_t> mHintSessionThreadIds;
Duration mLastTargetDurationSent = kDefaultTargetDuration;
// Whether we should emit ATRACE_INT data for hint sessions
static const bool sTraceHintSessionData;
- static constexpr Duration kDefaultTargetDuration{16ms};
+
+ // Default target duration for the hint session
+ static constexpr const Duration kDefaultTargetDuration{16ms};
+
+ // An adjustable safety margin which pads the "actual" value sent to PowerHAL,
+ // encouraging more aggressive boosting to give SurfaceFlinger a larger margin for error
+ static const Duration sTargetSafetyMargin;
+ static constexpr const Duration kDefaultTargetSafetyMargin{1ms};
+
+ // How long we expect hwc to run after the present call until it waits for the fence
+ static constexpr const Duration kFenceWaitStartDelayValidated{150us};
+ static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
};
} // namespace impl
diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
index ce21233..6af352c 100644
--- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.cpp
@@ -74,4 +74,23 @@
return LayerCreationArgs(other.flinger, other.client, other.name, other.flags, other.metadata);
}
+std::string LayerCreationArgs::getDebugString() const {
+ std::stringstream stream;
+ stream << "LayerCreationArgs{" << name << "[" << sequence << "] flags=" << flags
+ << " pid=" << ownerPid << " uid=" << ownerUid;
+ if (addToRoot) {
+ stream << " addToRoot=" << addToRoot;
+ }
+ if (parentId != UNASSIGNED_LAYER_ID) {
+ stream << " parentId=" << parentId;
+ }
+ if (layerIdToMirror != UNASSIGNED_LAYER_ID) {
+ stream << " layerIdToMirror=" << layerIdToMirror;
+ }
+ if (layerStackToMirror != ui::INVALID_LAYER_STACK) {
+ stream << " layerStackToMirror=" << layerStackToMirror.id;
+ }
+ return stream.str();
+}
+
} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
index 011250c..3a0fc6d 100644
--- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
+++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
@@ -44,6 +44,7 @@
bool internalLayer = false);
LayerCreationArgs(std::optional<uint32_t> id, bool internalLayer = false);
LayerCreationArgs() = default; // for tracing
+ std::string getDebugString() const;
android::SurfaceFlinger* flinger;
sp<android::Client> client;
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index 3706225..33d9dbe 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -164,7 +164,8 @@
}
}
-void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState>& transactions) {
+void LayerLifecycleManager::applyTransactions(const std::vector<TransactionState>& transactions,
+ bool ignoreUnknownLayers) {
for (const auto& transaction : transactions) {
for (const auto& resolvedComposerState : transaction.states) {
const auto& clientState = resolvedComposerState.state;
@@ -176,7 +177,8 @@
RequestedLayerState* layer = getLayerFromId(layerId);
if (layer == nullptr) {
- LOG_ALWAYS_FATAL("%s Layer with layerid=%d not found", __func__, layerId);
+ LOG_ALWAYS_FATAL_IF(!ignoreUnknownLayers, "%s Layer with layerid=%d not found",
+ __func__, layerId);
continue;
}
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
index 3d9a74c..f258678 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
@@ -39,7 +39,11 @@
public:
// External state changes should be updated in the following order:
void addLayers(std::vector<std::unique_ptr<RequestedLayerState>>);
- void applyTransactions(const std::vector<TransactionState>&);
+ // Ignore unknown layers when interoping with legacy front end. In legacy we destroy
+ // the layers it is unreachable. When using the LayerLifecycleManager for layer trace
+ // generation we may encounter layers which are known because we don't have an explicit
+ // lifecycle. Ignore these errors while we have to interop with legacy.
+ void applyTransactions(const std::vector<TransactionState>&, bool ignoreUnknownLayers = false);
// Ignore unknown handles when iteroping with legacy front end. In the old world, we
// would create child layers which are not necessary with the new front end. This means
// we will get notified for handle changes that don't exist in the new front end.
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 2d6d8ad..1e931a7 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -187,6 +187,8 @@
<< " geomLayerTransform={tx=" << geomLayerTransform.tx()
<< ",ty=" << geomLayerTransform.ty() << "}"
<< "}";
+ debug << " input{ touchCropId=" << touchCropId
+ << " replaceTouchableRegionWithCrop=" << inputInfo.replaceTouchableRegionWithCrop << "}";
return debug.str();
}
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 5491d9a..b167d3e 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -94,6 +94,7 @@
int32_t frameRateSelectionPriority;
LayerHierarchy::TraversalPath mirrorRootPath;
bool unreachable = true;
+ uint32_t touchCropId;
uid_t uid;
pid_t pid;
ChildState childState;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index bdd4427..25cbe7a 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -447,23 +447,36 @@
}
}
+ // Update touchable region crops outside the main update pass. This is because a layer could be
+ // cropped by any other layer and it requires both snapshots to be updated.
+ updateTouchableRegionCrop(args);
+
const bool hasUnreachableSnapshots = sortSnapshotsByZ(args);
clearChanges(mRootSnapshot);
- // Destroy unreachable snapshots
- if (!hasUnreachableSnapshots) {
+ // Destroy unreachable snapshots for clone layers. And destroy snapshots for non-clone
+ // layers if the layer have been destroyed.
+ // TODO(b/238781169) consider making clone layer ids stable as well
+ if (!hasUnreachableSnapshots && args.layerLifecycleManager.getDestroyedLayers().empty()) {
return;
}
+ std::unordered_set<uint32_t> destroyedLayerIds;
+ for (auto& destroyedLayer : args.layerLifecycleManager.getDestroyedLayers()) {
+ destroyedLayerIds.insert(destroyedLayer->id);
+ }
+
auto it = mSnapshots.begin();
while (it < mSnapshots.end()) {
auto& traversalPath = it->get()->path;
- if (!it->get()->unreachable) {
+ if (!it->get()->unreachable &&
+ destroyedLayerIds.find(traversalPath.id) == destroyedLayerIds.end()) {
it++;
continue;
}
mIdToSnapshot.erase(traversalPath);
+ mNeedsTouchableRegionCrop.erase(traversalPath);
mSnapshots.back()->globalZ = it->get()->globalZ;
std::iter_swap(it, mSnapshots.end() - 1);
mSnapshots.erase(mSnapshots.end() - 1);
@@ -554,7 +567,7 @@
mResortSnapshots = false;
for (auto& snapshot : mSnapshots) {
- snapshot->unreachable = true;
+ snapshot->unreachable = snapshot->path.isClone();
}
size_t globalZ = 0;
@@ -720,8 +733,8 @@
snapshot.sidebandStream = requested.sidebandStream;
snapshot.transparentRegionHint = requested.transparentRegion;
snapshot.color.rgb = requested.getColor().rgb;
- snapshot.currentSdrHdrRatio = requested.currentSdrHdrRatio;
- snapshot.desiredSdrHdrRatio = requested.desiredSdrHdrRatio;
+ snapshot.currentHdrSdrRatio = requested.currentHdrSdrRatio;
+ snapshot.desiredHdrSdrRatio = requested.desiredHdrSdrRatio;
}
if (snapshot.isHiddenByPolicyFromParent &&
@@ -739,6 +752,8 @@
// If root layer, use the layer stack otherwise get the parent's layer stack.
snapshot.color.a = parentSnapshot.color.a * requested.color.a;
snapshot.alpha = snapshot.color.a;
+ snapshot.inputInfo.alpha = snapshot.color.a;
+
snapshot.isSecure =
parentSnapshot.isSecure || (requested.flags & layer_state_t::eLayerSecure);
snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
@@ -986,9 +1001,11 @@
snapshot.inputInfo.ownerUid = static_cast<int32_t>(requested.ownerUid);
snapshot.inputInfo.ownerPid = requested.ownerPid;
}
+ snapshot.touchCropId = requested.touchCropId;
snapshot.inputInfo.id = static_cast<int32_t>(snapshot.uniqueSequence);
snapshot.inputInfo.displayId = static_cast<int32_t>(snapshot.outputFilter.layerStack.id);
+ updateVisibility(snapshot, snapshot.isVisible);
if (!needsInputInfo(snapshot, requested)) {
return;
}
@@ -1033,27 +1050,13 @@
}
auto cropLayerSnapshot = getSnapshot(requested.touchCropId);
- if (snapshot.inputInfo.replaceTouchableRegionWithCrop) {
- Rect inputBoundsInDisplaySpace;
- if (!cropLayerSnapshot) {
- FloatRect inputBounds = getInputBounds(snapshot, /*fillParentBounds=*/true).first;
- inputBoundsInDisplaySpace =
- getInputBoundsInDisplaySpace(snapshot, inputBounds, displayInfo.transform);
- } else {
- FloatRect inputBounds =
- getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
- inputBoundsInDisplaySpace =
- getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
- displayInfo.transform);
- }
- snapshot.inputInfo.touchableRegion = Region(inputBoundsInDisplaySpace);
- } else if (cropLayerSnapshot) {
- FloatRect inputBounds = getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
+ if (cropLayerSnapshot) {
+ mNeedsTouchableRegionCrop.insert(path);
+ } else if (snapshot.inputInfo.replaceTouchableRegionWithCrop) {
+ FloatRect inputBounds = getInputBounds(snapshot, /*fillParentBounds=*/true).first;
Rect inputBoundsInDisplaySpace =
- getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
- displayInfo.transform);
- snapshot.inputInfo.touchableRegion = snapshot.inputInfo.touchableRegion.intersect(
- displayInfo.transform.transform(inputBoundsInDisplaySpace));
+ getInputBoundsInDisplaySpace(snapshot, inputBounds, displayInfo.transform);
+ snapshot.inputInfo.touchableRegion = Region(inputBoundsInDisplaySpace);
}
// Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
@@ -1066,12 +1069,7 @@
// touches from going outside the cloned area.
if (path.isClone()) {
snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::CLONE;
- auto clonedRootSnapshot = getSnapshot(snapshot.mirrorRootPath);
- if (clonedRootSnapshot) {
- const Rect rect =
- displayInfo.transform.transform(Rect{clonedRootSnapshot->transformedBounds});
- snapshot.inputInfo.touchableRegion = snapshot.inputInfo.touchableRegion.intersect(rect);
- }
+ mNeedsTouchableRegionCrop.insert(path);
}
}
@@ -1117,4 +1115,77 @@
}
}
+void LayerSnapshotBuilder::updateTouchableRegionCrop(const Args& args) {
+ if (mNeedsTouchableRegionCrop.empty()) {
+ return;
+ }
+
+ static constexpr ftl::Flags<RequestedLayerState::Changes> AFFECTS_INPUT =
+ RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Created |
+ RequestedLayerState::Changes::Hierarchy | RequestedLayerState::Changes::Geometry |
+ RequestedLayerState::Changes::Input;
+
+ if (args.forceUpdate != ForceUpdateFlags::ALL &&
+ !args.layerLifecycleManager.getGlobalChanges().any(AFFECTS_INPUT)) {
+ return;
+ }
+
+ for (auto& path : mNeedsTouchableRegionCrop) {
+ frontend::LayerSnapshot* snapshot = getSnapshot(path);
+ if (!snapshot) {
+ continue;
+ }
+ const std::optional<frontend::DisplayInfo> displayInfoOpt =
+ args.displays.get(snapshot->outputFilter.layerStack);
+ static frontend::DisplayInfo sDefaultInfo = {.isSecure = false};
+ auto displayInfo = displayInfoOpt.value_or(sDefaultInfo);
+
+ bool needsUpdate =
+ args.forceUpdate == ForceUpdateFlags::ALL || snapshot->changes.any(AFFECTS_INPUT);
+ auto cropLayerSnapshot = getSnapshot(snapshot->touchCropId);
+ needsUpdate =
+ needsUpdate || (cropLayerSnapshot && cropLayerSnapshot->changes.any(AFFECTS_INPUT));
+ auto clonedRootSnapshot = path.isClone() ? getSnapshot(snapshot->mirrorRootPath) : nullptr;
+ needsUpdate = needsUpdate ||
+ (clonedRootSnapshot && clonedRootSnapshot->changes.any(AFFECTS_INPUT));
+
+ if (!needsUpdate) {
+ continue;
+ }
+
+ if (snapshot->inputInfo.replaceTouchableRegionWithCrop) {
+ Rect inputBoundsInDisplaySpace;
+ if (!cropLayerSnapshot) {
+ FloatRect inputBounds = getInputBounds(*snapshot, /*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(*snapshot, inputBounds, displayInfo.transform);
+ } else {
+ FloatRect inputBounds =
+ getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
+ inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
+ displayInfo.transform);
+ }
+ snapshot->inputInfo.touchableRegion = Region(inputBoundsInDisplaySpace);
+ } else if (cropLayerSnapshot) {
+ FloatRect inputBounds =
+ getInputBounds(*cropLayerSnapshot, /*fillParentBounds=*/true).first;
+ Rect inputBoundsInDisplaySpace =
+ getInputBoundsInDisplaySpace(*cropLayerSnapshot, inputBounds,
+ displayInfo.transform);
+ snapshot->inputInfo.touchableRegion = snapshot->inputInfo.touchableRegion.intersect(
+ displayInfo.transform.transform(inputBoundsInDisplaySpace));
+ }
+
+ // If the layer is a clone, we need to crop the input region to cloned root to prevent
+ // touches from going outside the cloned area.
+ if (clonedRootSnapshot) {
+ const Rect rect =
+ displayInfo.transform.transform(Rect{clonedRootSnapshot->transformedBounds});
+ snapshot->inputInfo.touchableRegion =
+ snapshot->inputInfo.touchableRegion.intersect(rect);
+ }
+ }
+}
+
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index 7b1ff27..148c98e 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -119,10 +119,14 @@
const LayerSnapshot& parentSnapshot);
void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
const Args& args);
+ void updateTouchableRegionCrop(const Args& args);
std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*,
LayerHierarchy::TraversalPathHash>
mIdToSnapshot;
+ // Track snapshots that needs touchable region crop from other snapshots
+ std::unordered_set<LayerHierarchy::TraversalPath, LayerHierarchy::TraversalPathHash>
+ mNeedsTouchableRegionCrop;
std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
LayerSnapshot mRootSnapshot;
bool mResortSnapshots = false;
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index a5fdaf4..1f670c8 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -100,8 +100,8 @@
layerStack = ui::DEFAULT_LAYER_STACK;
transformToDisplayInverse = false;
dataspace = ui::Dataspace::UNKNOWN;
- desiredSdrHdrRatio = 1.f;
- currentSdrHdrRatio = 1.f;
+ desiredHdrSdrRatio = 1.f;
+ currentHdrSdrRatio = 1.f;
dataspaceRequested = false;
hdrMetadata.validTypes = 0;
surfaceDamageRegion = Region::INVALID_REGION;
diff --git a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
index 8629671..a209cad 100644
--- a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
+++ b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
@@ -64,11 +64,61 @@
transactionsPendingBarrier = flushPendingTransactionQueues(transactions, flushState);
} while (lastTransactionsPendingBarrier != transactionsPendingBarrier);
+ applyUnsignaledBufferTransaction(transactions, flushState);
+
mPendingTransactionCount.fetch_sub(transactions.size());
ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
return transactions;
}
+void TransactionHandler::applyUnsignaledBufferTransaction(
+ std::vector<TransactionState>& transactions, TransactionFlushState& flushState) {
+ // only apply an unsignaled buffer transaction if it's the first one
+ if (!transactions.empty()) {
+ return;
+ }
+
+ if (!flushState.queueWithUnsignaledBuffer) {
+ return;
+ }
+
+ auto it = mPendingTransactionQueues.find(flushState.queueWithUnsignaledBuffer);
+ LOG_ALWAYS_FATAL_IF(it == mPendingTransactionQueues.end(),
+ "Could not find queue with unsignaled buffer!");
+
+ auto& queue = it->second;
+ popTransactionFromPending(transactions, flushState, queue);
+ if (queue.empty()) {
+ it = mPendingTransactionQueues.erase(it);
+ }
+}
+
+void TransactionHandler::popTransactionFromPending(std::vector<TransactionState>& transactions,
+ TransactionFlushState& flushState,
+ std::queue<TransactionState>& queue) {
+ auto& transaction = queue.front();
+ // Transaction is ready move it from the pending queue.
+ flushState.firstTransaction = false;
+ removeFromStalledTransactions(transaction.id);
+ transactions.emplace_back(std::move(transaction));
+ queue.pop();
+
+ auto& readyToApplyTransaction = transactions.back();
+ readyToApplyTransaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
+ const bool frameNumberChanged =
+ state.bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
+ if (frameNumberChanged) {
+ flushState.bufferLayersReadyToPresent.emplace_or_replace(state.surface.get(),
+ state.bufferData->frameNumber);
+ } else {
+ // Barrier function only used for BBQ which always includes a frame number.
+ // This value only used for barrier logic.
+ flushState.bufferLayersReadyToPresent
+ .emplace_or_replace(state.surface.get(), std::numeric_limits<uint64_t>::max());
+ }
+ });
+}
+
TransactionHandler::TransactionReadiness TransactionHandler::applyFilters(
TransactionFlushState& flushState) {
auto ready = TransactionReadiness::Ready;
@@ -79,8 +129,7 @@
case TransactionReadiness::NotReadyBarrier:
return perFilterReady;
- case TransactionReadiness::ReadyUnsignaled:
- case TransactionReadiness::ReadyUnsignaledSingle:
+ case TransactionReadiness::NotReadyUnsignaled:
// If one of the filters allows latching an unsignaled buffer, latch this ready
// state.
ready = perFilterReady;
@@ -97,17 +146,7 @@
int transactionsPendingBarrier = 0;
auto it = mPendingTransactionQueues.begin();
while (it != mPendingTransactionQueues.end()) {
- auto& queue = it->second;
- IBinder* queueToken = it->first.get();
-
- // if we have already flushed a transaction with an unsignaled buffer then stop queue
- // processing
- if (std::find(flushState.queuesWithUnsignaledBuffers.begin(),
- flushState.queuesWithUnsignaledBuffers.end(),
- queueToken) != flushState.queuesWithUnsignaledBuffers.end()) {
- continue;
- }
-
+ auto& [applyToken, queue] = *it;
while (!queue.empty()) {
auto& transaction = queue.front();
flushState.transaction = &transaction;
@@ -117,38 +156,14 @@
break;
} else if (ready == TransactionReadiness::NotReady) {
break;
- }
-
- // Transaction is ready move it from the pending queue.
- flushState.firstTransaction = false;
- removeFromStalledTransactions(transaction.id);
- transactions.emplace_back(std::move(transaction));
- queue.pop();
-
- // If the buffer is unsignaled, then we don't want to signal other transactions using
- // the buffer as a barrier.
- auto& readyToApplyTransaction = transactions.back();
- if (ready == TransactionReadiness::Ready) {
- readyToApplyTransaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
- const bool frameNumberChanged = state.bufferData->flags.test(
- BufferData::BufferDataChange::frameNumberChanged);
- if (frameNumberChanged) {
- flushState.bufferLayersReadyToPresent
- .emplace_or_replace(state.surface.get(),
- state.bufferData->frameNumber);
- } else {
- // Barrier function only used for BBQ which always includes a frame number.
- // This value only used for barrier logic.
- flushState.bufferLayersReadyToPresent
- .emplace_or_replace(state.surface.get(),
- std::numeric_limits<uint64_t>::max());
- }
- });
- } else if (ready == TransactionReadiness::ReadyUnsignaledSingle) {
- // Track queues with a flushed unsingaled buffer.
- flushState.queuesWithUnsignaledBuffers.emplace_back(queueToken);
+ } else if (ready == TransactionReadiness::NotReadyUnsignaled) {
+ // We maybe able to latch this transaction if it's the only transaction
+ // ready to be applied.
+ flushState.queueWithUnsignaledBuffer = applyToken;
break;
}
+ // ready == TransactionReadiness::Ready
+ popTransactionFromPending(transactions, flushState, queue);
}
if (queue.empty()) {
diff --git a/services/surfaceflinger/FrontEnd/TransactionHandler.h b/services/surfaceflinger/FrontEnd/TransactionHandler.h
index 7fc825e..865835f 100644
--- a/services/surfaceflinger/FrontEnd/TransactionHandler.h
+++ b/services/surfaceflinger/FrontEnd/TransactionHandler.h
@@ -40,14 +40,20 @@
// Layer handles that have transactions with buffers that are ready to be applied.
ftl::SmallMap<IBinder* /* binder address */, uint64_t /* framenumber */, 15>
bufferLayersReadyToPresent = {};
- ftl::SmallVector<IBinder* /* queueToken */, 15> queuesWithUnsignaledBuffers;
+ // Tracks the queue with an unsignaled buffer. This is used to handle
+ // LatchUnsignaledConfig::AutoSingleLayer to ensure we only apply an unsignaled buffer
+ // if it's the only transaction that is ready to be applied.
+ sp<IBinder> queueWithUnsignaledBuffer = nullptr;
};
enum class TransactionReadiness {
- NotReady,
- NotReadyBarrier,
+ // Transaction is ready to be applied
Ready,
- ReadyUnsignaled,
- ReadyUnsignaledSingle,
+ // Transaction has unmet conditions (fence, present time, etc) and cannot be applied.
+ NotReady,
+ // Transaction is waiting on a barrier (another buffer to be latched first)
+ NotReadyBarrier,
+ // Transaction has an unsignaled fence but can be applied if it's the only transaction
+ NotReadyUnsignaled,
};
using TransactionFilter = std::function<TransactionReadiness(const TransactionFlushState&)>;
@@ -64,6 +70,9 @@
friend class ::android::TestableSurfaceFlinger;
int flushPendingTransactionQueues(std::vector<TransactionState>&, TransactionFlushState&);
+ void applyUnsignaledBufferTransaction(std::vector<TransactionState>&, TransactionFlushState&);
+ void popTransactionFromPending(std::vector<TransactionState>&, TransactionFlushState&,
+ std::queue<TransactionState>&);
TransactionReadiness applyFilters(TransactionFlushState&);
std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash>
mPendingTransactionQueues;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7d16aad..3406e92 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -75,6 +75,7 @@
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerHandle.h"
#include "LayerProtoHelper.h"
+#include "MutexUtils.h"
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
#include "TunnelModeEnabledReporter.h"
@@ -303,10 +304,12 @@
auto layersInTree = getRootLayer()->getLayersInTree(LayerVector::StateSet::Current);
std::sort(layersInTree.begin(), layersInTree.end());
- traverse(LayerVector::StateSet::Current, [&](Layer* layer) {
- layer->removeFromCurrentState();
- layer->removeRelativeZ(layersInTree);
- });
+ REQUIRE_MUTEX(mFlinger->mStateLock);
+ traverse(LayerVector::StateSet::Current,
+ [&](Layer* layer) REQUIRES(layer->mFlinger->mStateLock) {
+ layer->removeFromCurrentState();
+ layer->removeRelativeZ(layersInTree);
+ });
}
void Layer::addToCurrentState() {
@@ -641,8 +644,8 @@
snapshot->surfaceDamage = surfaceDamageRegion;
snapshot->hasProtectedContent = isProtected();
snapshot->dimmingEnabled = isDimmingEnabled();
- snapshot->currentSdrHdrRatio = getCurrentSdrHdrRatio();
- snapshot->desiredSdrHdrRatio = getDesiredSdrHdrRatio();
+ snapshot->currentHdrSdrRatio = getCurrentHdrSdrRatio();
+ snapshot->desiredHdrSdrRatio = getDesiredHdrSdrRatio();
snapshot->cachingHint = getCachingHint();
const bool usesRoundedCorners = hasRoundedCorners();
@@ -1007,10 +1010,12 @@
mFlinger->mLayersAdded = true;
// set up SF to handle added color layer
if (isRemovedFromCurrentState()) {
+ MUTEX_ALIAS(mFlinger->mStateLock, mDrawingState.bgColorLayer->mFlinger->mStateLock);
mDrawingState.bgColorLayer->onRemovedFromCurrentState();
}
mFlinger->setTransactionFlags(eTransactionNeeded);
} else if (mDrawingState.bgColorLayer && alpha == 0) {
+ MUTEX_ALIAS(mFlinger->mStateLock, mDrawingState.bgColorLayer->mFlinger->mStateLock);
mDrawingState.bgColorLayer->reparent(nullptr);
mDrawingState.bgColorLayer = nullptr;
return true;
@@ -2120,7 +2125,9 @@
writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
- writeCompositionStateToProto(layerProto);
+ ui::LayerStack layerStack =
+ (mSnapshot) ? mSnapshot->outputFilter.layerStack : ui::INVALID_LAYER_STACK;
+ writeCompositionStateToProto(layerProto, layerStack);
}
for (const sp<Layer>& layer : mDrawingChildren) {
@@ -2130,14 +2137,15 @@
return layerProto;
}
-void Layer::writeCompositionStateToProto(LayerProto* layerProto) {
+void Layer::writeCompositionStateToProto(LayerProto* layerProto, ui::LayerStack layerStack) {
ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread.
+ ftl::FakeGuard mainThreadGuard(kMainThreadContext);
// Only populate for the primary display.
- if (const auto display = mFlinger->getDefaultDisplayDeviceLocked()) {
+ if (const auto display = mFlinger->getDisplayFromLayerStack(layerStack)) {
const auto compositionType = getCompositionType(*display);
layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
- LayerProtoHelper::writeToProto(getVisibleRegion(display.get()),
+ LayerProtoHelper::writeToProto(getVisibleRegion(display),
[&]() { return layerProto->mutable_visible_region(); });
}
}
@@ -3142,11 +3150,11 @@
}
bool Layer::setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio) {
- if (mDrawingState.currentSdrHdrRatio == currentBufferRatio &&
- mDrawingState.desiredSdrHdrRatio == desiredRatio)
+ if (mDrawingState.currentHdrSdrRatio == currentBufferRatio &&
+ mDrawingState.desiredHdrSdrRatio == desiredRatio)
return false;
- mDrawingState.currentSdrHdrRatio = currentBufferRatio;
- mDrawingState.desiredSdrHdrRatio = desiredRatio;
+ mDrawingState.currentHdrSdrRatio = currentBufferRatio;
+ mDrawingState.desiredHdrSdrRatio = desiredRatio;
mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -3437,8 +3445,8 @@
if (lastDataspace != mBufferInfo.mDataspace) {
mFlinger->mHdrLayerInfoChanged = true;
}
- if (mBufferInfo.mDesiredSdrHdrRatio != mDrawingState.desiredSdrHdrRatio) {
- mBufferInfo.mDesiredSdrHdrRatio = mDrawingState.desiredSdrHdrRatio;
+ if (mBufferInfo.mDesiredHdrSdrRatio != mDrawingState.desiredHdrSdrRatio) {
+ mBufferInfo.mDesiredHdrSdrRatio = mDrawingState.desiredHdrSdrRatio;
mFlinger->mHdrLayerInfoChanged = true;
}
mBufferInfo.mCrop = computeBufferCrop(mDrawingState);
@@ -3724,9 +3732,9 @@
}
if (s.what & layer_state_t::eExtendedRangeBrightnessChanged) {
- if (mDrawingState.currentSdrHdrRatio != s.currentSdrHdrRatio ||
- mDrawingState.desiredSdrHdrRatio != s.desiredSdrHdrRatio) {
- ALOGV("%s: false [eDimmingEnabledChanged changed]", __func__);
+ if (mDrawingState.currentHdrSdrRatio != s.currentHdrSdrRatio ||
+ mDrawingState.desiredHdrSdrRatio != s.desiredHdrSdrRatio) {
+ ALOGV("%s: false [eExtendedRangeBrightnessChanged changed]", __func__);
return false;
}
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 429df37..70b4e9b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -224,8 +224,8 @@
gui::DropInputMode dropInputMode;
bool autoRefresh = false;
bool dimmingEnabled = true;
- float currentSdrHdrRatio = 1.f;
- float desiredSdrHdrRatio = 1.f;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
int64_t latchedVsyncId = 0;
};
@@ -289,14 +289,14 @@
virtual bool setMetadata(const LayerMetadata& data);
virtual void setChildrenDrawingParent(const sp<Layer>&);
- virtual bool reparent(const sp<IBinder>& newParentHandle);
+ virtual bool reparent(const sp<IBinder>& newParentHandle) REQUIRES(mFlinger->mStateLock);
virtual bool setColorTransform(const mat4& matrix);
virtual mat4 getColorTransform() const;
virtual bool hasColorTransform() const;
virtual bool isColorSpaceAgnostic() const { return mDrawingState.colorSpaceAgnostic; }
virtual bool isDimmingEnabled() const { return getDrawingState().dimmingEnabled; }
- float getDesiredSdrHdrRatio() const { return getDrawingState().desiredSdrHdrRatio; }
- float getCurrentSdrHdrRatio() const { return getDrawingState().currentSdrHdrRatio; }
+ float getDesiredHdrSdrRatio() const { return getDrawingState().desiredHdrSdrRatio; }
+ float getCurrentHdrSdrRatio() const { return getDrawingState().currentHdrSdrRatio; }
gui::CachingHint getCachingHint() const { return getDrawingState().cachingHint; }
bool setTransform(uint32_t /*transform*/);
@@ -315,7 +315,8 @@
bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/);
bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/,
bool willPresent);
- virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
+ virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace)
+ REQUIRES(mFlinger->mStateLock);
virtual bool setColorSpaceAgnostic(const bool agnostic);
virtual bool setDimmingEnabled(const bool dimmingEnabled);
virtual bool setDefaultFrameRateCompatibility(FrameRateCompatibility compatibility);
@@ -515,7 +516,7 @@
uint64_t mFrameNumber;
bool mFrameLatencyNeeded{false};
- float mDesiredSdrHdrRatio = 1.f;
+ float mDesiredHdrSdrRatio = 1.f;
};
BufferInfo mBufferInfo;
@@ -608,7 +609,7 @@
bool isRemovedFromCurrentState() const;
LayerProto* writeToProto(LayersProto& layersProto, uint32_t traceFlags);
- void writeCompositionStateToProto(LayerProto* layerProto);
+ void writeCompositionStateToProto(LayerProto* layerProto, ui::LayerStack layerStack);
// Write states that are modified by the main thread. This includes drawing
// state as well as buffer data. This should be called in the main or tracing
@@ -639,13 +640,13 @@
/*
* Remove from current state and mark for removal.
*/
- void removeFromCurrentState();
+ void removeFromCurrentState() REQUIRES(mFlinger->mStateLock);
/*
* called with the state lock from a binder thread when the layer is
* removed from the current list to the pending removal list
*/
- void onRemovedFromCurrentState();
+ void onRemovedFromCurrentState() REQUIRES(mFlinger->mStateLock);
/*
* Called when the layer is added back to the current state list.
@@ -878,6 +879,9 @@
mTransformHint = transformHint;
}
+ // Exposed so SurfaceFlinger can assert that it's held
+ const sp<SurfaceFlinger> mFlinger;
+
protected:
// For unit tests
friend class TestableSurfaceFlinger;
@@ -939,9 +943,6 @@
*/
std::pair<FloatRect, bool> getInputBounds(bool fillParentBounds) const;
- // constant
- sp<SurfaceFlinger> mFlinger;
-
bool mPremultipliedAlpha{true};
const std::string mName;
const std::string mTransactionName{"TX - " + mName};
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index b5ae1a7..5d92485 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -332,7 +332,7 @@
if (mTraceFlags & LayerTracing::TRACE_COMPOSITION) {
auto it = mLegacyLayers.find(layer.id);
if (it != mLegacyLayers.end()) {
- it->second->writeCompositionStateToProto(layerProto);
+ it->second->writeCompositionStateToProto(layerProto, snapshot->outputFilter.layerStack);
}
}
diff --git a/services/surfaceflinger/MutexUtils.h b/services/surfaceflinger/MutexUtils.h
index f8be6f3..58f7cb4 100644
--- a/services/surfaceflinger/MutexUtils.h
+++ b/services/surfaceflinger/MutexUtils.h
@@ -50,4 +50,14 @@
const status_t status;
};
+// Require, under penalty of compilation failure, that the compiler thinks that a mutex is held.
+#define REQUIRE_MUTEX(expr) ([]() REQUIRES(expr) {})()
+
+// Tell the compiler that we know that a mutex is held.
+#define ASSERT_MUTEX(expr) ([]() ASSERT_CAPABILITY(expr) {})()
+
+// Specify that one mutex is an alias for another.
+// (e.g. SurfaceFlinger::mStateLock and Layer::mFlinger->mStateLock)
+#define MUTEX_ALIAS(held, alias) (REQUIRE_MUTEX(held), ASSERT_MUTEX(alias))
+
} // namespace android
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 327ca3f..531d277 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -347,7 +347,8 @@
}
visitor(layer);
};
- mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
+ mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {},
+ filterVisitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 57661f1..74665a7 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -525,7 +525,7 @@
bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
const sp<EventThreadConnection>& connection) const {
- const auto throttleVsync = [&] {
+ const auto throttleVsync = [&]() REQUIRES(mMutex) {
const auto& vsyncData = event.vsync.vsyncData;
if (connection->frameRate.isValid()) {
return !mVsyncSchedule->getTracker()
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 87e20a0..30869e9 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -205,7 +205,7 @@
TracedOrdinal<int> mVsyncTracer;
TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex);
- std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule;
+ std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule GUARDED_BY(mMutex);
TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now();
scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex);
frametimeline::TokenManager* const mTokenManager;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 7457b84..18c0a69 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -78,20 +78,42 @@
void MessageQueue::initVsync(std::shared_ptr<scheduler::VSyncDispatch> dispatch,
frametimeline::TokenManager& tokenManager,
std::chrono::nanoseconds workDuration) {
- std::lock_guard lock(mVsync.mutex);
- mVsync.workDuration = workDuration;
- mVsync.tokenManager = &tokenManager;
- onNewVsyncScheduleLocked(std::move(dispatch));
+ std::unique_ptr<scheduler::VSyncCallbackRegistration> oldRegistration;
+ {
+ std::lock_guard lock(mVsync.mutex);
+ mVsync.workDuration = workDuration;
+ mVsync.tokenManager = &tokenManager;
+ oldRegistration = onNewVsyncScheduleLocked(std::move(dispatch));
+ }
+
+ // See comments in onNewVsyncSchedule. Today, oldRegistration should be
+ // empty, but nothing prevents us from calling initVsync multiple times, so
+ // go ahead and destruct it outside the lock for safety.
+ oldRegistration.reset();
}
void MessageQueue::onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
- std::lock_guard lock(mVsync.mutex);
- onNewVsyncScheduleLocked(std::move(dispatch));
+ std::unique_ptr<scheduler::VSyncCallbackRegistration> oldRegistration;
+ {
+ std::lock_guard lock(mVsync.mutex);
+ oldRegistration = onNewVsyncScheduleLocked(std::move(dispatch));
+ }
+
+ // The old registration needs to be deleted after releasing mVsync.mutex to
+ // avoid deadlock. This is because the callback may be running on the timer
+ // thread. In that case, timerCallback sets
+ // VSyncDispatchTimerQueueEntry::mRunning to true, then attempts to lock
+ // mVsync.mutex. But if it's already locked, the VSyncCallbackRegistration's
+ // destructor has to wait until VSyncDispatchTimerQueueEntry::mRunning is
+ // set back to false, but it won't be until mVsync.mutex is released.
+ oldRegistration.reset();
}
-void MessageQueue::onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
+std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncScheduleLocked(
+ std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
const bool reschedule = mVsync.registration &&
mVsync.registration->cancel() == scheduler::CancelResult::Cancelled;
+ auto oldRegistration = std::move(mVsync.registration);
mVsync.registration = std::make_unique<
scheduler::VSyncCallbackRegistration>(std::move(dispatch),
std::bind(&MessageQueue::vsyncCallback, this,
@@ -105,6 +127,7 @@
.readyDuration = 0,
.earliestVsync = mVsync.lastCallbackTime.ns()});
}
+ return oldRegistration;
}
void MessageQueue::destroyVsync() {
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 9c9b2f3..a523147 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -117,9 +117,9 @@
struct Vsync {
frametimeline::TokenManager* tokenManager = nullptr;
- std::unique_ptr<scheduler::VSyncCallbackRegistration> registration;
mutable std::mutex mutex;
+ std::unique_ptr<scheduler::VSyncCallbackRegistration> registration GUARDED_BY(mutex);
TracedOrdinal<std::chrono::nanoseconds> workDuration
GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
TimePoint lastCallbackTime GUARDED_BY(mutex);
@@ -129,7 +129,10 @@
Vsync mVsync;
- void onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex);
+ // Returns the old registration so it can be destructed outside the lock to
+ // avoid deadlock.
+ std::unique_ptr<scheduler::VSyncCallbackRegistration> onNewVsyncScheduleLocked(
+ std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex);
public:
explicit MessageQueue(ICompositor&);
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index eec7c08..f136e9f 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -564,7 +564,7 @@
continue;
}
- const bool inPrimaryRange = policy->primaryRanges.physical.includes(modePtr->getFps());
+ const bool inPrimaryRange = policy->primaryRanges.render.includes(fps);
if ((primaryRangeIsSingleRate || !inPrimaryRange) &&
!(layer.focused &&
(layer.vote == LayerVoteType::ExplicitDefault ||
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index f18dfdc..3e12db6 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -109,7 +109,6 @@
void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
demotePacesetterDisplay();
- std::scoped_lock lock(mDisplayLock);
promotePacesetterDisplay(pacesetterIdOpt);
}
@@ -123,26 +122,34 @@
std::shared_ptr<VsyncSchedule> vsyncSchedule) {
demotePacesetterDisplay();
- std::scoped_lock lock(mDisplayLock);
- mRefreshRateSelectors.emplace_or_replace(displayId, std::move(selectorPtr));
- mVsyncSchedules.emplace_or_replace(displayId, std::move(vsyncSchedule));
+ std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
+ {
+ std::scoped_lock lock(mDisplayLock);
+ mRefreshRateSelectors.emplace_or_replace(displayId, std::move(selectorPtr));
+ mVsyncSchedules.emplace_or_replace(displayId, std::move(vsyncSchedule));
- promotePacesetterDisplay();
+ pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
+ }
+ applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
demotePacesetterDisplay();
- std::scoped_lock lock(mDisplayLock);
- mRefreshRateSelectors.erase(displayId);
- mVsyncSchedules.erase(displayId);
+ std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
+ {
+ std::scoped_lock lock(mDisplayLock);
+ mRefreshRateSelectors.erase(displayId);
+ mVsyncSchedules.erase(displayId);
- // Do not allow removing the final display. Code in the scheduler expects
- // there to be at least one display. (This may be relaxed in the future with
- // headless virtual display.)
- LOG_ALWAYS_FATAL_IF(mRefreshRateSelectors.empty(), "Cannot unregister all displays!");
+ // Do not allow removing the final display. Code in the scheduler expects
+ // there to be at least one display. (This may be relaxed in the future with
+ // headless virtual display.)
+ LOG_ALWAYS_FATAL_IF(mRefreshRateSelectors.empty(), "Cannot unregister all displays!");
- promotePacesetterDisplay();
+ pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
+ }
+ applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
void Scheduler::run() {
@@ -402,6 +409,7 @@
}
void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
+ ATRACE_CALL();
std::scoped_lock lock(mDisplayLock);
ftl::FakeGuard guard(kMainThreadContext);
@@ -678,6 +686,18 @@
}
void Scheduler::promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
+ std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
+
+ {
+ std::scoped_lock lock(mDisplayLock);
+ pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterIdOpt);
+ }
+
+ applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
+}
+
+std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
+ std::optional<PhysicalDisplayId> pacesetterIdOpt) {
// TODO(b/241286431): Choose the pacesetter display.
mPacesetterDisplayId = pacesetterIdOpt.value_or(mRefreshRateSelectors.begin()->first);
ALOGI("Display %s is the pacesetter", to_string(*mPacesetterDisplayId).c_str());
@@ -697,14 +717,22 @@
vsyncSchedule->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod(),
true /* force */);
}
+ return vsyncSchedule;
+}
+void Scheduler::applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule> vsyncSchedule) {
onNewVsyncSchedule(vsyncSchedule->getDispatch());
+ std::vector<android::EventThread*> threads;
{
std::lock_guard<std::mutex> lock(mConnectionsLock);
+ threads.reserve(mConnections.size());
for (auto& [_, connection] : mConnections) {
- connection.thread->onNewVsyncSchedule(vsyncSchedule);
+ threads.push_back(connection.thread.get());
}
}
+ for (auto* thread : threads) {
+ thread->onNewVsyncSchedule(vsyncSchedule);
+ }
}
void Scheduler::demotePacesetterDisplay() {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 74547d5..3423652 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -321,7 +321,18 @@
// Chooses a pacesetter among the registered displays, unless `pacesetterIdOpt` is specified.
// The new `mPacesetterDisplayId` is never `std::nullopt`.
void promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
+ REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+
+ // Changes to the displays (e.g. registering and unregistering) must be made
+ // while mDisplayLock is locked, and the new pacesetter then must be promoted while
+ // mDisplayLock is still locked. However, a new pacesetter means that
+ // MessageQueue and EventThread need to use the new pacesetter's
+ // VsyncSchedule, and this must happen while mDisplayLock is *not* locked,
+ // or else we may deadlock with EventThread.
+ std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(
+ std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
REQUIRES(kMainThreadContext, mDisplayLock);
+ void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);
// Blocks until the pacesetter's idle timer thread exits. `mDisplayLock` must not be locked by
// the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 076c683..2f024ce 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -478,10 +478,6 @@
mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
- // Power hint session mode, representing which hint(s) to send: early, late, or both)
- mPowerHintSessionMode =
- {.late = base::GetBoolProperty("debug.sf.send_late_power_session_hint"s, true),
- .early = base::GetBoolProperty("debug.sf.send_early_power_session_hint"s, false)};
mLayerLifecycleManagerEnabled =
base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, false);
mLegacyFrontEndEnabled = !mLayerLifecycleManagerEnabled ||
@@ -715,12 +711,12 @@
readPersistentProperties();
mPowerAdvisor->onBootFinished();
- const bool powerHintEnabled = mFlagManager.use_adpf_cpu_hint();
- mPowerAdvisor->enablePowerHint(powerHintEnabled);
- const bool powerHintUsed = mPowerAdvisor->usePowerHintSession();
+ const bool hintSessionEnabled = mFlagManager.use_adpf_cpu_hint();
+ mPowerAdvisor->enablePowerHintSession(hintSessionEnabled);
+ const bool hintSessionUsed = mPowerAdvisor->usePowerHintSession();
ALOGD("Power hint is %s",
- powerHintUsed ? "supported" : (powerHintEnabled ? "unsupported" : "disabled"));
- if (powerHintUsed) {
+ hintSessionUsed ? "supported" : (hintSessionEnabled ? "unsupported" : "disabled"));
+ if (hintSessionUsed) {
std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
std::vector<int32_t> tidList;
tidList.emplace_back(gettid());
@@ -2461,16 +2457,7 @@
mPowerAdvisor->setFrameDelay(frameDelay);
mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration);
-
- const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
- const Period vsyncPeriod = display->getActiveMode().fps.getPeriod();
- mPowerAdvisor->setTargetWorkDuration(vsyncPeriod);
-
- // Send early hint here to make sure there's not another frame pending
- if (mPowerHintSessionMode.early) {
- // Send a rough prediction for this frame based on last frame's timing info
- mPowerAdvisor->sendPredictedWorkDuration();
- }
+ mPowerAdvisor->updateTargetWorkDuration(vsyncPeriod);
}
if (mRefreshRateOverlaySpinner) {
@@ -2623,8 +2610,21 @@
const auto prevVsyncTime = mExpectedPresentTime - mScheduler->getVsyncSchedule()->period();
const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
- refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
- refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime;
+ const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
+ const bool threeVsyncsAhead = mExpectedPresentTime - frameTime > 2 * vsyncPeriod;
+
+ // We should wait for the earliest present time if HWC doesn't support ExpectedPresentTime,
+ // and the next vsync is not already taken by the previous frame.
+ const bool waitForEarliestPresent =
+ !getHwComposer().getComposer()->isSupported(
+ Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
+ (threeVsyncsAhead ||
+ mPreviousPresentFences[0].fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING);
+
+ if (waitForEarliestPresent) {
+ refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
+ }
+
refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
refreshArgs.expectedPresentTime = mExpectedPresentTime.ns();
refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;
@@ -2658,9 +2658,7 @@
mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(mPreviousPresentFences[0]
.fenceTime->getSignalTime()),
TimePoint::now());
- if (mPowerHintSessionMode.late) {
- mPowerAdvisor->sendActualWorkDuration();
- }
+ mPowerAdvisor->reportActualWorkDuration();
}
if (mScheduler->onPostComposition(presentTime)) {
@@ -2763,7 +2761,7 @@
// RANGE_EXTENDED layers may identify themselves as being "HDR" via a desired sdr/hdr ratio
if ((snapshot.dataspace & (int32_t)Dataspace::RANGE_MASK) ==
(int32_t)Dataspace::RANGE_EXTENDED &&
- snapshot.desiredSdrHdrRatio > 1.01f) {
+ snapshot.desiredHdrSdrRatio > 1.01f) {
return true;
}
return false;
@@ -2900,11 +2898,9 @@
const auto* outputLayer =
compositionDisplay->getOutputLayerForLayer(layerFe);
if (outputLayer) {
- // TODO(b/267350616): Rename SdrHdrRatio -> HdrSdrRatio
- // everywhere
- const float desiredHdrSdrRatio = snapshot.desiredSdrHdrRatio <= 1.f
+ const float desiredHdrSdrRatio = snapshot.desiredHdrSdrRatio <= 1.f
? std::numeric_limits<float>::infinity()
- : snapshot.desiredSdrHdrRatio;
+ : snapshot.desiredHdrSdrRatio;
info.mergeDesiredRatio(desiredHdrSdrRatio);
info.numberOfHdrLayers++;
const auto displayFrame = outputLayer->getState().displayFrame;
@@ -3725,11 +3721,8 @@
ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
if (updateWindowInfo) {
mWindowInfosListenerInvoker
- ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
- std::move(
- inputWindowCommands.windowInfosReportedListeners),
- /* forceImmediateCall= */
- !inputWindowCommands.focusRequests.empty());
+ ->windowInfosChanged(windowInfos, displayInfos,
+ inputWindowCommands.windowInfosReportedListeners);
} else {
// If there are listeners but no changes to input windows, call the listeners
// immediately.
@@ -4269,20 +4262,23 @@
return TraverseBuffersReturnValues::STOP_TRAVERSAL;
}
- // check fence status
- const bool allowLatchUnsignaled = shouldLatchUnsignaled(layer, s, transaction.states.size(),
- flushState.firstTransaction);
- ATRACE_FORMAT("%s allowLatchUnsignaled=%s", layer->getName().c_str(),
- allowLatchUnsignaled ? "true" : "false");
-
- const bool acquireFenceChanged = s.bufferData &&
+ // ignore the acquire fence if LatchUnsignaledConfig::Always is set.
+ const bool checkAcquireFence = enableLatchUnsignaledConfig != LatchUnsignaledConfig::Always;
+ const bool acquireFenceAvailable = s.bufferData &&
s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
s.bufferData->acquireFence;
- const bool fenceSignaled =
- (!acquireFenceChanged ||
- s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled);
+ const bool fenceSignaled = !checkAcquireFence || !acquireFenceAvailable ||
+ s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
if (!fenceSignaled) {
- if (!allowLatchUnsignaled) {
+ // check fence status
+ const bool allowLatchUnsignaled =
+ shouldLatchUnsignaled(layer, s, transaction.states.size(),
+ flushState.firstTransaction);
+ ATRACE_FORMAT("%s allowLatchUnsignaled=%s", layer->getName().c_str(),
+ allowLatchUnsignaled ? "true" : "false");
+ if (allowLatchUnsignaled) {
+ ready = TransactionReadiness::NotReadyUnsignaled;
+ } else {
ready = TransactionReadiness::NotReady;
auto& listener = s.bufferData->releaseBufferListener;
if (listener &&
@@ -4295,10 +4291,6 @@
}
return TraverseBuffersReturnValues::STOP_TRAVERSAL;
}
-
- ready = enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer
- ? TransactionReadiness::ReadyUnsignaledSingle
- : TransactionReadiness::ReadyUnsignaled;
}
return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL;
});
@@ -4762,6 +4754,7 @@
}
return 0;
}
+ MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock);
ui::LayerStack oldLayerStack = layer->getLayerStack(LayerVector::StateSet::Current);
@@ -4962,7 +4955,7 @@
if (layer->setDimmingEnabled(s.dimmingEnabled)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eExtendedRangeBrightnessChanged) {
- if (layer->setExtendedRangeBrightness(s.currentSdrHdrRatio, s.desiredSdrHdrRatio)) {
+ if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) {
flags |= eTraversalNeeded;
}
}
@@ -6888,6 +6881,7 @@
wp<const DisplayDevice> displayWeak;
ui::LayerStack layerStack;
ui::Size reqSize(args.width, args.height);
+ std::unordered_set<uint32_t> excludeLayerIds;
ui::Dataspace dataspace;
{
Mutex::Autolock lock(mStateLock);
@@ -6901,6 +6895,16 @@
reqSize = display->getLayerStackSpaceRect().getSize();
}
+ for (const auto& handle : args.excludeHandles) {
+ uint32_t excludeLayer = LayerHandle::getLayerId(handle);
+ if (excludeLayer != UNASSIGNED_LAYER_ID) {
+ excludeLayerIds.emplace(excludeLayer);
+ } else {
+ ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay");
+ return NAME_NOT_FOUND;
+ }
+ }
+
// Allow the caller to specify a dataspace regardless of the display's color mode, e.g. if
// it wants sRGB regardless of the display's wide color mode.
dataspace = args.dataspace == ui::Dataspace::UNKNOWN
@@ -6916,10 +6920,11 @@
GetLayerSnapshotsFunction getLayerSnapshots;
if (mLayerLifecycleManagerEnabled) {
getLayerSnapshots =
- getLayerSnapshotsForScreenshots(layerStack, args.uid, /*snapshotFilterFn=*/nullptr);
+ getLayerSnapshotsForScreenshots(layerStack, args.uid, std::move(excludeLayerIds));
} else {
- auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
- traverseLayersInLayerStack(layerStack, args.uid, visitor);
+ auto traverseLayers = [this, args, excludeLayerIds,
+ layerStack](const LayerVector::Visitor& visitor) {
+ traverseLayersInLayerStack(layerStack, args.uid, std::move(excludeLayerIds), visitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
@@ -6962,7 +6967,7 @@
/*snapshotFilterFn=*/nullptr);
} else {
auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
- traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
+ traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {}, visitor);
};
getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
}
@@ -7386,6 +7391,7 @@
}
void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
const LayerVector::Visitor& visitor) {
// We loop through the first level of layers without traversing,
// as we need to determine which layers belong to the requested display.
@@ -7404,6 +7410,17 @@
if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) {
return;
}
+
+ if (!excludeLayerIds.empty()) {
+ auto p = sp<Layer>::fromExisting(layer);
+ while (p != nullptr) {
+ if (excludeLayerIds.count(p->sequence) != 0) {
+ return;
+ }
+ p = p->getParent();
+ }
+ }
+
visitor(layer);
});
}
@@ -7732,6 +7749,7 @@
ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get());
return;
}
+ MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock);
sp<Layer> parent;
bool addToRoot = state.addToRoot;
@@ -7906,9 +7924,15 @@
ISurfaceComposerClient::eNoColorFill,
gui::LayerMetadata());
sp<Layer> childMirror;
- createEffectLayer(mirrorArgs, &unused, &childMirror);
- childMirror->setClonedChild(layer->createClone());
- childMirror->reparent(mirrorDisplay.rootHandle);
+ {
+ Mutex::Autolock lock(mStateLock);
+ createEffectLayer(mirrorArgs, &unused, &childMirror);
+ MUTEX_ALIAS(mStateLock, childMirror->mFlinger->mStateLock);
+ childMirror->setClonedChild(layer->createClone());
+ childMirror->reparent(mirrorDisplay.rootHandle);
+ }
+ // lock on mStateLock needs to be released before binder handle gets destroyed
+ unused.clear();
}
}
return true;
@@ -8059,6 +8083,44 @@
}
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
+SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
+ uint32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds) {
+ return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() {
+ if (excludeLayerIds.empty()) {
+ auto getLayerSnapshotsFn =
+ getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
+ return layers;
+ }
+
+ frontend::LayerSnapshotBuilder::Args
+ args{.root = mLayerHierarchyBuilder.getHierarchy(),
+ .layerLifecycleManager = mLayerLifecycleManager,
+ .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY,
+ .displays = mFrontEndDisplayInfos,
+ .displayChanges = true,
+ .globalShadowSettings = mDrawingState.globalShadowSettings,
+ .supportsBlur = mSupportsBlur,
+ .forceFullDamage = mForceFullDamage,
+ .excludeLayerIds = std::move(excludeLayerIds),
+ .supportedLayerGenericMetadata =
+ getHwComposer().getSupportedLayerGenericMetadata(),
+ .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap()};
+ mLayerSnapshotBuilder.update(args);
+
+ auto getLayerSnapshotsFn =
+ getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr);
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
+
+ args.excludeLayerIds.clear();
+ mLayerSnapshotBuilder.update(args);
+
+ return layers;
+ };
+}
+
+std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid,
std::unordered_set<uint32_t> excludeLayerIds,
bool childrenOnly,
@@ -8906,6 +8968,15 @@
static_cast<void>(mScheduler->scheduleDelayed([&]() { scheduleRepaint(); }, ms2ns(delayInMs)));
}
+const DisplayDevice* SurfaceFlinger::getDisplayFromLayerStack(ui::LayerStack layerStack) {
+ for (const auto& [_, display] : mDisplays) {
+ if (display->getLayerStack() == layerStack) {
+ return display.get();
+ }
+ }
+ return nullptr;
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 74d00dd..5783c8d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -174,10 +174,15 @@
// Latch unsignaled is permitted when a single layer is updated in a frame,
// and the update includes just a buffer update (i.e. no sync transactions
// or geometry changes).
+ // Latch unsignaled is also only permitted when a single transaction is ready
+ // to be applied. If we pass an unsignaled fence to HWC, HWC might miss presenting
+ // the frame if the fence does not fire in time. If we apply another transaction,
+ // we may penalize the other transaction unfairly.
AutoSingleLayer,
// All buffers are latched unsignaled. This behaviour is discouraged as it
// can break sync transactions, stall the display and cause undesired side effects.
+ // This is equivalent to ignoring the acquire fence when applying transactions.
Always,
};
@@ -323,6 +328,8 @@
bool mIgnoreHwcPhysicalDisplayOrientation = false;
void forceFutureUpdate(int delayInMs);
+ const DisplayDevice* getDisplayFromLayerStack(ui::LayerStack)
+ REQUIRES(mStateLock, kMainThreadContext);
protected:
// We're reference counted, never destroy SurfaceFlinger directly
@@ -797,7 +804,7 @@
status_t mirrorDisplay(DisplayId displayId, const LayerCreationArgs& args,
gui::CreateSurfaceResult& outResult);
- void markLayerPendingRemovalLocked(const sp<Layer>& layer);
+ void markLayerPendingRemovalLocked(const sp<Layer>& layer) REQUIRES(mStateLock);
// add a layer to SurfaceFlinger
status_t addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
@@ -826,7 +833,9 @@
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
// matching ownerUid
- void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, const LayerVector::Visitor&);
+ void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
+ const LayerVector::Visitor&);
void readPersistentProperties();
@@ -1381,6 +1390,9 @@
std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
snapshotFilterFn);
std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
+ std::optional<ui::LayerStack> layerStack, uint32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds);
+ std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds,
bool childrenOnly, const std::optional<FloatRect>& optionalParentCrop);
@@ -1408,10 +1420,6 @@
// These classes do not store any client state but help with managing transaction callbacks
// and stats.
std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers;
- struct {
- bool late = false;
- bool early = false;
- } mPowerHintSessionMode;
TransactionHandler mTransactionHandler;
display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos;
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index a64a9af..57d927b 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -586,7 +586,7 @@
displayInfo.receivesInput = proto.receives_input();
displayInfo.isSecure = proto.is_secure();
displayInfo.isPrimary = proto.is_primary();
- displayInfo.isPrimary = proto.is_virtual();
+ displayInfo.isVirtual = proto.is_virtual();
displayInfo.rotationFlags = (ui::Transform::RotationFlags)proto.rotation_flags();
displayInfo.transformHint = (ui::Transform::RotationFlags)proto.transform_hint();
return displayInfo;
@@ -594,7 +594,7 @@
void TransactionProtoParser::fromProto(
const google::protobuf::RepeatedPtrField<proto::DisplayInfo>& proto,
- display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos) {
+ display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos) {
outDisplayInfos.clear();
for (const proto::DisplayInfo& displayInfo : proto) {
outDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(displayInfo.layer_stack()),
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.h b/services/surfaceflinger/Tracing/TransactionProtoParser.h
index 50944fc..d6c98e1 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.h
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.h
@@ -49,15 +49,16 @@
proto::TransactionState toProto(const std::map<uint32_t /* layerId */, TracingLayerState>&);
proto::LayerCreationArgs toProto(const LayerCreationArgs& args);
proto::LayerState toProto(const ResolvedComposerState&);
- proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack);
+ static proto::DisplayInfo toProto(const frontend::DisplayInfo&, uint32_t layerStack);
TransactionState fromProto(const proto::TransactionState&);
void mergeFromProto(const proto::LayerState&, TracingLayerState& outState);
void fromProto(const proto::LayerCreationArgs&, LayerCreationArgs& outArgs);
std::unique_ptr<FlingerDataMapper> mMapper;
- frontend::DisplayInfo fromProto(const proto::DisplayInfo&);
- void fromProto(const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&,
- display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> outDisplayInfos);
+ static frontend::DisplayInfo fromProto(const proto::DisplayInfo&);
+ static void fromProto(
+ const google::protobuf::RepeatedPtrField<proto::DisplayInfo>&,
+ display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& outDisplayInfos);
private:
proto::DisplayState toProto(const DisplayState&);
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp
index 26ed878..87a633f 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.cpp
+++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp
@@ -271,6 +271,7 @@
for (const proto::LayerState& layerState : transaction.layer_changes()) {
auto it = mStartingStates.find(layerState.layer_id());
if (it == mStartingStates.end()) {
+ // TODO(b/238781169) make this log fatal when we switch over to using new fe
ALOGW("Could not find layer id %d", layerState.layer_id());
continue;
}
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 0ea421b..55004c5 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -14,14 +14,6 @@
* limitations under the License.
*/
-#include <ios>
-#include <memory>
-#include <vector>
-#include "FrontEnd/LayerCreationArgs.h"
-#include "FrontEnd/RequestedLayerState.h"
-#include "Tracing/LayerTracing.h"
-#include "TransactionState.h"
-#include "cutils/properties.h"
#undef LOG_TAG
#define LOG_TAG "LayerTraceGenerator"
//#define LOG_NDEBUG 0
@@ -33,8 +25,15 @@
#include <utils/String16.h>
#include <filesystem>
#include <fstream>
+#include <ios>
#include <string>
+#include <vector>
+#include "FrontEnd/LayerCreationArgs.h"
+#include "FrontEnd/RequestedLayerState.h"
#include "LayerProtoHelper.h"
+#include "Tracing/LayerTracing.h"
+#include "TransactionState.h"
+#include "cutils/properties.h"
#include "LayerTraceGenerator.h"
@@ -84,6 +83,7 @@
for (int j = 0; j < entry.added_layers_size(); j++) {
LayerCreationArgs args;
parser.fromProto(entry.added_layers(j), args);
+ ALOGV(" %s", args.getDebugString().c_str());
addedLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args));
}
@@ -92,12 +92,27 @@
for (int j = 0; j < entry.transactions_size(); j++) {
// apply transactions
TransactionState transaction = parser.fromProto(entry.transactions(j));
+ for (auto& resolvedComposerState : transaction.states) {
+ if (resolvedComposerState.state.what & layer_state_t::eInputInfoChanged) {
+ if (!resolvedComposerState.state.windowInfoHandle->getInfo()->inputConfig.test(
+ gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
+ // create a fake token since the FE expects a valid token
+ resolvedComposerState.state.windowInfoHandle->editInfo()->token =
+ sp<BBinder>::make();
+ }
+ }
+ }
transactions.emplace_back(std::move(transaction));
}
+ for (int j = 0; j < entry.destroyed_layers_size(); j++) {
+ ALOGV(" destroyedHandles=%d", entry.destroyed_layers(j));
+ }
+
std::vector<uint32_t> destroyedHandles;
destroyedHandles.reserve((size_t)entry.destroyed_layer_handles_size());
for (int j = 0; j < entry.destroyed_layer_handles_size(); j++) {
+ ALOGV(" destroyedHandles=%d", entry.destroyed_layer_handles(j));
destroyedHandles.push_back(entry.destroyed_layer_handles(j));
}
@@ -108,7 +123,7 @@
// apply updates
lifecycleManager.addLayers(std::move(addedLayers));
- lifecycleManager.applyTransactions(transactions);
+ lifecycleManager.applyTransactions(transactions, /*ignoreUnknownHandles=*/true);
lifecycleManager.onHandlesDestroyed(destroyedHandles, /*ignoreUnknownHandles=*/true);
if (lifecycleManager.getGlobalChanges().test(
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
index 73a7cae..292083b 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
@@ -25,14 +25,20 @@
using gui::IWindowInfosListener;
using gui::WindowInfo;
-struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener,
- IBinder::DeathRecipient {
- WindowInfosReportedListenerInvoker(size_t callbackCount,
- WindowInfosReportedListenerSet windowInfosReportedListeners)
+struct WindowInfosListenerInvoker::WindowInfosReportedListener : gui::BnWindowInfosReportedListener,
+ DeathRecipient {
+ explicit WindowInfosReportedListener(
+ size_t callbackCount,
+ const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ SpHash<gui::IWindowInfosReportedListener>>&
+ windowInfosReportedListeners)
: mCallbacksPending(callbackCount),
- mWindowInfosReportedListeners(std::move(windowInfosReportedListeners)) {}
+ mWindowInfosReportedListeners(windowInfosReportedListeners) {}
binder::Status onWindowInfosReported() override {
+ // TODO(b/222421815) There could potentially be callbacks that we don't need to wait for
+ // before calling the WindowInfosReportedListeners coming from InputWindowCommands. Filter
+ // the list of callbacks down to those from system server.
if (--mCallbacksPending == 0) {
for (const auto& listener : mWindowInfosReportedListeners) {
sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -48,7 +54,9 @@
private:
std::atomic<size_t> mCallbacksPending;
- WindowInfosReportedListenerSet mWindowInfosReportedListeners;
+ std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ SpHash<gui::IWindowInfosReportedListener>>
+ mWindowInfosReportedListeners;
};
void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
@@ -74,76 +82,38 @@
}
void WindowInfosListenerInvoker::windowInfosChanged(
- std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
- WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall) {
- reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
- auto callListeners = [this, windowInfos = std::move(windowInfos),
- displayInfos = std::move(displayInfos),
- reportedListeners = std::move(reportedListeners)]() mutable {
- ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
- {
- std::scoped_lock lock(mListenersMutex);
- for (const auto& [_, listener] : mWindowInfosListeners) {
- windowInfosListeners.push_back(listener);
- }
- }
-
- auto reportedInvoker =
- sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners.size(),
- std::move(reportedListeners));
-
- for (const auto& listener : windowInfosListeners) {
- sp<IBinder> asBinder = IInterface::asBinder(listener);
-
- // linkToDeath is used here to ensure that the windowInfosReportedListeners
- // are called even if one of the windowInfosListeners dies before
- // calling onWindowInfosReported.
- asBinder->linkToDeath(reportedInvoker);
-
- auto status =
- listener->onWindowInfosChanged(windowInfos, displayInfos, reportedInvoker);
- if (!status.isOk()) {
- reportedInvoker->onWindowInfosReported();
- }
- }
- };
-
+ const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos,
+ const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ SpHash<gui::IWindowInfosReportedListener>>&
+ windowInfosReportedListeners) {
+ ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
{
- std::scoped_lock lock(mMessagesMutex);
- // If there are unacked messages and this isn't a forced call, then return immediately.
- // If a forced window infos change doesn't happen first, the update will be sent after
- // the WindowInfosReportedListeners are called. If a forced window infos change happens or
- // if there are subsequent delayed messages before this update is sent, then this message
- // will be dropped and the listeners will only be called with the latest info. This is done
- // to reduce the amount of binder memory used.
- if (mActiveMessageCount > 0 && !forceImmediateCall) {
- mWindowInfosChangedDelayed = std::move(callListeners);
- return;
+ std::scoped_lock lock(mListenersMutex);
+ for (const auto& [_, listener] : mWindowInfosListeners) {
+ windowInfosListeners.push_back(listener);
}
-
- mWindowInfosChangedDelayed = nullptr;
- mActiveMessageCount++;
- }
- callListeners();
-}
-
-binder::Status WindowInfosListenerInvoker::onWindowInfosReported() {
- std::function<void()> callListeners;
-
- {
- std::scoped_lock lock{mMessagesMutex};
- mActiveMessageCount--;
- if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
- return binder::Status::ok();
- }
-
- mActiveMessageCount++;
- callListeners = std::move(mWindowInfosChangedDelayed);
- mWindowInfosChangedDelayed = nullptr;
}
- callListeners();
- return binder::Status::ok();
+ auto windowInfosReportedListener = windowInfosReportedListeners.empty()
+ ? nullptr
+ : sp<WindowInfosReportedListener>::make(windowInfosListeners.size(),
+ windowInfosReportedListeners);
+ for (const auto& listener : windowInfosListeners) {
+ sp<IBinder> asBinder = IInterface::asBinder(listener);
+
+ // linkToDeath is used here to ensure that the windowInfosReportedListeners
+ // are called even if one of the windowInfosListeners dies before
+ // calling onWindowInfosReported.
+ if (windowInfosReportedListener) {
+ asBinder->linkToDeath(windowInfosReportedListener);
+ }
+
+ auto status = listener->onWindowInfosChanged(windowInfos, displayInfos,
+ windowInfosReportedListener);
+ if (windowInfosReportedListener && !status.isOk()) {
+ windowInfosReportedListener->onWindowInfosReported();
+ }
+ }
}
} // namespace android
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h
index bfe036e..d60a9c4 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.h
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.h
@@ -23,40 +23,34 @@
#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <ftl/small_map.h>
-#include <gui/SpHash.h>
#include <utils/Mutex.h>
namespace android {
-using WindowInfosReportedListenerSet =
- std::unordered_set<sp<gui::IWindowInfosReportedListener>,
- gui::SpHash<gui::IWindowInfosReportedListener>>;
+class SurfaceFlinger;
-class WindowInfosListenerInvoker : public gui::BnWindowInfosReportedListener,
- public IBinder::DeathRecipient {
+class WindowInfosListenerInvoker : public IBinder::DeathRecipient {
public:
void addWindowInfosListener(sp<gui::IWindowInfosListener>);
void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);
- void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>,
- WindowInfosReportedListenerSet windowInfosReportedListeners,
- bool forceImmediateCall);
-
- binder::Status onWindowInfosReported() override;
+ void windowInfosChanged(const std::vector<gui::WindowInfo>&,
+ const std::vector<gui::DisplayInfo>&,
+ const std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ SpHash<gui::IWindowInfosReportedListener>>&
+ windowInfosReportedListeners);
protected:
void binderDied(const wp<IBinder>& who) override;
private:
+ struct WindowInfosReportedListener;
+
std::mutex mListenersMutex;
static constexpr size_t kStaticCapacity = 3;
ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
mWindowInfosListeners GUARDED_BY(mListenersMutex);
-
- std::mutex mMessagesMutex;
- uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0;
- std::function<void()> mWindowInfosChangedDelayed GUARDED_BY(mMessagesMutex);
};
} // namespace android
diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp
index 7350e09..f76a8d7 100644
--- a/services/surfaceflinger/fuzzer/Android.bp
+++ b/services/surfaceflinger/fuzzer/Android.bp
@@ -69,6 +69,7 @@
"-Wno-unused-result",
"-Wno-conversion",
"-Wno-sign-compare",
+ "-Wno-unused-function",
],
fuzz_config: {
cc: [
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
index 8a6af10..a9247fe 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_displayhardware_fuzzer.cpp
@@ -222,7 +222,7 @@
std::optional<impl::HWComposer::DeviceRequestedChanges> outChanges;
mHwc.getDeviceCompositionChanges(halDisplayID,
mFdp.ConsumeBool() /*frameUsesClientComposition*/,
- std::chrono::steady_clock::now(), FenceTime::NO_FENCE,
+ std::chrono::steady_clock::now(),
mFdp.ConsumeIntegral<nsecs_t>(), &outChanges);
}
@@ -555,8 +555,7 @@
mHwc.setClientTarget(halDisplayID, mFdp.ConsumeIntegral<uint32_t>(), Fence::NO_FENCE,
sp<GraphicBuffer>::make(), mFdp.PickValueInArray(kDataspaces));
- mHwc.presentAndGetReleaseFences(halDisplayID, std::chrono::steady_clock::now(),
- FenceTime::NO_FENCE);
+ mHwc.presentAndGetReleaseFences(halDisplayID, std::chrono::steady_clock::now());
mHwc.setPowerMode(mPhysicalDisplayId, mFdp.PickValueInArray(kPowerModes));
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 6074bb7..c1bab0e 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -49,6 +49,7 @@
#include "SurfaceFlingerDefaultFactory.h"
#include "ThreadContext.h"
#include "TimeStats/TimeStats.h"
+#include "surfaceflinger_scheduler_fuzzer.h"
#include "renderengine/mock/RenderEngine.h"
#include "scheduler/TimeKeeper.h"
@@ -237,7 +238,8 @@
const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
registerDisplayInternal(displayId, std::move(selectorPtr),
std::shared_ptr<VsyncSchedule>(
- new VsyncSchedule(displayId, std::move(tracker), nullptr,
+ new VsyncSchedule(displayId, std::move(tracker),
+ std::make_shared<FuzzImplVSyncDispatch>(),
std::move(controller))));
}
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index e6be9a8..a32750e 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -129,6 +129,11 @@
return (scheduler::ScheduleResult)0;
}
+ scheduler::ScheduleResult update(CallbackToken /* token */,
+ ScheduleTiming /* scheduleTiming */) override {
+ return (scheduler::ScheduleResult)0;
+ }
+
scheduler::CancelResult cancel(CallbackToken /* token */) override {
return (scheduler::CancelResult)0;
}
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 976ee35..013694f 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -222,6 +222,14 @@
mCapture->checkPixel(0, 0, 200, 200, 200);
}
+TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) {
+ mCaptureArgs.excludeHandles = {mFGSurfaceControl->getHandle()};
+ ScreenCapture::captureDisplay(&mCapture, mCaptureArgs);
+ mCapture->expectBGColor(0, 0);
+ // Doesn't capture FG layer which is at 64, 64
+ mCapture->expectBGColor(64, 64);
+}
+
// Like the last test but verifies that children are also exclude.
TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
auto fgHandle = mFGSurfaceControl->getHandle();
diff --git a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
index 7355c35..2b29530 100644
--- a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
+++ b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
@@ -22,6 +22,7 @@
#include <string>
#include <unordered_map>
+#include <LayerProtoHelper.h>
#include <LayerTraceGenerator.h>
#include <Tracing/TransactionProtoParser.h>
#include <layerproto/LayerProtoHeader.h>
@@ -94,11 +95,14 @@
float y;
uint32_t bufferWidth;
uint32_t bufferHeight;
+ Rect touchableRegionBounds;
};
bool operator==(const LayerInfo& lh, const LayerInfo& rh) {
- return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame) ==
- std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame);
+ return std::make_tuple(lh.id, lh.name, lh.parent, lh.z, lh.curr_frame, lh.bufferWidth,
+ lh.bufferHeight, lh.touchableRegionBounds) ==
+ std::make_tuple(rh.id, rh.name, rh.parent, rh.z, rh.curr_frame, rh.bufferWidth,
+ rh.bufferHeight, rh.touchableRegionBounds);
}
bool compareById(const LayerInfo& a, const LayerInfo& b) {
@@ -109,7 +113,9 @@
*os << "Layer [" << info.id << "] name=" << info.name << " parent=" << info.parent
<< " z=" << info.z << " curr_frame=" << info.curr_frame << " x=" << info.x
<< " y=" << info.y << " bufferWidth=" << info.bufferWidth
- << " bufferHeight=" << info.bufferHeight;
+ << " bufferHeight=" << info.bufferHeight << "touchableRegionBounds={"
+ << info.touchableRegionBounds.left << "," << info.touchableRegionBounds.top << ","
+ << info.touchableRegionBounds.right << "," << info.touchableRegionBounds.bottom << "}";
}
struct find_id : std::unary_function<LayerInfo, bool> {
@@ -119,6 +125,17 @@
};
static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& proto) {
+ Rect touchableRegionBounds = Rect::INVALID_RECT;
+ // ignore touchable region for layers without buffers, the new fe aggressively avoids
+ // calculating state for layers that are not visible which could lead to mismatches
+ if (proto.has_input_window_info() && proto.input_window_info().has_touchable_region() &&
+ proto.has_active_buffer()) {
+ Region touchableRegion;
+ LayerProtoHelper::readFromProto(proto.input_window_info().touchable_region(),
+ touchableRegion);
+ touchableRegionBounds = touchableRegion.bounds();
+ }
+
return {proto.id(),
proto.name(),
proto.parent(),
@@ -127,7 +144,37 @@
proto.has_position() ? proto.position().x() : -1,
proto.has_position() ? proto.position().y() : -1,
proto.has_active_buffer() ? proto.active_buffer().width() : 0,
- proto.has_active_buffer() ? proto.active_buffer().height() : 0};
+ proto.has_active_buffer() ? proto.active_buffer().height() : 0,
+ touchableRegionBounds};
+}
+
+static std::vector<LayerInfo> getLayerInfosFromProto(
+ android::surfaceflinger::LayersTraceProto& entry) {
+ std::unordered_map<int32_t /* snapshotId*/, int32_t /*layerId*/> snapshotIdToLayerId;
+ std::vector<LayerInfo> layers;
+ layers.reserve(static_cast<size_t>(entry.layers().layers_size()));
+ bool mapSnapshotIdToLayerId = false;
+ for (int i = 0; i < entry.layers().layers_size(); i++) {
+ auto layer = entry.layers().layers(i);
+ LayerInfo layerInfo = getLayerInfoFromProto(layer);
+
+ snapshotIdToLayerId[layerInfo.id] = static_cast<int32_t>(layer.original_id());
+ if (layer.original_id() != 0) {
+ mapSnapshotIdToLayerId = true;
+ }
+ layers.push_back(layerInfo);
+ }
+ std::sort(layers.begin(), layers.end(), compareById);
+
+ if (!mapSnapshotIdToLayerId) {
+ return layers;
+ }
+ for (auto& layer : layers) {
+ layer.id = snapshotIdToLayerId[layer.id];
+ auto it = snapshotIdToLayerId.find(layer.parent);
+ layer.parent = it == snapshotIdToLayerId.end() ? -1 : it->second;
+ }
+ return layers;
}
TEST_P(TransactionTraceTestSuite, validateEndState) {
@@ -140,32 +187,9 @@
EXPECT_EQ(expectedLastEntry.layers().layers_size(), actualLastEntry.layers().layers_size());
- std::vector<LayerInfo> expectedLayers;
- expectedLayers.reserve(static_cast<size_t>(expectedLastEntry.layers().layers_size()));
- for (int i = 0; i < expectedLastEntry.layers().layers_size(); i++) {
- auto layer = expectedLastEntry.layers().layers(i);
- LayerInfo layerInfo = getLayerInfoFromProto(layer);
- expectedLayers.push_back(layerInfo);
- }
- std::sort(expectedLayers.begin(), expectedLayers.end(), compareById);
-
- std::unordered_map<int32_t /* snapshotId*/, int32_t /*layerId*/> snapshotIdToLayerId;
- std::vector<LayerInfo> actualLayers;
- actualLayers.reserve(static_cast<size_t>(actualLastEntry.layers().layers_size()));
- for (int i = 0; i < actualLastEntry.layers().layers_size(); i++) {
- auto layer = actualLastEntry.layers().layers(i);
- LayerInfo layerInfo = getLayerInfoFromProto(layer);
- snapshotIdToLayerId[layerInfo.id] = static_cast<int32_t>(layer.original_id());
- actualLayers.push_back(layerInfo);
- }
-
- for (auto& layer : actualLayers) {
- layer.id = snapshotIdToLayerId[layer.id];
- auto it = snapshotIdToLayerId.find(layer.parent);
- layer.parent = it == snapshotIdToLayerId.end() ? -1 : it->second;
- }
-
- std::sort(actualLayers.begin(), actualLayers.end(), compareById);
+ std::vector<LayerInfo> expectedLayers = getLayerInfosFromProto(expectedLastEntry);
+ std::vector<LayerInfo> actualLayers = getLayerInfosFromProto(actualLastEntry);
+ ;
size_t i = 0;
for (; i < actualLayers.size() && i < expectedLayers.size(); i++) {
diff --git a/services/surfaceflinger/tests/tracing/testdata/layers_trace_b275630566.winscope b/services/surfaceflinger/tests/tracing/testdata/layers_trace_b275630566.winscope
new file mode 100644
index 0000000..fe504d7
--- /dev/null
+++ b/services/surfaceflinger/tests/tracing/testdata/layers_trace_b275630566.winscope
Binary files differ
diff --git a/services/surfaceflinger/tests/tracing/testdata/transactions_trace_b275630566.winscope b/services/surfaceflinger/tests/tracing/testdata/transactions_trace_b275630566.winscope
new file mode 100644
index 0000000..6f7ba15
--- /dev/null
+++ b/services/surfaceflinger/tests/tracing/testdata/transactions_trace_b275630566.winscope
Binary files differ
diff --git a/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp b/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp
deleted file mode 100644
index 513f779..0000000
--- a/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "AidlPowerHalWrapperTest"
-
-#include <android-base/stringprintf.h>
-#include <android/hardware/power/IPower.h>
-#include <android/hardware/power/IPowerHintSession.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <algorithm>
-#include <chrono>
-#include <memory>
-#include "DisplayHardware/PowerAdvisor.h"
-#include "android/hardware/power/WorkDuration.h"
-#include "binder/Status.h"
-#include "log/log_main.h"
-#include "mock/DisplayHardware/MockIPower.h"
-#include "mock/DisplayHardware/MockIPowerHintSession.h"
-#include "utils/Timers.h"
-
-using namespace android;
-using namespace android::Hwc2::mock;
-using namespace android::hardware::power;
-using namespace std::chrono_literals;
-using namespace testing;
-
-namespace android::Hwc2::impl {
-
-class AidlPowerHalWrapperTest : public testing::Test {
-public:
- void SetUp() override;
-
-protected:
- std::unique_ptr<AidlPowerHalWrapper> mWrapper = nullptr;
- sp<NiceMock<MockIPower>> mMockHal = nullptr;
- sp<NiceMock<MockIPowerHintSession>> mMockSession = nullptr;
- void verifyAndClearExpectations();
- void sendActualWorkDurationGroup(std::vector<WorkDuration> durations);
- static constexpr std::chrono::duration kStaleTimeout = 100ms;
-};
-
-void AidlPowerHalWrapperTest::SetUp() {
- mMockHal = sp<NiceMock<MockIPower>>::make();
- mMockSession = sp<NiceMock<MockIPowerHintSession>>::make();
- ON_CALL(*mMockHal.get(), getHintSessionPreferredRate(_)).WillByDefault(Return(Status::ok()));
- mWrapper = std::make_unique<AidlPowerHalWrapper>(mMockHal);
-}
-
-void AidlPowerHalWrapperTest::verifyAndClearExpectations() {
- Mock::VerifyAndClearExpectations(mMockHal.get());
- Mock::VerifyAndClearExpectations(mMockSession.get());
-}
-
-void AidlPowerHalWrapperTest::sendActualWorkDurationGroup(std::vector<WorkDuration> durations) {
- for (size_t i = 0; i < durations.size(); i++) {
- auto duration = durations[i];
- mWrapper->sendActualWorkDuration(Duration::fromNs(duration.durationNanos),
- TimePoint::fromNs(duration.timeStampNanos));
- }
-}
-
-WorkDuration toWorkDuration(std::chrono::nanoseconds durationNanos, int64_t timeStampNanos) {
- WorkDuration duration;
- duration.durationNanos = durationNanos.count();
- duration.timeStampNanos = timeStampNanos;
- return duration;
-}
-
-WorkDuration toWorkDuration(std::pair<std::chrono::nanoseconds, nsecs_t> timePair) {
- return toWorkDuration(timePair.first, timePair.second);
-}
-
-std::string printWorkDurations(const ::std::vector<WorkDuration>& durations) {
- std::ostringstream os;
- for (auto duration : durations) {
- os << duration.toString();
- os << "\n";
- }
- return os.str();
-}
-
-namespace {
-TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
- Mock::VerifyAndClearExpectations(mMockHal.get());
- ON_CALL(*mMockHal.get(), getHintSessionPreferredRate(_))
- .WillByDefault(Return(Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE)));
- auto newWrapper = AidlPowerHalWrapper(mMockHal);
- EXPECT_FALSE(newWrapper.supportsPowerHintSession());
-}
-
-TEST_F(AidlPowerHalWrapperTest, startPowerHintSession) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
- std::vector<int32_t> threadIds = {1, 2};
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- EXPECT_TRUE(mWrapper->startPowerHintSession());
- EXPECT_FALSE(mWrapper->startPowerHintSession());
-}
-
-TEST_F(AidlPowerHalWrapperTest, restartNewPowerHintSessionWithNewThreadIds) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
-
- std::vector<int32_t> threadIds = {1, 2};
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_EQ(mWrapper->getPowerHintSessionThreadIds(), threadIds);
- ASSERT_TRUE(mWrapper->startPowerHintSession());
- verifyAndClearExpectations();
-
- threadIds = {2, 3};
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- EXPECT_CALL(*mMockSession.get(), close()).Times(1);
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_EQ(mWrapper->getPowerHintSessionThreadIds(), threadIds);
- verifyAndClearExpectations();
-
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _)).Times(0);
- EXPECT_CALL(*mMockSession.get(), close()).Times(0);
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- verifyAndClearExpectations();
-}
-
-TEST_F(AidlPowerHalWrapperTest, setTargetWorkDuration) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
-
- std::vector<int32_t> threadIds = {1, 2};
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- ASSERT_TRUE(mWrapper->startPowerHintSession());
- verifyAndClearExpectations();
-
- std::chrono::nanoseconds base = 100ms;
- // test cases with target work duration and whether it should update hint against baseline 100ms
- const std::vector<std::pair<std::chrono::nanoseconds, bool>> testCases =
- {{0ms, true}, {-1ms, true}, {200ms, true}, {2ms, true}, {100ms, false}, {109ms, true}};
-
- for (const auto& test : testCases) {
- // reset to 100ms baseline
- mWrapper->setTargetWorkDuration(1ns);
- mWrapper->setTargetWorkDuration(base);
-
- std::chrono::nanoseconds target = test.first;
- EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(target.count()))
- .Times(test.second ? 1 : 0);
- mWrapper->setTargetWorkDuration(target);
- verifyAndClearExpectations();
- }
-}
-
-TEST_F(AidlPowerHalWrapperTest, setTargetWorkDuration_shouldReconnectOnError) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
-
- std::vector<int32_t> threadIds = {1, 2};
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- ASSERT_TRUE(mWrapper->startPowerHintSession());
- verifyAndClearExpectations();
-
- EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(1))
- .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE)));
- mWrapper->setTargetWorkDuration(1ns);
- EXPECT_TRUE(mWrapper->shouldReconnectHAL());
-}
-
-TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
-
- std::vector<int32_t> threadIds = {1, 2};
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- ASSERT_TRUE(mWrapper->startPowerHintSession());
- verifyAndClearExpectations();
-
- auto base = toWorkDuration(100ms, 0);
- // test cases with actual work durations and whether it should update hint against baseline
- // 100ms
- const std::vector<std::pair<std::vector<std::pair<std::chrono::nanoseconds, nsecs_t>>, bool>>
- testCases = {{{{-1ms, 100}}, false},
- {{{50ms, 100}}, true},
- {{{100ms, 100}, {200ms, 200}}, true},
- {{{100ms, 500}, {100ms, 600}, {3ms, 600}}, true}};
-
- for (const auto& test : testCases) {
- // reset actual duration
- sendActualWorkDurationGroup({base});
-
- auto raw = test.first;
- std::vector<WorkDuration> durations(raw.size());
- std::transform(raw.begin(), raw.end(), durations.begin(),
- [](auto d) { return toWorkDuration(d); });
- for (auto& duration : durations) {
- EXPECT_CALL(*mMockSession.get(),
- reportActualWorkDuration(std::vector<WorkDuration>{duration}))
- .Times(test.second ? 1 : 0);
- }
- sendActualWorkDurationGroup(durations);
- verifyAndClearExpectations();
- }
-}
-
-TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_shouldReconnectOnError) {
- ASSERT_TRUE(mWrapper->supportsPowerHintSession());
-
- std::vector<int32_t> threadIds = {1, 2};
- mWrapper->setPowerHintSessionThreadIds(threadIds);
- EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
- .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
- ASSERT_TRUE(mWrapper->startPowerHintSession());
- verifyAndClearExpectations();
- WorkDuration duration;
- duration.durationNanos = 1;
- EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_))
- .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_ILLEGAL_STATE)));
- sendActualWorkDurationGroup({duration});
- EXPECT_TRUE(mWrapper->shouldReconnectHAL());
-}
-
-} // namespace
-} // namespace android::Hwc2::impl
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index df3ffd2..201d37f 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -24,7 +24,7 @@
filegroup {
name: "libsurfaceflinger_mock_sources",
srcs: [
- "mock/DisplayHardware/MockAidlPowerHalWrapper.cpp",
+ "mock/DisplayHardware/MockPowerHalController.cpp",
"mock/DisplayHardware/MockComposer.cpp",
"mock/DisplayHardware/MockHWC2.cpp",
"mock/DisplayHardware/MockIPower.cpp",
@@ -70,7 +70,6 @@
":libsurfaceflinger_mock_sources",
":libsurfaceflinger_sources",
"libsurfaceflinger_unittest_main.cpp",
- "AidlPowerHalWrapperTest.cpp",
"CompositionTest.cpp",
"DisplayIdGeneratorTest.cpp",
"DisplayTransactionTest.cpp",
@@ -196,6 +195,7 @@
"libinput",
"liblog",
"libnativewindow",
+ "libpowermanager",
"libprocessgroup",
"libprotobuf-cpp-lite",
"libSurfaceFlingerProp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 6391fec..156007b 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -204,7 +204,7 @@
auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
return mFlinger.traverseLayersInLayerStack(mDisplay->getLayerStack(),
- CaptureArgs::UNSET_UID, visitor);
+ CaptureArgs::UNSET_UID, {}, visitor);
};
auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 5b3c7ef..79cfd6a 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -278,6 +278,25 @@
mLifecycleManager.applyTransactions(transactions);
}
+ void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId,
+ bool replaceTouchableRegionWithCrop) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.windowInfoHandle =
+ sp<gui::WindowInfoHandle>::make();
+ auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+ inputInfo->touchableRegion = region;
+ inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop;
+ transactions.back().states.front().touchCropId = touchCropId;
+
+ inputInfo->token = sp<BBinder>::make();
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
LayerLifecycleManager mLifecycleManager;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index b8c4781..5a066a6 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -308,6 +308,31 @@
EXPECT_EQ(getSnapshot(1)->frameRate.type, scheduler::LayerInfo::FrameRateCompatibility::NoVote);
}
+TEST_F(LayerSnapshotTest, canCropTouchableRegion) {
+ // ROOT
+ // ├── 1
+ // │ ├── 11
+ // │ │ └── 111 (touchregion set to touch but cropped by layer 13)
+ // │ ├── 12
+ // │ │ ├── 121
+ // │ │ └── 122
+ // │ │ └── 1221
+ // │ └── 13 (crop set to touchCrop)
+ // └── 2
+
+ Rect touchCrop{300, 300, 400, 500};
+ setCrop(13, touchCrop);
+ Region touch{Rect{0, 0, 1000, 1000}};
+ setTouchableRegionCrop(111, touch, /*touchCropId=*/13, /*replaceTouchableRegionWithCrop=*/true);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot({.id = 111})->inputInfo.touchableRegion.bounds(), touchCrop);
+
+ Rect modifiedTouchCrop{100, 300, 400, 700};
+ setCrop(13, modifiedTouchCrop);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot({.id = 111})->inputInfo.touchableRegion.bounds(), modifiedTouchCrop);
+}
+
// Display Mirroring Tests
// tree with 3 levels of children
// ROOT (DISPLAY 0)
diff --git a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
index 2d66d3c..0d66d59 100644
--- a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
@@ -25,13 +25,15 @@
#include <ui/DisplayId.h>
#include <chrono>
#include "TestableSurfaceFlinger.h"
-#include "mock/DisplayHardware/MockAidlPowerHalWrapper.h"
+#include "mock/DisplayHardware/MockIPowerHintSession.h"
+#include "mock/DisplayHardware/MockPowerHalController.h"
using namespace android;
using namespace android::Hwc2::mock;
using namespace android::hardware::power;
using namespace std::chrono_literals;
using namespace testing;
+using namespace android::power;
namespace android::Hwc2::impl {
@@ -42,28 +44,32 @@
void fakeBasicFrameTiming(TimePoint startTime, Duration vsyncPeriod);
void setExpectedTiming(Duration totalFrameTargetDuration, TimePoint expectedPresentTime);
Duration getFenceWaitDelayDuration(bool skipValidate);
+ Duration getErrorMargin();
protected:
TestableSurfaceFlinger mFlinger;
std::unique_ptr<PowerAdvisor> mPowerAdvisor;
- NiceMock<MockAidlPowerHalWrapper>* mMockAidlWrapper;
- Duration kErrorMargin = 1ms;
+ MockPowerHalController* mMockPowerHalController;
+ sp<MockIPowerHintSession> mMockPowerHintSession;
};
-void PowerAdvisorTest::SetUp() FTL_FAKE_GUARD(mPowerAdvisor->mPowerHalMutex) {
- std::unique_ptr<MockAidlPowerHalWrapper> mockAidlWrapper =
- std::make_unique<NiceMock<MockAidlPowerHalWrapper>>();
- mPowerAdvisor = std::make_unique<PowerAdvisor>(*mFlinger.flinger());
- ON_CALL(*mockAidlWrapper.get(), supportsPowerHintSession()).WillByDefault(Return(true));
- ON_CALL(*mockAidlWrapper.get(), startPowerHintSession()).WillByDefault(Return(true));
- mPowerAdvisor->mHalWrapper = std::move(mockAidlWrapper);
- mMockAidlWrapper =
- reinterpret_cast<NiceMock<MockAidlPowerHalWrapper>*>(mPowerAdvisor->mHalWrapper.get());
+void PowerAdvisorTest::SetUp() {
+ mPowerAdvisor = std::make_unique<impl::PowerAdvisor>(*mFlinger.flinger());
+ mPowerAdvisor->mPowerHal = std::make_unique<NiceMock<MockPowerHalController>>();
+ mMockPowerHalController =
+ reinterpret_cast<MockPowerHalController*>(mPowerAdvisor->mPowerHal.get());
+ ON_CALL(*mMockPowerHalController, getHintSessionPreferredRate)
+ .WillByDefault(Return(HalResult<int64_t>::fromStatus(binder::Status::ok(), 16000)));
}
void PowerAdvisorTest::startPowerHintSession() {
const std::vector<int32_t> threadIds = {1, 2, 3};
- mPowerAdvisor->enablePowerHint(true);
+ mMockPowerHintSession = android::sp<NiceMock<MockIPowerHintSession>>::make();
+ ON_CALL(*mMockPowerHalController, createHintSession)
+ .WillByDefault(
+ Return(HalResult<sp<IPowerHintSession>>::fromStatus(binder::Status::ok(),
+ mMockPowerHintSession)));
+ mPowerAdvisor->enablePowerHintSession(true);
mPowerAdvisor->startPowerHintSession(threadIds);
}
@@ -76,7 +82,7 @@
void PowerAdvisorTest::fakeBasicFrameTiming(TimePoint startTime, Duration vsyncPeriod) {
mPowerAdvisor->setCommitStart(startTime);
mPowerAdvisor->setFrameDelay(0ns);
- mPowerAdvisor->setTargetWorkDuration(vsyncPeriod);
+ mPowerAdvisor->updateTargetWorkDuration(vsyncPeriod);
}
Duration PowerAdvisorTest::getFenceWaitDelayDuration(bool skipValidate) {
@@ -84,6 +90,10 @@
: PowerAdvisor::kFenceWaitStartDelayValidated);
}
+Duration PowerAdvisorTest::getErrorMargin() {
+ return mPowerAdvisor->sTargetSafetyMargin;
+}
+
namespace {
TEST_F(PowerAdvisorTest, hintSessionUseHwcDisplay) {
@@ -109,8 +119,11 @@
// increment the frame
startTime += vsyncPeriod;
- const Duration expectedDuration = kErrorMargin + presentDuration + postCompDuration;
- EXPECT_CALL(*mMockAidlWrapper, sendActualWorkDuration(Eq(expectedDuration), _)).Times(1);
+ const Duration expectedDuration = getErrorMargin() + presentDuration + postCompDuration;
+ EXPECT_CALL(*mMockPowerHintSession,
+ reportActualWorkDuration(ElementsAre(
+ Field(&WorkDuration::durationNanos, Eq(expectedDuration.ns())))))
+ .Times(1);
fakeBasicFrameTiming(startTime, vsyncPeriod);
setExpectedTiming(vsyncPeriod, startTime + vsyncPeriod);
@@ -118,7 +131,7 @@
mPowerAdvisor->setHwcValidateTiming(displayIds[0], startTime + 1ms, startTime + 1500us);
mPowerAdvisor->setHwcPresentTiming(displayIds[0], startTime + 2ms, startTime + 2500us);
mPowerAdvisor->setSfPresentTiming(startTime, startTime + presentDuration);
- mPowerAdvisor->sendActualWorkDuration();
+ mPowerAdvisor->reportActualWorkDuration();
}
TEST_F(PowerAdvisorTest, hintSessionSubtractsHwcFenceTime) {
@@ -145,9 +158,12 @@
// increment the frame
startTime += vsyncPeriod;
- const Duration expectedDuration = kErrorMargin + presentDuration +
+ const Duration expectedDuration = getErrorMargin() + presentDuration +
getFenceWaitDelayDuration(false) - hwcBlockedDuration + postCompDuration;
- EXPECT_CALL(*mMockAidlWrapper, sendActualWorkDuration(Eq(expectedDuration), _)).Times(1);
+ EXPECT_CALL(*mMockPowerHintSession,
+ reportActualWorkDuration(ElementsAre(
+ Field(&WorkDuration::durationNanos, Eq(expectedDuration.ns())))))
+ .Times(1);
fakeBasicFrameTiming(startTime, vsyncPeriod);
setExpectedTiming(vsyncPeriod, startTime + vsyncPeriod);
@@ -157,7 +173,7 @@
// now report the fence as having fired during the display HWC time
mPowerAdvisor->setSfPresentTiming(startTime + 2ms + hwcBlockedDuration,
startTime + presentDuration);
- mPowerAdvisor->sendActualWorkDuration();
+ mPowerAdvisor->reportActualWorkDuration();
}
TEST_F(PowerAdvisorTest, hintSessionUsingSecondaryVirtualDisplays) {
@@ -185,8 +201,11 @@
// increment the frame
startTime += vsyncPeriod;
- const Duration expectedDuration = kErrorMargin + presentDuration + postCompDuration;
- EXPECT_CALL(*mMockAidlWrapper, sendActualWorkDuration(Eq(expectedDuration), _)).Times(1);
+ const Duration expectedDuration = getErrorMargin() + presentDuration + postCompDuration;
+ EXPECT_CALL(*mMockPowerHintSession,
+ reportActualWorkDuration(ElementsAre(
+ Field(&WorkDuration::durationNanos, Eq(expectedDuration.ns())))))
+ .Times(1);
fakeBasicFrameTiming(startTime, vsyncPeriod);
setExpectedTiming(vsyncPeriod, startTime + vsyncPeriod);
@@ -196,7 +215,7 @@
mPowerAdvisor->setHwcValidateTiming(displayIds[0], startTime + 1ms, startTime + 1500us);
mPowerAdvisor->setHwcPresentTiming(displayIds[0], startTime + 2ms, startTime + 2500us);
mPowerAdvisor->setSfPresentTiming(startTime, startTime + presentDuration);
- mPowerAdvisor->sendActualWorkDuration();
+ mPowerAdvisor->reportActualWorkDuration();
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index 63ed87b..d63e187 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -3026,5 +3026,21 @@
EXPECT_FRAME_RATE_MODE(kMode60, 30_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
+TEST_P(RefreshRateSelectorTest, frameRateNotInRange) {
+ auto selector = createSelector(kModes_60_90, kModeId60);
+
+ constexpr FpsRanges k60Only = {{60_Hz, 90_Hz}, {60_Hz, 60_Hz}};
+ constexpr FpsRanges kAll = {{0_Hz, 90_Hz}, {0_Hz, 90_Hz}};
+
+ EXPECT_EQ(SetPolicyResult::Changed,
+ selector.setDisplayManagerPolicy({DisplayModeId(kModeId60), k60Only, kAll}));
+
+ std::vector<LayerRequirement> layers = {{.weight = 1.f}};
+ layers[0].name = "Test layer";
+ layers[0].vote = LayerVoteType::Heuristic;
+ layers[0].desiredRefreshRate = 45_Hz;
+ EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
+}
+
} // namespace
} // namespace android::scheduler
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
index 7839ef0..d0290ea 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
@@ -70,7 +70,6 @@
mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats));
mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
- mFlinger.setPowerHintSessionMode(true, true);
mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor));
static constexpr bool kIsPrimary = true;
FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, hal::DisplayType::PHYSICAL, kIsPrimary)
@@ -100,7 +99,7 @@
TEST_F(SurfaceFlingerPowerHintTest, sendDurationsIncludingHwcWaitTime) {
ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true));
- EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(1);
+ EXPECT_CALL(*mPowerAdvisor, updateTargetWorkDuration(_)).Times(1);
EXPECT_CALL(*mDisplaySurface,
prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc))
.Times(1);
@@ -109,7 +108,7 @@
std::this_thread::sleep_for(kMockHwcRunTime);
return hardware::graphics::composer::V2_1::Error::NONE;
});
- EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration()).Times(1);
+ EXPECT_CALL(*mPowerAdvisor, reportActualWorkDuration()).Times(1);
const TimePoint frameTime = scheduler::SchedulerClock::now();
constexpr Period kMockVsyncPeriod = 15ms;
@@ -121,7 +120,7 @@
mDisplay->setPowerMode(hal::PowerMode::DOZE);
- EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(0);
+ EXPECT_CALL(*mPowerAdvisor, updateTargetWorkDuration(_)).Times(0);
EXPECT_CALL(*mDisplaySurface,
prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc))
.Times(1);
@@ -130,7 +129,7 @@
std::this_thread::sleep_for(kMockHwcRunTime);
return hardware::graphics::composer::V2_1::Error::NONE;
});
- EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration()).Times(0);
+ EXPECT_CALL(*mPowerAdvisor, reportActualWorkDuration()).Times(0);
const TimePoint frameTime = scheduler::SchedulerClock::now();
constexpr Period kMockVsyncPeriod = 15ms;
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index fc9e653..6f48df8 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -344,10 +344,6 @@
layer->mDrawingParent = drawingParent;
}
- void setPowerHintSessionMode(bool early, bool late) {
- mFlinger->mPowerHintSessionMode = {.late = late, .early = early};
- }
-
/* ------------------------------------------------------------------------
* Forwarding for functions being tested
*/
@@ -446,8 +442,10 @@
}
auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,
+ std::unordered_set<uint32_t> excludeLayerIds,
const LayerVector::Visitor& visitor) {
- return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, visitor);
+ return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid,
+ excludeLayerIds, visitor);
}
auto getDisplayNativePrimaries(const sp<IBinder>& displayToken,
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index d4e2357..03c4e71 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -294,7 +294,8 @@
return fence;
}
- ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what) {
+ ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
+ std::optional<sp<IBinder>> layerHandle = std::nullopt) {
ComposerState state;
state.state.bufferData =
std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
@@ -302,15 +303,20 @@
/* outUsage */ 0);
state.state.bufferData->acquireFence = std::move(fence);
state.state.layerId = layerId;
- state.state.surface =
+ state.state.surface = layerHandle.value_or(
sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
- ->getHandle();
+ ->getHandle());
state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
state.state.what = what;
if (what & layer_state_t::eCropChanged) {
state.state.crop = Rect(1, 2, 3, 4);
}
+ if (what & layer_state_t::eFlagsChanged) {
+ state.state.flags = layer_state_t::eEnableBackpressure;
+ state.state.mask = layer_state_t::eEnableBackpressure;
+ }
+
return state;
}
@@ -601,6 +607,41 @@
setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
}
+TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
+ const sp<IBinder> kApplyToken1 =
+ IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
+ const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
+ const auto kLayerId1 = 1;
+ const auto kLayerId2 = 2;
+ const auto kExpectedTransactionsPending = 1u;
+
+ const auto signaledTransaction =
+ createTransactionInfo(kApplyToken1,
+ {
+ createComposerState(kLayerId1,
+ fence(Fence::Status::Signaled),
+ layer_state_t::eBufferChanged),
+ });
+ const auto signaledTransaction2 =
+ createTransactionInfo(kApplyToken2,
+ {
+ createComposerState(kLayerId1,
+ fence(Fence::Status::Signaled),
+ layer_state_t::eBufferChanged),
+ });
+ const auto unsignaledTransaction =
+ createTransactionInfo(kApplyToken3,
+ {
+ createComposerState(kLayerId2,
+ fence(Fence::Status::Unsignaled),
+ layer_state_t::eBufferChanged),
+ });
+
+ setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
+ kExpectedTransactionsPending);
+}
+
class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
public:
void SetUp() override {
@@ -943,6 +984,43 @@
kExpectedTransactionsPending);
}
+TEST_F(LatchUnsignaledAlwaysTest, RespectsBackPressureFlag) {
+ const sp<IBinder> kApplyToken1 =
+ IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
+ const auto kLayerId1 = 1;
+ const auto kExpectedTransactionsPending = 1u;
+ auto layer =
+ sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}));
+ auto layerHandle = layer->getHandle();
+ const auto setBackPressureFlagTransaction =
+ createTransactionInfo(kApplyToken1,
+ {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
+ layer_state_t::eBufferChanged |
+ layer_state_t::eFlagsChanged,
+ {layerHandle})});
+ setTransactionStates({setBackPressureFlagTransaction}, 0u);
+
+ const auto unsignaledTransaction =
+ createTransactionInfo(kApplyToken1,
+ {
+ createComposerState(kLayerId1,
+ fence(Fence::Status::Unsignaled),
+ layer_state_t::eBufferChanged,
+ {layerHandle}),
+ });
+ const auto unsignaledTransaction2 =
+ createTransactionInfo(kApplyToken1,
+ {
+ createComposerState(kLayerId1,
+ fence(Fence::Status::Unsignaled),
+ layer_state_t::eBufferChanged,
+ {layerHandle}),
+ });
+ setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
+ kExpectedTransactionsPending);
+}
+
TEST_F(LatchUnsignaledAlwaysTest, LatchUnsignaledWhenEarlyOffset) {
const sp<IBinder> kApplyToken =
IInterface::asBinder(TransactionCompletedListener::getIInstance());
diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
index 3dea189..dd72174 100644
--- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
@@ -19,6 +19,7 @@
#include <limits> // std::numeric_limits
#include <gui/SurfaceComposerClient.h>
+#include <ui/Rotation.h>
#include "LayerProtoHelper.h"
#include "Tracing/TransactionProtoParser.h"
@@ -103,4 +104,48 @@
ASSERT_EQ(t1.displays[0].token, t2.displays[0].token);
}
+TEST(TransactionProtoParserTest, parseDisplayInfo) {
+ frontend::DisplayInfo d1;
+ d1.info.displayId = 42;
+ d1.info.logicalWidth = 43;
+ d1.info.logicalHeight = 44;
+ d1.info.transform.set(1, 2, 3, 4);
+ d1.transform = d1.info.transform.inverse();
+ d1.receivesInput = true;
+ d1.isSecure = false;
+ d1.isPrimary = true;
+ d1.isVirtual = false;
+ d1.rotationFlags = ui::Transform::ROT_180;
+ d1.transformHint = ui::Transform::ROT_90;
+
+ const uint32_t layerStack = 2;
+ google::protobuf::RepeatedPtrField<proto::DisplayInfo> displayProtos;
+ auto displayInfoProto = displayProtos.Add();
+ *displayInfoProto = TransactionProtoParser::toProto(d1, layerStack);
+ display::DisplayMap<ui::LayerStack, frontend::DisplayInfo> displayInfos;
+ TransactionProtoParser::fromProto(displayProtos, displayInfos);
+
+ ASSERT_TRUE(displayInfos.contains(ui::LayerStack::fromValue(layerStack)));
+ frontend::DisplayInfo d2 = displayInfos.get(ui::LayerStack::fromValue(layerStack))->get();
+ EXPECT_EQ(d1.info.displayId, d2.info.displayId);
+ EXPECT_EQ(d1.info.logicalWidth, d2.info.logicalWidth);
+ EXPECT_EQ(d1.info.logicalHeight, d2.info.logicalHeight);
+
+ EXPECT_EQ(d1.info.transform.dsdx(), d2.info.transform.dsdx());
+ EXPECT_EQ(d1.info.transform.dsdy(), d2.info.transform.dsdy());
+ EXPECT_EQ(d1.info.transform.dtdx(), d2.info.transform.dtdx());
+ EXPECT_EQ(d1.info.transform.dtdy(), d2.info.transform.dtdy());
+
+ EXPECT_EQ(d1.transform.dsdx(), d2.transform.dsdx());
+ EXPECT_EQ(d1.transform.dsdy(), d2.transform.dsdy());
+ EXPECT_EQ(d1.transform.dtdx(), d2.transform.dtdx());
+ EXPECT_EQ(d1.transform.dtdy(), d2.transform.dtdy());
+
+ EXPECT_EQ(d1.receivesInput, d2.receivesInput);
+ EXPECT_EQ(d1.isSecure, d2.isSecure);
+ EXPECT_EQ(d1.isVirtual, d2.isVirtual);
+ EXPECT_EQ(d1.rotationFlags, d2.rotationFlags);
+ EXPECT_EQ(d1.transformHint, d2.transformHint);
+}
+
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.h
deleted file mode 100644
index 5654691..0000000
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gmock/gmock.h>
-#include <scheduler/Time.h>
-
-#include "DisplayHardware/PowerAdvisor.h"
-
-namespace android {
-namespace hardware {
-namespace power {
-class IPower;
-}
-} // namespace hardware
-} // namespace android
-
-namespace android::Hwc2::mock {
-
-class MockAidlPowerHalWrapper : public Hwc2::impl::AidlPowerHalWrapper {
-public:
- MockAidlPowerHalWrapper();
- ~MockAidlPowerHalWrapper() override;
- MOCK_METHOD(bool, setExpensiveRendering, (bool enabled), (override));
- MOCK_METHOD(bool, notifyDisplayUpdateImminentAndCpuReset, (), (override));
- MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
- MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
- MOCK_METHOD(void, restartPowerHintSession, (), (override));
- MOCK_METHOD(void, setPowerHintSessionThreadIds, (const std::vector<int32_t>& threadIds),
- (override));
- MOCK_METHOD(bool, startPowerHintSession, (), (override));
- MOCK_METHOD(void, setTargetWorkDuration, (Duration targetDuration), (override));
- MOCK_METHOD(void, sendActualWorkDuration, (Duration actualDuration, TimePoint timestamp),
- (override));
- MOCK_METHOD(bool, shouldReconnectHAL, (), (override));
-};
-
-} // namespace android::Hwc2::mock
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index 7fc625c..3caa2b9 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -35,11 +35,10 @@
MOCK_METHOD(void, notifyDisplayUpdateImminentAndCpuReset, (), (override));
MOCK_METHOD(bool, usePowerHintSession, (), (override));
MOCK_METHOD(bool, supportsPowerHintSession, (), (override));
- MOCK_METHOD(bool, isPowerHintSessionRunning, (), (override));
- MOCK_METHOD(void, setTargetWorkDuration, (Duration targetDuration), (override));
- MOCK_METHOD(void, sendActualWorkDuration, (), (override));
- MOCK_METHOD(void, sendPredictedWorkDuration, (), (override));
- MOCK_METHOD(void, enablePowerHint, (bool enabled), (override));
+ MOCK_METHOD(bool, ensurePowerHintSessionRunning, (), (override));
+ MOCK_METHOD(void, updateTargetWorkDuration, (Duration targetDuration), (override));
+ MOCK_METHOD(void, reportActualWorkDuration, (), (override));
+ MOCK_METHOD(void, enablePowerHintSession, (bool enabled), (override));
MOCK_METHOD(bool, startPowerHintSession, (const std::vector<int32_t>& threadIds), (override));
MOCK_METHOD(void, setGpuFenceTime,
(DisplayId displayId, std::unique_ptr<FenceTime>&& fenceTime), (override));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.cpp
similarity index 67%
rename from services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.cpp
rename to services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.cpp
index 5049b1d..3ec5c2d 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockAidlPowerHalWrapper.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-#include "MockAidlPowerHalWrapper.h"
-#include "MockIPower.h"
+#include "MockPowerHalController.h"
namespace android::Hwc2::mock {
-MockAidlPowerHalWrapper::MockAidlPowerHalWrapper()
- : AidlPowerHalWrapper(sp<testing::NiceMock<MockIPower>>::make()){};
-MockAidlPowerHalWrapper::~MockAidlPowerHalWrapper() = default;
+MockPowerHalController::MockPowerHalController() = default;
+MockPowerHalController::~MockPowerHalController() = default;
} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h
new file mode 100644
index 0000000..358395d
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerHalController.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+#include <scheduler/Time.h>
+
+#include <powermanager/PowerHalController.h>
+
+namespace android {
+namespace hardware {
+namespace power {
+class IPower;
+}
+} // namespace hardware
+} // namespace android
+
+namespace android::Hwc2::mock {
+
+using android::hardware::power::Boost;
+using android::hardware::power::Mode;
+using android::power::HalResult;
+
+class MockPowerHalController : public power::PowerHalController {
+public:
+ MockPowerHalController();
+ ~MockPowerHalController() override;
+ MOCK_METHOD(HalResult<void>, setBoost, (Boost, int32_t), (override));
+ MOCK_METHOD(HalResult<void>, setMode, (Mode, bool), (override));
+ MOCK_METHOD(HalResult<sp<hardware::power::IPowerHintSession>>, createHintSession,
+ (int32_t, int32_t, const std::vector<int32_t>&, int64_t), (override));
+ MOCK_METHOD(HalResult<int64_t>, getHintSessionPreferredRate, (), (override));
+};
+
+} // namespace android::Hwc2::mock
\ No newline at end of file