Skip to content

Commit

Permalink
bootctrl: Update to AIDL implementation
Browse files Browse the repository at this point in the history
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 <fangjian.zhong@intel.com>
  • Loading branch information
Zhong,Fangjian committed Oct 17, 2023
1 parent ea4b046 commit d5c05c0
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 141 deletions.
59 changes: 47 additions & 12 deletions boot/Android.bp
Original file line number Diff line number Diff line change
@@ -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,
}
210 changes: 121 additions & 89 deletions boot/BootControl.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 <memory>
#define LOG_TAG "android.hardware.boot-service.intel"

#include <log/log.h>
#include <hardware/boot_control.h>
#include <hardware/hardware.h>
#include "BootControl.h"
#include "boot_control_avb.h"
#include <cstdint>
#include <log/log.h>

namespace android {
namespace hardware {
namespace boot {
namespace V1_2 {
namespace implementation {
#include <android-base/logging.h>

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<uint32_t> BootControl::getNumberSlots() {
return mModule->getNumberSlots(mModule);
}
BootControl::BootControl() {
int ret = 0;

boot_control_module_t *module = NULL;
hw_module_t **hwm = reinterpret_cast<hw_module_t **>(&module);
ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast<const hw_module_t **>(hwm));
if (ret) {
ALOGE("hw_get_module %s failed: %d", BOOT_CONTROL_HARDWARE_MODULE_ID, ret);
} else {
mModule = module;
}

Return<uint32_t> BootControl::getCurrentSlot() {
return mModule->getCurrentSlot(mModule);
mModule->init(mModule);
}

Return<void> 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<void> 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<void> 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<BoolResult> 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<BoolResult> 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<void> 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<bool> 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<MergeStatus> 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<uint32_t> 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<hw_module_t **>(&module);
ret = hw_get_module(BOOT_CONTROL_HARDWARE_MODULE_ID, const_cast<const hw_module_t **>(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
Loading

0 comments on commit d5c05c0

Please sign in to comment.