From 0473214d390e89055df8b8d7d0a52be8b66bd4d4 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 7 Oct 2019 13:34:24 -0700 Subject: [PATCH] Add a default implementation and tests of IBootControl 1.1. Bug: 138861550 Test: VtsHalBootV1_0TargetTest VtsHalBootV1_1TargetTest Change-Id: I53ea2465612b03435c37c3b4edeaff72c368373b --- boot/1.1/default/Android.bp | 43 ++++++ boot/1.1/default/BootControl.cpp | 129 ++++++++++++++++++ boot/1.1/default/BootControl.h | 64 +++++++++ .../android.hardware.boot@1.1-service.rc | 6 + boot/1.1/default/service.cpp | 26 ++++ boot/1.1/vts/functional/Android.bp | 28 ++++ .../functional/VtsHalBootV1_1TargetTest.cpp | 86 ++++++++++++ 7 files changed, 382 insertions(+) create mode 100644 boot/1.1/default/Android.bp create mode 100644 boot/1.1/default/BootControl.cpp create mode 100644 boot/1.1/default/BootControl.h create mode 100644 boot/1.1/default/android.hardware.boot@1.1-service.rc create mode 100644 boot/1.1/default/service.cpp create mode 100644 boot/1.1/vts/functional/Android.bp create mode 100644 boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp diff --git a/boot/1.1/default/Android.bp b/boot/1.1/default/Android.bp new file mode 100644 index 0000000000..dca5c2635a --- /dev/null +++ b/boot/1.1/default/Android.bp @@ -0,0 +1,43 @@ +cc_library_shared { + name: "android.hardware.boot@1.1-impl", + 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", + ], + static_libs: [ + "libboot_control", + "libfstab", + ], +} + +cc_binary { + name: "android.hardware.boot@1.1-service", + defaults: ["hidl_defaults"], + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.boot@1.1-service.rc"], + srcs: ["service.cpp"], + + shared_libs: [ + "liblog", + "libhardware", + "libhidlbase", + "libutils", + "android.hardware.boot@1.0", + "android.hardware.boot@1.1", + ], + +} diff --git a/boot/1.1/default/BootControl.cpp b/boot/1.1/default/BootControl.cpp new file mode 100644 index 0000000000..c9c62a43d0 --- /dev/null +++ b/boot/1.1/default/BootControl.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2019 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.1-impl" + +#include + +#include + +#include "BootControl.h" + +namespace android { +namespace hardware { +namespace boot { +namespace V1_1 { +namespace implementation { + +using ::android::hardware::boot::V1_0::CommandResult; + +bool BootControl::Init() { + return impl_.Init(); +} + +// Methods from ::android::hardware::boot::V1_0::IBootControl follow. +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(); +} + +Return BootControl::setSnapshotMergeStatus(MergeStatus status) { + return impl_.SetSnapshotMergeStatus(status); +} + +Return BootControl::getSnapshotMergeStatus() { + return impl_.GetSnapshotMergeStatus(); +} + +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_1 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/boot/1.1/default/BootControl.h b/boot/1.1/default/BootControl.h new file mode 100644 index 0000000000..75511b638f --- /dev/null +++ b/boot/1.1/default/BootControl.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 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_1 { +namespace implementation { + +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::boot::V1_0::BoolResult; +using ::android::hardware::boot::V1_1::IBootControl; +using ::android::hardware::boot::V1_1::MergeStatus; + +class BootControl : public IBootControl { + public: + bool Init(); + + // Methods from ::android::hardware::boot::V1_0::IBootControl follow. + 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 follow. + Return setSnapshotMergeStatus(MergeStatus status) override; + Return getSnapshotMergeStatus() override; + + private: + android::bootable::BootControl impl_; +}; + +extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name); + +} // namespace implementation +} // namespace V1_1 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/boot/1.1/default/android.hardware.boot@1.1-service.rc b/boot/1.1/default/android.hardware.boot@1.1-service.rc new file mode 100644 index 0000000000..83fa9d0212 --- /dev/null +++ b/boot/1.1/default/android.hardware.boot@1.1-service.rc @@ -0,0 +1,6 @@ +service vendor.boot-hal-1-1 /vendor/bin/hw/android.hardware.boot@1.1-service + interface android.hardware.boot@1.0::IBootControl default + interface android.hardware.boot@1.1::IBootControl default + class early_hal + user root + group root diff --git a/boot/1.1/default/service.cpp b/boot/1.1/default/service.cpp new file mode 100644 index 0000000000..b24b46456a --- /dev/null +++ b/boot/1.1/default/service.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 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.1-service" + +#include +#include + +using android::hardware::defaultPassthroughServiceImplementation; +using ::android::hardware::boot::V1_1::IBootControl; + +int main(int /* argc */, char* /* argv */[]) { + return defaultPassthroughServiceImplementation(); +} diff --git a/boot/1.1/vts/functional/Android.bp b/boot/1.1/vts/functional/Android.bp new file mode 100644 index 0000000000..49ea09a15e --- /dev/null +++ b/boot/1.1/vts/functional/Android.bp @@ -0,0 +1,28 @@ +// +// Copyright (C) 2019 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_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalBootV1_1TargetTest.cpp"], + static_libs: [ + "android.hardware.boot@1.0", + "android.hardware.boot@1.1", + "libgmock", + ], + test_suites: ["device-tests"], +} + diff --git a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp new file mode 100644 index 0000000000..fba9a5ec0c --- /dev/null +++ b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 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 +#include + +#include + +using ::android::sp; +using ::android::hardware::hidl_enum_range; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::boot::V1_1::IBootControl; +using ::android::hardware::boot::V1_1::MergeStatus; +using ::testing::Contains; + +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; +}; + +static std::vector ValidMergeStatusValues() { + std::vector values; + for (const auto value : hidl_enum_range()) { + if (value == MergeStatus::UNKNOWN) { + continue; + } + values.push_back(value); + } + return values; +} + +/** + * Ensure merge status can be retrieved. + */ +TEST_P(BootHidlTest, GetSnapshotMergeStatus) { + auto values = ValidMergeStatusValues(); + auto status = (MergeStatus)boot->getSnapshotMergeStatus(); + EXPECT_THAT(values, Contains(status)); +} + +/** + * Ensure merge status can be set to arbitrary value. + */ +TEST_P(BootHidlTest, SetSnapshotMergeStatus) { + for (const auto value : ValidMergeStatusValues()) { + EXPECT_TRUE(boot->setSnapshotMergeStatus(value).withDefault(false)); + auto status = boot->getSnapshotMergeStatus(); + EXPECT_EQ(status, value); + } +} + +INSTANTIATE_TEST_SUITE_P( + , BootHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBootControl::descriptor)), + android::hardware::PrintInstanceNameToString);