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