1 /*
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"
22 #include "InputDispatcherFactory.h"
23 #include "InputReaderFactory.h"
24 #include "UnwantedInteractionBlocker.h"
25
26 #include <aidl/com/android/server/inputflinger/IInputFlingerRust.h>
27 #include <android/binder_interface_utils.h>
28 #include <android/sysprop/InputProperties.sysprop.h>
29 #include <binder/IPCThreadState.h>
30 #include <com_android_input_flags.h>
31 #include <inputflinger_bootstrap.rs.h>
32 #include <log/log.h>
33 #include <private/android_filesystem_config.h>
34
35 namespace input_flags = com::android::input::flags;
36
37 namespace android {
38
39 namespace {
40
41 const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
42 sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
43
44 const bool ENABLE_INPUT_FILTER_RUST = input_flags::enable_input_filter_rust_impl();
45
exceptionCodeFromStatusT(status_t status)46 int32_t exceptionCodeFromStatusT(status_t status) {
47 switch (status) {
48 case OK:
49 return binder::Status::EX_NONE;
50 case INVALID_OPERATION:
51 return binder::Status::EX_UNSUPPORTED_OPERATION;
52 case BAD_VALUE:
53 case BAD_TYPE:
54 case NAME_NOT_FOUND:
55 return binder::Status::EX_ILLEGAL_ARGUMENT;
56 case NO_INIT:
57 return binder::Status::EX_ILLEGAL_STATE;
58 case PERMISSION_DENIED:
59 return binder::Status::EX_SECURITY;
60 default:
61 return binder::Status::EX_TRANSACTION_FAILED;
62 }
63 }
64
65 // Convert a binder interface into a raw pointer to an AIBinder.
66 using IInputFlingerRustBootstrapCallback = aidl::com::android::server::inputflinger::
67 IInputFlingerRust::IInputFlingerRustBootstrapCallback;
binderToPointer(IInputFlingerRustBootstrapCallback & interface)68 IInputFlingerRustBootstrapCallbackAIBinder* binderToPointer(
69 IInputFlingerRustBootstrapCallback& interface) {
70 ndk::SpAIBinder spAIBinder = interface.asBinder();
71 auto* ptr = spAIBinder.get();
72 AIBinder_incStrong(ptr);
73 return ptr;
74 }
75
76 // Create the Rust component of InputFlinger that uses AIDL interfaces as a the foreign function
77 // interface (FFI). The bootstraping process for IInputFlingerRust is as follows:
78 // - Create BnInputFlingerRustBootstrapCallback in C++.
79 // - Use the cxxbridge ffi interface to call the Rust function `create_inputflinger_rust()`, and
80 // pass the callback binder object as a raw pointer.
81 // - The Rust implementation will create the implementation of IInputFlingerRust, and pass it
82 // to C++ through the callback.
83 // - After the Rust function returns, the binder interface provided to the callback will be the
84 // only strong reference to the IInputFlingerRust.
createInputFlingerRust()85 std::shared_ptr<IInputFlingerRust> createInputFlingerRust() {
86 using namespace aidl::com::android::server::inputflinger;
87
88 class Callback : public IInputFlingerRust::BnInputFlingerRustBootstrapCallback {
89 ndk::ScopedAStatus onProvideInputFlingerRust(
90 const std::shared_ptr<IInputFlingerRust>& inputFlingerRust) override {
91 mService = inputFlingerRust;
92 return ndk::ScopedAStatus::ok();
93 }
94
95 public:
96 std::shared_ptr<IInputFlingerRust> consumeInputFlingerRust() {
97 auto service = mService;
98 mService.reset();
99 return service;
100 }
101
102 private:
103 std::shared_ptr<IInputFlingerRust> mService;
104 };
105
106 auto callback = ndk::SharedRefBase::make<Callback>();
107 create_inputflinger_rust(binderToPointer(*callback));
108 auto service = callback->consumeInputFlingerRust();
109 LOG_ALWAYS_FATAL_IF(!service,
110 "create_inputflinger_rust did not provide the IInputFlingerRust "
111 "implementation through the callback.");
112 return service;
113 }
114
115 } // namespace
116
117 /**
118 * The event flow is via the "InputListener" interface, as follows:
119 * InputReader
120 * -> UnwantedInteractionBlocker
121 * -> InputFilter
122 * -> PointerChoreographer
123 * -> InputProcessor
124 * -> InputDeviceMetricsCollector
125 * -> InputDispatcher
126 */
InputManager(const sp<InputReaderPolicyInterface> & readerPolicy,InputDispatcherPolicyInterface & dispatcherPolicy,PointerChoreographerPolicyInterface & choreographerPolicy,InputFilterPolicyInterface & inputFilterPolicy)127 InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
128 InputDispatcherPolicyInterface& dispatcherPolicy,
129 PointerChoreographerPolicyInterface& choreographerPolicy,
130 InputFilterPolicyInterface& inputFilterPolicy) {
131 mInputFlingerRust = createInputFlingerRust();
132
133 mDispatcher = createInputDispatcher(dispatcherPolicy);
134 mTracingStages.emplace_back(
135 std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher));
136
137 if (ENABLE_INPUT_FILTER_RUST) {
138 mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust,
139 inputFilterPolicy);
140 mTracingStages.emplace_back(
141 std::make_unique<TracedInputListener>("InputFilter", *mInputFilter));
142 }
143
144 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
145 mCollector = std::make_unique<InputDeviceMetricsCollector>(*mTracingStages.back());
146 mTracingStages.emplace_back(
147 std::make_unique<TracedInputListener>("MetricsCollector", *mCollector));
148 }
149
150 mProcessor = std::make_unique<InputProcessor>(*mTracingStages.back());
151 mTracingStages.emplace_back(
152 std::make_unique<TracedInputListener>("InputProcessor", *mProcessor));
153
154 mChoreographer =
155 std::make_unique<PointerChoreographer>(*mTracingStages.back(), choreographerPolicy);
156 mTracingStages.emplace_back(
157 std::make_unique<TracedInputListener>("PointerChoreographer", *mChoreographer));
158
159 mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mTracingStages.back());
160 mTracingStages.emplace_back(
161 std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker));
162
163 mReader = createInputReader(readerPolicy, *mTracingStages.back());
164 }
165
~InputManager()166 InputManager::~InputManager() {
167 stop();
168 }
169
start()170 status_t InputManager::start() {
171 status_t result = mDispatcher->start();
172 if (result) {
173 ALOGE("Could not start InputDispatcher thread due to error %d.", result);
174 return result;
175 }
176
177 result = mReader->start();
178 if (result) {
179 ALOGE("Could not start InputReader due to error %d.", result);
180
181 mDispatcher->stop();
182 return result;
183 }
184
185 return OK;
186 }
187
stop()188 status_t InputManager::stop() {
189 status_t status = OK;
190
191 status_t result = mReader->stop();
192 if (result) {
193 ALOGW("Could not stop InputReader due to error %d.", result);
194 status = result;
195 }
196
197 result = mDispatcher->stop();
198 if (result) {
199 ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
200 status = result;
201 }
202
203 return status;
204 }
205
getReader()206 InputReaderInterface& InputManager::getReader() {
207 return *mReader;
208 }
209
getChoreographer()210 PointerChoreographerInterface& InputManager::getChoreographer() {
211 return *mChoreographer;
212 }
213
getProcessor()214 InputProcessorInterface& InputManager::getProcessor() {
215 return *mProcessor;
216 }
217
getMetricsCollector()218 InputDeviceMetricsCollectorInterface& InputManager::getMetricsCollector() {
219 return *mCollector;
220 }
221
getDispatcher()222 InputDispatcherInterface& InputManager::getDispatcher() {
223 return *mDispatcher;
224 }
225
getInputFilter()226 InputFilterInterface& InputManager::getInputFilter() {
227 return *mInputFilter;
228 }
229
monitor()230 void InputManager::monitor() {
231 mReader->monitor();
232 mBlocker->monitor();
233 mProcessor->monitor();
234 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
235 mCollector->monitor();
236 }
237 mDispatcher->monitor();
238 }
239
dump(std::string & dump)240 void InputManager::dump(std::string& dump) {
241 mReader->dump(dump);
242 dump += '\n';
243 mBlocker->dump(dump);
244 dump += '\n';
245 mChoreographer->dump(dump);
246 dump += '\n';
247 mProcessor->dump(dump);
248 dump += '\n';
249 if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
250 mCollector->dump(dump);
251 dump += '\n';
252 }
253 mDispatcher->dump(dump);
254 dump += '\n';
255 }
256
257 // Used by tests only.
createInputChannel(const std::string & name,android::os::InputChannelCore * outChannel)258 binder::Status InputManager::createInputChannel(const std::string& name,
259 android::os::InputChannelCore* outChannel) {
260 IPCThreadState* ipc = IPCThreadState::self();
261 const uid_t uid = ipc->getCallingUid();
262 if (uid != AID_SHELL && uid != AID_ROOT) {
263 LOG(ERROR) << __func__ << " can only be called by SHELL or ROOT users, "
264 << "but was called from UID " << uid;
265 return binder::Status::
266 fromExceptionCode(EX_SECURITY,
267 "This uid is not allowed to call createInputChannel");
268 }
269
270 base::Result<std::unique_ptr<InputChannel>> channel = mDispatcher->createInputChannel(name);
271 if (!channel.ok()) {
272 return binder::Status::fromExceptionCode(exceptionCodeFromStatusT(channel.error().code()),
273 channel.error().message().c_str());
274 }
275 InputChannel::moveChannel(std::move(*channel), *outChannel);
276 return binder::Status::ok();
277 }
278
removeInputChannel(const sp<IBinder> & connectionToken)279 binder::Status InputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
280 mDispatcher->removeInputChannel(connectionToken);
281 return binder::Status::ok();
282 }
283
dump(int fd,const Vector<String16> & args)284 status_t InputManager::dump(int fd, const Vector<String16>& args) {
285 std::string dump;
286
287 dump += " InputFlinger dump\n";
288
289 TEMP_FAILURE_RETRY(::write(fd, dump.c_str(), dump.size()));
290 return NO_ERROR;
291 }
292
setFocusedWindow(const gui::FocusRequest & request)293 binder::Status InputManager::setFocusedWindow(const gui::FocusRequest& request) {
294 mDispatcher->setFocusedWindow(request);
295 return binder::Status::ok();
296 }
297
298 } // namespace android
299