Loading services/inputflinger/Android.bp +9 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ cc_defaults { srcs: [":libinputflinger_sources"], shared_libs: [ "android.hardware.input.processor-V1-ndk", "com.android.server.inputflinger-ndk", "libbase", "libbinder", "libbinder_ndk", Loading @@ -107,6 +108,14 @@ cc_defaults { "libpalmrejection", "libui-types", ], generated_headers: [ "cxx-bridge-header", "inputflinger_rs_bootstrap_bridge_header", ], header_libs: ["inputflinger_rs_bootstrap_cxx_headers"], generated_sources: ["inputflinger_rs_bootstrap_bridge_code"], whole_static_libs: ["libinputflinger_rs"], export_shared_lib_headers: ["com.android.server.inputflinger-ndk"], target: { android: { shared_libs: [ Loading services/inputflinger/InputManager.cpp +62 −8 Original line number Diff line number Diff line Loading @@ -23,22 +23,22 @@ #include "InputReaderFactory.h" #include "UnwantedInteractionBlocker.h" #include <aidl/com/android/server/inputflinger/IInputFlingerRust.h> #include <android/binder_interface_utils.h> #include <android/sysprop/InputProperties.sysprop.h> #include <binder/IPCThreadState.h> #include <inputflinger_bootstrap.rs.h> #include <log/log.h> #include <unordered_map> #include <private/android_filesystem_config.h> namespace android { static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS = sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true); namespace { using gui::FocusRequest; const bool ENABLE_INPUT_DEVICE_USAGE_METRICS = sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true); static int32_t exceptionCodeFromStatusT(status_t status) { int32_t exceptionCodeFromStatusT(status_t status) { switch (status) { case OK: return binder::Status::EX_NONE; Loading @@ -57,6 +57,58 @@ static int32_t exceptionCodeFromStatusT(status_t status) { } } // Convert a binder interface into a raw pointer to an AIBinder. using IInputFlingerRustBootstrapCallback = aidl::com::android::server::inputflinger:: IInputFlingerRust::IInputFlingerRustBootstrapCallback; IInputFlingerRustBootstrapCallbackAIBinder* binderToPointer( IInputFlingerRustBootstrapCallback& interface) { ndk::SpAIBinder spAIBinder = interface.asBinder(); auto* ptr = spAIBinder.get(); AIBinder_incStrong(ptr); return ptr; } // Create the Rust component of InputFlinger that uses AIDL interfaces as a the foreign function // interface (FFI). The bootstraping process for IInputFlingerRust is as follows: // - Create BnInputFlingerRustBootstrapCallback in C++. // - Use the cxxbridge ffi interface to call the Rust function `create_inputflinger_rust()`, and // pass the callback binder object as a raw pointer. // - The Rust implementation will create the implementation of IInputFlingerRust, and pass it // to C++ through the callback. // - After the Rust function returns, the binder interface provided to the callback will be the // only strong reference to the IInputFlingerRust. std::shared_ptr<IInputFlingerRust> createInputFlingerRust() { using namespace aidl::com::android::server::inputflinger; class Callback : public IInputFlingerRust::BnInputFlingerRustBootstrapCallback { ndk::ScopedAStatus onProvideInputFlingerRust( const std::shared_ptr<IInputFlingerRust>& inputFlingerRust) override { mService = inputFlingerRust; return ndk::ScopedAStatus::ok(); } public: std::shared_ptr<IInputFlingerRust> consumeInputFlingerRust() { auto service = mService; mService.reset(); return service; } private: std::shared_ptr<IInputFlingerRust> mService; }; auto callback = ndk::SharedRefBase::make<Callback>(); create_inputflinger_rust(binderToPointer(*callback)); auto service = callback->consumeInputFlingerRust(); LOG_ALWAYS_FATAL_IF(!service, "create_inputflinger_rust did not provide the IInputFlingerRust " "implementation through the callback."); return service; } } // namespace /** * The event flow is via the "InputListener" interface, as follows: * InputReader Loading @@ -67,6 +119,8 @@ static int32_t exceptionCodeFromStatusT(status_t status) { */ InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy, InputDispatcherPolicyInterface& dispatcherPolicy) { mInputFlingerRust = createInputFlingerRust(); mDispatcher = createInputDispatcher(dispatcherPolicy); if (ENABLE_INPUT_DEVICE_USAGE_METRICS) { Loading Loading @@ -190,7 +244,7 @@ status_t InputManager::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } binder::Status InputManager::setFocusedWindow(const FocusRequest& request) { binder::Status InputManager::setFocusedWindow(const gui::FocusRequest& request) { mDispatcher->setFocusedWindow(request); return binder::Status::ok(); } Loading services/inputflinger/InputManager.h +5 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <input/Input.h> #include <input/InputTransport.h> #include <aidl/com/android/server/inputflinger/IInputFlingerRust.h> #include <android/os/BnInputFlinger.h> #include <utils/Errors.h> #include <utils/RefBase.h> Loading @@ -37,6 +38,8 @@ using android::os::BnInputFlinger; using aidl::com::android::server::inputflinger::IInputFlingerRust; namespace android { class InputChannel; class InputDispatcherThread; Loading Loading @@ -132,6 +135,8 @@ private: std::unique_ptr<InputDeviceMetricsCollectorInterface> mCollector; std::unique_ptr<InputDispatcherInterface> mDispatcher; std::shared_ptr<IInputFlingerRust> mInputFlingerRust; }; } // namespace android services/inputflinger/aidl/Android.bp 0 → 100644 +31 −0 Original line number Diff line number Diff line // Copyright 2023 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. aidl_interface { name: "com.android.server.inputflinger", srcs: ["**/*.aidl"], unstable: true, host_supported: true, backend: { cpp: { enabled: false, }, java: { enabled: false, }, rust: { enabled: true, }, }, } services/inputflinger/aidl/com/android/server/inputflinger/IInputFlingerRust.aidl 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.inputflinger; /** * A local AIDL interface used as a foreign function interface (ffi) to * communicate with the Rust component of inputflinger. * * NOTE: Since we use this as a local interface, all processing happens on the * calling thread. */ interface IInputFlingerRust { /** * An interface used to get a strong reference to IInputFlingerRust on boot. */ interface IInputFlingerRustBootstrapCallback { void onProvideInputFlingerRust(in IInputFlingerRust inputFlingerRust); } } Loading
services/inputflinger/Android.bp +9 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ cc_defaults { srcs: [":libinputflinger_sources"], shared_libs: [ "android.hardware.input.processor-V1-ndk", "com.android.server.inputflinger-ndk", "libbase", "libbinder", "libbinder_ndk", Loading @@ -107,6 +108,14 @@ cc_defaults { "libpalmrejection", "libui-types", ], generated_headers: [ "cxx-bridge-header", "inputflinger_rs_bootstrap_bridge_header", ], header_libs: ["inputflinger_rs_bootstrap_cxx_headers"], generated_sources: ["inputflinger_rs_bootstrap_bridge_code"], whole_static_libs: ["libinputflinger_rs"], export_shared_lib_headers: ["com.android.server.inputflinger-ndk"], target: { android: { shared_libs: [ Loading
services/inputflinger/InputManager.cpp +62 −8 Original line number Diff line number Diff line Loading @@ -23,22 +23,22 @@ #include "InputReaderFactory.h" #include "UnwantedInteractionBlocker.h" #include <aidl/com/android/server/inputflinger/IInputFlingerRust.h> #include <android/binder_interface_utils.h> #include <android/sysprop/InputProperties.sysprop.h> #include <binder/IPCThreadState.h> #include <inputflinger_bootstrap.rs.h> #include <log/log.h> #include <unordered_map> #include <private/android_filesystem_config.h> namespace android { static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS = sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true); namespace { using gui::FocusRequest; const bool ENABLE_INPUT_DEVICE_USAGE_METRICS = sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true); static int32_t exceptionCodeFromStatusT(status_t status) { int32_t exceptionCodeFromStatusT(status_t status) { switch (status) { case OK: return binder::Status::EX_NONE; Loading @@ -57,6 +57,58 @@ static int32_t exceptionCodeFromStatusT(status_t status) { } } // Convert a binder interface into a raw pointer to an AIBinder. using IInputFlingerRustBootstrapCallback = aidl::com::android::server::inputflinger:: IInputFlingerRust::IInputFlingerRustBootstrapCallback; IInputFlingerRustBootstrapCallbackAIBinder* binderToPointer( IInputFlingerRustBootstrapCallback& interface) { ndk::SpAIBinder spAIBinder = interface.asBinder(); auto* ptr = spAIBinder.get(); AIBinder_incStrong(ptr); return ptr; } // Create the Rust component of InputFlinger that uses AIDL interfaces as a the foreign function // interface (FFI). The bootstraping process for IInputFlingerRust is as follows: // - Create BnInputFlingerRustBootstrapCallback in C++. // - Use the cxxbridge ffi interface to call the Rust function `create_inputflinger_rust()`, and // pass the callback binder object as a raw pointer. // - The Rust implementation will create the implementation of IInputFlingerRust, and pass it // to C++ through the callback. // - After the Rust function returns, the binder interface provided to the callback will be the // only strong reference to the IInputFlingerRust. std::shared_ptr<IInputFlingerRust> createInputFlingerRust() { using namespace aidl::com::android::server::inputflinger; class Callback : public IInputFlingerRust::BnInputFlingerRustBootstrapCallback { ndk::ScopedAStatus onProvideInputFlingerRust( const std::shared_ptr<IInputFlingerRust>& inputFlingerRust) override { mService = inputFlingerRust; return ndk::ScopedAStatus::ok(); } public: std::shared_ptr<IInputFlingerRust> consumeInputFlingerRust() { auto service = mService; mService.reset(); return service; } private: std::shared_ptr<IInputFlingerRust> mService; }; auto callback = ndk::SharedRefBase::make<Callback>(); create_inputflinger_rust(binderToPointer(*callback)); auto service = callback->consumeInputFlingerRust(); LOG_ALWAYS_FATAL_IF(!service, "create_inputflinger_rust did not provide the IInputFlingerRust " "implementation through the callback."); return service; } } // namespace /** * The event flow is via the "InputListener" interface, as follows: * InputReader Loading @@ -67,6 +119,8 @@ static int32_t exceptionCodeFromStatusT(status_t status) { */ InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy, InputDispatcherPolicyInterface& dispatcherPolicy) { mInputFlingerRust = createInputFlingerRust(); mDispatcher = createInputDispatcher(dispatcherPolicy); if (ENABLE_INPUT_DEVICE_USAGE_METRICS) { Loading Loading @@ -190,7 +244,7 @@ status_t InputManager::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } binder::Status InputManager::setFocusedWindow(const FocusRequest& request) { binder::Status InputManager::setFocusedWindow(const gui::FocusRequest& request) { mDispatcher->setFocusedWindow(request); return binder::Status::ok(); } Loading
services/inputflinger/InputManager.h +5 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <input/Input.h> #include <input/InputTransport.h> #include <aidl/com/android/server/inputflinger/IInputFlingerRust.h> #include <android/os/BnInputFlinger.h> #include <utils/Errors.h> #include <utils/RefBase.h> Loading @@ -37,6 +38,8 @@ using android::os::BnInputFlinger; using aidl::com::android::server::inputflinger::IInputFlingerRust; namespace android { class InputChannel; class InputDispatcherThread; Loading Loading @@ -132,6 +135,8 @@ private: std::unique_ptr<InputDeviceMetricsCollectorInterface> mCollector; std::unique_ptr<InputDispatcherInterface> mDispatcher; std::shared_ptr<IInputFlingerRust> mInputFlingerRust; }; } // namespace android
services/inputflinger/aidl/Android.bp 0 → 100644 +31 −0 Original line number Diff line number Diff line // Copyright 2023 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. aidl_interface { name: "com.android.server.inputflinger", srcs: ["**/*.aidl"], unstable: true, host_supported: true, backend: { cpp: { enabled: false, }, java: { enabled: false, }, rust: { enabled: true, }, }, }
services/inputflinger/aidl/com/android/server/inputflinger/IInputFlingerRust.aidl 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.inputflinger; /** * A local AIDL interface used as a foreign function interface (ffi) to * communicate with the Rust component of inputflinger. * * NOTE: Since we use this as a local interface, all processing happens on the * calling thread. */ interface IInputFlingerRust { /** * An interface used to get a strong reference to IInputFlingerRust on boot. */ interface IInputFlingerRustBootstrapCallback { void onProvideInputFlingerRust(in IInputFlingerRust inputFlingerRust); } }