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

Commit 531b5ba1 authored by Jesus Sanchez-Palencia's avatar Jesus Sanchez-Palencia
Browse files

lights: Re-write example service in Rust

Add a re-implementation of the Lights HAL example service in Rust. This
was originally written as the start of a Cuttlefish specific
implementation of this service, but it's simple / small enough that
replacing the current Android C++ one with it shouldn't bring in any
trouble while providing yet another Rust service example to the tree.

Tested: built VtsHalLightTargetTest and ran in Cuttlefish
Bug: 286106270
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a796fb113c405838424e61fd0b4cd6e0ef86c5a7)

Change-Id: I01eaf9ce7c6086e1429f52ff4f7f92cebc5360b6
parent 4a7c3810
Loading
Loading
Loading
Loading
+7 −9
Original line number Diff line number Diff line
@@ -7,19 +7,17 @@ package {
    default_applicable_licenses: ["hardware_interfaces_license"],
}

cc_binary {
rust_binary {
    name: "android.hardware.lights-service.example",
    relative_install_path: "hw",
    init_rc: ["lights-default.rc"],
    vintf_fragments: ["lights-default.xml"],
    vendor: true,
    shared_libs: [
        "libbase",
        "libbinder_ndk",
        "android.hardware.light-V2-ndk",
    ],
    srcs: [
        "Lights.cpp",
        "main.cpp",
    rustlibs: [
        "liblogger",
        "liblog_rust",
        "libbinder_rs",
        "android.hardware.light-V2-rust",
    ],
    srcs: [ "main.rs" ],
}
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 * Copyright (C) 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.
@@ -13,23 +13,43 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//! This module implements the ILights AIDL interface.

#pragma once
use log::info;

#include <aidl/android/hardware/light/BnLights.h>
use android_hardware_light::aidl::android::hardware::light::{
    HwLight::HwLight, HwLightState::HwLightState, ILights::ILights, LightType::LightType,
};

namespace aidl {
namespace android {
namespace hardware {
namespace light {
use binder::{ExceptionCode, Interface, Status};

// Default implementation that reports a few placeholder lights.
class Lights : public BnLights {
    ndk::ScopedAStatus setLightState(int id, const HwLightState& state) override;
    ndk::ScopedAStatus getLights(std::vector<HwLight>* lights) override;
};
/// Defined so we can implement the ILights AIDL interface.
pub struct LightsService;

impl Interface for LightsService {}

const NUM_DEFAULT_LIGHTS: i32 = 3;

impl ILights for LightsService {
    fn setLightState(&self, id: i32, state: &HwLightState) -> binder::Result<()> {
        info!("Lights setting state for id={} to color {:x}", id, state.color);
        if id <= 0 || id > NUM_DEFAULT_LIGHTS {
            return Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, None));
        }

        Ok(())
    }

    fn getLights(&self) -> binder::Result<Vec<HwLight>> {
        let mut lights: Vec<HwLight> = Vec::with_capacity(NUM_DEFAULT_LIGHTS.try_into().unwrap());

        for i in 1..=NUM_DEFAULT_LIGHTS {
            let light = HwLight { id: i, ordinal: i, r#type: LightType::BACKLIGHT };

            lights.push(light);
        }

}  // namespace light
}  // namespace hardware
}  // namespace android
}  // namespace aidl
        info!("Lights reporting supported lights");
        Ok(lights)
    }
}

light/aidl/default/main.cpp

deleted100644 → 0
+0 −35
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

#include "Lights.h"

#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>

using ::aidl::android::hardware::light::Lights;

int main() {
    ABinderProcess_setThreadPoolMaxThreadCount(0);
    std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();

    const std::string instance = std::string() + Lights::descriptor + "/default";
    binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str());
    CHECK_EQ(status, STATUS_OK);

    ABinderProcess_joinThreadPool();
    return EXIT_FAILURE;  // should not reached
}
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 * Copyright (C) 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.
@@ -13,36 +13,34 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//! This implements the Lights Example Service.

#include "Lights.h"
use android_hardware_light::aidl::android::hardware::light::ILights::{BnLights, ILights};
use binder::BinderFeatures;

#include <android-base/logging.h>
mod lights;
use lights::LightsService;

namespace aidl {
namespace android {
namespace hardware {
namespace light {
const LOG_TAG: &str = "lights_service_example_rust";

static constexpr int kNumDefaultLights = 3;
use log::Level;

ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
    LOG(INFO) << "Lights setting state for id=" << id << " to color " << std::hex << state.color;
    if (id <= 0 || id > kNumDefaultLights) {
        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    } else {
        return ndk::ScopedAStatus::ok();
    }
fn main() {
    let logger_success = logger::init(
        logger::Config::default().with_tag_on_device(LOG_TAG).with_min_level(Level::Trace),
    );
    if !logger_success {
        panic!("{LOG_TAG}: Failed to start logger.");
    }

ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
    for (int i = 1; i <= kNumDefaultLights; i++) {
        lights->push_back({i, i});
    }
    LOG(INFO) << "Lights reporting supported lights";
    return ndk::ScopedAStatus::ok();
}
    binder::ProcessState::set_thread_pool_max_thread_count(0);

}  // namespace light
}  // namespace hardware
}  // namespace android
}  // namespace aidl
    let lights_service = LightsService;
    let lights_service_binder = BnLights::new_binder(lights_service, BinderFeatures::default());

    let service_name = format!("{}/default", LightsService::get_descriptor());
    binder::add_service(&service_name, lights_service_binder.as_binder())
        .expect("Failed to register service");

    binder::ProcessState::join_thread_pool()
}
Loading