diff --git a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h index 546865887f..ac17d6dbd8 100644 --- a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h +++ b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h @@ -32,6 +32,7 @@ class BootControl { unsigned int GetNumberSlots(); unsigned int GetCurrentSlot(); bool MarkBootSuccessful(); + unsigned int GetActiveBootSlot(); bool SetActiveBootSlot(unsigned int slot); bool SetSlotAsUnbootable(unsigned int slot); bool SetSlotBootable(unsigned int slot); diff --git a/boot/1.1/default/boot_control/libboot_control.cpp b/boot/1.1/default/boot_control/libboot_control.cpp index 2c6ccafd7d..9387c32b14 100644 --- a/boot/1.1/default/boot_control/libboot_control.cpp +++ b/boot/1.1/default/boot_control/libboot_control.cpp @@ -261,6 +261,24 @@ bool BootControl::MarkBootSuccessful() { 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) { if (slot >= kMaxNumSlots || slot >= num_slots_) { // Invalid slot number. diff --git a/boot/1.2/Android.bp b/boot/1.2/Android.bp new file mode 100644 index 0000000000..e51c5cdc4d --- /dev/null +++ b/boot/1.2/Android.bp @@ -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, +} diff --git a/boot/1.2/IBootControl.hal b/boot/1.2/IBootControl.hal new file mode 100644 index 0000000000..bb0ad1338c --- /dev/null +++ b/boot/1.2/IBootControl.hal @@ -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); +}; + diff --git a/boot/1.2/default/Android.bp b/boot/1.2/default/Android.bp new file mode 100644 index 0000000000..c097667d1d --- /dev/null +++ b/boot/1.2/default/Android.bp @@ -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", + ], + +} diff --git a/boot/1.2/default/BootControl.cpp b/boot/1.2/default/BootControl.cpp new file mode 100644 index 0000000000..c0bf02f8f2 --- /dev/null +++ b/boot/1.2/default/BootControl.cpp @@ -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 + +#include + +#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 BootControl::getNumberSlots() { + return impl_.GetNumberSlots(); +} + +Return BootControl::getCurrentSlot() { + return impl_.GetCurrentSlot(); +} + +Return 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 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 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 BootControl::isSlotBootable(uint32_t slot) { + if (!impl_.IsValidSlot(slot)) { + return BoolResult::INVALID_SLOT; + } + return impl_.IsSlotBootable(slot) ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::isSlotMarkedSuccessful(uint32_t slot) { + if (!impl_.IsValidSlot(slot)) { + return BoolResult::INVALID_SLOT; + } + return impl_.IsSlotMarkedSuccessful(slot) ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return 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 BootControl::setSnapshotMergeStatus(MergeStatus status) { + return impl_.SetSnapshotMergeStatus(status); +} + +Return BootControl::getSnapshotMergeStatus() { + return impl_.GetSnapshotMergeStatus(); +} + +// Methods from ::android::hardware::boot::V1_2::IBootControl. +Return BootControl::getActiveBootSlot() { + return impl_.GetActiveBootSlot(); +} + +IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) { + auto module = std::make_unique(); + 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 diff --git a/boot/1.2/default/BootControl.h b/boot/1.2/default/BootControl.h new file mode 100644 index 0000000000..5791699658 --- /dev/null +++ b/boot/1.2/default/BootControl.h @@ -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 +#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; + +class BootControl : public IBootControl { + public: + bool Init(); + + // 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; + + // Methods from ::android::hardware::boot::V1_2::IBootControl. + Return 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 diff --git a/boot/1.2/default/android.hardware.boot@1.2-service.rc b/boot/1.2/default/android.hardware.boot@1.2-service.rc new file mode 100644 index 0000000000..14926c0a2b --- /dev/null +++ b/boot/1.2/default/android.hardware.boot@1.2-service.rc @@ -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 diff --git a/boot/1.2/default/android.hardware.boot@1.2.xml b/boot/1.2/default/android.hardware.boot@1.2.xml new file mode 100644 index 0000000000..ba91e8f716 --- /dev/null +++ b/boot/1.2/default/android.hardware.boot@1.2.xml @@ -0,0 +1,7 @@ + + + android.hardware.boot + hwbinder + @1.2::IBootControl/default + + diff --git a/boot/1.2/default/service.cpp b/boot/1.2/default/service.cpp new file mode 100644 index 0000000000..30539576db --- /dev/null +++ b/boot/1.2/default/service.cpp @@ -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 +#include + +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(); +} diff --git a/boot/1.2/vts/functional/Android.bp b/boot/1.2/vts/functional/Android.bp new file mode 100644 index 0000000000..a7f5ccb440 --- /dev/null +++ b/boot/1.2/vts/functional/Android.bp @@ -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", + ], +} diff --git a/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp b/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp new file mode 100644 index 0000000000..9df23c3708 --- /dev/null +++ b/boot/1.2/vts/functional/VtsHalBootV1_2TargetTest.cpp @@ -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 +#include +#include +#include +#include +#include + +#include + +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 { + public: + virtual void SetUp() override { + boot = IBootControl::getService(GetParam()); + ASSERT_NE(boot, nullptr); + + LOG(INFO) << "Test is remote " << boot->isRemote(); + } + + sp 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 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); diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 6c8cb580b3..1957f8c794 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -122,7 +122,7 @@ android.hardware.boot - 1.1 + 1.2 IBootControl default