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