diff options
-rw-r--r-- | Android.bp | 10 | ||||
-rw-r--r-- | bootloader_message/bootloader_message.cpp | 37 | ||||
-rw-r--r-- | bootloader_message/include/bootloader_message/bootloader_message.h | 15 | ||||
-rw-r--r-- | etc/init.rc | 11 | ||||
-rw-r--r-- | misc_writer/Android.bp | 80 | ||||
-rw-r--r-- | misc_writer/include/misc_writer/misc_writer.h | 66 | ||||
-rw-r--r-- | misc_writer/misc_writer.cpp | 127 | ||||
-rw-r--r-- | misc_writer/misc_writer_main.cpp | 109 | ||||
-rw-r--r-- | misc_writer/misc_writer_test.cpp | 140 | ||||
-rw-r--r-- | tests/unit/bootloader_message_test.cpp | 34 |
10 files changed, 463 insertions, 166 deletions
diff --git a/Android.bp b/Android.bp index 7df53a43a..a8e032e21 100644 --- a/Android.bp +++ b/Android.bp @@ -99,6 +99,14 @@ cc_library_static { ], } +prebuilt_etc { + name: "init_recovery.rc", + filename: "init.rc", + src: "etc/init.rc", + sub_dir: "init/hw", + recovery: true, +} + cc_binary { name: "recovery", recovery: true, @@ -124,11 +132,13 @@ cc_binary { required: [ "e2fsdroid.recovery", + "init_recovery.rc", "librecovery_ui_ext", "minadbd", "mke2fs.conf.recovery", "mke2fs.recovery", "recovery_deps", + "ueventd.rc.recovery", ], } diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp index 4f7085db9..b70d54e5c 100644 --- a/bootloader_message/bootloader_message.cpp +++ b/bootloader_message/bootloader_message.cpp @@ -45,7 +45,7 @@ void SetMiscBlockDeviceForTest(std::string_view misc_device) { g_misc_device_for_test = misc_device; } -static std::string get_misc_blk_device(std::string* err) { +std::string get_misc_blk_device(std::string* err) { if (g_misc_device_for_test.has_value() && !g_misc_device_for_test->empty()) { return *g_misc_device_for_test; } @@ -111,8 +111,8 @@ static bool read_misc_partition(void* p, size_t size, const std::string& misc_bl return true; } -static bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device, - size_t offset, std::string* err) { +bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device, + size_t offset, std::string* err) { android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY)); if (fd == -1) { *err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(), @@ -261,37 +261,6 @@ bool write_wipe_package(const std::string& package_data, std::string* err) { WIPE_PACKAGE_OFFSET_IN_MISC, err); } -static bool OffsetAndSizeInVendorSpace(size_t offset, size_t size) { - auto total_size = WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC; - return size <= total_size && offset <= total_size - size; -} - -bool ReadMiscPartitionVendorSpace(void* data, size_t size, size_t offset, std::string* err) { - if (!OffsetAndSizeInVendorSpace(offset, size)) { - *err = android::base::StringPrintf("Out of bound read (offset %zu size %zu)", offset, size); - return false; - } - auto misc_blk_device = get_misc_blk_device(err); - if (misc_blk_device.empty()) { - return false; - } - return read_misc_partition(data, size, misc_blk_device, VENDOR_SPACE_OFFSET_IN_MISC + offset, - err); -} - -bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, std::string* err) { - if (!OffsetAndSizeInVendorSpace(offset, size)) { - *err = android::base::StringPrintf("Out of bound write (offset %zu size %zu)", offset, size); - return false; - } - auto misc_blk_device = get_misc_blk_device(err); - if (misc_blk_device.empty()) { - return false; - } - return write_misc_partition(data, size, misc_blk_device, VENDOR_SPACE_OFFSET_IN_MISC + offset, - err); -} - static bool ValidateSystemSpaceRegion(size_t offset, size_t size, std::string* err) { if (size <= SYSTEM_SPACE_SIZE_IN_MISC && offset <= (SYSTEM_SPACE_SIZE_IN_MISC - size)) { return true; diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h index 3a3b862aa..a27e80bcc 100644 --- a/bootloader_message/include/bootloader_message/bootloader_message.h +++ b/bootloader_message/include/bootloader_message/bootloader_message.h @@ -212,11 +212,18 @@ struct misc_system_space_layout { #include <string> #include <vector> +// Gets the block device name of /misc partition. +std::string get_misc_blk_device(std::string* err); // Return the block device name for the bootloader message partition and waits // for the device for up to 10 seconds. In case of error returns the empty // string. std::string get_bootloader_message_blk_device(std::string* err); +// Writes |size| bytes of data from buffer |p| to |misc_blk_device| at |offset|. If the write fails, +// sets the error message in |err|. +bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device, + size_t offset, std::string* err); + // Read bootloader message into boot. Error message will be set in err. bool read_bootloader_message(bootloader_message* boot, std::string* err); @@ -261,14 +268,6 @@ bool read_wipe_package(std::string* package_data, size_t size, std::string* err) // Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC). bool write_wipe_package(const std::string& package_data, std::string* err); -// Reads data from the vendor space in /misc partition, with the given offset and size. Note that -// offset is in relative to the start of vendor space. -bool ReadMiscPartitionVendorSpace(void* data, size_t size, size_t offset, std::string* err); - -// Writes the given data to the vendor space in /misc partition, at the given offset. Note that -// offset is in relative to the start of the vendor space. -bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, std::string* err); - // Read or write the Virtual A/B message from system space in /misc. bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err); bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err); diff --git a/etc/init.rc b/etc/init.rc index d5b056ae8..12411ac14 100644 --- a/etc/init.rc +++ b/etc/init.rc @@ -44,10 +44,6 @@ on boot class_start default -# Load properties from /system/ + /factory after fs mount. -on load_system_props_action - load_system_props - on firmware_mounts_complete rm /dev/.booting @@ -58,11 +54,6 @@ on late-init trigger post-fs trigger post-fs-data - # Load properties from /system/ + /factory after fs mount. Place - # this in another action so that the load will be scheduled after the prior - # issued fs triggers have completed. - trigger load_system_props_action - # Remove a file to wake up anything waiting for firmware trigger firmware_mounts_complete @@ -130,7 +121,7 @@ on property:sys.usb.config=fastboot on property:sys.usb.config=none && property:sys.usb.configfs=0 stop adbd - stop fastboot + stop fastbootd write /sys/class/android_usb/android0/enable 0 setprop sys.usb.state ${sys.usb.config} diff --git a/misc_writer/Android.bp b/misc_writer/Android.bp index 567143c79..73c44d2eb 100644 --- a/misc_writer/Android.bp +++ b/misc_writer/Android.bp @@ -14,14 +14,30 @@ // limitations under the License. // -cc_binary { - name: "misc_writer", +cc_defaults { + name: "misc_writer_defaults", vendor: true, + cpp_std: "experimental", - srcs: [ - "misc_writer.cpp", + cflags: [ + "-Wall", + "-Werror", + ], + + shared_libs: [ + "libbase", + ], + + static_libs: [ + "libbootloader_message_vendor", + "libfstab", ], +} +// TODO(xunchang) Remove duplicates after we convert the device specific librecovery_ui to recovery +// module. Then libmisc_writer can build as a vendor module available in recovery. +cc_library_static { + name: "libmisc_writer", cpp_std: "experimental", cflags: [ @@ -34,7 +50,61 @@ cc_binary { ], static_libs: [ - "libbootloader_message_vendor", + "libbootloader_message", "libfstab", ], + + srcs: [ + "misc_writer.cpp", + ], + + export_include_dirs: [ + "include", + ], +} + +cc_library_static { + name: "libmisc_writer_vendor", + defaults: [ + "misc_writer_defaults", + ], + + srcs: [ + "misc_writer.cpp", + ], + + export_include_dirs: [ + "include", + ], +} + +cc_binary { + name: "misc_writer", + defaults: [ + "misc_writer_defaults", + ], + + srcs: [ + "misc_writer_main.cpp", + ], + + static_libs: [ + "libmisc_writer_vendor", + ] +} + +cc_test { + name: "misc_writer_test", + defaults: [ + "misc_writer_defaults", + ], + + srcs: [ + "misc_writer_test.cpp", + ], + test_suites: ["device-tests"], + + static_libs: [ + "libmisc_writer_vendor", + ] } diff --git a/misc_writer/include/misc_writer/misc_writer.h b/misc_writer/include/misc_writer/misc_writer.h new file mode 100644 index 000000000..6a32ffe46 --- /dev/null +++ b/misc_writer/include/misc_writer/misc_writer.h @@ -0,0 +1,66 @@ +/* + * 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 <stddef.h> +#include <stdint.h> + +#include <optional> +#include <string> + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +enum class MiscWriterActions : int32_t { + kSetDarkThemeFlag = 0, + kClearDarkThemeFlag, + kSetSotaFlag, + kClearSotaFlag, + + kUnset = -1, +}; + +class MiscWriter { + public: + static constexpr uint32_t kThemeFlagOffsetInVendorSpace = 0; + static constexpr char kDarkThemeFlag[] = "theme-dark"; + static constexpr uint32_t kSotaFlagOffsetInVendorSpace = 32; + static constexpr char kSotaFlag[] = "enable-sota"; + + // Returns true of |size| bytes data starting from |offset| is fully inside the vendor space. + static bool OffsetAndSizeInVendorSpace(size_t offset, size_t size); + // Writes the given data to the vendor space in /misc partition, at the given offset. Note that + // offset is in relative to the start of the vendor space. + static bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, + std::string* err); + + explicit MiscWriter(const MiscWriterActions& action) : action_(action) {} + + // Performs the stored MiscWriterActions. If |override_offset| is set, writes to the input offset + // in the vendor space of /misc instead of the default offset. + bool PerformAction(std::optional<size_t> override_offset = std::nullopt); + + private: + MiscWriterActions action_{ MiscWriterActions::kUnset }; +}; + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/misc_writer/misc_writer.cpp b/misc_writer/misc_writer.cpp index 1d9702ebf..bf589d31f 100644 --- a/misc_writer/misc_writer.cpp +++ b/misc_writer/misc_writer.cpp @@ -14,93 +14,70 @@ * limitations under the License. */ -#include <errno.h> -#include <getopt.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> +#include "misc_writer/misc_writer.h" -#include <iostream> -#include <string> -#include <string_view> -#include <vector> +#include <string.h> +#include <android-base/file.h> #include <android-base/logging.h> -#include <android-base/parseint.h> +#include <android-base/stringprintf.h> #include <bootloader_message/bootloader_message.h> -using namespace std::string_literals; +namespace android { +namespace hardware { +namespace google { +namespace pixel { -static std::vector<uint8_t> ParseHexString(std::string_view hex_string) { - auto length = hex_string.size(); - if (length % 2 != 0 || length == 0) { - return {}; - } - - std::vector<uint8_t> result(length / 2); - for (size_t i = 0; i < length / 2; i++) { - auto sub = "0x" + std::string(hex_string.substr(i * 2, 2)); - if (!android::base::ParseUint(sub, &result[i])) { - return {}; - } - } - return result; +bool MiscWriter::OffsetAndSizeInVendorSpace(size_t offset, size_t size) { + auto total_size = WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC; + return size <= total_size && offset <= total_size - size; } -static int Usage(std::string_view name) { - std::cerr << name << " usage:\n"; - std::cerr << name << " [--vendor-space-offset <offset>] --hex-string 0xABCDEF\n"; - std::cerr << "Writes the given hex string to the specified offset in vendor space in /misc " - "partition. Offset defaults to 0 if unspecified.\n"; - return EXIT_FAILURE; +bool MiscWriter::WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, + std::string* err) { + if (!OffsetAndSizeInVendorSpace(offset, size)) { + *err = android::base::StringPrintf("Out of bound write (offset %zu size %zu)", offset, size); + return false; + } + auto misc_blk_device = get_misc_blk_device(err); + if (misc_blk_device.empty()) { + return false; + } + return write_misc_partition(data, size, misc_blk_device, VENDOR_SPACE_OFFSET_IN_MISC + offset, + err); } -// misc_writer is a vendor tool that writes data to the vendor space in /misc. -int main(int argc, char** argv) { - constexpr struct option OPTIONS[] = { - { "vendor-space-offset", required_argument, nullptr, 0 }, - { "hex-string", required_argument, nullptr, 0 }, - { nullptr, 0, nullptr, 0 }, - }; - - // Offset defaults to 0 if unspecified. +bool MiscWriter::PerformAction(std::optional<size_t> override_offset) { size_t offset = 0; - std::string_view hex_string; - - int arg; - int option_index; - while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) { - if (arg != 0) { - LOG(ERROR) << "Invalid command argument"; - return Usage(argv[0]); - } - auto option_name = OPTIONS[option_index].name; - if (option_name == "vendor-space-offset"s) { - if (!android::base::ParseUint(optarg, &offset)) { - LOG(ERROR) << "Failed to parse the offset: " << optarg; - return Usage(argv[0]); - } - } else if (option_name == "hex-string"s) { - hex_string = optarg; - } - } - - if (hex_string.starts_with("0x") || hex_string.starts_with("0X")) { - hex_string = hex_string.substr(2); - } - if (hex_string.empty()) { - LOG(ERROR) << "Invalid input hex string: " << hex_string; - return Usage(argv[0]); + std::string content; + switch (action_) { + case MiscWriterActions::kSetDarkThemeFlag: + case MiscWriterActions::kClearDarkThemeFlag: + offset = override_offset.value_or(kThemeFlagOffsetInVendorSpace); + content = (action_ == MiscWriterActions::kSetDarkThemeFlag) + ? kDarkThemeFlag + : std::string(strlen(kDarkThemeFlag), 0); + break; + case MiscWriterActions::kSetSotaFlag: + case MiscWriterActions::kClearSotaFlag: + offset = override_offset.value_or(kSotaFlagOffsetInVendorSpace); + content = (action_ == MiscWriterActions::kSetSotaFlag) ? kSotaFlag + : std::string(strlen(kSotaFlag), 0); + break; + case MiscWriterActions::kUnset: + LOG(ERROR) << "The misc writer action must be set"; + return false; } - auto data = ParseHexString(hex_string); - if (data.empty()) { - LOG(ERROR) << "Failed to parse the input hex string: " << hex_string; - return EXIT_FAILURE; - } - if (std::string err; !WriteMiscPartitionVendorSpace(data.data(), data.size(), offset, &err)) { - LOG(ERROR) << "Failed to write to misc partition: " << err; - return EXIT_FAILURE; + if (std::string err; + !WriteMiscPartitionVendorSpace(content.data(), content.size(), offset, &err)) { + LOG(ERROR) << "Failed to write " << content << " at offset " << offset << " : " << err; + return false; } - return EXIT_SUCCESS; + return true; } + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/misc_writer/misc_writer_main.cpp b/misc_writer/misc_writer_main.cpp new file mode 100644 index 000000000..69a9fe3df --- /dev/null +++ b/misc_writer/misc_writer_main.cpp @@ -0,0 +1,109 @@ +/* + * 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. + */ + +#include <getopt.h> +#include <stdint.h> +#include <stdlib.h> + +#include <iostream> +#include <map> +#include <memory> +#include <optional> +#include <string> +#include <string_view> + +#include <android-base/logging.h> +#include <android-base/parseint.h> + +#include "misc_writer/misc_writer.h" + +using namespace std::string_literals; +using android::hardware::google::pixel::MiscWriter; +using android::hardware::google::pixel::MiscWriterActions; + +static int Usage(std::string_view name) { + std::cerr << name << " usage:\n"; + std::cerr << name << " [--override-vendor-space-offset <offset>] --<misc_writer_action>\n"; + std::cerr << "Supported misc_writer_action is one of: \n"; + std::cerr << " --set-dark-theme Write the dark theme flag\n"; + std::cerr << " --clear-dark-theme Clear the dark theme flag\n"; + std::cerr << " --set-sota Write the silent OTA flag\n"; + std::cerr << " --clear-sota Clear the silent OTA flag\n"; + std::cerr << "Writes the given hex string to the specified offset in vendor space in /misc " + "partition.\nDefault offset is used for each action unless " + "--override-vendor-space-offset is specified.\n"; + return EXIT_FAILURE; +} + +// misc_writer is a vendor tool that writes data to the vendor space in /misc. +int main(int argc, char** argv) { + constexpr struct option OPTIONS[] = { + { "set-dark-theme", no_argument, nullptr, 0 }, + { "clear-dark-theme", no_argument, nullptr, 0 }, + { "set-sota", no_argument, nullptr, 0 }, + { "clear-sota", no_argument, nullptr, 0 }, + { "override-vendor-space-offset", required_argument, nullptr, 0 }, + { nullptr, 0, nullptr, 0 }, + }; + + std::map<std::string, MiscWriterActions> action_map{ + { "set-dark-theme", MiscWriterActions::kSetDarkThemeFlag }, + { "clear-dark-theme", MiscWriterActions::kClearDarkThemeFlag }, + { "set-sota", MiscWriterActions::kSetSotaFlag }, + { "clear-sota", MiscWriterActions::kClearSotaFlag }, + }; + + std::unique_ptr<MiscWriter> misc_writer; + std::optional<size_t> override_offset; + + int arg; + int option_index = 0; + while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) { + if (arg != 0) { + LOG(ERROR) << "Invalid command argument"; + return Usage(argv[0]); + } + auto option_name = OPTIONS[option_index].name; + if (option_name == "override-vendor-space-offset"s) { + LOG(WARNING) << "Overriding the vendor space offset in misc partition to " << optarg; + size_t offset; + if (!android::base::ParseUint(optarg, &offset)) { + LOG(ERROR) << "Failed to parse the offset: " << optarg; + return Usage(argv[0]); + } + override_offset = offset; + } else if (auto iter = action_map.find(option_name); iter != action_map.end()) { + if (misc_writer) { + LOG(ERROR) << "Misc writer action has already been set"; + return Usage(argv[0]); + } + misc_writer = std::make_unique<MiscWriter>(iter->second); + } else { + LOG(FATAL) << "Unreachable path, option_name: " << option_name; + } + } + + if (!misc_writer) { + LOG(ERROR) << "An action must be specified for misc writer"; + return Usage(argv[0]); + } + + if (!misc_writer->PerformAction(override_offset)) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/misc_writer/misc_writer_test.cpp b/misc_writer/misc_writer_test.cpp new file mode 100644 index 000000000..e8b207afd --- /dev/null +++ b/misc_writer/misc_writer_test.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016 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 <memory> +#include <string> +#include <string_view> +#include <vector> + +#include <android-base/file.h> +#include <bootloader_message/bootloader_message.h> +#include <gtest/gtest.h> + +#include "misc_writer/misc_writer.h" + +using namespace std::string_literals; + +namespace android { +namespace hardware { +namespace google { +namespace pixel { + +class MiscWriterTest : public ::testing::Test { + protected: + void TearDown() override { + // Clear the vendor space. + auto zeros = std::string(WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC, 0); + std::string err; + ASSERT_TRUE(MiscWriter::WriteMiscPartitionVendorSpace(zeros.data(), zeros.size(), 0, &err)) + << err; + } + + void CheckMiscPartitionVendorSpaceContent(size_t offset, const std::string& expected); + + std::unique_ptr<MiscWriter> misc_writer_; +}; + +void MiscWriterTest::CheckMiscPartitionVendorSpaceContent(size_t offset, + const std::string& expected) { + ASSERT_TRUE(MiscWriter::OffsetAndSizeInVendorSpace(offset, expected.size())); + std::string err; + auto misc_blk_device = get_misc_blk_device(&err); + ASSERT_FALSE(misc_blk_device.empty()); + android::base::unique_fd fd(open(misc_blk_device.c_str(), O_RDONLY)); + ASSERT_NE(-1, fd); + + std::string content(expected.size(), 0); + ASSERT_TRUE(android::base::ReadFullyAtOffset(fd, content.data(), content.size(), + VENDOR_SPACE_OFFSET_IN_MISC + offset)); + ASSERT_EQ(expected, content); +} + +TEST_F(MiscWriterTest, SetClearDarkTheme) { + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kSetDarkThemeFlag); + ASSERT_TRUE(misc_writer_); + ASSERT_TRUE(misc_writer_->PerformAction()); + std::string expected = "theme-dark"; + CheckMiscPartitionVendorSpaceContent(0, expected); + + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kClearDarkThemeFlag); + ASSERT_TRUE(misc_writer_->PerformAction()); + std::string zeros(expected.size(), 0); + CheckMiscPartitionVendorSpaceContent(0, zeros); +} + +TEST_F(MiscWriterTest, SetClearDarkTheme_OffsetOverride) { + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kSetDarkThemeFlag); + size_t offset = 12360; + ASSERT_TRUE(misc_writer_->PerformAction(offset)); + std::string expected = "theme-dark"; + CheckMiscPartitionVendorSpaceContent(offset, expected); + + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kClearDarkThemeFlag); + ASSERT_TRUE(misc_writer_->PerformAction(offset)); + std::string zeros(expected.size(), 0); + CheckMiscPartitionVendorSpaceContent(offset, zeros); +} + +TEST_F(MiscWriterTest, SetClearSota) { + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kSetSotaFlag); + ASSERT_TRUE(misc_writer_); + ASSERT_TRUE(misc_writer_->PerformAction()); + std::string expected = "enable-sota"; + CheckMiscPartitionVendorSpaceContent(32, expected); + + // Test we can write to the override offset. + size_t override_offset = 12360; + ASSERT_FALSE(misc_writer_->PerformAction(override_offset)); + CheckMiscPartitionVendorSpaceContent(override_offset, expected); + + misc_writer_ = std::make_unique<MiscWriter>(MiscWriterActions::kClearSotaFlag); + ASSERT_TRUE(misc_writer_->PerformAction()); + std::string zeros(expected.size(), 0); + CheckMiscPartitionVendorSpaceContent(32, zeros); +} + +TEST_F(MiscWriterTest, WriteMiscPartitionVendorSpace) { + std::string kTestMessage = "kTestMessage"; + std::string err; + ASSERT_TRUE( + MiscWriter::WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), 0, &err)); + + CheckMiscPartitionVendorSpaceContent(0, kTestMessage); + + // Write with an offset. + ASSERT_TRUE(MiscWriter::WriteMiscPartitionVendorSpace("\x00\x00", 2, 5, &err)); + CheckMiscPartitionVendorSpaceContent(0, "kTest\x00\x00ssage"s); + + // Write with the right size. + auto start_offset = + WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC - kTestMessage.size(); + ASSERT_TRUE(MiscWriter::WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), + start_offset, &err)); + + // Out-of-bound write. + ASSERT_FALSE(MiscWriter::WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), + start_offset + 1, &err)); + + // Message won't fit. + std::string long_message(WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC + 1, 'a'); + ASSERT_FALSE( + MiscWriter::WriteMiscPartitionVendorSpace(long_message.data(), long_message.size(), 0, &err)); +} + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android diff --git a/tests/unit/bootloader_message_test.cpp b/tests/unit/bootloader_message_test.cpp index 95d875e69..731c8feb7 100644 --- a/tests/unit/bootloader_message_test.cpp +++ b/tests/unit/bootloader_message_test.cpp @@ -118,37 +118,3 @@ TEST(BootloaderMessageTest, update_bootloader_message_recovery_options_long) { ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'), std::string(boot.reserved, sizeof(boot.reserved))); } - -TEST(BootloaderMessageTest, WriteMiscPartitionVendorSpace) { - TemporaryFile temp_misc; - ASSERT_TRUE(android::base::WriteStringToFile(std::string(4096, '\x00'), temp_misc.path)); - SetMiscBlockDeviceForTest(temp_misc.path); - - constexpr std::string_view kTestMessage = "kTestMessage"; - std::string err; - ASSERT_TRUE(WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), 0, &err)); - - std::string message; - message.resize(kTestMessage.size()); - ASSERT_TRUE(ReadMiscPartitionVendorSpace(message.data(), message.size(), 0, &err)); - ASSERT_EQ(kTestMessage, message); - - // Write with an offset. - ASSERT_TRUE(WriteMiscPartitionVendorSpace("\x00\x00", 2, 5, &err)); - ASSERT_TRUE(ReadMiscPartitionVendorSpace(message.data(), message.size(), 0, &err)); - ASSERT_EQ("kTest\x00\x00ssage"s, message); - - // Write with the right size. - auto start_offset = - WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC - kTestMessage.size(); - ASSERT_TRUE( - WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), start_offset, &err)); - - // Out-of-bound write. - ASSERT_FALSE(WriteMiscPartitionVendorSpace(kTestMessage.data(), kTestMessage.size(), - start_offset + 1, &err)); - - // Message won't fit. - std::string long_message(WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC + 1, 'a'); - ASSERT_FALSE(WriteMiscPartitionVendorSpace(long_message.data(), long_message.size(), 0, &err)); -} |