blob: 823df67d16556d393a428a88761142f1ef80f9ff [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 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#define LOG_TAG "InputManager"
18
19//#define LOG_NDEBUG 0
20
21#include "InputManager.h"
Garfield Tane84e6f92019-08-29 17:28:41 -070022#include "InputDispatcherFactory.h"
Prabir Pradhan29c95332018-11-14 20:14:11 -080023#include "InputReaderFactory.h"
Siarhei Vishniakouba0a8752021-09-14 14:43:25 -070024#include "UnwantedInteractionBlocker.h"
Michael Wrightd02c5b62014-02-10 15:10:22 -080025
Prabir Pradhan44e6e832023-06-06 00:03:25 +000026#include <aidl/com/android/server/inputflinger/IInputFlingerRust.h>
27#include <android/binder_interface_utils.h>
Prabir Pradhanaddf8e92023-04-06 00:28:48 +000028#include <android/sysprop/InputProperties.sysprop.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070029#include <binder/IPCThreadState.h>
Prabir Pradhan678405c2023-09-08 17:18:32 +000030#include <com_android_input_flags.h>
Prabir Pradhan44e6e832023-06-06 00:03:25 +000031#include <inputflinger_bootstrap.rs.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070032#include <log/log.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070033#include <private/android_filesystem_config.h>
34
Prabir Pradhan678405c2023-09-08 17:18:32 +000035namespace input_flags = com::android::input::flags;
36
Michael Wrightd02c5b62014-02-10 15:10:22 -080037namespace android {
38
Prabir Pradhan44e6e832023-06-06 00:03:25 +000039namespace {
40
41const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
Prabir Pradhan7adabad2023-06-28 16:16:27 +000042 sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
Prabir Pradhanaddf8e92023-04-06 00:28:48 +000043
Prabir Pradhan678405c2023-09-08 17:18:32 +000044const bool ENABLE_POINTER_CHOREOGRAPHER = input_flags::enable_pointer_choreographer();
Vaibhav Devmurari5766aee2023-11-03 17:21:25 +000045const bool ENABLE_INPUT_FILTER_RUST = input_flags::enable_input_filter_rust_impl();
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000046
Prabir Pradhan44e6e832023-06-06 00:03:25 +000047int32_t exceptionCodeFromStatusT(status_t status) {
Garfield Tan15601662020-09-22 15:32:38 -070048 switch (status) {
49 case OK:
50 return binder::Status::EX_NONE;
51 case INVALID_OPERATION:
52 return binder::Status::EX_UNSUPPORTED_OPERATION;
53 case BAD_VALUE:
54 case BAD_TYPE:
55 case NAME_NOT_FOUND:
56 return binder::Status::EX_ILLEGAL_ARGUMENT;
57 case NO_INIT:
58 return binder::Status::EX_ILLEGAL_STATE;
59 case PERMISSION_DENIED:
60 return binder::Status::EX_SECURITY;
61 default:
62 return binder::Status::EX_TRANSACTION_FAILED;
63 }
64}
65
Prabir Pradhan44e6e832023-06-06 00:03:25 +000066// Convert a binder interface into a raw pointer to an AIBinder.
67using IInputFlingerRustBootstrapCallback = aidl::com::android::server::inputflinger::
68 IInputFlingerRust::IInputFlingerRustBootstrapCallback;
69IInputFlingerRustBootstrapCallbackAIBinder* binderToPointer(
70 IInputFlingerRustBootstrapCallback& interface) {
71 ndk::SpAIBinder spAIBinder = interface.asBinder();
72 auto* ptr = spAIBinder.get();
73 AIBinder_incStrong(ptr);
74 return ptr;
75}
76
77// Create the Rust component of InputFlinger that uses AIDL interfaces as a the foreign function
78// interface (FFI). The bootstraping process for IInputFlingerRust is as follows:
79// - Create BnInputFlingerRustBootstrapCallback in C++.
80// - Use the cxxbridge ffi interface to call the Rust function `create_inputflinger_rust()`, and
81// pass the callback binder object as a raw pointer.
82// - The Rust implementation will create the implementation of IInputFlingerRust, and pass it
83// to C++ through the callback.
84// - After the Rust function returns, the binder interface provided to the callback will be the
85// only strong reference to the IInputFlingerRust.
86std::shared_ptr<IInputFlingerRust> createInputFlingerRust() {
87 using namespace aidl::com::android::server::inputflinger;
88
89 class Callback : public IInputFlingerRust::BnInputFlingerRustBootstrapCallback {
90 ndk::ScopedAStatus onProvideInputFlingerRust(
91 const std::shared_ptr<IInputFlingerRust>& inputFlingerRust) override {
92 mService = inputFlingerRust;
93 return ndk::ScopedAStatus::ok();
94 }
95
96 public:
97 std::shared_ptr<IInputFlingerRust> consumeInputFlingerRust() {
98 auto service = mService;
99 mService.reset();
100 return service;
101 }
102
103 private:
104 std::shared_ptr<IInputFlingerRust> mService;
105 };
106
107 auto callback = ndk::SharedRefBase::make<Callback>();
108 create_inputflinger_rust(binderToPointer(*callback));
109 auto service = callback->consumeInputFlingerRust();
110 LOG_ALWAYS_FATAL_IF(!service,
111 "create_inputflinger_rust did not provide the IInputFlingerRust "
112 "implementation through the callback.");
113 return service;
114}
115
116} // namespace
117
Siarhei Vishniakouba0a8752021-09-14 14:43:25 -0700118/**
119 * The event flow is via the "InputListener" interface, as follows:
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000120 * InputReader
121 * -> UnwantedInteractionBlocker
Vaibhav Devmurari5766aee2023-11-03 17:21:25 +0000122 * -> InputFilter
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000123 * -> PointerChoreographer
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000124 * -> InputProcessor
125 * -> InputDeviceMetricsCollector
126 * -> InputDispatcher
Siarhei Vishniakouba0a8752021-09-14 14:43:25 -0700127 */
Prabir Pradhana41d2442023-04-20 21:30:40 +0000128InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000129 InputDispatcherPolicyInterface& dispatcherPolicy,
Vaibhav Devmurarie948d4b2023-12-28 13:41:32 +0000130 PointerChoreographerPolicyInterface& choreographerPolicy,
131 InputFilterPolicyInterface& inputFilterPolicy) {
Prabir Pradhan44e6e832023-06-06 00:03:25 +0000132 mInputFlingerRust = createInputFlingerRust();
133
Garfield Tane84e6f92019-08-29 17:28:41 -0700134 mDispatcher = createInputDispatcher(dispatcherPolicy);
Prabir Pradhan274aa2c2023-08-18 17:27:07 +0000135 mTracingStages.emplace_back(
136 std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher));
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000137
Vaibhav Devmurari5766aee2023-11-03 17:21:25 +0000138 if (ENABLE_INPUT_FILTER_RUST) {
Vaibhav Devmurarie948d4b2023-12-28 13:41:32 +0000139 mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust,
140 inputFilterPolicy);
Vaibhav Devmurari5766aee2023-11-03 17:21:25 +0000141 mTracingStages.emplace_back(
142 std::make_unique<TracedInputListener>("InputFilter", *mInputFilter));
143 }
144
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000145 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
Prabir Pradhan274aa2c2023-08-18 17:27:07 +0000146 mCollector = std::make_unique<InputDeviceMetricsCollector>(*mTracingStages.back());
147 mTracingStages.emplace_back(
148 std::make_unique<TracedInputListener>("MetricsCollector", *mCollector));
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000149 }
150
Prabir Pradhan274aa2c2023-08-18 17:27:07 +0000151 mProcessor = std::make_unique<InputProcessor>(*mTracingStages.back());
152 mTracingStages.emplace_back(
153 std::make_unique<TracedInputListener>("InputProcessor", *mProcessor));
154
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000155 if (ENABLE_POINTER_CHOREOGRAPHER) {
156 mChoreographer =
157 std::make_unique<PointerChoreographer>(*mTracingStages.back(), choreographerPolicy);
158 mTracingStages.emplace_back(
159 std::make_unique<TracedInputListener>("PointerChoreographer", *mChoreographer));
160 }
161
Prabir Pradhan274aa2c2023-08-18 17:27:07 +0000162 mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mTracingStages.back());
163 mTracingStages.emplace_back(
164 std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker));
165
166 mReader = createInputReader(readerPolicy, *mTracingStages.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800167}
168
169InputManager::~InputManager() {
170 stop();
171}
172
Michael Wrightd02c5b62014-02-10 15:10:22 -0800173status_t InputManager::start() {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700174 status_t result = mDispatcher->start();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 if (result) {
176 ALOGE("Could not start InputDispatcher thread due to error %d.", result);
177 return result;
178 }
179
Prabir Pradhan28efc192019-11-05 01:10:04 +0000180 result = mReader->start();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 if (result) {
Prabir Pradhan28efc192019-11-05 01:10:04 +0000182 ALOGE("Could not start InputReader due to error %d.", result);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800183
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700184 mDispatcher->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 return result;
186 }
187
188 return OK;
189}
190
191status_t InputManager::stop() {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700192 status_t status = OK;
193
Prabir Pradhan28efc192019-11-05 01:10:04 +0000194 status_t result = mReader->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195 if (result) {
Prabir Pradhan28efc192019-11-05 01:10:04 +0000196 ALOGW("Could not stop InputReader due to error %d.", result);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700197 status = result;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198 }
199
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700200 result = mDispatcher->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800201 if (result) {
202 ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700203 status = result;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 }
205
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700206 return status;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800207}
208
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700209InputReaderInterface& InputManager::getReader() {
210 return *mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211}
212
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000213PointerChoreographerInterface& InputManager::getChoreographer() {
214 return *mChoreographer;
215}
216
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700217InputProcessorInterface& InputManager::getProcessor() {
218 return *mProcessor;
Siarhei Vishniakoua028c442019-02-04 14:33:23 -0800219}
220
Prabir Pradhan8ede1d12023-05-08 19:37:44 +0000221InputDeviceMetricsCollectorInterface& InputManager::getMetricsCollector() {
222 return *mCollector;
223}
224
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700225InputDispatcherInterface& InputManager::getDispatcher() {
226 return *mDispatcher;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227}
228
Vaibhav Devmurari953e6a42023-11-21 18:24:19 +0000229InputFilterInterface& InputManager::getInputFilter() {
230 return *mInputFilter;
231}
232
Siarhei Vishniakou9f330c52022-05-17 05:03:42 -0700233void InputManager::monitor() {
234 mReader->monitor();
235 mBlocker->monitor();
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700236 mProcessor->monitor();
Prabir Pradhan95019ac2023-12-06 22:38:21 +0000237 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
238 mCollector->monitor();
239 }
Siarhei Vishniakou9f330c52022-05-17 05:03:42 -0700240 mDispatcher->monitor();
241}
242
Prabir Pradhan370dbc92023-04-06 00:02:05 +0000243void InputManager::dump(std::string& dump) {
244 mReader->dump(dump);
245 dump += '\n';
246 mBlocker->dump(dump);
247 dump += '\n';
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000248 if (ENABLE_POINTER_CHOREOGRAPHER) {
249 mChoreographer->dump(dump);
250 dump += '\n';
251 }
Prabir Pradhan370dbc92023-04-06 00:02:05 +0000252 mProcessor->dump(dump);
253 dump += '\n';
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000254 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
255 mCollector->dump(dump);
256 dump += '\n';
257 }
Prabir Pradhan370dbc92023-04-06 00:02:05 +0000258 mDispatcher->dump(dump);
259 dump += '\n';
260}
261
Robert Carr1c4c5592018-09-24 13:18:43 -0700262// Used by tests only.
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800263binder::Status InputManager::createInputChannel(const std::string& name,
264 android::os::InputChannelCore* outChannel) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700265 IPCThreadState* ipc = IPCThreadState::self();
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800266 const uid_t uid = ipc->getCallingUid();
Robert Carr1c4c5592018-09-24 13:18:43 -0700267 if (uid != AID_SHELL && uid != AID_ROOT) {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800268 LOG(ERROR) << __func__ << " can only be called by SHELL or ROOT users, "
269 << "but was called from UID " << uid;
270 return binder::Status::
271 fromExceptionCode(EX_SECURITY,
272 "This uid is not allowed to call createInputChannel");
Robert Carr1c4c5592018-09-24 13:18:43 -0700273 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500274
Garfield Tan15601662020-09-22 15:32:38 -0700275 base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
Bernie Innocenti189c0f82020-12-22 19:45:18 +0900276 if (!channel.ok()) {
Garfield Tan15601662020-09-22 15:32:38 -0700277 return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
278 channel.error().message().c_str());
279 }
280 (*channel)->copyTo(*outChannel);
Chris Ye0783e992020-06-02 21:34:49 -0700281 return binder::Status::ok();
Robert Carr1c4c5592018-09-24 13:18:43 -0700282}
283
Garfield Tan15601662020-09-22 15:32:38 -0700284binder::Status InputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
285 mDispatcher->removeInputChannel(connectionToken);
Chris Ye0783e992020-06-02 21:34:49 -0700286 return binder::Status::ok();
287}
288
289status_t InputManager::dump(int fd, const Vector<String16>& args) {
290 std::string dump;
291
292 dump += " InputFlinger dump\n";
293
Siarhei Vishniakoucac84272023-06-28 14:43:25 -0700294 TEMP_FAILURE_RETRY(::write(fd, dump.c_str(), dump.size()));
Chris Ye0783e992020-06-02 21:34:49 -0700295 return NO_ERROR;
Robert Carr1c4c5592018-09-24 13:18:43 -0700296}
297
Prabir Pradhan44e6e832023-06-06 00:03:25 +0000298binder::Status InputManager::setFocusedWindow(const gui::FocusRequest& request) {
Vishnu Naire798b472020-07-23 13:52:21 -0700299 mDispatcher->setFocusedWindow(request);
300 return binder::Status::ok();
301}
302
Michael Wrightd02c5b62014-02-10 15:10:22 -0800303} // namespace android