Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98d61f5d authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Bootstrap IInputFlingerRust - the Rust component of inputflinger" into main

parents 30feaa2a 44e6e832
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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",
@@ -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: [
+62 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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) {
@@ -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();
}
+5 −0
Original line number Diff line number Diff line
@@ -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>
@@ -37,6 +38,8 @@

using android::os::BnInputFlinger;

using aidl::com::android::server::inputflinger::IInputFlingerRust;

namespace android {
class InputChannel;
class InputDispatcherThread;
@@ -132,6 +135,8 @@ private:
    std::unique_ptr<InputDeviceMetricsCollectorInterface> mCollector;

    std::unique_ptr<InputDispatcherInterface> mDispatcher;

    std::shared_ptr<IInputFlingerRust> mInputFlingerRust;
};

} // namespace android
+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,
        },
    },
}
+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