From d5c05c0c41dd798a7f33c8e43b2819026f7de21e Mon Sep 17 00:00:00 2001 From: "Zhong,Fangjian" Date: Wed, 21 Jun 2023 02:15:31 +0800 Subject: [PATCH] bootctrl: Update to AIDL implementation The minimum requirement for Boot HAL in android 14 should be AIDL implementation to meet target-level 8, API level 34 requirement. Tracked-On: OAM-112811 Signed-off-by: Zhong,Fangjian --- boot/Android.bp | 59 ++++- boot/BootControl.cpp | 210 ++++++++++-------- boot/BootControl.h | 63 ++---- boot/android.hardware.boot-service.rc | 4 + .../android.hardware.boot-service.recovery.rc | 6 + boot/android.hardware.boot-service.xml | 6 + boot/main.cpp | 38 ++++ 7 files changed, 245 insertions(+), 141 deletions(-) create mode 100644 boot/android.hardware.boot-service.rc create mode 100644 boot/android.hardware.boot-service.recovery.rc create mode 100644 boot/android.hardware.boot-service.xml create mode 100644 boot/main.cpp diff --git a/boot/Android.bp b/boot/Android.bp index 0799058..49d14af 100644 --- a/boot/Android.bp +++ b/boot/Android.bp @@ -1,25 +1,60 @@ -cc_library_shared { - name: "android.hardware.boot@1.2-impl-intel", - stem: "android.hardware.boot@1.0-impl-1.2-intel", +// +// Copyright (C) 2022 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. +// - relative_install_path: "hw", - vendor: true, - recovery_available: true, - srcs: ["BootControl.cpp"], +//package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + //default_applicable_licenses: ["hardware_interfaces_license"], +//} +cc_defaults { + name: "android.hardware.boot-service", + relative_install_path: "hw", + defaults: ["libboot_control_defaults"], + vintf_fragments: ["android.hardware.boot-service.xml"], shared_libs: [ - "liblog", - "libhidlbase", + "libbase", + "libbinder_ndk", "libhardware", "libutils", - "android.hardware.boot@1.0", "android.hardware.boot@1.1", - "android.hardware.boot@1.2", + "android.hardware.boot-V1-ndk", ], static_libs: [ - "libfstab", + "libboot_control", ], include_dirs: [ "hardware/intel/bootctrl", ], + srcs: ["main.cpp", "BootControl.cpp"], +} + +cc_binary { + name: "android.hardware.boot-service.intel", + defaults: ["android.hardware.boot-service"], + init_rc: ["android.hardware.boot-service.rc"], + vendor: true, +} + +cc_binary { + name: "android.hardware.boot-service.recovery", + defaults: ["android.hardware.boot-service"], + init_rc: ["android.hardware.boot-service.recovery.rc"], + recovery: true, } diff --git a/boot/BootControl.cpp b/boot/BootControl.cpp index 5167f4d..a737b13 100644 --- a/boot/BootControl.cpp +++ b/boot/BootControl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2022 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,132 +13,164 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "android.hardware.boot@1.2-impl-intel" -#include +#define LOG_TAG "android.hardware.boot-service.intel" -#include -#include -#include #include "BootControl.h" #include "boot_control_avb.h" +#include +#include -namespace android { -namespace hardware { -namespace boot { -namespace V1_2 { -namespace implementation { +#include -using ::android::hardware::boot::V1_0::CommandResult; -using ::android::hardware::boot::V1_1::MergeStatus; +using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus; +using ndk::ScopedAStatus; -BootControl::BootControl(boot_control_module_t *module) : mModule(module) {} +namespace aidl::android::hardware::boot { -// Methods from ::android::hardware::boot::V1_0::IBootControl. -Return BootControl::getNumberSlots() { - return mModule->getNumberSlots(mModule); -} +BootControl::BootControl() { + int ret = 0; + + boot_control_module_t *module = NULL; + hw_module_t **hwm = reinterpret_cast(&module); + ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast(hwm)); + if (ret) { + ALOGE("hw_get_module %s failed: %d", BOOT_CONTROL_HARDWARE_MODULE_ID, ret); + } else { + mModule = module; + } -Return BootControl::getCurrentSlot() { - return mModule->getCurrentSlot(mModule); + mModule->init(mModule); } -Return BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) { - int ret = mModule->markBootSuccessful(mModule); - struct CommandResult cr; - cr.success = (ret == 0); - cr.errMsg = strerror(-ret); - _hidl_cb(cr); - return Void(); +ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) { + *_aidl_return = mModule->getActiveBootSlot(mModule); + return ScopedAStatus::ok(); } -Return BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) { - int ret = mModule->setActiveBootSlot(mModule, slot); - struct CommandResult cr; - cr.success = (ret == 0); - cr.errMsg = strerror(-ret); - _hidl_cb(cr); - return Void(); +ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) { + *_aidl_return = mModule->getCurrentSlot(mModule); + return ScopedAStatus::ok(); } -Return BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) { - int ret = mModule->setSlotAsUnbootable(mModule, slot); - struct CommandResult cr; - cr.success = (ret == 0); - cr.errMsg = strerror(-ret); - _hidl_cb(cr); - return Void(); +ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) { + *_aidl_return = mModule->getNumberSlots(mModule); + return ScopedAStatus::ok(); } -Return BootControl::isSlotBootable(uint32_t slot) { - int32_t ret = mModule->isSlotBootable(mModule, slot); - if (ret < 0) { - return BoolResult::INVALID_SLOT; +namespace { + +static constexpr MergeStatus ToAIDLMergeStatus(HIDLMergeStatus status) { + switch (status) { + case HIDLMergeStatus::NONE: + return MergeStatus::NONE; + case HIDLMergeStatus::UNKNOWN: + return MergeStatus::UNKNOWN; + case HIDLMergeStatus::SNAPSHOTTED: + return MergeStatus::SNAPSHOTTED; + case HIDLMergeStatus::MERGING: + return MergeStatus::MERGING; + case HIDLMergeStatus::CANCELLED: + return MergeStatus::CANCELLED; } - return ret ? BoolResult::TRUE : BoolResult::FALSE; } -Return BootControl::isSlotMarkedSuccessful(uint32_t slot) { - int32_t ret = mModule->isSlotMarkedSuccessful(mModule, slot); - if (ret < 0) { - return BoolResult::INVALID_SLOT; +static constexpr HIDLMergeStatus ToHIDLMergeStatus(MergeStatus status) { + switch (status) { + case MergeStatus::NONE: + return HIDLMergeStatus::NONE; + case MergeStatus::UNKNOWN: + return HIDLMergeStatus::UNKNOWN; + case MergeStatus::SNAPSHOTTED: + return HIDLMergeStatus::SNAPSHOTTED; + case MergeStatus::MERGING: + return HIDLMergeStatus::MERGING; + case MergeStatus::CANCELLED: + return HIDLMergeStatus::CANCELLED; } - return ret ? BoolResult::TRUE : BoolResult::FALSE; } -Return BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) { - hidl_string ans; - const char *suffix = mModule->getSuffix(mModule, slot); +} + +ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) { + private_boot_control_t *pModule = (private_boot_control_t *)(mModule); + + *_aidl_return = ToAIDLMergeStatus((HIDLMergeStatus)pModule->GetSnapshotMergeStatus()); + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) { + const char *suffix = mModule->getSuffix(mModule, in_slot); + if (suffix) { - ans = suffix; + *_aidl_return = suffix; } - _hidl_cb(ans); - return Void(); + + return ScopedAStatus::ok(); } -// Methods from ::android::hardware::boot::V1_1::IBootControl. -// Snapshot merge status is only used by virtual a/b update. -Return BootControl::setSnapshotMergeStatus(MergeStatus status) { - private_boot_control_t *pModule = (private_boot_control_t *)(mModule); - return pModule->SetSnapshotMergeStatus((uint8_t)status); +ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) { + int ret = mModule->isSlotBootable(mModule, in_slot); + + if (ret < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + } + *_aidl_return = ret; + + return ScopedAStatus::ok(); } -Return BootControl::getSnapshotMergeStatus() { - private_boot_control_t *pModule = (private_boot_control_t *)(mModule); - return (MergeStatus)(pModule->GetSnapshotMergeStatus()); +ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) { + int ret = mModule->isSlotMarkedSuccessful(mModule, in_slot); + + if (ret < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + } + *_aidl_return = ret; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::markBootSuccessful() { + if (mModule->markBootSuccessful(mModule)) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Operation failed"); + } + return ScopedAStatus::ok(); } +ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) { + int ret = mModule->setActiveBootSlot(mModule, in_slot); -// Methods from ::android::hardware::boot::V1_2::IBootControl. -Return BootControl::getActiveBootSlot() { - auto get_active_slot = mModule->getActiveBootSlot; - if (!get_active_slot) { - ALOGE("Failed to find the implementation of getActiveBootSlot in boot" - " control HAL."); - return 0; + if (ret != 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); } - return get_active_slot(mModule); + return ScopedAStatus::ok(); } -IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) { - int ret = 0; - boot_control_module_t *module = NULL; - hw_module_t **hwm = reinterpret_cast(&module); - ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast(hwm)); - if (ret) { - ALOGE("hw_get_module %s failed: %d", BOOT_CONTROL_HARDWARE_MODULE_ID, ret); - return nullptr; +ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) { + int ret = mModule->setSlotAsUnbootable(mModule, in_slot); + + if (ret != 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); } - module->init(module); - auto hal = new BootControl(module); - return hal; + return ScopedAStatus::ok(); +} +ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) { + private_boot_control_t *pModule = (private_boot_control_t *)(mModule); + + if (!pModule->SetSnapshotMergeStatus((uint8_t)ToHIDLMergeStatus(in_status))) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Operation failed"); + } + return ScopedAStatus::ok(); } -} // namespace implementation -} // namespace V1_2 -} // namespace boot -} // namespace hardware -} // namespace android +} // namespace aidl::android::hardware::boot diff --git a/boot/BootControl.h b/boot/BootControl.h index 02d7cf6..57008cd 100644 --- a/boot/BootControl.h +++ b/boot/BootControl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2022 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. @@ -16,50 +16,33 @@ #pragma once -#include -#include -#include +#include +#include +#include -namespace android { -namespace hardware { -namespace boot { -namespace V1_2 { -namespace implementation { -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::boot::V1_0::BoolResult; -using ::android::hardware::boot::V1_1::MergeStatus; -using ::android::hardware::boot::V1_2::IBootControl; +using ndk::ScopedAStatus; -class BootControl : public IBootControl { - public: - explicit BootControl(boot_control_module_t *module); - - // Methods from ::android::hardware::boot::V1_0::IBootControl. - Return getNumberSlots() override; - Return getCurrentSlot() override; - Return markBootSuccessful(markBootSuccessful_cb _hidl_cb) override; - Return setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) override; - Return setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) override; - Return isSlotBootable(uint32_t slot) override; - Return isSlotMarkedSuccessful(uint32_t slot) override; - Return getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override; - - // Methods from ::android::hardware::boot::V1_1::IBootControl. - Return setSnapshotMergeStatus(MergeStatus status) override; - Return getSnapshotMergeStatus() override; +namespace aidl::android::hardware::boot { - // Methods from ::android::hardware::boot::V1_2::IBootControl. - Return getActiveBootSlot() override; +class BootControl final : public BnBootControl { + public: + BootControl(); + ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override; + ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override; + ScopedAStatus getNumberSlots(int32_t* _aidl_return) override; + ScopedAStatus getSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override; + ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override; + ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override; + ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override; + ScopedAStatus markBootSuccessful() override; + ScopedAStatus setActiveBootSlot(int32_t in_slot) override; + ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override; + ScopedAStatus setSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus in_status) override; private: boot_control_module_t *mModule; }; -extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name); - -} // namespace implementation -} // namespace V1_2 -} // namespace boot -} // namespace hardware -} // namespace android +} // namespace aidl::android::hardware::boot diff --git a/boot/android.hardware.boot-service.rc b/boot/android.hardware.boot-service.rc new file mode 100644 index 0000000..c8c2261 --- /dev/null +++ b/boot/android.hardware.boot-service.rc @@ -0,0 +1,4 @@ +service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.intel + class early_hal + user root + group root diff --git a/boot/android.hardware.boot-service.recovery.rc b/boot/android.hardware.boot-service.recovery.rc new file mode 100644 index 0000000..0648593 --- /dev/null +++ b/boot/android.hardware.boot-service.recovery.rc @@ -0,0 +1,6 @@ +service vendor.boot-default /system/bin/hw/android.hardware.boot-service.recovery + class early_hal + user root + group root + interface aidl android.hardware.boot.IBootControl/default + diff --git a/boot/android.hardware.boot-service.xml b/boot/android.hardware.boot-service.xml new file mode 100644 index 0000000..23ccc4e --- /dev/null +++ b/boot/android.hardware.boot-service.xml @@ -0,0 +1,6 @@ + + + android.hardware.boot + IBootControl/default + + diff --git a/boot/main.cpp b/boot/main.cpp new file mode 100644 index 0000000..70b284e --- /dev/null +++ b/boot/main.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 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 "BootControl.h" + +#include +#include +#include + +using aidl::android::hardware::boot::BootControl; +using aidl::android::hardware::boot::IBootControl; + +int main(int, char* argv[]) { + android::base::InitLogging(argv, android::base::KernelLogger); + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr service = ndk::SharedRefBase::make(); + + const std::string instance = std::string(BootControl::descriptor) + "/default"; + auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str()); + CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status; + LOG(INFO) << "IBootControl AIDL service running..."; + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +}