blob: f9a2855974ef4c827e456332dd477bf44e1a7ad2 [file] [log] [blame]
Garfield Tane84e6f92019-08-29 17:28:41 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "InputTarget.h"
18
Siarhei Vishniakouf4043212023-09-18 19:33:03 -070019#include <android-base/logging.h>
Garfield Tane84e6f92019-08-29 17:28:41 -070020#include <android-base/stringprintf.h>
Siarhei Vishniakouf4043212023-09-18 19:33:03 -070021#include <input/PrintTools.h>
Garfield Tane84e6f92019-08-29 17:28:41 -070022#include <inttypes.h>
23#include <string>
24
Siarhei Vishniakou59967592024-04-01 16:17:46 -070025using android::base::Error;
26using android::base::Result;
Garfield Tane84e6f92019-08-29 17:28:41 -070027using android::base::StringPrintf;
28
29namespace android::inputdispatcher {
30
Prabir Pradhanc32a4112024-01-23 23:20:37 +000031namespace {
32
33const static ui::Transform kIdentityTransform{};
34
35}
36
37InputTarget::InputTarget(const std::shared_ptr<Connection>& connection, ftl::Flags<Flags> flags)
38 : connection(connection), flags(flags) {}
39
Siarhei Vishniakou59967592024-04-01 16:17:46 -070040Result<void> InputTarget::addPointers(std::bitset<MAX_POINTER_ID + 1> newPointerIds,
41 const ui::Transform& transform) {
Arthur Hungb75c2aa2022-07-15 09:35:36 +000042 // The pointerIds can be empty, but still a valid InputTarget. This can happen when there is no
43 // valid pointer property from the input event.
Siarhei Vishniakou8a878352023-01-30 14:05:01 -080044 if (newPointerIds.none()) {
chaviw1ff3d1e2020-07-01 15:53:47 -070045 setDefaultPointerTransform(transform);
Siarhei Vishniakou59967592024-04-01 16:17:46 -070046 return {};
Chavi Weingarten65f98b82020-01-16 18:56:50 +000047 }
48
49 // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
Prabir Pradhanc32a4112024-01-23 23:20:37 +000050 if ((getPointerIds() & newPointerIds).any()) {
Siarhei Vishniakou59967592024-04-01 16:17:46 -070051 return Error() << __func__ << " - overlap with incoming pointers "
52 << bitsetToString(newPointerIds) << " in " << *this;
Siarhei Vishniakouf4043212023-09-18 19:33:03 -070053 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +000054
Prabir Pradhanc32a4112024-01-23 23:20:37 +000055 for (auto& [existingTransform, existingPointers] : mPointerTransforms) {
56 if (transform == existingTransform) {
57 existingPointers |= newPointerIds;
Siarhei Vishniakou59967592024-04-01 16:17:46 -070058 return {};
Siarhei Vishniakou8a878352023-01-30 14:05:01 -080059 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +000060 }
Prabir Pradhanc32a4112024-01-23 23:20:37 +000061 mPointerTransforms.emplace_back(transform, newPointerIds);
Siarhei Vishniakou59967592024-04-01 16:17:46 -070062 return {};
Chavi Weingarten65f98b82020-01-16 18:56:50 +000063}
64
chaviw1ff3d1e2020-07-01 15:53:47 -070065void InputTarget::setDefaultPointerTransform(const ui::Transform& transform) {
Prabir Pradhanc32a4112024-01-23 23:20:37 +000066 mPointerTransforms = {{transform, {}}};
Chavi Weingarten65f98b82020-01-16 18:56:50 +000067}
68
chaviw1ff3d1e2020-07-01 15:53:47 -070069bool InputTarget::useDefaultPointerTransform() const {
Prabir Pradhanc32a4112024-01-23 23:20:37 +000070 return mPointerTransforms.size() <= 1;
Chavi Weingarten65f98b82020-01-16 18:56:50 +000071}
72
chaviw1ff3d1e2020-07-01 15:53:47 -070073const ui::Transform& InputTarget::getDefaultPointerTransform() const {
Prabir Pradhanc32a4112024-01-23 23:20:37 +000074 if (!useDefaultPointerTransform()) {
75 LOG(FATAL) << __func__ << ": Not using default pointer transform";
76 }
77 return mPointerTransforms.size() == 1 ? mPointerTransforms[0].first : kIdentityTransform;
78}
79
80const ui::Transform& InputTarget::getTransformForPointer(int32_t pointerId) const {
81 for (const auto& [transform, ids] : mPointerTransforms) {
82 if (ids.test(pointerId)) {
83 return transform;
84 }
85 }
86
87 LOG(FATAL) << __func__
88 << ": Cannot get transform: The following Pointer ID does not exist in target: "
89 << pointerId;
90 return kIdentityTransform;
Chavi Weingarten65f98b82020-01-16 18:56:50 +000091}
92
93std::string InputTarget::getPointerInfoString() const {
chaviw85b44202020-07-24 11:46:21 -070094 std::string out = "\n";
chaviw1ff3d1e2020-07-01 15:53:47 -070095 if (useDefaultPointerTransform()) {
96 const ui::Transform& transform = getDefaultPointerTransform();
chaviw85b44202020-07-24 11:46:21 -070097 transform.dump(out, "default", " ");
chaviw1ff3d1e2020-07-01 15:53:47 -070098 return out;
Chavi Weingarten65f98b82020-01-16 18:56:50 +000099 }
100
Prabir Pradhanc32a4112024-01-23 23:20:37 +0000101 for (const auto& [transform, ids] : mPointerTransforms) {
102 const std::string name = "pointerIds " + bitsetToString(ids) + ":";
103 transform.dump(out, name.c_str(), " ");
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000104 }
105 return out;
106}
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700107
Prabir Pradhanc32a4112024-01-23 23:20:37 +0000108std::bitset<MAX_POINTER_ID + 1> InputTarget::getPointerIds() const {
109 PointerIds allIds;
110 for (const auto& [_, ids] : mPointerTransforms) {
111 allIds |= ids;
112 }
113 return allIds;
114}
115
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700116std::ostream& operator<<(std::ostream& out, const InputTarget& target) {
Siarhei Vishniakou18cbdb82024-01-31 17:58:13 -0800117 out << "{connection=";
118 if (target.connection != nullptr) {
119 out << target.connection->getInputChannelName();
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700120 } else {
121 out << "<null>";
122 }
123 out << ", windowHandle=";
124 if (target.windowHandle != nullptr) {
125 out << target.windowHandle->getName();
126 } else {
127 out << "<null>";
128 }
Prabir Pradhan4b09c1f2023-11-17 03:16:25 +0000129 out << ", dispatchMode=" << ftl::enum_string(target.dispatchMode).c_str();
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700130 out << ", targetFlags=" << target.flags.string();
131 out << ", pointers=" << target.getPointerInfoString();
132 out << "}";
133 return out;
134}
135
Garfield Tane84e6f92019-08-29 17:28:41 -0700136} // namespace android::inputdispatcher