blob: da79ae3a4844993972afa520c619c9db22768ee4 [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 Pradhan44e6e832023-06-06 00:03:25 +000030#include <inputflinger_bootstrap.rs.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070031#include <log/log.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070032#include <private/android_filesystem_config.h>
33
Michael Wrightd02c5b62014-02-10 15:10:22 -080034namespace android {
35
Prabir Pradhan44e6e832023-06-06 00:03:25 +000036namespace {
37
38const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
Prabir Pradhan7adabad2023-06-28 16:16:27 +000039 sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
Prabir Pradhanaddf8e92023-04-06 00:28:48 +000040
Prabir Pradhan44e6e832023-06-06 00:03:25 +000041int32_t exceptionCodeFromStatusT(status_t status) {
Garfield Tan15601662020-09-22 15:32:38 -070042 switch (status) {
43 case OK:
44 return binder::Status::EX_NONE;
45 case INVALID_OPERATION:
46 return binder::Status::EX_UNSUPPORTED_OPERATION;
47 case BAD_VALUE:
48 case BAD_TYPE:
49 case NAME_NOT_FOUND:
50 return binder::Status::EX_ILLEGAL_ARGUMENT;
51 case NO_INIT:
52 return binder::Status::EX_ILLEGAL_STATE;
53 case PERMISSION_DENIED:
54 return binder::Status::EX_SECURITY;
55 default:
56 return binder::Status::EX_TRANSACTION_FAILED;
57 }
58}
59
Prabir Pradhan44e6e832023-06-06 00:03:25 +000060// Convert a binder interface into a raw pointer to an AIBinder.
61using IInputFlingerRustBootstrapCallback = aidl::com::android::server::inputflinger::
62 IInputFlingerRust::IInputFlingerRustBootstrapCallback;
63IInputFlingerRustBootstrapCallbackAIBinder* binderToPointer(
64 IInputFlingerRustBootstrapCallback& interface) {
65 ndk::SpAIBinder spAIBinder = interface.asBinder();
66 auto* ptr = spAIBinder.get();
67 AIBinder_incStrong(ptr);
68 return ptr;
69}
70
71// Create the Rust component of InputFlinger that uses AIDL interfaces as a the foreign function
72// interface (FFI). The bootstraping process for IInputFlingerRust is as follows:
73// - Create BnInputFlingerRustBootstrapCallback in C++.
74// - Use the cxxbridge ffi interface to call the Rust function `create_inputflinger_rust()`, and
75// pass the callback binder object as a raw pointer.
76// - The Rust implementation will create the implementation of IInputFlingerRust, and pass it
77// to C++ through the callback.
78// - After the Rust function returns, the binder interface provided to the callback will be the
79// only strong reference to the IInputFlingerRust.
80std::shared_ptr<IInputFlingerRust> createInputFlingerRust() {
81 using namespace aidl::com::android::server::inputflinger;
82
83 class Callback : public IInputFlingerRust::BnInputFlingerRustBootstrapCallback {
84 ndk::ScopedAStatus onProvideInputFlingerRust(
85 const std::shared_ptr<IInputFlingerRust>& inputFlingerRust) override {
86 mService = inputFlingerRust;
87 return ndk::ScopedAStatus::ok();
88 }
89
90 public:
91 std::shared_ptr<IInputFlingerRust> consumeInputFlingerRust() {
92 auto service = mService;
93 mService.reset();
94 return service;
95 }
96
97 private:
98 std::shared_ptr<IInputFlingerRust> mService;
99 };
100
101 auto callback = ndk::SharedRefBase::make<Callback>();
102 create_inputflinger_rust(binderToPointer(*callback));
103 auto service = callback->consumeInputFlingerRust();
104 LOG_ALWAYS_FATAL_IF(!service,
105 "create_inputflinger_rust did not provide the IInputFlingerRust "
106 "implementation through the callback.");
107 return service;
108}
109
110} // namespace
111
Siarhei Vishniakouba0a8752021-09-14 14:43:25 -0700112/**
113 * The event flow is via the "InputListener" interface, as follows:
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000114 * InputReader
115 * -> UnwantedInteractionBlocker
116 * -> InputProcessor
117 * -> InputDeviceMetricsCollector
118 * -> InputDispatcher
Siarhei Vishniakouba0a8752021-09-14 14:43:25 -0700119 */
Prabir Pradhana41d2442023-04-20 21:30:40 +0000120InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
121 InputDispatcherPolicyInterface& dispatcherPolicy) {
Prabir Pradhan44e6e832023-06-06 00:03:25 +0000122 mInputFlingerRust = createInputFlingerRust();
123
Garfield Tane84e6f92019-08-29 17:28:41 -0700124 mDispatcher = createInputDispatcher(dispatcherPolicy);
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000125
126 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
127 mCollector = std::make_unique<InputDeviceMetricsCollector>(*mDispatcher);
128 }
129
130 mProcessor = ENABLE_INPUT_DEVICE_USAGE_METRICS ? std::make_unique<InputProcessor>(*mCollector)
131 : std::make_unique<InputProcessor>(*mDispatcher);
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700132 mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mProcessor);
Siarhei Vishniakou9f330c52022-05-17 05:03:42 -0700133 mReader = createInputReader(readerPolicy, *mBlocker);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134}
135
136InputManager::~InputManager() {
137 stop();
138}
139
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140status_t InputManager::start() {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700141 status_t result = mDispatcher->start();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 if (result) {
143 ALOGE("Could not start InputDispatcher thread due to error %d.", result);
144 return result;
145 }
146
Prabir Pradhan28efc192019-11-05 01:10:04 +0000147 result = mReader->start();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 if (result) {
Prabir Pradhan28efc192019-11-05 01:10:04 +0000149 ALOGE("Could not start InputReader due to error %d.", result);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800150
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700151 mDispatcher->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152 return result;
153 }
154
155 return OK;
156}
157
158status_t InputManager::stop() {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700159 status_t status = OK;
160
Prabir Pradhan28efc192019-11-05 01:10:04 +0000161 status_t result = mReader->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162 if (result) {
Prabir Pradhan28efc192019-11-05 01:10:04 +0000163 ALOGW("Could not stop InputReader due to error %d.", result);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700164 status = result;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165 }
166
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700167 result = mDispatcher->stop();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168 if (result) {
169 ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700170 status = result;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171 }
172
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700173 return status;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174}
175
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700176InputReaderInterface& InputManager::getReader() {
177 return *mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178}
179
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700180InputProcessorInterface& InputManager::getProcessor() {
181 return *mProcessor;
Siarhei Vishniakoua028c442019-02-04 14:33:23 -0800182}
183
Prabir Pradhan8ede1d12023-05-08 19:37:44 +0000184InputDeviceMetricsCollectorInterface& InputManager::getMetricsCollector() {
185 return *mCollector;
186}
187
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700188InputDispatcherInterface& InputManager::getDispatcher() {
189 return *mDispatcher;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190}
191
Siarhei Vishniakou9f330c52022-05-17 05:03:42 -0700192void InputManager::monitor() {
193 mReader->monitor();
194 mBlocker->monitor();
Siarhei Vishniakou98996032022-08-03 11:54:47 -0700195 mProcessor->monitor();
Siarhei Vishniakou9f330c52022-05-17 05:03:42 -0700196 mDispatcher->monitor();
197}
198
Prabir Pradhan370dbc92023-04-06 00:02:05 +0000199void InputManager::dump(std::string& dump) {
200 mReader->dump(dump);
201 dump += '\n';
202 mBlocker->dump(dump);
203 dump += '\n';
204 mProcessor->dump(dump);
205 dump += '\n';
Prabir Pradhanaddf8e92023-04-06 00:28:48 +0000206 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
207 mCollector->dump(dump);
208 dump += '\n';
209 }
Prabir Pradhan370dbc92023-04-06 00:02:05 +0000210 mDispatcher->dump(dump);
211 dump += '\n';
212}
213
Robert Carr1c4c5592018-09-24 13:18:43 -0700214// Used by tests only.
Garfield Tan15601662020-09-22 15:32:38 -0700215binder::Status InputManager::createInputChannel(const std::string& name, InputChannel* outChannel) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700216 IPCThreadState* ipc = IPCThreadState::self();
217 const int uid = ipc->getCallingUid();
218 if (uid != AID_SHELL && uid != AID_ROOT) {
219 ALOGE("Invalid attempt to register input channel over IPC"
220 "from non shell/root entity (PID: %d)", ipc->getCallingPid());
Chris Ye0783e992020-06-02 21:34:49 -0700221 return binder::Status::ok();
Robert Carr1c4c5592018-09-24 13:18:43 -0700222 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500223
Garfield Tan15601662020-09-22 15:32:38 -0700224 base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
Bernie Innocenti189c0f82020-12-22 19:45:18 +0900225 if (!channel.ok()) {
Garfield Tan15601662020-09-22 15:32:38 -0700226 return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
227 channel.error().message().c_str());
228 }
229 (*channel)->copyTo(*outChannel);
Chris Ye0783e992020-06-02 21:34:49 -0700230 return binder::Status::ok();
Robert Carr1c4c5592018-09-24 13:18:43 -0700231}
232
Garfield Tan15601662020-09-22 15:32:38 -0700233binder::Status InputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
234 mDispatcher->removeInputChannel(connectionToken);
Chris Ye0783e992020-06-02 21:34:49 -0700235 return binder::Status::ok();
236}
237
238status_t InputManager::dump(int fd, const Vector<String16>& args) {
239 std::string dump;
240
241 dump += " InputFlinger dump\n";
242
Siarhei Vishniakoucac84272023-06-28 14:43:25 -0700243 TEMP_FAILURE_RETRY(::write(fd, dump.c_str(), dump.size()));
Chris Ye0783e992020-06-02 21:34:49 -0700244 return NO_ERROR;
Robert Carr1c4c5592018-09-24 13:18:43 -0700245}
246
Prabir Pradhan44e6e832023-06-06 00:03:25 +0000247binder::Status InputManager::setFocusedWindow(const gui::FocusRequest& request) {
Vishnu Naire798b472020-07-23 13:52:21 -0700248 mDispatcher->setFocusedWindow(request);
249 return binder::Status::ok();
250}
251
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252} // namespace android