• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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