Merge "Extend the bootcontrol HAL to get the active slot" am: 5919616361 am: f880de9ab1

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1513020

Change-Id: I8f7fc7fc2cd49b0aa2123d9fc6fce0bfc08dec05
This commit is contained in:
Tianjie Xu
2020-12-04 08:23:45 +00:00
committed by Automerger Merge Worker
13 changed files with 465 additions and 1 deletions

View File

@@ -32,6 +32,7 @@ class BootControl {
unsigned int GetNumberSlots(); unsigned int GetNumberSlots();
unsigned int GetCurrentSlot(); unsigned int GetCurrentSlot();
bool MarkBootSuccessful(); bool MarkBootSuccessful();
unsigned int GetActiveBootSlot();
bool SetActiveBootSlot(unsigned int slot); bool SetActiveBootSlot(unsigned int slot);
bool SetSlotAsUnbootable(unsigned int slot); bool SetSlotAsUnbootable(unsigned int slot);
bool SetSlotBootable(unsigned int slot); bool SetSlotBootable(unsigned int slot);

View File

@@ -261,6 +261,24 @@ bool BootControl::MarkBootSuccessful() {
return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl); return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl);
} }
unsigned int BootControl::GetActiveBootSlot() {
bootloader_control bootctrl;
if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false;
// Use the current slot by default.
unsigned int active_boot_slot = current_slot_;
unsigned int max_priority = bootctrl.slot_info[current_slot_].priority;
// Find the slot with the highest priority.
for (unsigned int i = 0; i < num_slots_; ++i) {
if (bootctrl.slot_info[i].priority > max_priority) {
max_priority = bootctrl.slot_info[i].priority;
active_boot_slot = i;
}
}
return active_boot_slot;
}
bool BootControl::SetActiveBootSlot(unsigned int slot) { bool BootControl::SetActiveBootSlot(unsigned int slot) {
if (slot >= kMaxNumSlots || slot >= num_slots_) { if (slot >= kMaxNumSlots || slot >= num_slots_) {
// Invalid slot number. // Invalid slot number.

15
boot/1.2/Android.bp Normal file
View File

@@ -0,0 +1,15 @@
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "android.hardware.boot@1.2",
root: "android.hardware",
srcs: [
"IBootControl.hal",
],
interfaces: [
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
"android.hidl.base@1.0",
],
gen_java: true,
}

35
boot/1.2/IBootControl.hal Normal file
View File

@@ -0,0 +1,35 @@
/*
* Copyright 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.
*/
package android.hardware.boot@1.2;
import @1.0::IBootControl;
import @1.0::Slot;
import @1.1::IBootControl;
interface IBootControl extends @1.1::IBootControl {
/**
* Returns the active slot to boot into on the next boot. If
* setActiveBootSlot() has been called, the getter function should return the
* same slot as the one provided in the last setActiveBootSlot() call.
* The returned value is always guaranteed to be strictly less than the
* value returned by getNumberSlots. Slots start at 0 and finish at
* getNumberSlots() - 1. For instance, a system with A/B must return 0 or 1.
*/
getActiveBootSlot() generates (Slot slot);
};

View File

@@ -0,0 +1,50 @@
cc_library_shared {
name: "android.hardware.boot@1.2-impl",
stem: "android.hardware.boot@1.0-impl-1.2",
defaults: [
"hidl_defaults",
"libboot_control_defaults",
],
relative_install_path: "hw",
vendor: true,
recovery_available: true,
srcs: ["BootControl.cpp"],
shared_libs: [
"liblog",
"libhidlbase",
"libhardware",
"libutils",
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
"android.hardware.boot@1.2",
],
static_libs: [
"libboot_control",
"libfstab",
],
}
cc_binary {
name: "android.hardware.boot@1.2-service",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
vendor: true,
init_rc: ["android.hardware.boot@1.2-service.rc"],
srcs: ["service.cpp"],
vintf_fragments: [
"android.hardware.boot@1.2.xml",
],
shared_libs: [
"liblog",
"libhardware",
"libhidlbase",
"libutils",
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
"android.hardware.boot@1.2",
],
}

View File

@@ -0,0 +1,135 @@
/*
* 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.
*/
#define LOG_TAG "android.hardware.boot@1.2-impl"
#include <memory>
#include <log/log.h>
#include "BootControl.h"
namespace android {
namespace hardware {
namespace boot {
namespace V1_2 {
namespace implementation {
using ::android::hardware::boot::V1_0::CommandResult;
bool BootControl::Init() {
return impl_.Init();
}
// Methods from ::android::hardware::boot::V1_0::IBootControl.
Return<uint32_t> BootControl::getNumberSlots() {
return impl_.GetNumberSlots();
}
Return<uint32_t> BootControl::getCurrentSlot() {
return impl_.GetCurrentSlot();
}
Return<void> BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) {
struct CommandResult cr;
if (impl_.MarkBootSuccessful()) {
cr.success = true;
cr.errMsg = "Success";
} else {
cr.success = false;
cr.errMsg = "Operation failed";
}
_hidl_cb(cr);
return Void();
}
Return<void> BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) {
struct CommandResult cr;
if (impl_.SetActiveBootSlot(slot)) {
cr.success = true;
cr.errMsg = "Success";
} else {
cr.success = false;
cr.errMsg = "Operation failed";
}
_hidl_cb(cr);
return Void();
}
Return<void> BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) {
struct CommandResult cr;
if (impl_.SetSlotAsUnbootable(slot)) {
cr.success = true;
cr.errMsg = "Success";
} else {
cr.success = false;
cr.errMsg = "Operation failed";
}
_hidl_cb(cr);
return Void();
}
Return<BoolResult> BootControl::isSlotBootable(uint32_t slot) {
if (!impl_.IsValidSlot(slot)) {
return BoolResult::INVALID_SLOT;
}
return impl_.IsSlotBootable(slot) ? BoolResult::TRUE : BoolResult::FALSE;
}
Return<BoolResult> BootControl::isSlotMarkedSuccessful(uint32_t slot) {
if (!impl_.IsValidSlot(slot)) {
return BoolResult::INVALID_SLOT;
}
return impl_.IsSlotMarkedSuccessful(slot) ? BoolResult::TRUE : BoolResult::FALSE;
}
Return<void> BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) {
hidl_string ans;
const char* suffix = impl_.GetSuffix(slot);
if (suffix) {
ans = suffix;
}
_hidl_cb(ans);
return Void();
}
// Methods from ::android::hardware::boot::V1_1::IBootControl.
Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus status) {
return impl_.SetSnapshotMergeStatus(status);
}
Return<MergeStatus> BootControl::getSnapshotMergeStatus() {
return impl_.GetSnapshotMergeStatus();
}
// Methods from ::android::hardware::boot::V1_2::IBootControl.
Return<uint32_t> BootControl::getActiveBootSlot() {
return impl_.GetActiveBootSlot();
}
IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) {
auto module = std::make_unique<BootControl>();
if (!module->Init()) {
ALOGE("Could not initialize BootControl module");
return nullptr;
}
return module.release();
}
} // namespace implementation
} // namespace V1_2
} // namespace boot
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,66 @@
/*
* 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.
*/
#pragma once
#include <android/hardware/boot/1.2/IBootControl.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <libboot_control/libboot_control.h>
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;
class BootControl : public IBootControl {
public:
bool Init();
// Methods from ::android::hardware::boot::V1_0::IBootControl.
Return<uint32_t> getNumberSlots() override;
Return<uint32_t> getCurrentSlot() override;
Return<void> markBootSuccessful(markBootSuccessful_cb _hidl_cb) override;
Return<void> setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) override;
Return<void> setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) override;
Return<BoolResult> isSlotBootable(uint32_t slot) override;
Return<BoolResult> isSlotMarkedSuccessful(uint32_t slot) override;
Return<void> getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override;
// Methods from ::android::hardware::boot::V1_1::IBootControl.
Return<bool> setSnapshotMergeStatus(MergeStatus status) override;
Return<MergeStatus> getSnapshotMergeStatus() override;
// Methods from ::android::hardware::boot::V1_2::IBootControl.
Return<uint32_t> getActiveBootSlot() override;
private:
android::bootable::BootControl impl_;
};
extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name);
} // namespace implementation
} // namespace V1_2
} // namespace boot
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,7 @@
service vendor.boot-hal-1-2 /vendor/bin/hw/android.hardware.boot@1.2-service
interface android.hardware.boot@1.0::IBootControl default
interface android.hardware.boot@1.1::IBootControl default
interface android.hardware.boot@1.2::IBootControl default
class early_hal
user root
group root

View File

@@ -0,0 +1,7 @@
<manifest version="1.0" type="device">
<hal format="hidl">
<name>android.hardware.boot</name>
<transport>hwbinder</transport>
<fqname>@1.2::IBootControl/default</fqname>
</hal>
</manifest>

View File

@@ -0,0 +1,27 @@
/*
* 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.
*/
#define LOG_TAG "android.hardware.boot@1.2-service"
#include <android/hardware/boot/1.2/IBootControl.h>
#include <hidl/LegacySupport.h>
using android::hardware::defaultPassthroughServiceImplementation;
using IBootControl_V1_0 = android::hardware::boot::V1_0::IBootControl;
using IBootControl_V1_2 = android::hardware::boot::V1_2::IBootControl;
int main(int /* argc */, char* /* argv */[]) {
return defaultPassthroughServiceImplementation<IBootControl_V1_0, IBootControl_V1_2>();
}

View File

@@ -0,0 +1,31 @@
//
// 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.
//
cc_test {
name: "VtsHalBootV1_2TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalBootV1_2TargetTest.cpp"],
static_libs: [
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
"android.hardware.boot@1.2",
"libgmock",
],
test_suites: [
"device-tests",
"vts",
],
}

View File

@@ -0,0 +1,72 @@
/*
* 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.
*/
#define LOG_TAG "boot_hidl_hal_test"
#include <android-base/logging.h>
#include <android/hardware/boot/1.2/IBootControl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
#include <unistd.h>
using ::android::sp;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::boot::V1_0::CommandResult;
using ::android::hardware::boot::V1_0::Slot;
using ::android::hardware::boot::V1_2::IBootControl;
class BootHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
boot = IBootControl::getService(GetParam());
ASSERT_NE(boot, nullptr);
LOG(INFO) << "Test is remote " << boot->isRemote();
}
sp<IBootControl> boot;
};
auto generate_callback(CommandResult* dest) {
return [=](CommandResult cr) { *dest = cr; };
}
TEST_P(BootHidlTest, GetActiveBootSlot) {
Slot curSlot = boot->getCurrentSlot();
Slot otherSlot = curSlot ? 0 : 1;
// Set the active slot, then check if the getter returns the correct slot.
CommandResult cr;
Return<void> result = boot->setActiveBootSlot(otherSlot, generate_callback(&cr));
EXPECT_TRUE(result.isOk());
Slot activeSlot = boot->getActiveBootSlot();
EXPECT_EQ(otherSlot, activeSlot);
result = boot->setActiveBootSlot(curSlot, generate_callback(&cr));
EXPECT_TRUE(result.isOk());
activeSlot = boot->getActiveBootSlot();
EXPECT_EQ(curSlot, activeSlot);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BootHidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, BootHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBootControl::descriptor)),
android::hardware::PrintInstanceNameToString);

View File

@@ -122,7 +122,7 @@
</hal> </hal>
<hal format="hidl" optional="true"> <hal format="hidl" optional="true">
<name>android.hardware.boot</name> <name>android.hardware.boot</name>
<version>1.1</version> <version>1.2</version>
<interface> <interface>
<name>IBootControl</name> <name>IBootControl</name>
<instance>default</instance> <instance>default</instance>