From 769fcd7249c1ec7f50e53b3042c83dcf8eeb3026 Mon Sep 17 00:00:00 2001 From: Luis Delgado de Mendoza Date: Tue, 14 Nov 2023 16:04:43 -0800 Subject: [PATCH 01/35] Modify gs-common sepolicy for the new BT comms to AoC Bug: 308452948 Test: Validated in husky with all changes. Change-Id: I6496b7760e6f20b3b7e09910ed42446a1eb703cf --- aoc/sepolicy/file_contexts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aoc/sepolicy/file_contexts b/aoc/sepolicy/file_contexts index c3a4754..58edf2f 100644 --- a/aoc/sepolicy/file_contexts +++ b/aoc/sepolicy/file_contexts @@ -20,6 +20,8 @@ /dev/acd-com.google.usf.non_wake_up u:object_r:aoc_device:s0 /dev/acd-com.google.chre u:object_r:aoc_device:s0 /dev/acd-com.google.chre.non_wake_up u:object_r:aoc_device:s0 +/dev/acd-com.google.bt u:object_r:aoc_device:s0 +/dev/acd-com.google.bt.non_wake_up u:object_r:aoc_device:s0 /dev/acd-logging u:object_r:aoc_device:s0 /dev/aoc u:object_r:aoc_device:s0 /dev/acd-audio_ap_offload_rx u:object_r:aoc_device:s0 From 3ed60cec02e9917141f3fb854ebf8edf9f351e8d Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Fri, 10 Nov 2023 14:40:18 +0800 Subject: [PATCH 02/35] dump_modemlog: move all files to subdirectory Since radioext has already moved to this folder, it doesn't make sense for the base folder to be dump_modemlog. This change moves it to its own subfolder so that we can also add more in the future. Test: build and flash, trigger bugreport and check modem logs are there Bug: 302435001 Change-Id: Ia83378074068526023f591d63b1e5ac4700b8103 --- modem/{ => dump_modemlog}/Android.bp | 16 ++++++++-------- modem/{ => dump_modemlog}/dump_modem.sh | 0 modem/{ => dump_modemlog}/dump_modemlog.cpp | 13 ++++++------- modem/dump_modemlog/dump_modemlog.mk | 5 +++++ .../include/android_property_manager.h | 7 +++---- modem/{ => dump_modemlog}/include/dumper.h | 7 +++---- .../include/modem_log_constants.h | 7 +++---- .../include/modem_log_dumper.h | 6 ++---- modem/{ => dump_modemlog}/modem_log_dumper.cpp | 7 +++---- .../modem_log_dumper_test.cpp | 7 +++---- modem/{ => dump_modemlog}/sepolicy/dump_modem.te | 0 .../sepolicy/dump_modemlog.te | 0 modem/{ => dump_modemlog}/sepolicy/file.te | 0 modem/{ => dump_modemlog}/sepolicy/file_contexts | 0 .../{ => dump_modemlog}/sepolicy/genfs_contexts | 0 .../test/include/fake_android_property_manager.h | 12 +++++------- modem/modem.mk | 6 +----- 17 files changed, 42 insertions(+), 51 deletions(-) rename modem/{ => dump_modemlog}/Android.bp (65%) rename modem/{ => dump_modemlog}/dump_modem.sh (100%) rename modem/{ => dump_modemlog}/dump_modemlog.cpp (89%) create mode 100644 modem/dump_modemlog/dump_modemlog.mk rename modem/{ => dump_modemlog}/include/android_property_manager.h (86%) rename modem/{ => dump_modemlog}/include/dumper.h (96%) rename modem/{ => dump_modemlog}/include/modem_log_constants.h (96%) rename modem/{ => dump_modemlog}/include/modem_log_dumper.h (96%) rename modem/{ => dump_modemlog}/modem_log_dumper.cpp (96%) rename modem/{test => dump_modemlog}/modem_log_dumper_test.cpp (97%) rename modem/{ => dump_modemlog}/sepolicy/dump_modem.te (100%) rename modem/{ => dump_modemlog}/sepolicy/dump_modemlog.te (100%) rename modem/{ => dump_modemlog}/sepolicy/file.te (100%) rename modem/{ => dump_modemlog}/sepolicy/file_contexts (100%) rename modem/{ => dump_modemlog}/sepolicy/genfs_contexts (100%) rename modem/{ => dump_modemlog}/test/include/fake_android_property_manager.h (91%) diff --git a/modem/Android.bp b/modem/dump_modemlog/Android.bp similarity index 65% rename from modem/Android.bp rename to modem/dump_modemlog/Android.bp index dbc1cac..b264609 100644 --- a/modem/Android.bp +++ b/modem/dump_modemlog/Android.bp @@ -11,9 +11,9 @@ sh_binary { cc_defaults { name: "dump_modemlog_defaults", - srcs: ["modem_log_dumper.cpp"], - local_include_dirs: ["include"], - shared_libs: ["liblog"], + srcs: [ "modem_log_dumper.cpp" ], + local_include_dirs: [ "include" ], + shared_libs: [ "liblog" ], } cc_binary { @@ -29,16 +29,16 @@ cc_binary { "libdump", "liblog", ], - defaults: ["dump_modemlog_defaults"], + defaults: [ "dump_modemlog_defaults" ], vendor: true, relative_install_path: "dump", } cc_test { name: "dump_modemlog_test", - srcs: ["test/*.cpp"], - defaults: ["dump_modemlog_defaults"], - local_include_dirs: ["test/include"], - static_libs: ["libgmock"], + srcs: [ "*_test.cpp" ], + defaults: [ "dump_modemlog_defaults" ], + local_include_dirs: [ "test/include" ], + static_libs: [ "libgmock" ], vendor: true, } diff --git a/modem/dump_modem.sh b/modem/dump_modemlog/dump_modem.sh similarity index 100% rename from modem/dump_modem.sh rename to modem/dump_modemlog/dump_modem.sh diff --git a/modem/dump_modemlog.cpp b/modem/dump_modemlog/dump_modemlog.cpp similarity index 89% rename from modem/dump_modemlog.cpp rename to modem/dump_modemlog/dump_modemlog.cpp index 1b6b2e9..47181cb 100644 --- a/modem/dump_modemlog.cpp +++ b/modem/dump_modemlog/dump_modemlog.cpp @@ -19,8 +19,7 @@ #include "dumper.h" #include "modem_log_dumper.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { /** * @brief Implementation of AndroidPropertyManager that directly forwards to @@ -59,13 +58,13 @@ class DumperImpl : public Dumper { } }; -} // namespace logging -} // namespace modem +} // namespace pixel_modem::logging int main() { - modem::logging::DumperImpl dumper_impl; - modem::logging::AndroidPropertyManagerImpl android_property_manager_impl; - modem::logging::ModemLogDumper modem_log_dumper( + pixel_modem::logging::DumperImpl dumper_impl; + pixel_modem::logging::AndroidPropertyManagerImpl + android_property_manager_impl; + pixel_modem::logging::ModemLogDumper modem_log_dumper( dumper_impl, android_property_manager_impl); modem_log_dumper.DumpModemLogs(); diff --git a/modem/dump_modemlog/dump_modemlog.mk b/modem/dump_modemlog/dump_modemlog.mk new file mode 100644 index 0000000..5e91ab7 --- /dev/null +++ b/modem/dump_modemlog/dump_modemlog.mk @@ -0,0 +1,5 @@ +BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/modem/dump_modemlog/sepolicy + +PRODUCT_PACKAGES += dump_modem.sh +PRODUCT_PACKAGES += dump_modemlog + diff --git a/modem/include/android_property_manager.h b/modem/dump_modemlog/include/android_property_manager.h similarity index 86% rename from modem/include/android_property_manager.h rename to modem/dump_modemlog/include/android_property_manager.h index 7135d66..eb426c3 100644 --- a/modem/include/android_property_manager.h +++ b/modem/dump_modemlog/include/android_property_manager.h @@ -2,8 +2,7 @@ #include -namespace modem { -namespace logging { +namespace pixel_modem::logging { /** * @brief Interface for interacting with Android System Properties. @@ -17,5 +16,5 @@ class AndroidPropertyManager { virtual int GetIntProperty(const std::string& key, int default_value); virtual void SetProperty(const std::string& key, const std::string& value); }; -} // namespace logging -} // namespace modem + +} // namespace pixel_modem::logging diff --git a/modem/include/dumper.h b/modem/dump_modemlog/include/dumper.h similarity index 96% rename from modem/include/dumper.h rename to modem/dump_modemlog/include/dumper.h index 348e666..a9b96c6 100644 --- a/modem/include/dumper.h +++ b/modem/dump_modemlog/include/dumper.h @@ -3,8 +3,7 @@ #include #include -namespace modem { -namespace logging { +namespace pixel_modem::logging { /** * @brief Data object for information about dumpings logs. @@ -67,5 +66,5 @@ class Dumper { virtual void DumpLogs(const LogDumpInfo& log_dump_info); virtual void CopyFile(const FileCopyInfo& file_copy_info); }; -} // namespace logging -} // namespace modem + +} // namespace pixel_modem::logging diff --git a/modem/include/modem_log_constants.h b/modem/dump_modemlog/include/modem_log_constants.h similarity index 96% rename from modem/include/modem_log_constants.h rename to modem/dump_modemlog/include/modem_log_constants.h index 29a0fa8..8183ec3 100644 --- a/modem/include/modem_log_constants.h +++ b/modem/dump_modemlog/include/modem_log_constants.h @@ -3,8 +3,7 @@ #include "dumper.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { // Modem related Android System Properties @@ -52,5 +51,5 @@ constexpr static FileCopyInfo kFileCopyInfo[] = { {.src_dir = "/mnt/vendor/efs/nv_protected.bin", .dest_dir = "/data/vendor/radio/logs/always-on/all_logs/nv_protected.bin"}}; -} // namespace logging -} // namespace modem + +} // namespace pixel_modem::logging diff --git a/modem/include/modem_log_dumper.h b/modem/dump_modemlog/include/modem_log_dumper.h similarity index 96% rename from modem/include/modem_log_dumper.h rename to modem/dump_modemlog/include/modem_log_dumper.h index 96911b0..1533217 100644 --- a/modem/include/modem_log_dumper.h +++ b/modem/dump_modemlog/include/modem_log_dumper.h @@ -3,8 +3,7 @@ #include "android_property_manager.h" #include "dumper.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { /** * @brief Responsible for dumping all relevant modem logs. @@ -77,5 +76,4 @@ class ModemLogDumper { AndroidPropertyManager& android_property_manager_; }; -} // namespace logging -} // namespace modem +} // namespace pixel_modem::logging diff --git a/modem/modem_log_dumper.cpp b/modem/dump_modemlog/modem_log_dumper.cpp similarity index 96% rename from modem/modem_log_dumper.cpp rename to modem/dump_modemlog/modem_log_dumper.cpp index fad8d29..b5e7a07 100644 --- a/modem/modem_log_dumper.cpp +++ b/modem/dump_modemlog/modem_log_dumper.cpp @@ -5,8 +5,7 @@ #include "dumper.h" #include "modem_log_constants.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { void ModemLogDumper::DumpModemLogs() { bool shouldRestartModemLogging = @@ -76,5 +75,5 @@ void ModemLogDumper::startModemLogging() { android_property_manager_.SetProperty(kModemLoggingEnabledProperty.data(), "true"); } -} // namespace logging -} // namespace modem + +} // namespace pixel_modem::logging diff --git a/modem/test/modem_log_dumper_test.cpp b/modem/dump_modemlog/modem_log_dumper_test.cpp similarity index 97% rename from modem/test/modem_log_dumper_test.cpp rename to modem/dump_modemlog/modem_log_dumper_test.cpp index a052d43..d9917e1 100644 --- a/modem/test/modem_log_dumper_test.cpp +++ b/modem/dump_modemlog/modem_log_dumper_test.cpp @@ -7,8 +7,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { namespace { using ::testing::Eq; @@ -101,6 +100,6 @@ TEST_F(ModemLogDumperTest, EXPECT_FALSE(fake_android_property_manager.ModemLoggingHasRestarted()); } + } // namespace -} // namespace logging -} // namespace modem +} // namespace pixel_modem::logging diff --git a/modem/sepolicy/dump_modem.te b/modem/dump_modemlog/sepolicy/dump_modem.te similarity index 100% rename from modem/sepolicy/dump_modem.te rename to modem/dump_modemlog/sepolicy/dump_modem.te diff --git a/modem/sepolicy/dump_modemlog.te b/modem/dump_modemlog/sepolicy/dump_modemlog.te similarity index 100% rename from modem/sepolicy/dump_modemlog.te rename to modem/dump_modemlog/sepolicy/dump_modemlog.te diff --git a/modem/sepolicy/file.te b/modem/dump_modemlog/sepolicy/file.te similarity index 100% rename from modem/sepolicy/file.te rename to modem/dump_modemlog/sepolicy/file.te diff --git a/modem/sepolicy/file_contexts b/modem/dump_modemlog/sepolicy/file_contexts similarity index 100% rename from modem/sepolicy/file_contexts rename to modem/dump_modemlog/sepolicy/file_contexts diff --git a/modem/sepolicy/genfs_contexts b/modem/dump_modemlog/sepolicy/genfs_contexts similarity index 100% rename from modem/sepolicy/genfs_contexts rename to modem/dump_modemlog/sepolicy/genfs_contexts diff --git a/modem/test/include/fake_android_property_manager.h b/modem/dump_modemlog/test/include/fake_android_property_manager.h similarity index 91% rename from modem/test/include/fake_android_property_manager.h rename to modem/dump_modemlog/test/include/fake_android_property_manager.h index 79fd4f1..0d5731a 100644 --- a/modem/test/include/fake_android_property_manager.h +++ b/modem/dump_modemlog/test/include/fake_android_property_manager.h @@ -7,8 +7,7 @@ #include "android_property_manager.h" #include "modem_log_constants.h" -namespace modem { -namespace logging { +namespace pixel_modem::logging { /** * @brief Fake Implementation of AndroidPropertyManager that mocks some of the @@ -20,9 +19,8 @@ class FakeAndroidPropertyManager : public AndroidPropertyManager { inline constexpr static std::string_view kFalseString = "false"; bool GetBoolProperty(const std::string& key, bool default_value) override { - return MapContainsKey(key) - ? GetPropertyInternal(key) == kTruthString - : default_value; + return MapContainsKey(key) ? GetPropertyInternal(key) == kTruthString + : default_value; }; std::string GetProperty(const std::string& key, @@ -73,5 +71,5 @@ class FakeAndroidPropertyManager : public AndroidPropertyManager { bool modem_logging_has_been_off_ = false; bool modem_logging_has_restarted_ = false; }; -} // namespace logging -} // namespace modem + +} // namespace pixel_modem::logging diff --git a/modem/modem.mk b/modem/modem.mk index 10df7d4..d921e74 100644 --- a/modem/modem.mk +++ b/modem/modem.mk @@ -1,5 +1 @@ -BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/modem/sepolicy - -PRODUCT_PACKAGES += dump_modem.sh -PRODUCT_PACKAGES += dump_modemlog - +include device/google/gs-common/modem/dump_modemlog/dump_modemlog.mk From 047f0aca49217d58b4af8c8ac8652585d5b29eb3 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Fri, 10 Nov 2023 15:02:57 +0800 Subject: [PATCH 03/35] dump_modemlog: move android_property_manager android_property_manager is moved to its own folder in the root of the modem folder. This is so that libeomservice proxy has a specific build target to include. Test: build, flash, check modem logs in bugreport Bug: 302435001 Change-Id: Ifc4a0c888717f5c28cf9b642d0b978b495be29d0 --- modem/android_property_manager/Android.bp | 9 +++ .../android_property_manager/fake/Android.bp | 23 ++++++ .../fake/fake_android_property_manager.cpp | 80 +++++++++++++++++++ .../include/fake_android_property_manager.h | 54 +++++++++++++ .../android_property_manager/impl/Android.bp | 18 +++++ .../impl/android_property_manager_impl.cpp | 29 +++++++ .../include/android_property_manager_impl.h | 25 ++++++ .../include/android_property_manager.h | 19 +++-- modem/dump_modemlog/Android.bp | 54 ++++++++++--- modem/dump_modemlog/dump_modemlog.cpp | 26 +----- .../include/fake_android_property_manager.h | 75 ----------------- 11 files changed, 296 insertions(+), 116 deletions(-) create mode 100644 modem/android_property_manager/Android.bp create mode 100644 modem/android_property_manager/fake/Android.bp create mode 100644 modem/android_property_manager/fake/fake_android_property_manager.cpp create mode 100644 modem/android_property_manager/fake/include/fake_android_property_manager.h create mode 100644 modem/android_property_manager/impl/Android.bp create mode 100644 modem/android_property_manager/impl/android_property_manager_impl.cpp create mode 100644 modem/android_property_manager/impl/include/android_property_manager_impl.h rename modem/{dump_modemlog => android_property_manager}/include/android_property_manager.h (53%) delete mode 100644 modem/dump_modemlog/test/include/fake_android_property_manager.h diff --git a/modem/android_property_manager/Android.bp b/modem/android_property_manager/Android.bp new file mode 100644 index 0000000..af89aec --- /dev/null +++ b/modem/android_property_manager/Android.bp @@ -0,0 +1,9 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library { + name: "modem_android_property_manager", + export_include_dirs: [ "include" ], + vendor_available: true, +} diff --git a/modem/android_property_manager/fake/Android.bp b/modem/android_property_manager/fake/Android.bp new file mode 100644 index 0000000..247b97c --- /dev/null +++ b/modem/android_property_manager/fake/Android.bp @@ -0,0 +1,23 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +// When `modem_android_property_manager_fake` is included statically, its +// dependencies are not transitively included, so the target will also have to +// include this default to restate them. +cc_defaults { + name: "modem_android_property_manager_fake_defaults", + static_libs: [ + "modem_android_property_manager", + "libbase", + "modem_log_constants", + ], +} + +cc_library_static { + name: "modem_android_property_manager_fake", + export_include_dirs: [ "include" ], + srcs: [ "fake_android_property_manager.cpp" ], + defaults: [ "modem_android_property_manager_fake_defaults" ], + vendor_available: true, +} diff --git a/modem/android_property_manager/fake/fake_android_property_manager.cpp b/modem/android_property_manager/fake/fake_android_property_manager.cpp new file mode 100644 index 0000000..d25d6da --- /dev/null +++ b/modem/android_property_manager/fake/fake_android_property_manager.cpp @@ -0,0 +1,80 @@ +#include "fake_android_property_manager.h" + +#include +#include + +#include +#include +#include + +#include "modem_log_constants.h" + +namespace pixel_modem { + +bool FakeAndroidPropertyManager::GetBoolProperty(const std::string& key, + bool default_value) { + auto value_result = GetProperty(key); + return value_result.ok() ? (*value_result) == kTruthString : default_value; +} + +std::string FakeAndroidPropertyManager::GetProperty( + const std::string& key, const std::string& default_value) { + auto value_result = GetProperty(key); + return value_result.ok() ? *value_result : default_value; +} + +int FakeAndroidPropertyManager::GetIntProperty(const std::string& key, + int default_value) { + int value = default_value; + + auto property_result = GetProperty(key); + if (property_result.ok()) { + android::base::ParseInt((*property_result).data(), &value); + } + return value; +} + +/** + * This function needs to copy the behaviour of `modem_logging_control` to + * ensure that the right properties are being set in order. + * + * More specifically, this function will also set the + * `kModemLoggingStatusProperty` whenever `kModemLoggingEnabledProperty` is + * set to simulate modem logging stopping / starting. + */ +bool FakeAndroidPropertyManager::SetProperty(const std::string& key, + const std::string& value) { + if (key == logging::kModemLoggingEnabledProperty) { + property_map_[logging::kModemLoggingStatusProperty.data()] = value; + + // need to track if modem logging has restarted or not + if (value == kFalseString) { + modem_logging_has_been_off_ = true; + } + if (modem_logging_has_been_off_ && (value == kTruthString)) { + modem_logging_has_restarted_ = true; + } + } + property_map_[key] = value; + return true; +} + +/** + * @brief Gets android system property if present. + * + * @param[in] key Name of property. + * + * @return Status of get operation and value if successful. + * @retval EINVAL Key not present in map. + */ +android::base::Result FakeAndroidPropertyManager::GetProperty( + const std::string& key) { + const auto it = property_map_.find(key); + if (it == property_map_.end()) { + return android::base::Error() + << "Property: " << key << " not found." << EINVAL; + } + return it->second; +} + +} // namespace pixel_modem diff --git a/modem/android_property_manager/fake/include/fake_android_property_manager.h b/modem/android_property_manager/fake/include/fake_android_property_manager.h new file mode 100644 index 0000000..eeea5a0 --- /dev/null +++ b/modem/android_property_manager/fake/include/fake_android_property_manager.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +#include "android-base/result.h" +#include "android_property_manager.h" + +namespace pixel_modem { + +/** + * @brief Fake Implementation of AndroidPropertyManager that mocks some of the + * property changing behaviour from pixellogger's `modem_logging_control`. + */ +class FakeAndroidPropertyManager : public AndroidPropertyManager { + public: + bool GetBoolProperty(const std::string& key, bool default_value) override; + + std::string GetProperty(const std::string& key, + const std::string& default_value) override; + + int GetIntProperty(const std::string& key, int default_value) override; + + /** + * This function needs to copy the behaviour of `modem_logging_control` to + * ensure that the right properties are being set in order. + * + * More specifically, this function will also set the + * `kModemLoggingStatusProperty` whenever `kModemLoggingEnabledProperty` is + * set to simulate modem logging stopping / starting. + */ + bool SetProperty(const std::string& key, const std::string& value) override; + + inline bool ModemLoggingHasRestarted() { + return modem_logging_has_restarted_; + } + + private: + /** + * @brief Gets android system property if present. + * + * @param[in] key Name of property. + * + * @return Status of get operation and value if successful. + * @retval EINVAL Key not present in map. + */ + android::base::Result GetProperty(const std::string& key); + + std::map property_map_; + bool modem_logging_has_been_off_ = false; + bool modem_logging_has_restarted_ = false; +}; + +} // namespace pixel_modem diff --git a/modem/android_property_manager/impl/Android.bp b/modem/android_property_manager/impl/Android.bp new file mode 100644 index 0000000..2023e8f --- /dev/null +++ b/modem/android_property_manager/impl/Android.bp @@ -0,0 +1,18 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +modem_android_property_manager_impl_public_deps = [ + "modem_android_property_manager", +] + +cc_library_shared { + name: "modem_android_property_manager_impl", + export_include_dirs: [ "include" ], + srcs: [ "android_property_manager_impl.cpp" ], + shared_libs: modem_android_property_manager_impl_public_deps + [ + "libbase", + ], + export_shared_lib_headers: modem_android_property_manager_impl_public_deps, + vendor_available: true, +} diff --git a/modem/android_property_manager/impl/android_property_manager_impl.cpp b/modem/android_property_manager/impl/android_property_manager_impl.cpp new file mode 100644 index 0000000..b6b900a --- /dev/null +++ b/modem/android_property_manager/impl/android_property_manager_impl.cpp @@ -0,0 +1,29 @@ +#include "android_property_manager_impl.h" + +#include + +#include + +namespace pixel_modem { + +bool AndroidPropertyManagerImpl::GetBoolProperty(const std::string& key, + bool default_value) { + return android::base::GetBoolProperty(key, default_value); +} + +std::string AndroidPropertyManagerImpl::GetProperty( + const std::string& key, const std::string& default_value) { + return android::base::GetProperty(key, default_value); +} + +int AndroidPropertyManagerImpl::GetIntProperty(const std::string& key, + int default_value) { + return android::base::GetIntProperty(key, default_value); +} + +bool AndroidPropertyManagerImpl::SetProperty(const std::string& key, + const std::string& value) { + return android::base::SetProperty(key, value); +} + +} // namespace pixel_modem diff --git a/modem/android_property_manager/impl/include/android_property_manager_impl.h b/modem/android_property_manager/impl/include/android_property_manager_impl.h new file mode 100644 index 0000000..91cee25 --- /dev/null +++ b/modem/android_property_manager/impl/include/android_property_manager_impl.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "android_property_manager.h" + +namespace pixel_modem { + +/** + * @brief Implementation of AndroidPropertyManager that directly forwards to + * android base methods. + */ +class AndroidPropertyManagerImpl : public AndroidPropertyManager { + public: + bool GetBoolProperty(const std::string& key, bool default_value) override; + + std::string GetProperty(const std::string& key, + const std::string& default_value) override; + + int GetIntProperty(const std::string& key, int default_value) override; + + bool SetProperty(const std::string& key, const std::string& value) override; +}; + +} // namespace pixel_modem diff --git a/modem/dump_modemlog/include/android_property_manager.h b/modem/android_property_manager/include/android_property_manager.h similarity index 53% rename from modem/dump_modemlog/include/android_property_manager.h rename to modem/android_property_manager/include/android_property_manager.h index eb426c3..e41a28d 100644 --- a/modem/dump_modemlog/include/android_property_manager.h +++ b/modem/android_property_manager/include/android_property_manager.h @@ -1,8 +1,14 @@ + #pragma once #include +#include -namespace pixel_modem::logging { +namespace pixel_modem { + +// Used to set boolean parameters to true / false +inline constexpr std::string_view kTruthString = "true"; +inline constexpr std::string_view kFalseString = "false"; /** * @brief Interface for interacting with Android System Properties. @@ -10,11 +16,12 @@ namespace pixel_modem::logging { class AndroidPropertyManager { public: virtual ~AndroidPropertyManager() = default; - virtual bool GetBoolProperty(const std::string& key, bool default_value); + virtual bool GetBoolProperty(const std::string& key, bool default_value) = 0; virtual std::string GetProperty(const std::string& key, - const std::string& default_value); - virtual int GetIntProperty(const std::string& key, int default_value); - virtual void SetProperty(const std::string& key, const std::string& value); + const std::string& default_value) = 0; + virtual int GetIntProperty(const std::string& key, int default_value) = 0; + virtual bool SetProperty(const std::string& key, + const std::string& value) = 0; }; -} // namespace pixel_modem::logging +} // namespace pixel_modem diff --git a/modem/dump_modemlog/Android.bp b/modem/dump_modemlog/Android.bp index b264609..cad6e49 100644 --- a/modem/dump_modemlog/Android.bp +++ b/modem/dump_modemlog/Android.bp @@ -1,5 +1,5 @@ package { - default_applicable_licenses: ["Android-Apache-2.0"], + default_applicable_licenses: [ "Android-Apache-2.0" ], } sh_binary { @@ -9,16 +9,38 @@ sh_binary { sub_dir: "dump", } +// Modem Log Dumper + +modem_log_dumper_public_deps = [ + "modem_android_property_manager", +] + +// When `modem_log_dumper` is included statically, its dependencies are not +// transitively included, so the target will also have to include this default +// to restate them. cc_defaults { - name: "dump_modemlog_defaults", - srcs: [ "modem_log_dumper.cpp" ], - local_include_dirs: [ "include" ], - shared_libs: [ "liblog" ], + name: "modem_log_dumper_defaults", + shared_libs: modem_log_dumper_public_deps + [ + "libbase", + // liblog is not directly used by us, but it's a transitive dependency of libbase + "liblog", + ], } +cc_library { + name: "modem_log_dumper", + srcs: [ "modem_log_dumper.cpp" ], + defaults: [ "modem_log_dumper_defaults" ], + export_shared_lib_headers: modem_log_dumper_public_deps, + export_include_dirs: [ "include" ], + vendor_available: true, +} + +// dump_modemlog + cc_binary { name: "dump_modemlog", - srcs: ["dump_modemlog.cpp"], + srcs: [ "dump_modemlog.cpp" ], cflags: [ "-Wall", "-Wextra", @@ -28,17 +50,27 @@ cc_binary { "libbase", "libdump", "liblog", + "modem_android_property_manager_impl", + "modem_log_dumper", ], - defaults: [ "dump_modemlog_defaults" ], vendor: true, relative_install_path: "dump", } cc_test { name: "dump_modemlog_test", - srcs: [ "*_test.cpp" ], - defaults: [ "dump_modemlog_defaults" ], - local_include_dirs: [ "test/include" ], - static_libs: [ "libgmock" ], + srcs: [ "modem_log_dumper_test.cpp" ], + defaults: [ + "modem_log_dumper_defaults", + "modem_android_property_manager_fake_defaults", + ], + static_libs: [ + "modem_log_dumper", + "modem_android_property_manager_fake", + "libgmock", + ], vendor: true, + // Shared libs in vendor folder are guarded by SEPolicy, so tests need root + // access to run them. + require_root: true, } diff --git a/modem/dump_modemlog/dump_modemlog.cpp b/modem/dump_modemlog/dump_modemlog.cpp index 47181cb..bed936c 100644 --- a/modem/dump_modemlog/dump_modemlog.cpp +++ b/modem/dump_modemlog/dump_modemlog.cpp @@ -16,33 +16,12 @@ #include #include +#include "android_property_manager_impl.h" #include "dumper.h" #include "modem_log_dumper.h" namespace pixel_modem::logging { -/** - * @brief Implementation of AndroidPropertyManager that directly forwards to - * android base methods. - */ -class AndroidPropertyManagerImpl : public AndroidPropertyManager { - public: - bool GetBoolProperty(const std::string& key, bool default_value) override { - return android::base::GetBoolProperty(key, default_value); - }; - - std::string GetProperty(const std::string& key, - const std::string& default_value) override { - return android::base::GetProperty(key, default_value); - }; - int GetIntProperty(const std::string& key, int default_value) override { - return android::base::GetIntProperty(key, default_value); - }; - void SetProperty(const std::string& key, const std::string& value) override { - android::base::SetProperty(key, value); - }; -}; - /** * @brief Implementation of Dumper that directly forwards to their corresponding * dumpstate methods. @@ -62,8 +41,7 @@ class DumperImpl : public Dumper { int main() { pixel_modem::logging::DumperImpl dumper_impl; - pixel_modem::logging::AndroidPropertyManagerImpl - android_property_manager_impl; + pixel_modem::AndroidPropertyManagerImpl android_property_manager_impl; pixel_modem::logging::ModemLogDumper modem_log_dumper( dumper_impl, android_property_manager_impl); diff --git a/modem/dump_modemlog/test/include/fake_android_property_manager.h b/modem/dump_modemlog/test/include/fake_android_property_manager.h deleted file mode 100644 index 0d5731a..0000000 --- a/modem/dump_modemlog/test/include/fake_android_property_manager.h +++ /dev/null @@ -1,75 +0,0 @@ - - -#include -#include -#include - -#include "android_property_manager.h" -#include "modem_log_constants.h" - -namespace pixel_modem::logging { - -/** - * @brief Fake Implementation of AndroidPropertyManager that mocks some of the - * property changing behaviour from pixellogger's `modem_logging_control`. - */ -class FakeAndroidPropertyManager : public AndroidPropertyManager { - public: - inline constexpr static std::string_view kTruthString = "true"; - inline constexpr static std::string_view kFalseString = "false"; - - bool GetBoolProperty(const std::string& key, bool default_value) override { - return MapContainsKey(key) ? GetPropertyInternal(key) == kTruthString - : default_value; - }; - - std::string GetProperty(const std::string& key, - const std::string& default_value) override { - return MapContainsKey(key) ? GetPropertyInternal(key) : default_value; - ; - }; - - int GetIntProperty(const std::string& key, int default_value) override { - return MapContainsKey(key) ? std::stoi(GetPropertyInternal(key)) - : default_value; - }; - - /** - * This function needs to copy the behaviour of `modem_logging_control` to - * ensure that the right properties are being set in order. - * - * More specifically, this function will also set the - * `kModemLoggingStatusProperty` whenever `kModemLoggingEnabledProperty` is - * set to simulate modem logging stopping / starting. - */ - void SetProperty(const std::string& key, const std::string& value) override { - if (key == kModemLoggingEnabledProperty) { - property_map_[kModemLoggingStatusProperty.data()] = value; - - // need to track if modem logging has restarted or not - if (value == kFalseString) { - modem_logging_has_been_off_ = true; - } - if (modem_logging_has_been_off_ && (value == kTruthString)) { - modem_logging_has_restarted_ = true; - } - } - property_map_[key] = value; - }; - - bool ModemLoggingHasRestarted() { return modem_logging_has_restarted_; } - - private: - bool MapContainsKey(const std::string& key) { - return property_map_.find(key) != property_map_.end(); - } - std::string GetPropertyInternal(const std::string& key) { - return property_map_.find(key)->second; - } - - std::map property_map_; - bool modem_logging_has_been_off_ = false; - bool modem_logging_has_restarted_ = false; -}; - -} // namespace pixel_modem::logging From 0944a8db529a01a9a7a770b1dd2833311ec8f212 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Fri, 10 Nov 2023 15:25:02 +0800 Subject: [PATCH 04/35] gs-common/modem: clock manager interface A lot of modem code requires sleeping while vendor services do some background processing. Since we don't want to actually sleep for unit tests, an interface is provided here so that a fake sleep can be injected. Test: N/A. Directly forwards methods or does nothing. Bug: 302435001 Change-Id: I3bcf0307156d93756d69cd9f749c88b508ba9466 --- modem/clock_manager/Android.bp | 9 ++++++ modem/clock_manager/fake/Android.bp | 15 ++++++++++ .../fake/include/fake_clock_manager.h | 21 ++++++++++++++ modem/clock_manager/impl/Android.bp | 16 +++++++++++ .../clock_manager/impl/clock_manager_impl.cpp | 9 ++++++ .../impl/include/clock_manager_impl.h | 13 +++++++++ modem/clock_manager/include/clock_manager.h | 28 +++++++++++++++++++ 7 files changed, 111 insertions(+) create mode 100644 modem/clock_manager/Android.bp create mode 100644 modem/clock_manager/fake/Android.bp create mode 100644 modem/clock_manager/fake/include/fake_clock_manager.h create mode 100644 modem/clock_manager/impl/Android.bp create mode 100644 modem/clock_manager/impl/clock_manager_impl.cpp create mode 100644 modem/clock_manager/impl/include/clock_manager_impl.h create mode 100644 modem/clock_manager/include/clock_manager.h diff --git a/modem/clock_manager/Android.bp b/modem/clock_manager/Android.bp new file mode 100644 index 0000000..98aff6f --- /dev/null +++ b/modem/clock_manager/Android.bp @@ -0,0 +1,9 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library { + name: "modem_clock_manager", + export_include_dirs: [ "include" ], + vendor_available: true, +} diff --git a/modem/clock_manager/fake/Android.bp b/modem/clock_manager/fake/Android.bp new file mode 100644 index 0000000..eb16445 --- /dev/null +++ b/modem/clock_manager/fake/Android.bp @@ -0,0 +1,15 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_defaults { + name: "fake_modem_clock_manager_defaults", + shared_libs: [ "modem_clock_manager" ], +} + +cc_library_static { + name: "fake_modem_clock_manager", + export_include_dirs: [ "include" ], + defaults: [ "fake_modem_clock_manager_defaults" ], + vendor_available: true, +} diff --git a/modem/clock_manager/fake/include/fake_clock_manager.h b/modem/clock_manager/fake/include/fake_clock_manager.h new file mode 100644 index 0000000..8956777 --- /dev/null +++ b/modem/clock_manager/fake/include/fake_clock_manager.h @@ -0,0 +1,21 @@ +#include "clock_manager.h" + +namespace pixel_modem { + +/** + * @brief Fake implementation of clock manager that doesn't actually sleep. + * + * A lot of vendor code don't have return values and instead force the client + * codes to sleep for a specified period of time before checking some system + * properties. However, since unit tests don't rely on the real vendor + * implementations, these sleeps should be ignored and so a fake clock should be + * used. + * + * Since this definition is unlikely to change, it will be defined in the header + * and not an implementation file. + */ +struct FakeClockManager : public ClockManager { + void Sleep(size_t /*seconds*/) const override{}; +}; + +} // namespace pixel_modem diff --git a/modem/clock_manager/impl/Android.bp b/modem/clock_manager/impl/Android.bp new file mode 100644 index 0000000..13f4cc6 --- /dev/null +++ b/modem/clock_manager/impl/Android.bp @@ -0,0 +1,16 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +modem_clock_manager_impl_public_deps = [ + "modem_clock_manager", +] + +cc_library { + name: "modem_clock_manager_impl", + export_include_dirs: [ "include" ], + srcs: [ "clock_manager_impl.cpp" ], + shared_libs: modem_clock_manager_impl_public_deps, + export_shared_lib_headers: modem_clock_manager_impl_public_deps, + vendor_available: true, +} diff --git a/modem/clock_manager/impl/clock_manager_impl.cpp b/modem/clock_manager/impl/clock_manager_impl.cpp new file mode 100644 index 0000000..dc61a63 --- /dev/null +++ b/modem/clock_manager/impl/clock_manager_impl.cpp @@ -0,0 +1,9 @@ +#include "clock_manager_impl.h" + +#include + +namespace pixel_modem { + +void ClockManagerImpl::Sleep(size_t seconds) const { sleep(seconds); } + +} // namespace pixel_modem diff --git a/modem/clock_manager/impl/include/clock_manager_impl.h b/modem/clock_manager/impl/include/clock_manager_impl.h new file mode 100644 index 0000000..d626b98 --- /dev/null +++ b/modem/clock_manager/impl/include/clock_manager_impl.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include "clock_manager.h" + +namespace pixel_modem { + +struct ClockManagerImpl : public ClockManager { + void Sleep(size_t seconds) const override; +}; + +} // namespace pixel_modem diff --git a/modem/clock_manager/include/clock_manager.h b/modem/clock_manager/include/clock_manager.h new file mode 100644 index 0000000..1db88c5 --- /dev/null +++ b/modem/clock_manager/include/clock_manager.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace pixel_modem { + +/** + * @brief Interface for time based operations. + * + * This interface was intentionally not called `Clock`, like the Java side + * counterpart since it's likely that clients would call the local variable + * `clock(_)`, which would clash with the C defined `clock` method. + */ +struct ClockManager { + virtual ~ClockManager() = default; + + /** + * @brief Sleep the thread for a given number of seconds. + * + * @param seconds Minimum number of seconds to sleep for. Note, this is + * different than the Java android clock which accepts seconds. This was done + * because C++ developers are likely more familiar with the `sleep` command, + * which accepts seconds. + */ + virtual void Sleep(size_t seconds) const = 0; +}; + +} // namespace pixel_modem From b2f0956771141a4b81865ceeaf88e8d894c8216d Mon Sep 17 00:00:00 2001 From: Randall Huang Date: Wed, 22 Nov 2023 13:53:05 +0800 Subject: [PATCH 05/35] Move sg_device related policy Bug: 312582937 Test: make selinux_policy Change-Id: Ic71e4eb53e22b24651e76e2d480d34affa01460b Signed-off-by: Randall Huang --- storage/sepolicy/file.te | 1 + storage/sepolicy/vendor_init.te | 1 + trusty/sepolicy/tee.te | 1 + 3 files changed, 3 insertions(+) create mode 100644 storage/sepolicy/vendor_init.te create mode 100644 trusty/sepolicy/tee.te diff --git a/storage/sepolicy/file.te b/storage/sepolicy/file.te index c1f082d..ed4f925 100644 --- a/storage/sepolicy/file.te +++ b/storage/sepolicy/file.te @@ -1,3 +1,4 @@ type debugfs_f2fs, debugfs_type, fs_type; type dump_storage_data_file, file_type, data_file_type; +type sg_device, dev_type; type sg_util_exec, exec_type, vendor_file_type, file_type; diff --git a/storage/sepolicy/vendor_init.te b/storage/sepolicy/vendor_init.te new file mode 100644 index 0000000..da4fcba --- /dev/null +++ b/storage/sepolicy/vendor_init.te @@ -0,0 +1 @@ +allow vendor_init sg_device:chr_file r_file_perms; diff --git a/trusty/sepolicy/tee.te b/trusty/sepolicy/tee.te new file mode 100644 index 0000000..50aab69 --- /dev/null +++ b/trusty/sepolicy/tee.te @@ -0,0 +1 @@ +allow tee sg_device:chr_file rw_file_perms; From 0a00bc714ab87e6fbe82605693ddbd89639c3f57 Mon Sep 17 00:00:00 2001 From: samou Date: Wed, 22 Nov 2023 06:42:35 +0000 Subject: [PATCH 06/35] bm: Add Battery SOC for each platforms Bug: 299700579 Change-Id: Id2f9b86ded4d9f31fd5faf2d761b5ded7bab5aff Signed-off-by: samou --- battery_mitigation/battery_mitigation.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/battery_mitigation/battery_mitigation.cpp b/battery_mitigation/battery_mitigation.cpp index cb33205..18bb63d 100644 --- a/battery_mitigation/battery_mitigation.cpp +++ b/battery_mitigation/battery_mitigation.cpp @@ -119,19 +119,31 @@ const struct MitigationConfig::EventThreadConfig eventThreadCfg = { { .MainPmicName = "s2mpg10-odpm\n", .SubPmicName = "s2mpg11-odpm\n", + .NumericSysfsStatPaths = { + {"battery_soc", "/sys/class/power_supply/max77759fg/capacity"}, + }, }, { .MainPmicName = "s2mpg12-odpm\n", .SubPmicName = "s2mpg13-odpm\n", + .NumericSysfsStatPaths = { + {"battery_soc", "/sys/class/power_supply/max77759fg/capacity"}, + }, }, { .MainPmicName = "s2mpg14-odpm\n", .SubPmicName = "s2mpg15-odpm\n", + .NumericSysfsStatPaths = { + {"battery_soc", "/sys/class/power_supply/max77779fg/capacity"}, + }, }, /* MAX_SUPPORTED_PLATFORM */ { .MainPmicName = "s2mpg14-odpm\n", .SubPmicName = "s2mpg15-odpm\n", + .NumericSysfsStatPaths = { + {"battery_soc", "/sys/class/power_supply/max77779fg/capacity"}, + }, }, }, From e7cffe4da5b0125fcaa2063fd43cc4681bda7ea9 Mon Sep 17 00:00:00 2001 From: Dinesh Yadav Date: Wed, 22 Nov 2023 13:03:29 +0000 Subject: [PATCH 07/35] Allow edgetpu_tachyon_service to access GXP device & Dmabuf. As gxp stack will be using Tachyon service to process kernels on aurora dsp, these permissions will be needed. Bug: 279655948 Change-Id: I04c11575208d0ca1a3dda68db1367804c4d7596d Signed-off-by: Dinesh Yadav --- edgetpu/sepolicy/edgetpu_tachyon_service.te | 3 +++ gxp/sepolicy/edgetpu_tachyon_service.te | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 gxp/sepolicy/edgetpu_tachyon_service.te diff --git a/edgetpu/sepolicy/edgetpu_tachyon_service.te b/edgetpu/sepolicy/edgetpu_tachyon_service.te index 66a4667..5ead23b 100644 --- a/edgetpu/sepolicy/edgetpu_tachyon_service.te +++ b/edgetpu/sepolicy/edgetpu_tachyon_service.te @@ -27,6 +27,9 @@ allow edgetpu_tachyon_server gpu_device:chr_file rw_file_perms; allow edgetpu_tachyon_server gpu_device:dir r_dir_perms; allow edgetpu_tachyon_server ion_device:chr_file r_file_perms; +# Allow Tachyon service to access dmabuf sysytem. +allow edgetpu_tachyon_server dmabuf_system_heap_device:chr_file r_file_perms; + # Allow Tachyon service to read the overcommit_memory info. allow edgetpu_tachyon_server proc_overcommit_memory:file r_file_perms; diff --git a/gxp/sepolicy/edgetpu_tachyon_service.te b/gxp/sepolicy/edgetpu_tachyon_service.te new file mode 100644 index 0000000..35987dd --- /dev/null +++ b/gxp/sepolicy/edgetpu_tachyon_service.te @@ -0,0 +1,3 @@ +# Allow Tachyon service to access the GXP device and read GXP properties. +allow edgetpu_tachyon_server gxp_device:chr_file rw_file_perms; +get_prop(edgetpu_tachyon_server, vendor_gxp_prop) From c7af470aac55c610a8d1fa49b35e79b60160b746 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 9 Nov 2023 20:50:57 +0800 Subject: [PATCH 08/35] gs-common: add device_google_gs-common_license reference device/google/zuma Bug: 265063384 Change-Id: Ibc35993341b137b1c4229197cacac64512e9e897 Signed-off-by: Jason Chiu --- Android.bp | 45 +++++++++++++ NOTICE | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 Android.bp create mode 100644 NOTICE diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..52a1055 --- /dev/null +++ b/Android.bp @@ -0,0 +1,45 @@ +// +// Copyright (C) 2023 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 { + default_applicable_licenses: ["device_google_gs-common_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "device_google_gs-common_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-BSD", + ], + license_text: [ + "NOTICE", + ], +} diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..316b4eb --- /dev/null +++ b/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2014, 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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + From 34acb6f0b5a615cd97a03b01fd36cecfe702e172 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:52:08 +0800 Subject: [PATCH 09/35] gs-common: move bootctrl hal aidl implementation to gs-common copy from device/google/zuma/interfaces/boot $ git log --oneline -1 interfaces/boot/ 193e5e8 zuma:interfaces:boot: add aidl interface support Bug: 265063384 Change-Id: I6f21c4af66a8404b34bc1ab5cce108f23e1962b3 Signed-off-by: Jason Chiu --- bootctrl/aidl/Android.bp | 65 +++ bootctrl/aidl/BootControl.cpp | 538 ++++++++++++++++++ bootctrl/aidl/BootControl.h | 61 ++ bootctrl/aidl/DevInfo.h | 53 ++ bootctrl/aidl/GptUtils.cpp | 185 ++++++ bootctrl/aidl/GptUtils.h | 71 +++ ...oid.hardware.boot-service.default-pixel.rc | 5 + ...are.boot-service.default_recovery-pixel.rc | 7 + ...re.boot-service.default_recovery-pixel.xml | 6 + bootctrl/aidl/service.cpp | 44 ++ 10 files changed, 1035 insertions(+) create mode 100644 bootctrl/aidl/Android.bp create mode 100644 bootctrl/aidl/BootControl.cpp create mode 100644 bootctrl/aidl/BootControl.h create mode 100644 bootctrl/aidl/DevInfo.h create mode 100644 bootctrl/aidl/GptUtils.cpp create mode 100644 bootctrl/aidl/GptUtils.h create mode 100644 bootctrl/aidl/android.hardware.boot-service.default-pixel.rc create mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc create mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml create mode 100644 bootctrl/aidl/service.cpp diff --git a/bootctrl/aidl/Android.bp b/bootctrl/aidl/Android.bp new file mode 100644 index 0000000..9e47cca --- /dev/null +++ b/bootctrl/aidl/Android.bp @@ -0,0 +1,65 @@ +// +// Copyright (C) 2023 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "//device/google/gs-common:device_google_gs-common_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: [ + "//device/google/gs-common:device_google_gs-common_license", + ], +} + +cc_defaults { + name: "android.hardware.boot-service_common-pixel", + relative_install_path: "hw", + defaults: ["libboot_control_defaults"], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "libz", + "libtrusty", + "android.hardware.boot@1.1", + "android.hardware.boot-V1-ndk", + ], + static_libs: [ + "libboot_control", + "libbootloader_message_vendor", + ], + srcs: [ + "BootControl.cpp", + "GptUtils.cpp", + "service.cpp" + ], +} + +cc_binary { + name: "android.hardware.boot-service.default-pixel", + defaults: ["android.hardware.boot-service_common-pixel"], + init_rc: ["android.hardware.boot-service.default-pixel.rc"], + vendor: true, +} + +cc_binary { + name: "android.hardware.boot-service.default_recovery-pixel", + defaults: ["android.hardware.boot-service_common-pixel"], + vintf_fragments: ["android.hardware.boot-service.default_recovery-pixel.xml"], + init_rc: ["android.hardware.boot-service.default_recovery-pixel.rc"], + recovery: true, +} diff --git a/bootctrl/aidl/BootControl.cpp b/bootctrl/aidl/BootControl.cpp new file mode 100644 index 0000000..941b0d2 --- /dev/null +++ b/bootctrl/aidl/BootControl.cpp @@ -0,0 +1,538 @@ +/* + * Copyright (C) 2023 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 "bootcontrolhal" + +#include "BootControl.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DevInfo.h" +#include "GptUtils.h" + +using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus; +using ndk::ScopedAStatus; + +using android::bootable::GetMiscVirtualAbMergeStatus; +using android::bootable::InitMiscVirtualAbMessageIfNeeded; +using android::bootable::SetMiscVirtualAbMergeStatus; + +namespace aidl::android::hardware::boot { + +namespace { + +// clang-format off + +#define BOOT_A_PATH "/dev/block/by-name/boot_a" +#define BOOT_B_PATH "/dev/block/by-name/boot_b" +#define DEVINFO_PATH "/dev/block/by-name/devinfo" + +// slot flags +#define AB_ATTR_PRIORITY_SHIFT 52 +#define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) +#define AB_ATTR_ACTIVE_SHIFT 54 +#define AB_ATTR_ACTIVE (1UL << AB_ATTR_ACTIVE_SHIFT) +#define AB_ATTR_RETRY_COUNT_SHIFT (55) +#define AB_ATTR_RETRY_COUNT_MASK (7UL << AB_ATTR_RETRY_COUNT_SHIFT) +#define AB_ATTR_SUCCESSFUL (1UL << 58) +#define AB_ATTR_UNBOOTABLE (1UL << 59) + +#define AB_ATTR_MAX_PRIORITY 3UL +#define AB_ATTR_MAX_RETRY_COUNT 3UL + +// clang-format on + +static std::string getDevPath(int32_t in_slot) { + char real_path[PATH_MAX]; + + const char *path = in_slot == 0 ? BOOT_A_PATH : BOOT_B_PATH; + + int ret = readlink(path, real_path, sizeof real_path); + if (ret < 0) { + ALOGE("readlink failed for boot device %s\n", strerror(errno)); + return std::string(); + } + + std::string dp(real_path); + // extract /dev/sda.. part + return dp.substr(0, sizeof "/dev/block/sdX" - 1); +} + +static bool isSlotFlagSet(int32_t in_slot, uint64_t flag) { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", in_slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + return !!(e->attr & flag); +} + +static bool setSlotFlag(int32_t in_slot, uint64_t flag) { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", in_slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + e->attr |= flag; + gpt.Sync(); + + return true; +} + +static bool is_devinfo_valid; +static bool is_devinfo_initialized; +static std::mutex devinfo_lock; +static devinfo_t devinfo; + +static bool isDevInfoValid() { + const std::lock_guard lock(devinfo_lock); + + if (is_devinfo_initialized) { + return is_devinfo_valid; + } + + is_devinfo_initialized = true; + + ::android::base::unique_fd fd(open(DEVINFO_PATH, O_RDONLY)); + ::android::base::ReadFully(fd, &devinfo, sizeof devinfo); + + if (devinfo.magic != DEVINFO_MAGIC) { + return is_devinfo_valid; + } + + uint32_t version = ((uint32_t)devinfo.ver_major << 16) | devinfo.ver_minor; + // only version 3.3+ supports A/B data + if (version >= 0x0003'0003) { + is_devinfo_valid = true; + } + + return is_devinfo_valid; +} + +static bool DevInfoSync() { + if (!isDevInfoValid()) { + return false; + } + + ::android::base::unique_fd fd(open(DEVINFO_PATH, O_WRONLY | O_DSYNC)); + return ::android::base::WriteFully(fd, &devinfo, sizeof devinfo); +} + +static void DevInfoInitSlot(devinfo_ab_slot_data_t &slot_data) { + slot_data.retry_count = AB_ATTR_MAX_RETRY_COUNT; + slot_data.unbootable = 0; + slot_data.successful = 0; + slot_data.active = 1; + slot_data.fastboot_ok = 0; +} + +static int blow_otp_AR(bool secure) { + static const char *dev_name = "/dev/trusty-ipc-dev0"; + static const char *otp_name = "com.android.trusty.otp_manager.tidl"; + int fd = 1, ret = 0; + uint32_t cmd = secure? OTP_CMD_write_antirbk_secure_ap : OTP_CMD_write_antirbk_non_secure_ap; + fd = tipc_connect(dev_name, otp_name); + if (fd < 0) { + ALOGI("Failed to connect to OTP_MGR ns TA - is it missing?\n"); + ret = -1; + return ret; + } + + struct otp_mgr_req_base req = { + .command = cmd, + .resp_payload_size = 0, + }; + struct iovec iov[] = { + { + .iov_base = &req, + .iov_len = sizeof(req), + }, + }; + + size_t rc = tipc_send(fd, iov, 1, NULL, 0); + if (rc != sizeof(req)) { + ALOGI("Send fail! %zx\n", rc); + return rc; + } + + struct otp_mgr_rsp_base resp; + rc = read(fd, &resp, sizeof(resp)); + if (rc < 0) { + ALOGI("Read fail! %zx\n", rc); + return rc; + } + + if (rc < sizeof(resp)) { + ALOGI("Not enough data! %zx\n", rc); + return -EIO; + } + + if (resp.command != (cmd | OTP_RESP_BIT)) { + ALOGI("Wrong command! %x\n", resp.command); + return -EINVAL; + } + + if (resp.result != 0) { + fprintf(stderr, "AR writing error! %x\n", resp.result); + return -EINVAL; + } + + tipc_close(fd); + return 0; +} + +static bool blowAR() { + int ret = blow_otp_AR(true); + if (ret) { + ALOGI("Blow secure anti-rollback OTP failed"); + return false; + } + + ret = blow_otp_AR(false); + if (ret) { + ALOGI("Blow non-secure anti-rollback OTP failed"); + return false; + } + + return true; +} + +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; + } +} + +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; + } +} + +} // namespace + +BootControl::BootControl() { + CHECK(InitMiscVirtualAbMessageIfNeeded()); +} + +ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + *_aidl_return = 0; + return ScopedAStatus::ok(); + } + + if (isDevInfoValid()) { + *_aidl_return = devinfo.ab_data.slots[1].active ? 1 : 0; + return ScopedAStatus::ok(); + } + *_aidl_return = isSlotFlagSet(1, AB_ATTR_ACTIVE) ? 1 : 0; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) { + char suffix[PROPERTY_VALUE_MAX]; + property_get("ro.boot.slot_suffix", suffix, "_a"); + *_aidl_return = std::string(suffix) == "_b" ? 1 : 0; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) { + int32_t slots = 0; + + if (access(BOOT_A_PATH, F_OK) == 0) + slots++; + + if (access(BOOT_B_PATH, F_OK) == 0) + slots++; + + *_aidl_return = slots; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) { + HIDLMergeStatus status; + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (!GetMiscVirtualAbMergeStatus(current_slot, &status)) { + *_aidl_return = MergeStatus::UNKNOWN; + return ScopedAStatus::ok(); + } + *_aidl_return = ToAIDLMergeStatus(status); + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) { + *_aidl_return = in_slot == 0 ? "_a" : in_slot == 1 ? "_b" : ""; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + *_aidl_return = false; + return ScopedAStatus::ok(); + } + if (in_slot >= slots) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + bool unbootable; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + unbootable = !!slot_data.unbootable; + } else { + unbootable = isSlotFlagSet(in_slot, AB_ATTR_UNBOOTABLE); + } + + *_aidl_return = unbootable ? false: true; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + // just return true so that we don't we another call trying to mark it as successful + // when there is no slots + *_aidl_return = true; + return ScopedAStatus::ok(); + } + if (in_slot >= slots) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + bool successful; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + successful = !!slot_data.successful; + } else { + successful = isSlotFlagSet(in_slot, AB_ATTR_SUCCESSFUL); + } + + *_aidl_return = successful ? true : false; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::markBootSuccessful() { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + // no slots, just return true otherwise Android keeps trying + return ScopedAStatus::ok(); + } + + bool ret; + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (isDevInfoValid()) { + auto const slot = current_slot; + devinfo.ab_data.slots[slot].successful = 1; + ret = DevInfoSync(); + } else { + ret = setSlotFlag(current_slot, AB_ATTR_SUCCESSFUL); + } + + if (!ret) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Failed to set successful flag"); + } + + if (!blowAR()) { + ALOGE("Failed to blow anti-rollback counter"); + // Ignore the error, since ABL will re-trigger it on reboot + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) { + if (in_slot >= 2) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + } + + if (isDevInfoValid()) { + auto &active_slot_data = devinfo.ab_data.slots[in_slot]; + auto &inactive_slot_data = devinfo.ab_data.slots[!in_slot]; + + inactive_slot_data.active = 0; + DevInfoInitSlot(active_slot_data); + + if (!DevInfoSync()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not update DevInfo data"); + } + } else { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not get device path for slot"); + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "failed to load gpt data"); + } + + gpt_entry *active_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_a" : "boot_b"); + gpt_entry *inactive_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_b" : "boot_a"); + if (active_entry == nullptr || inactive_entry == nullptr) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "failed to get entries for boot partitions"); + } + + ALOGV("slot active attributes %lx\n", active_entry->attr); + ALOGV("slot inactive attributes %lx\n", inactive_entry->attr); + + // update attributes for active and inactive + inactive_entry->attr &= ~AB_ATTR_ACTIVE; + active_entry->attr = AB_ATTR_ACTIVE | (AB_ATTR_MAX_PRIORITY << AB_ATTR_PRIORITY_SHIFT) | + (AB_ATTR_MAX_RETRY_COUNT << AB_ATTR_RETRY_COUNT_SHIFT); + } + + char boot_dev[PROPERTY_VALUE_MAX]; + property_get("ro.boot.bootdevice", boot_dev, ""); + if (boot_dev[0] == '\0') { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "invalid ro.boot.bootdevice prop"); + } + + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/pixel/boot_lun_enabled"; + int fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + // Try old path for kernels < 5.4 + // TODO: remove once kernel 4.19 support is deprecated + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/attributes/boot_lun_enabled"; + fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "failed to open ufs attr boot_lun_enabled"); + } + } + + // + // bBootLunEn + // 0x1 => Boot LU A = enabled, Boot LU B = disable + // 0x2 => Boot LU A = disable, Boot LU B = enabled + // + int ret = ::android::base::WriteStringToFd(in_slot == 0 ? "1" : "2", fd); + close(fd); + if (ret < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "faied to write boot_lun_enabled attribute"); + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) { + if (in_slot >= 2) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + slot_data.unbootable = 1; + if (!DevInfoSync()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not update DevInfo data"); + } + } else { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not get device path for slot"); + } + + GptUtils gpt(dev_path); + gpt.Load(); + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + e->attr |= AB_ATTR_UNBOOTABLE; + + gpt.Sync(); + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) { + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (!SetMiscVirtualAbMergeStatus(current_slot, ToHIDLMergeStatus(in_status))) + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Operation failed"); + return ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::boot diff --git a/bootctrl/aidl/BootControl.h b/bootctrl/aidl/BootControl.h new file mode 100644 index 0000000..a54f66d --- /dev/null +++ b/bootctrl/aidl/BootControl.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2023 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 + +namespace aidl::android::hardware::boot { + +class BootControl final : public BnBootControl { + public: + BootControl(); + ::ndk::ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getNumberSlots(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override; + ::ndk::ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override; + ::ndk::ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override; + ::ndk::ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override; + ::ndk::ScopedAStatus markBootSuccessful() override; + ::ndk::ScopedAStatus setActiveBootSlot(int32_t in_slot) override; + ::ndk::ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override; + ::ndk::ScopedAStatus setSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus in_status) override; +}; + +enum otpmgr_command : uint32_t { + OTP_REQ_SHIFT = 1, + OTP_RESP_BIT = 1, + OTP_CMD_write_antirbk_non_secure_ap = (7 << OTP_REQ_SHIFT), + OTP_CMD_write_antirbk_secure_ap = (8 << OTP_REQ_SHIFT), +}; + +struct otp_mgr_req_base { + uint32_t command; + uint32_t resp_payload_size; + uint8_t handle; +}__packed; + +struct otp_mgr_rsp_base { + uint32_t command; + uint32_t resp_payload_size; + int result; +}__packed; + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/DevInfo.h b/bootctrl/aidl/DevInfo.h new file mode 100644 index 0000000..aa5f5d3 --- /dev/null +++ b/bootctrl/aidl/DevInfo.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 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 + +namespace aidl::android::hardware::boot { + +// +// definitions taken from ABL code +// + +constexpr uint32_t DEVINFO_MAGIC = 0x49564544; +constexpr size_t DEVINFO_AB_SLOT_COUNT = 2; + +struct devinfo_ab_slot_data_t { + uint8_t retry_count; + uint8_t unbootable : 1; + uint8_t successful : 1; + uint8_t active : 1; + uint8_t fastboot_ok : 1; + uint8_t : 4; + uint8_t unused[2]; +} __attribute__((packed)); + +typedef struct { + devinfo_ab_slot_data_t slots[DEVINFO_AB_SLOT_COUNT]; +} __attribute__((packed)) devinfo_ab_data_t; + +struct devinfo_t { + uint32_t magic; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t unused[40]; + devinfo_ab_data_t ab_data; + uint8_t unused1[72]; // use remaining up to complete 128 bytes +} __attribute__((packed)); + +static_assert(sizeof(devinfo_t) == 128, "invalid devinfo struct size"); + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.cpp b/bootctrl/aidl/GptUtils.cpp new file mode 100644 index 0000000..34dec11 --- /dev/null +++ b/bootctrl/aidl/GptUtils.cpp @@ -0,0 +1,185 @@ +/* + * 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 "bootcontrolhal" + +#include "GptUtils.h" + +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::boot { + +namespace { + +static int ValidateGptHeader(gpt_header *gpt) { + if (gpt->signature != GPT_SIGNATURE) { + ALOGE("invalid gpt signature 0x%lx\n", gpt->signature); + return -1; + } + + if (gpt->header_size != sizeof(gpt_header)) { + ALOGE("invalid gpt header size %u\n", gpt->header_size); + return -1; + } + + if (gpt->entry_size != sizeof(gpt_entry)) { + ALOGE("invalid gpt entry size %u\n", gpt->entry_size); + return -1; + } + + return 0; +} + +} // namespace + +GptUtils::GptUtils(const std::string dev_path) : dev_path(dev_path), fd(0) {} + +int GptUtils::Load(void) { + fd = open(dev_path.c_str(), O_RDWR); + if (fd < 0) { + ALOGE("failed to open block dev %s, %d\n", dev_path.c_str(), errno); + return -1; + } + + int ret = ioctl(fd, BLKSSZGET, &block_size); + if (ret < 0) { + ALOGE("failed to get block size %d\n", errno); + return -1; + } + + // read primary header + lseek64(fd, block_size, SEEK_SET); + ret = read(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to read gpt primary header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_primary)) { + ALOGE("error validating gpt header\n"); + return -1; + } + + // read partition entries + entry_array.resize(gpt_primary.entry_count); + uint32_t entries_size = gpt_primary.entry_size * gpt_primary.entry_count; + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = read(fd, entry_array.data(), entries_size); + if (ret < 0) { + ALOGE("failed to read gpt partition entries %d\n", errno); + return -1; + } + + // read gpt back header + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = read(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to read gpt backup header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_backup)) { + ALOGW("error validating gpt backup\n"); // just warn about it, not fail + } + + // Create map + auto get_name = [](const uint16_t *efi_name) { + char name[37] = {}; + for (size_t i = 0; efi_name[i] && i < sizeof name - 1; ++i) name[i] = efi_name[i]; + return std::string(name); + }; + + for (auto const &e : entry_array) { + if (e.name[0] == 0) + break; // stop at the first partition with no name + std::string s = get_name(e.name); + entries[s] = const_cast(&e); + } + + return 0; +} + +gpt_entry *GptUtils::GetPartitionEntry(std::string name) { + return entries.find(name) != entries.end() ? entries[name] : nullptr; +} + +int GptUtils::Sync(void) { + if (!fd) + return -1; + + // calculate crc and check if we need to update gpt + gpt_primary.entries_crc32 = crc32(0, reinterpret_cast(entry_array.data()), + entry_array.size() * sizeof(gpt_entry)); + + // save old crc + uint32_t crc = gpt_primary.crc32; + gpt_primary.crc32 = 0; + + gpt_primary.crc32 = crc32(0, reinterpret_cast(&gpt_primary), sizeof gpt_primary); + if (crc == gpt_primary.crc32) + return 0; // nothing to do (no changes) + + ALOGI("updating GPT\n"); + + lseek64(fd, block_size * gpt_primary.current_lba, SEEK_SET); + int ret = write(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to write gpt primary header %d\n", errno); + return -1; + } + + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt partition entries %d\n", errno); + return -1; + } + + // update GPT backup entries and backup + lseek64(fd, block_size * gpt_backup.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt backup partition entries %d\n", errno); + return -1; + } + + gpt_backup.entries_crc32 = gpt_primary.entries_crc32; + gpt_backup.crc32 = 0; + gpt_backup.crc32 = crc32(0, reinterpret_cast(&gpt_backup), sizeof gpt_backup); + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = write(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to write gpt backup header %d\n", errno); + return -1; + } + + fsync(fd); + + return 0; +} + +GptUtils::~GptUtils() { + if (fd) { + Sync(); + close(fd); + } +} + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.h b/bootctrl/aidl/GptUtils.h new file mode 100644 index 0000000..ec68cf6 --- /dev/null +++ b/bootctrl/aidl/GptUtils.h @@ -0,0 +1,71 @@ +/* + * 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 + +namespace aidl::android::hardware::boot { + +#define GPT_SIGNATURE 0x5452415020494645UL + +typedef struct { + uint8_t type_guid[16]; + uint8_t guid[16]; + uint64_t first_lba; + uint64_t last_lba; + uint64_t attr; + uint16_t name[36]; +} __attribute__((packed)) gpt_entry; + +typedef struct { + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t reserved; + uint64_t current_lba; + uint64_t backup_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + uint8_t disk_guid[16]; + uint64_t start_lba; + uint32_t entry_count; + uint32_t entry_size; + uint32_t entries_crc32; +} __attribute__((packed)) gpt_header; + +class GptUtils { + public: + GptUtils(const std::string dev_path); + int Load(void); + gpt_entry *GetPartitionEntry(std::string name); + int Sync(void); + ~GptUtils(); + + private: + std::string dev_path; + int fd; + uint32_t block_size; + gpt_header gpt_primary; + gpt_header gpt_backup; + std::vector entry_array; + std::map entries; +}; + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc new file mode 100644 index 0000000..a9887b9 --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc @@ -0,0 +1,5 @@ +service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.default-pixel + class early_hal + user root + group root drmrpc + diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc new file mode 100644 index 0000000..e58617e --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc @@ -0,0 +1,7 @@ +service vendor.boot-default /system/bin/hw/android.hardware.boot-service.default_recovery-pixel + class early_hal + user root + group root + seclabel u:r:hal_bootctl_default:s0 + interface aidl android.hardware.boot.IBootControl/default + diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml new file mode 100644 index 0000000..23ccc4e --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml @@ -0,0 +1,6 @@ + + + android.hardware.boot + IBootControl/default + + diff --git a/bootctrl/aidl/service.cpp b/bootctrl/aidl/service.cpp new file mode 100644 index 0000000..41b6c25 --- /dev/null +++ b/bootctrl/aidl/service.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2023 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 "aidl.android.hardware.boot-service.default" + +#include +#include +#include +#include +#include + +#include "BootControl.h" + +using aidl::android::hardware::boot::BootControl; +using aidl::android::hardware::boot::IBootControl; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; + +int main(int, char* argv[]) { + android::base::InitLogging(argv, android::base::KernelLogger); + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr service = ndk::SharedRefBase::make(); + + const std::string instance = std::string(BootControl::descriptor) + "/default"; + auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str()); + CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status; + LOG(INFO) << "IBootControl AIDL service running..."; + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} From e2592f8850f736182151ac7508a32493f96e7524 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:53:59 +0800 Subject: [PATCH 10/35] gs-common: create bootctrl_aidl.mk and include related modules Bug: 265063384 Change-Id: I9c52053300022989987dda7405942215fb55f8ba Signed-off-by: Jason Chiu --- bootctrl/bootctrl_aidl.mk | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 bootctrl/bootctrl_aidl.mk diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk new file mode 100644 index 0000000..5ec9445 --- /dev/null +++ b/bootctrl/bootctrl_aidl.mk @@ -0,0 +1,3 @@ +PRODUCT_PACKAGES += \ + android.hardware.boot-service.default-pixel \ + android.hardware.boot-service.default_recovery-pixel From 989583723944ec4af3a49a0a080f9086b14bb836 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:58:15 +0800 Subject: [PATCH 11/35] gs-common: move sepolicy related to bootctrl hal aidl to gs-common Bug: 265063384 Change-Id: I8f090f4601e0719ae3abe3e9d0981710fdc8b6af Signed-off-by: Jason Chiu --- bootctrl/bootctrl_aidl.mk | 2 ++ bootctrl/sepolicy/aidl/device.te | 5 +++++ bootctrl/sepolicy/aidl/file.te | 2 ++ bootctrl/sepolicy/aidl/file_contexts | 1 + bootctrl/sepolicy/aidl/hal_bootctl_default.te | 8 ++++++++ 5 files changed, 18 insertions(+) create mode 100644 bootctrl/sepolicy/aidl/device.te create mode 100644 bootctrl/sepolicy/aidl/file.te create mode 100644 bootctrl/sepolicy/aidl/file_contexts create mode 100644 bootctrl/sepolicy/aidl/hal_bootctl_default.te diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk index 5ec9445..6133c0e 100644 --- a/bootctrl/bootctrl_aidl.mk +++ b/bootctrl/bootctrl_aidl.mk @@ -1,3 +1,5 @@ PRODUCT_PACKAGES += \ android.hardware.boot-service.default-pixel \ android.hardware.boot-service.default_recovery-pixel + +BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/bootctrl/sepolicy/aidl diff --git a/bootctrl/sepolicy/aidl/device.te b/bootctrl/sepolicy/aidl/device.te new file mode 100644 index 0000000..4fd0240 --- /dev/null +++ b/bootctrl/sepolicy/aidl/device.te @@ -0,0 +1,5 @@ +# devinfo block device +type devinfo_block_device, dev_type; + +# OTA +type sda_block_device, dev_type; diff --git a/bootctrl/sepolicy/aidl/file.te b/bootctrl/sepolicy/aidl/file.te new file mode 100644 index 0000000..5357fa9 --- /dev/null +++ b/bootctrl/sepolicy/aidl/file.te @@ -0,0 +1,2 @@ +# sysfs +type sysfs_ota, sysfs_type, fs_type; diff --git a/bootctrl/sepolicy/aidl/file_contexts b/bootctrl/sepolicy/aidl/file_contexts new file mode 100644 index 0000000..339896f --- /dev/null +++ b/bootctrl/sepolicy/aidl/file_contexts @@ -0,0 +1 @@ +/vendor/bin/hw/android\.hardware\.boot-service\.default-pixel u:object_r:hal_bootctl_default_exec:s0 diff --git a/bootctrl/sepolicy/aidl/hal_bootctl_default.te b/bootctrl/sepolicy/aidl/hal_bootctl_default.te new file mode 100644 index 0000000..2ffeb27 --- /dev/null +++ b/bootctrl/sepolicy/aidl/hal_bootctl_default.te @@ -0,0 +1,8 @@ +allow hal_bootctl_default devinfo_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sda_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sysfs_ota:file rw_file_perms; +allow hal_bootctl_default tee_device:chr_file rw_file_perms; + +recovery_only(` + allow hal_bootctl_default rootfs:dir r_dir_perms; +') From 93c22b6672a3b19a58ccf9692b45160130fea7d3 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Fri, 10 Nov 2023 15:32:26 +0800 Subject: [PATCH 12/35] modem/modem_log_constants: create common folder A lot of different modem related processes require reading / writing to the same android system properties. This CL solifies them all into one place to avoid duplication. Test: build Bug: 302435001 Change-Id: I113f43bb68833224f45ad91668cd327587e1649b --- modem/dump_modemlog/Android.bp | 5 +- .../include/bugreport_constants.h | 33 +++++++++++ .../include/modem_log_constants.h | 55 ------------------- modem/dump_modemlog/modem_log_dumper.cpp | 1 + modem/dump_modemlog/modem_log_dumper_test.cpp | 8 ++- modem/modem_log_constants/Android.bp | 9 +++ .../include/modem_log_constants.h | 31 +++++++++++ 7 files changed, 83 insertions(+), 59 deletions(-) create mode 100644 modem/dump_modemlog/include/bugreport_constants.h delete mode 100644 modem/dump_modemlog/include/modem_log_constants.h create mode 100644 modem/modem_log_constants/Android.bp create mode 100644 modem/modem_log_constants/include/modem_log_constants.h diff --git a/modem/dump_modemlog/Android.bp b/modem/dump_modemlog/Android.bp index cad6e49..aca7b20 100644 --- a/modem/dump_modemlog/Android.bp +++ b/modem/dump_modemlog/Android.bp @@ -24,6 +24,7 @@ cc_defaults { "libbase", // liblog is not directly used by us, but it's a transitive dependency of libbase "liblog", + "modem_log_constants", ], } @@ -65,8 +66,10 @@ cc_test { "modem_android_property_manager_fake_defaults", ], static_libs: [ - "modem_log_dumper", + "modem_android_property_manager", "modem_android_property_manager_fake", + "modem_log_constants", + "modem_log_dumper", "libgmock", ], vendor: true, diff --git a/modem/dump_modemlog/include/bugreport_constants.h b/modem/dump_modemlog/include/bugreport_constants.h new file mode 100644 index 0000000..25c800f --- /dev/null +++ b/modem/dump_modemlog/include/bugreport_constants.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "dumper.h" + +namespace pixel_modem::logging { + +inline constexpr std::string_view kBugreportPackingDirectory = + "/data/vendor/radio/logs/always-on/all_logs"; + +inline constexpr LogDumpInfo kLogDumpInfo[] = { + {.src_dir = "/data/vendor/radio/extended_logs", + .dest_dir = kBugreportPackingDirectory, + .limit = 20, + .prefix = "extended_log_"}, + {.src_dir = "/data/vendor/radio/sim/", + .dest_dir = kBugreportPackingDirectory, + .limit = 1, + .prefix = "sim_poweron_log_"}, + {.src_dir = "data/vendor/radio/logs/history", + .dest_dir = kBugreportPackingDirectory, + .limit = 2, + .prefix = "Logging"}}; + +constexpr FileCopyInfo kFileCopyInfo[] = { + {.src_dir = "/mnt/vendor/efs/nv_normal.bin", + .dest_dir = "/data/vendor/radio/logs/always-on/all_logs/nv_normal.bin"}, + {.src_dir = "/mnt/vendor/efs/nv_protected.bin", + .dest_dir = + "/data/vendor/radio/logs/always-on/all_logs/nv_protected.bin"}}; + +} // namespace pixel_modem::logging diff --git a/modem/dump_modemlog/include/modem_log_constants.h b/modem/dump_modemlog/include/modem_log_constants.h deleted file mode 100644 index 8183ec3..0000000 --- a/modem/dump_modemlog/include/modem_log_constants.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include - -#include "dumper.h" - -namespace pixel_modem::logging { - -// Modem related Android System Properties - -// Controls triggering `modem_logging_start` and `modem_logging_stop`. -inline constexpr static std::string_view kModemLoggingEnabledProperty = - "vendor.sys.modem.logging.enable"; -// Signals the current modem logging state. This will be set to -// `vendor.sys.modem.logging.enable` when `modem_log_start` or `modem_log_stop` -// terminates. -inline constexpr static std::string_view kModemLoggingStatusProperty = - "vendor.sys.modem.logging.status"; -// Int which specifies how many files to include in the bugreport. -inline constexpr static std::string_view kModemLoggingNumberBugreportProperty = - "persist.vendor.sys.modem.logging.br_num"; -// Signals the current location that is being logged to. This can be used to -// determine the logging type. -inline constexpr static std::string_view kModemLoggingPathProperty = - "vendor.sys.modem.logging.log_path"; - -// Bugreport constants -inline constexpr static int kDefaultBugreportNumberFiles = 100; -inline constexpr static std::string_view kModemAlwaysOnLogDirectory = - "/data/vendor/radio/logs/always-on"; -inline constexpr static std::string_view kModemLogPrefix = "sbuff_"; -inline constexpr static std::string_view kBugreportPackingDirectory = - "/data/vendor/radio/logs/always-on/all_logs"; - -inline constexpr static LogDumpInfo kLogDumpInfo[] = { - {.src_dir = "/data/vendor/radio/extended_logs", - .dest_dir = kBugreportPackingDirectory, - .limit = 20, - .prefix = "extended_log_"}, - {.src_dir = "/data/vendor/radio/sim/", - .dest_dir = kBugreportPackingDirectory, - .limit = 1, - .prefix = "sim_poweron_log_"}, - {.src_dir = "data/vendor/radio/logs/history", - .dest_dir = kBugreportPackingDirectory, - .limit = 2, - .prefix = "Logging"}}; - -constexpr static FileCopyInfo kFileCopyInfo[] = { - {.src_dir = "/mnt/vendor/efs/nv_normal.bin", - .dest_dir = "/data/vendor/radio/logs/always-on/all_logs/nv_normal.bin"}, - {.src_dir = "/mnt/vendor/efs/nv_protected.bin", - .dest_dir = - "/data/vendor/radio/logs/always-on/all_logs/nv_protected.bin"}}; - -} // namespace pixel_modem::logging diff --git a/modem/dump_modemlog/modem_log_dumper.cpp b/modem/dump_modemlog/modem_log_dumper.cpp index b5e7a07..951f89f 100644 --- a/modem/dump_modemlog/modem_log_dumper.cpp +++ b/modem/dump_modemlog/modem_log_dumper.cpp @@ -2,6 +2,7 @@ #include +#include "bugreport_constants.h" #include "dumper.h" #include "modem_log_constants.h" diff --git a/modem/dump_modemlog/modem_log_dumper_test.cpp b/modem/dump_modemlog/modem_log_dumper_test.cpp index d9917e1..81bec8b 100644 --- a/modem/dump_modemlog/modem_log_dumper_test.cpp +++ b/modem/dump_modemlog/modem_log_dumper_test.cpp @@ -2,10 +2,13 @@ #include +#include "android_property_manager.h" +#include "bugreport_constants.h" #include "dumper.h" #include "fake_android_property_manager.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "modem_log_constants.h" namespace pixel_modem::logging { namespace { @@ -22,9 +25,8 @@ inline constexpr static LogDumpInfo kAlwaysOnLogDumpInfo = { void StartModemLogging( FakeAndroidPropertyManager& fake_android_property_manager) { - fake_android_property_manager.SetProperty( - kModemLoggingEnabledProperty.data(), - FakeAndroidPropertyManager::kTruthString.data()); + fake_android_property_manager.SetProperty(kModemLoggingEnabledProperty.data(), + kTruthString.data()); } class MockDumper : public Dumper { diff --git a/modem/modem_log_constants/Android.bp b/modem/modem_log_constants/Android.bp new file mode 100644 index 0000000..f4e3177 --- /dev/null +++ b/modem/modem_log_constants/Android.bp @@ -0,0 +1,9 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_library { + name: "modem_log_constants", + export_include_dirs: [ "include" ], + vendor_available: true, +} diff --git a/modem/modem_log_constants/include/modem_log_constants.h b/modem/modem_log_constants/include/modem_log_constants.h new file mode 100644 index 0000000..133a2a2 --- /dev/null +++ b/modem/modem_log_constants/include/modem_log_constants.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +namespace pixel_modem::logging { + +// Modem related Android System Properties + +// Controls triggering `modem_logging_start` and `modem_logging_stop`. +inline constexpr std::string_view kModemLoggingEnabledProperty = + "vendor.sys.modem.logging.enable"; +// Signals the current modem logging state. This will be set to +// `vendor.sys.modem.logging.enable` when `modem_log_start` or `modem_log_stop` +// terminates. +inline constexpr std::string_view kModemLoggingStatusProperty = + "vendor.sys.modem.logging.status"; +// Int which specifies how many files to include in the bugreport. +inline constexpr std::string_view kModemLoggingNumberBugreportProperty = + "persist.vendor.sys.modem.logging.br_num"; +// Signals the current location that is being logged to. This can be used to +// determine the logging type. +inline constexpr std::string_view kModemLoggingPathProperty = + "vendor.sys.modem.logging.log_path"; + +// Bugreport constants +inline constexpr int kDefaultBugreportNumberFiles = 100; +inline constexpr std::string_view kModemAlwaysOnLogDirectory = + "/data/vendor/radio/logs/always-on"; +inline constexpr std::string_view kModemLogPrefix = "sbuff_"; + +} // namespace pixel_modem::logging From da3ebae5adab2a2b379d60d9d35a7de938eb4976 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Mon, 13 Nov 2023 15:04:32 +0800 Subject: [PATCH 13/35] modem_log_constants: System props for logging Several different services need to be able to set the output directory for copying modem logs, as well as how many files should be copied. Test: N/A just defining constants Bug: 302435001 Change-Id: I3e9f2462a42e3b074810e6fb0a925a8ca026f89d --- modem/modem_log_constants/include/modem_log_constants.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modem/modem_log_constants/include/modem_log_constants.h b/modem/modem_log_constants/include/modem_log_constants.h index 133a2a2..68004cf 100644 --- a/modem/modem_log_constants/include/modem_log_constants.h +++ b/modem/modem_log_constants/include/modem_log_constants.h @@ -21,6 +21,10 @@ inline constexpr std::string_view kModemLoggingNumberBugreportProperty = // determine the logging type. inline constexpr std::string_view kModemLoggingPathProperty = "vendor.sys.modem.logging.log_path"; +inline constexpr std::string_view kModemLoggingLogCountProperty = + "vendor.sys.modem.logging.log_count"; +inline constexpr std::string_view kModemLoggingLogPath = + "vendor.sys.modem.logging.log_path"; // Bugreport constants inline constexpr int kDefaultBugreportNumberFiles = 100; From c7da8aa098f3a1675eba9567b5bf4f57d9a8b720 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Wed, 15 Nov 2023 15:04:21 +0800 Subject: [PATCH 14/35] dump_modemlog: always move modem logs Dynamic log mask events can occur without leaving the logging status property as enabled, which means when dumpstate should always try to stop modem logging so that the new logs can be copied over. Having the copying of logs and stopping of modem logging combined in one command is no longer an ideal design, so b/289435256 was created to find a better solution to this. Test: build, flash, trigger log mask event, check logs in bugreport. Bug: 302435001 Change-Id: I56358d3f08ac1f2a6099ede14c5e17b5ebffabbd --- modem/dump_modemlog/modem_log_dumper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modem/dump_modemlog/modem_log_dumper.cpp b/modem/dump_modemlog/modem_log_dumper.cpp index 951f89f..127478e 100644 --- a/modem/dump_modemlog/modem_log_dumper.cpp +++ b/modem/dump_modemlog/modem_log_dumper.cpp @@ -15,7 +15,11 @@ void ModemLogDumper::DumpModemLogs() { kModemLoggingNumberBugreportProperty.data(), kDefaultBugreportNumberFiles); - if (shouldRestartModemLogging) { + // Should always trigger `stopModemLogging`. This is because currently copying + // modem logs and stopping modem logging are entangled. + // TODO: b/289435256 - Always copy logs and return this to checking if logging + // is actively running. + if (allowedToStopModemLogging()) { // If modem logging is running at time of bugreport, it needs to be stopped // to ensure that the most recent logs are included in the bugreport. If // this command fails, only older log files will be included, as seen in From dff1155fa2dc5716e1984895109fad16c415bea8 Mon Sep 17 00:00:00 2001 From: kierancyphus Date: Fri, 1 Dec 2023 06:33:57 +0000 Subject: [PATCH 15/35] owners: give apps and services team ownership Since we have a lot of code for modem apps and services that is shared across a lot of different devices and will live in gs-common, it would be nice to have ownership of these files so that we can push code without having to involve the gs-common team. Test: N/A Bug: N/A (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3cf675e1f557d5dcc2358457820177a3fa6d7335) Merged-In: I909392864ee9e0aa29f415d13869ba0083449094 Change-Id: I909392864ee9e0aa29f415d13869ba0083449094 --- modem/OWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 modem/OWNERS diff --git a/modem/OWNERS b/modem/OWNERS new file mode 100644 index 0000000..4b70b88 --- /dev/null +++ b/modem/OWNERS @@ -0,0 +1,3 @@ +# Give ownership of code files to Apps and Services team. +# SEPolicy files are intentionally ignored since they should be reviewed by the SEPolicy team. +per-file *.bp,*.cpp,*.h,*.sh=kierancyphus@google.com,everrosales@google.com,nicoleytlee@google.com,alanblc@google.com From b52878371b4d29dbba7b0c19c4d34bf57cbd4f5f Mon Sep 17 00:00:00 2001 From: Ray Hsu Date: Fri, 1 Dec 2023 06:54:56 +0000 Subject: [PATCH 16/35] Add one variable to decide if need TTS voice packs For factory ROM UPH concern, we did not need TTS voice packs. Add one variable to decide if need TTS voice packs and then it could reduce super image size and increase flash station speed. Bug: 314245991 Test: Check super image size and boot to home Change-Id: Id84c3eef5a702317ab7976ded340b5795c0a3700 --- device.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/device.mk b/device.mk index 4787315..45b7da8 100644 --- a/device.mk +++ b/device.mk @@ -14,7 +14,9 @@ # limitations under the License. # +ifeq (,$(filter true, $(PRODUCT_WITHOUT_TTS_VOICE_PACKS))) include device/google/gs-common/tts/voice_packs.mk +endif PRODUCT_SOONG_NAMESPACES += \ device/google/gs-common/powerstats From 1638fa1a3604a1b2dfc7fa6d857fd74b462efe15 Mon Sep 17 00:00:00 2001 From: Sebastian Pickl Date: Fri, 1 Dec 2023 11:30:35 +0000 Subject: [PATCH 17/35] Revert "gs-common: move sepolicy related to bootctrl hal aidl to..." Revert submission 25477883-gs-common_bootctrl-aidl Reason for revert: breaking builds b/314240126 Bug: 314240126 Reverted changes: /q/submissionid:25477883-gs-common_bootctrl-aidl Change-Id: I091dda3aa16bbc381b49674a642b2bfa93dfdfa8 --- bootctrl/bootctrl_aidl.mk | 2 -- bootctrl/sepolicy/aidl/device.te | 5 ----- bootctrl/sepolicy/aidl/file.te | 2 -- bootctrl/sepolicy/aidl/file_contexts | 1 - bootctrl/sepolicy/aidl/hal_bootctl_default.te | 8 -------- 5 files changed, 18 deletions(-) delete mode 100644 bootctrl/sepolicy/aidl/device.te delete mode 100644 bootctrl/sepolicy/aidl/file.te delete mode 100644 bootctrl/sepolicy/aidl/file_contexts delete mode 100644 bootctrl/sepolicy/aidl/hal_bootctl_default.te diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk index 6133c0e..5ec9445 100644 --- a/bootctrl/bootctrl_aidl.mk +++ b/bootctrl/bootctrl_aidl.mk @@ -1,5 +1,3 @@ PRODUCT_PACKAGES += \ android.hardware.boot-service.default-pixel \ android.hardware.boot-service.default_recovery-pixel - -BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/bootctrl/sepolicy/aidl diff --git a/bootctrl/sepolicy/aidl/device.te b/bootctrl/sepolicy/aidl/device.te deleted file mode 100644 index 4fd0240..0000000 --- a/bootctrl/sepolicy/aidl/device.te +++ /dev/null @@ -1,5 +0,0 @@ -# devinfo block device -type devinfo_block_device, dev_type; - -# OTA -type sda_block_device, dev_type; diff --git a/bootctrl/sepolicy/aidl/file.te b/bootctrl/sepolicy/aidl/file.te deleted file mode 100644 index 5357fa9..0000000 --- a/bootctrl/sepolicy/aidl/file.te +++ /dev/null @@ -1,2 +0,0 @@ -# sysfs -type sysfs_ota, sysfs_type, fs_type; diff --git a/bootctrl/sepolicy/aidl/file_contexts b/bootctrl/sepolicy/aidl/file_contexts deleted file mode 100644 index 339896f..0000000 --- a/bootctrl/sepolicy/aidl/file_contexts +++ /dev/null @@ -1 +0,0 @@ -/vendor/bin/hw/android\.hardware\.boot-service\.default-pixel u:object_r:hal_bootctl_default_exec:s0 diff --git a/bootctrl/sepolicy/aidl/hal_bootctl_default.te b/bootctrl/sepolicy/aidl/hal_bootctl_default.te deleted file mode 100644 index 2ffeb27..0000000 --- a/bootctrl/sepolicy/aidl/hal_bootctl_default.te +++ /dev/null @@ -1,8 +0,0 @@ -allow hal_bootctl_default devinfo_block_device:blk_file rw_file_perms; -allow hal_bootctl_default sda_block_device:blk_file rw_file_perms; -allow hal_bootctl_default sysfs_ota:file rw_file_perms; -allow hal_bootctl_default tee_device:chr_file rw_file_perms; - -recovery_only(` - allow hal_bootctl_default rootfs:dir r_dir_perms; -') From b88437ab276ac2ea6e7e2c7034fcfae222c23128 Mon Sep 17 00:00:00 2001 From: Sebastian Pickl Date: Fri, 1 Dec 2023 11:30:35 +0000 Subject: [PATCH 18/35] Revert "gs-common: create bootctrl_aidl.mk and include related m..." Revert submission 25477883-gs-common_bootctrl-aidl Reason for revert: breaking builds b/314240126 Bug: 314240126 Reverted changes: /q/submissionid:25477883-gs-common_bootctrl-aidl Change-Id: I98a529afec0ba2eb01f1628215e36769dc5c2cf9 --- bootctrl/bootctrl_aidl.mk | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 bootctrl/bootctrl_aidl.mk diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk deleted file mode 100644 index 5ec9445..0000000 --- a/bootctrl/bootctrl_aidl.mk +++ /dev/null @@ -1,3 +0,0 @@ -PRODUCT_PACKAGES += \ - android.hardware.boot-service.default-pixel \ - android.hardware.boot-service.default_recovery-pixel From 60a8e27b76c25d278c08248196d726c5b76ce193 Mon Sep 17 00:00:00 2001 From: Sebastian Pickl Date: Fri, 1 Dec 2023 11:30:35 +0000 Subject: [PATCH 19/35] Revert "gs-common: move bootctrl hal aidl implementation to gs-c..." Revert submission 25477883-gs-common_bootctrl-aidl Reason for revert: breaking builds b/314240126 Bug: 314240126 Reverted changes: /q/submissionid:25477883-gs-common_bootctrl-aidl Change-Id: Id9d272e7f9832a5b27b2c02d50665ee1b26ae9f8 --- bootctrl/aidl/Android.bp | 65 --- bootctrl/aidl/BootControl.cpp | 538 ------------------ bootctrl/aidl/BootControl.h | 61 -- bootctrl/aidl/DevInfo.h | 53 -- bootctrl/aidl/GptUtils.cpp | 185 ------ bootctrl/aidl/GptUtils.h | 71 --- ...oid.hardware.boot-service.default-pixel.rc | 5 - ...are.boot-service.default_recovery-pixel.rc | 7 - ...re.boot-service.default_recovery-pixel.xml | 6 - bootctrl/aidl/service.cpp | 44 -- 10 files changed, 1035 deletions(-) delete mode 100644 bootctrl/aidl/Android.bp delete mode 100644 bootctrl/aidl/BootControl.cpp delete mode 100644 bootctrl/aidl/BootControl.h delete mode 100644 bootctrl/aidl/DevInfo.h delete mode 100644 bootctrl/aidl/GptUtils.cpp delete mode 100644 bootctrl/aidl/GptUtils.h delete mode 100644 bootctrl/aidl/android.hardware.boot-service.default-pixel.rc delete mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc delete mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml delete mode 100644 bootctrl/aidl/service.cpp diff --git a/bootctrl/aidl/Android.bp b/bootctrl/aidl/Android.bp deleted file mode 100644 index 9e47cca..0000000 --- a/bootctrl/aidl/Android.bp +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (C) 2023 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "//device/google/gs-common:device_google_gs-common_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: [ - "//device/google/gs-common:device_google_gs-common_license", - ], -} - -cc_defaults { - name: "android.hardware.boot-service_common-pixel", - relative_install_path: "hw", - defaults: ["libboot_control_defaults"], - shared_libs: [ - "libbase", - "libbinder_ndk", - "libcutils", - "libz", - "libtrusty", - "android.hardware.boot@1.1", - "android.hardware.boot-V1-ndk", - ], - static_libs: [ - "libboot_control", - "libbootloader_message_vendor", - ], - srcs: [ - "BootControl.cpp", - "GptUtils.cpp", - "service.cpp" - ], -} - -cc_binary { - name: "android.hardware.boot-service.default-pixel", - defaults: ["android.hardware.boot-service_common-pixel"], - init_rc: ["android.hardware.boot-service.default-pixel.rc"], - vendor: true, -} - -cc_binary { - name: "android.hardware.boot-service.default_recovery-pixel", - defaults: ["android.hardware.boot-service_common-pixel"], - vintf_fragments: ["android.hardware.boot-service.default_recovery-pixel.xml"], - init_rc: ["android.hardware.boot-service.default_recovery-pixel.rc"], - recovery: true, -} diff --git a/bootctrl/aidl/BootControl.cpp b/bootctrl/aidl/BootControl.cpp deleted file mode 100644 index 941b0d2..0000000 --- a/bootctrl/aidl/BootControl.cpp +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (C) 2023 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 "bootcontrolhal" - -#include "BootControl.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "DevInfo.h" -#include "GptUtils.h" - -using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus; -using ndk::ScopedAStatus; - -using android::bootable::GetMiscVirtualAbMergeStatus; -using android::bootable::InitMiscVirtualAbMessageIfNeeded; -using android::bootable::SetMiscVirtualAbMergeStatus; - -namespace aidl::android::hardware::boot { - -namespace { - -// clang-format off - -#define BOOT_A_PATH "/dev/block/by-name/boot_a" -#define BOOT_B_PATH "/dev/block/by-name/boot_b" -#define DEVINFO_PATH "/dev/block/by-name/devinfo" - -// slot flags -#define AB_ATTR_PRIORITY_SHIFT 52 -#define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) -#define AB_ATTR_ACTIVE_SHIFT 54 -#define AB_ATTR_ACTIVE (1UL << AB_ATTR_ACTIVE_SHIFT) -#define AB_ATTR_RETRY_COUNT_SHIFT (55) -#define AB_ATTR_RETRY_COUNT_MASK (7UL << AB_ATTR_RETRY_COUNT_SHIFT) -#define AB_ATTR_SUCCESSFUL (1UL << 58) -#define AB_ATTR_UNBOOTABLE (1UL << 59) - -#define AB_ATTR_MAX_PRIORITY 3UL -#define AB_ATTR_MAX_RETRY_COUNT 3UL - -// clang-format on - -static std::string getDevPath(int32_t in_slot) { - char real_path[PATH_MAX]; - - const char *path = in_slot == 0 ? BOOT_A_PATH : BOOT_B_PATH; - - int ret = readlink(path, real_path, sizeof real_path); - if (ret < 0) { - ALOGE("readlink failed for boot device %s\n", strerror(errno)); - return std::string(); - } - - std::string dp(real_path); - // extract /dev/sda.. part - return dp.substr(0, sizeof "/dev/block/sdX" - 1); -} - -static bool isSlotFlagSet(int32_t in_slot, uint64_t flag) { - std::string dev_path = getDevPath(in_slot); - if (dev_path.empty()) { - ALOGI("Could not get device path for slot %d\n", in_slot); - return false; - } - - GptUtils gpt(dev_path); - if (gpt.Load()) { - ALOGI("failed to load gpt data\n"); - return false; - } - - gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); - if (e == nullptr) { - ALOGI("failed to get gpt entry\n"); - return false; - } - - return !!(e->attr & flag); -} - -static bool setSlotFlag(int32_t in_slot, uint64_t flag) { - std::string dev_path = getDevPath(in_slot); - if (dev_path.empty()) { - ALOGI("Could not get device path for slot %d\n", in_slot); - return false; - } - - GptUtils gpt(dev_path); - if (gpt.Load()) { - ALOGI("failed to load gpt data\n"); - return false; - } - - gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); - if (e == nullptr) { - ALOGI("failed to get gpt entry\n"); - return false; - } - - e->attr |= flag; - gpt.Sync(); - - return true; -} - -static bool is_devinfo_valid; -static bool is_devinfo_initialized; -static std::mutex devinfo_lock; -static devinfo_t devinfo; - -static bool isDevInfoValid() { - const std::lock_guard lock(devinfo_lock); - - if (is_devinfo_initialized) { - return is_devinfo_valid; - } - - is_devinfo_initialized = true; - - ::android::base::unique_fd fd(open(DEVINFO_PATH, O_RDONLY)); - ::android::base::ReadFully(fd, &devinfo, sizeof devinfo); - - if (devinfo.magic != DEVINFO_MAGIC) { - return is_devinfo_valid; - } - - uint32_t version = ((uint32_t)devinfo.ver_major << 16) | devinfo.ver_minor; - // only version 3.3+ supports A/B data - if (version >= 0x0003'0003) { - is_devinfo_valid = true; - } - - return is_devinfo_valid; -} - -static bool DevInfoSync() { - if (!isDevInfoValid()) { - return false; - } - - ::android::base::unique_fd fd(open(DEVINFO_PATH, O_WRONLY | O_DSYNC)); - return ::android::base::WriteFully(fd, &devinfo, sizeof devinfo); -} - -static void DevInfoInitSlot(devinfo_ab_slot_data_t &slot_data) { - slot_data.retry_count = AB_ATTR_MAX_RETRY_COUNT; - slot_data.unbootable = 0; - slot_data.successful = 0; - slot_data.active = 1; - slot_data.fastboot_ok = 0; -} - -static int blow_otp_AR(bool secure) { - static const char *dev_name = "/dev/trusty-ipc-dev0"; - static const char *otp_name = "com.android.trusty.otp_manager.tidl"; - int fd = 1, ret = 0; - uint32_t cmd = secure? OTP_CMD_write_antirbk_secure_ap : OTP_CMD_write_antirbk_non_secure_ap; - fd = tipc_connect(dev_name, otp_name); - if (fd < 0) { - ALOGI("Failed to connect to OTP_MGR ns TA - is it missing?\n"); - ret = -1; - return ret; - } - - struct otp_mgr_req_base req = { - .command = cmd, - .resp_payload_size = 0, - }; - struct iovec iov[] = { - { - .iov_base = &req, - .iov_len = sizeof(req), - }, - }; - - size_t rc = tipc_send(fd, iov, 1, NULL, 0); - if (rc != sizeof(req)) { - ALOGI("Send fail! %zx\n", rc); - return rc; - } - - struct otp_mgr_rsp_base resp; - rc = read(fd, &resp, sizeof(resp)); - if (rc < 0) { - ALOGI("Read fail! %zx\n", rc); - return rc; - } - - if (rc < sizeof(resp)) { - ALOGI("Not enough data! %zx\n", rc); - return -EIO; - } - - if (resp.command != (cmd | OTP_RESP_BIT)) { - ALOGI("Wrong command! %x\n", resp.command); - return -EINVAL; - } - - if (resp.result != 0) { - fprintf(stderr, "AR writing error! %x\n", resp.result); - return -EINVAL; - } - - tipc_close(fd); - return 0; -} - -static bool blowAR() { - int ret = blow_otp_AR(true); - if (ret) { - ALOGI("Blow secure anti-rollback OTP failed"); - return false; - } - - ret = blow_otp_AR(false); - if (ret) { - ALOGI("Blow non-secure anti-rollback OTP failed"); - return false; - } - - return true; -} - -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; - } -} - -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; - } -} - -} // namespace - -BootControl::BootControl() { - CHECK(InitMiscVirtualAbMessageIfNeeded()); -} - -ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) { - int32_t slots = 0; - getNumberSlots(&slots); - if (slots == 0) { - *_aidl_return = 0; - return ScopedAStatus::ok(); - } - - if (isDevInfoValid()) { - *_aidl_return = devinfo.ab_data.slots[1].active ? 1 : 0; - return ScopedAStatus::ok(); - } - *_aidl_return = isSlotFlagSet(1, AB_ATTR_ACTIVE) ? 1 : 0; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) { - char suffix[PROPERTY_VALUE_MAX]; - property_get("ro.boot.slot_suffix", suffix, "_a"); - *_aidl_return = std::string(suffix) == "_b" ? 1 : 0; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) { - int32_t slots = 0; - - if (access(BOOT_A_PATH, F_OK) == 0) - slots++; - - if (access(BOOT_B_PATH, F_OK) == 0) - slots++; - - *_aidl_return = slots; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) { - HIDLMergeStatus status; - int32_t current_slot = 0; - getCurrentSlot(¤t_slot); - if (!GetMiscVirtualAbMergeStatus(current_slot, &status)) { - *_aidl_return = MergeStatus::UNKNOWN; - return ScopedAStatus::ok(); - } - *_aidl_return = ToAIDLMergeStatus(status); - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) { - *_aidl_return = in_slot == 0 ? "_a" : in_slot == 1 ? "_b" : ""; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) { - int32_t slots = 0; - getNumberSlots(&slots); - if (slots == 0) { - *_aidl_return = false; - return ScopedAStatus::ok(); - } - if (in_slot >= slots) - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); - - bool unbootable; - if (isDevInfoValid()) { - auto &slot_data = devinfo.ab_data.slots[in_slot]; - unbootable = !!slot_data.unbootable; - } else { - unbootable = isSlotFlagSet(in_slot, AB_ATTR_UNBOOTABLE); - } - - *_aidl_return = unbootable ? false: true; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) { - int32_t slots = 0; - getNumberSlots(&slots); - if (slots == 0) { - // just return true so that we don't we another call trying to mark it as successful - // when there is no slots - *_aidl_return = true; - return ScopedAStatus::ok(); - } - if (in_slot >= slots) - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); - - bool successful; - if (isDevInfoValid()) { - auto &slot_data = devinfo.ab_data.slots[in_slot]; - successful = !!slot_data.successful; - } else { - successful = isSlotFlagSet(in_slot, AB_ATTR_SUCCESSFUL); - } - - *_aidl_return = successful ? true : false; - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::markBootSuccessful() { - int32_t slots = 0; - getNumberSlots(&slots); - if (slots == 0) { - // no slots, just return true otherwise Android keeps trying - return ScopedAStatus::ok(); - } - - bool ret; - int32_t current_slot = 0; - getCurrentSlot(¤t_slot); - if (isDevInfoValid()) { - auto const slot = current_slot; - devinfo.ab_data.slots[slot].successful = 1; - ret = DevInfoSync(); - } else { - ret = setSlotFlag(current_slot, AB_ATTR_SUCCESSFUL); - } - - if (!ret) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, - "Failed to set successful flag"); - } - - if (!blowAR()) { - ALOGE("Failed to blow anti-rollback counter"); - // Ignore the error, since ABL will re-trigger it on reboot - } - - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) { - if (in_slot >= 2) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); - } - - if (isDevInfoValid()) { - auto &active_slot_data = devinfo.ab_data.slots[in_slot]; - auto &inactive_slot_data = devinfo.ab_data.slots[!in_slot]; - - inactive_slot_data.active = 0; - DevInfoInitSlot(active_slot_data); - - if (!DevInfoSync()) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "Could not update DevInfo data"); - } - } else { - std::string dev_path = getDevPath(in_slot); - if (dev_path.empty()) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "Could not get device path for slot"); - } - - GptUtils gpt(dev_path); - if (gpt.Load()) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, - "failed to load gpt data"); - } - - gpt_entry *active_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_a" : "boot_b"); - gpt_entry *inactive_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_b" : "boot_a"); - if (active_entry == nullptr || inactive_entry == nullptr) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "failed to get entries for boot partitions"); - } - - ALOGV("slot active attributes %lx\n", active_entry->attr); - ALOGV("slot inactive attributes %lx\n", inactive_entry->attr); - - // update attributes for active and inactive - inactive_entry->attr &= ~AB_ATTR_ACTIVE; - active_entry->attr = AB_ATTR_ACTIVE | (AB_ATTR_MAX_PRIORITY << AB_ATTR_PRIORITY_SHIFT) | - (AB_ATTR_MAX_RETRY_COUNT << AB_ATTR_RETRY_COUNT_SHIFT); - } - - char boot_dev[PROPERTY_VALUE_MAX]; - property_get("ro.boot.bootdevice", boot_dev, ""); - if (boot_dev[0] == '\0') { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "invalid ro.boot.bootdevice prop"); - } - - std::string boot_lun_path = - std::string("/sys/devices/platform/") + boot_dev + "/pixel/boot_lun_enabled"; - int fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); - if (fd < 0) { - // Try old path for kernels < 5.4 - // TODO: remove once kernel 4.19 support is deprecated - std::string boot_lun_path = - std::string("/sys/devices/platform/") + boot_dev + "/attributes/boot_lun_enabled"; - fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); - if (fd < 0) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "failed to open ufs attr boot_lun_enabled"); - } - } - - // - // bBootLunEn - // 0x1 => Boot LU A = enabled, Boot LU B = disable - // 0x2 => Boot LU A = disable, Boot LU B = enabled - // - int ret = ::android::base::WriteStringToFd(in_slot == 0 ? "1" : "2", fd); - close(fd); - if (ret < 0) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "faied to write boot_lun_enabled attribute"); - } - - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) { - if (in_slot >= 2) - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); - - if (isDevInfoValid()) { - auto &slot_data = devinfo.ab_data.slots[in_slot]; - slot_data.unbootable = 1; - if (!DevInfoSync()) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "Could not update DevInfo data"); - } - } else { - std::string dev_path = getDevPath(in_slot); - if (dev_path.empty()) { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "Could not get device path for slot"); - } - - GptUtils gpt(dev_path); - gpt.Load(); - - gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); - e->attr |= AB_ATTR_UNBOOTABLE; - - gpt.Sync(); - } - - return ScopedAStatus::ok(); -} - -ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) { - int32_t current_slot = 0; - getCurrentSlot(¤t_slot); - if (!SetMiscVirtualAbMergeStatus(current_slot, ToHIDLMergeStatus(in_status))) - return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, - "Operation failed"); - return ScopedAStatus::ok(); -} - -} // namespace aidl::android::hardware::boot diff --git a/bootctrl/aidl/BootControl.h b/bootctrl/aidl/BootControl.h deleted file mode 100644 index a54f66d..0000000 --- a/bootctrl/aidl/BootControl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2023 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 - -namespace aidl::android::hardware::boot { - -class BootControl final : public BnBootControl { - public: - BootControl(); - ::ndk::ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override; - ::ndk::ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override; - ::ndk::ScopedAStatus getNumberSlots(int32_t* _aidl_return) override; - ::ndk::ScopedAStatus getSnapshotMergeStatus( - ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override; - ::ndk::ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override; - ::ndk::ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override; - ::ndk::ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override; - ::ndk::ScopedAStatus markBootSuccessful() override; - ::ndk::ScopedAStatus setActiveBootSlot(int32_t in_slot) override; - ::ndk::ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override; - ::ndk::ScopedAStatus setSnapshotMergeStatus( - ::aidl::android::hardware::boot::MergeStatus in_status) override; -}; - -enum otpmgr_command : uint32_t { - OTP_REQ_SHIFT = 1, - OTP_RESP_BIT = 1, - OTP_CMD_write_antirbk_non_secure_ap = (7 << OTP_REQ_SHIFT), - OTP_CMD_write_antirbk_secure_ap = (8 << OTP_REQ_SHIFT), -}; - -struct otp_mgr_req_base { - uint32_t command; - uint32_t resp_payload_size; - uint8_t handle; -}__packed; - -struct otp_mgr_rsp_base { - uint32_t command; - uint32_t resp_payload_size; - int result; -}__packed; - -} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/DevInfo.h b/bootctrl/aidl/DevInfo.h deleted file mode 100644 index aa5f5d3..0000000 --- a/bootctrl/aidl/DevInfo.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2021 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 - -namespace aidl::android::hardware::boot { - -// -// definitions taken from ABL code -// - -constexpr uint32_t DEVINFO_MAGIC = 0x49564544; -constexpr size_t DEVINFO_AB_SLOT_COUNT = 2; - -struct devinfo_ab_slot_data_t { - uint8_t retry_count; - uint8_t unbootable : 1; - uint8_t successful : 1; - uint8_t active : 1; - uint8_t fastboot_ok : 1; - uint8_t : 4; - uint8_t unused[2]; -} __attribute__((packed)); - -typedef struct { - devinfo_ab_slot_data_t slots[DEVINFO_AB_SLOT_COUNT]; -} __attribute__((packed)) devinfo_ab_data_t; - -struct devinfo_t { - uint32_t magic; - uint16_t ver_major; - uint16_t ver_minor; - uint8_t unused[40]; - devinfo_ab_data_t ab_data; - uint8_t unused1[72]; // use remaining up to complete 128 bytes -} __attribute__((packed)); - -static_assert(sizeof(devinfo_t) == 128, "invalid devinfo struct size"); - -} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.cpp b/bootctrl/aidl/GptUtils.cpp deleted file mode 100644 index 34dec11..0000000 --- a/bootctrl/aidl/GptUtils.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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 "bootcontrolhal" - -#include "GptUtils.h" - -#include -#include -#include -#include -#include - -namespace aidl::android::hardware::boot { - -namespace { - -static int ValidateGptHeader(gpt_header *gpt) { - if (gpt->signature != GPT_SIGNATURE) { - ALOGE("invalid gpt signature 0x%lx\n", gpt->signature); - return -1; - } - - if (gpt->header_size != sizeof(gpt_header)) { - ALOGE("invalid gpt header size %u\n", gpt->header_size); - return -1; - } - - if (gpt->entry_size != sizeof(gpt_entry)) { - ALOGE("invalid gpt entry size %u\n", gpt->entry_size); - return -1; - } - - return 0; -} - -} // namespace - -GptUtils::GptUtils(const std::string dev_path) : dev_path(dev_path), fd(0) {} - -int GptUtils::Load(void) { - fd = open(dev_path.c_str(), O_RDWR); - if (fd < 0) { - ALOGE("failed to open block dev %s, %d\n", dev_path.c_str(), errno); - return -1; - } - - int ret = ioctl(fd, BLKSSZGET, &block_size); - if (ret < 0) { - ALOGE("failed to get block size %d\n", errno); - return -1; - } - - // read primary header - lseek64(fd, block_size, SEEK_SET); - ret = read(fd, &gpt_primary, sizeof gpt_primary); - if (ret < 0) { - ALOGE("failed to read gpt primary header %d\n", errno); - return -1; - } - - if (ValidateGptHeader(&gpt_primary)) { - ALOGE("error validating gpt header\n"); - return -1; - } - - // read partition entries - entry_array.resize(gpt_primary.entry_count); - uint32_t entries_size = gpt_primary.entry_size * gpt_primary.entry_count; - lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); - ret = read(fd, entry_array.data(), entries_size); - if (ret < 0) { - ALOGE("failed to read gpt partition entries %d\n", errno); - return -1; - } - - // read gpt back header - lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); - ret = read(fd, &gpt_backup, sizeof gpt_backup); - if (ret < 0) { - ALOGE("failed to read gpt backup header %d\n", errno); - return -1; - } - - if (ValidateGptHeader(&gpt_backup)) { - ALOGW("error validating gpt backup\n"); // just warn about it, not fail - } - - // Create map - auto get_name = [](const uint16_t *efi_name) { - char name[37] = {}; - for (size_t i = 0; efi_name[i] && i < sizeof name - 1; ++i) name[i] = efi_name[i]; - return std::string(name); - }; - - for (auto const &e : entry_array) { - if (e.name[0] == 0) - break; // stop at the first partition with no name - std::string s = get_name(e.name); - entries[s] = const_cast(&e); - } - - return 0; -} - -gpt_entry *GptUtils::GetPartitionEntry(std::string name) { - return entries.find(name) != entries.end() ? entries[name] : nullptr; -} - -int GptUtils::Sync(void) { - if (!fd) - return -1; - - // calculate crc and check if we need to update gpt - gpt_primary.entries_crc32 = crc32(0, reinterpret_cast(entry_array.data()), - entry_array.size() * sizeof(gpt_entry)); - - // save old crc - uint32_t crc = gpt_primary.crc32; - gpt_primary.crc32 = 0; - - gpt_primary.crc32 = crc32(0, reinterpret_cast(&gpt_primary), sizeof gpt_primary); - if (crc == gpt_primary.crc32) - return 0; // nothing to do (no changes) - - ALOGI("updating GPT\n"); - - lseek64(fd, block_size * gpt_primary.current_lba, SEEK_SET); - int ret = write(fd, &gpt_primary, sizeof gpt_primary); - if (ret < 0) { - ALOGE("failed to write gpt primary header %d\n", errno); - return -1; - } - - lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); - ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); - if (ret < 0) { - ALOGE("failed to write gpt partition entries %d\n", errno); - return -1; - } - - // update GPT backup entries and backup - lseek64(fd, block_size * gpt_backup.start_lba, SEEK_SET); - ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); - if (ret < 0) { - ALOGE("failed to write gpt backup partition entries %d\n", errno); - return -1; - } - - gpt_backup.entries_crc32 = gpt_primary.entries_crc32; - gpt_backup.crc32 = 0; - gpt_backup.crc32 = crc32(0, reinterpret_cast(&gpt_backup), sizeof gpt_backup); - lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); - ret = write(fd, &gpt_backup, sizeof gpt_backup); - if (ret < 0) { - ALOGE("failed to write gpt backup header %d\n", errno); - return -1; - } - - fsync(fd); - - return 0; -} - -GptUtils::~GptUtils() { - if (fd) { - Sync(); - close(fd); - } -} - -} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.h b/bootctrl/aidl/GptUtils.h deleted file mode 100644 index ec68cf6..0000000 --- a/bootctrl/aidl/GptUtils.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 - -namespace aidl::android::hardware::boot { - -#define GPT_SIGNATURE 0x5452415020494645UL - -typedef struct { - uint8_t type_guid[16]; - uint8_t guid[16]; - uint64_t first_lba; - uint64_t last_lba; - uint64_t attr; - uint16_t name[36]; -} __attribute__((packed)) gpt_entry; - -typedef struct { - uint64_t signature; - uint32_t revision; - uint32_t header_size; - uint32_t crc32; - uint32_t reserved; - uint64_t current_lba; - uint64_t backup_lba; - uint64_t first_usable_lba; - uint64_t last_usable_lba; - uint8_t disk_guid[16]; - uint64_t start_lba; - uint32_t entry_count; - uint32_t entry_size; - uint32_t entries_crc32; -} __attribute__((packed)) gpt_header; - -class GptUtils { - public: - GptUtils(const std::string dev_path); - int Load(void); - gpt_entry *GetPartitionEntry(std::string name); - int Sync(void); - ~GptUtils(); - - private: - std::string dev_path; - int fd; - uint32_t block_size; - gpt_header gpt_primary; - gpt_header gpt_backup; - std::vector entry_array; - std::map entries; -}; - -} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc deleted file mode 100644 index a9887b9..0000000 --- a/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc +++ /dev/null @@ -1,5 +0,0 @@ -service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.default-pixel - class early_hal - user root - group root drmrpc - diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc deleted file mode 100644 index e58617e..0000000 --- a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc +++ /dev/null @@ -1,7 +0,0 @@ -service vendor.boot-default /system/bin/hw/android.hardware.boot-service.default_recovery-pixel - class early_hal - user root - group root - seclabel u:r:hal_bootctl_default:s0 - interface aidl android.hardware.boot.IBootControl/default - diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml deleted file mode 100644 index 23ccc4e..0000000 --- a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - android.hardware.boot - IBootControl/default - - diff --git a/bootctrl/aidl/service.cpp b/bootctrl/aidl/service.cpp deleted file mode 100644 index 41b6c25..0000000 --- a/bootctrl/aidl/service.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 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 "aidl.android.hardware.boot-service.default" - -#include -#include -#include -#include -#include - -#include "BootControl.h" - -using aidl::android::hardware::boot::BootControl; -using aidl::android::hardware::boot::IBootControl; -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; - -int main(int, char* argv[]) { - android::base::InitLogging(argv, android::base::KernelLogger); - ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr service = ndk::SharedRefBase::make(); - - const std::string instance = std::string(BootControl::descriptor) + "/default"; - auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str()); - CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status; - LOG(INFO) << "IBootControl AIDL service running..."; - - ABinderProcess_joinThreadPool(); - return EXIT_FAILURE; // should not reach -} From 7eaf22a3ce6c3c49f844de0b35784c4a123414f3 Mon Sep 17 00:00:00 2001 From: Sebastian Pickl Date: Fri, 1 Dec 2023 11:30:35 +0000 Subject: [PATCH 20/35] Revert "gs-common: add device_google_gs-common_license" Revert submission 25477883-gs-common_bootctrl-aidl Reason for revert: breaking builds b/314240126 Bug: 314240126 Reverted changes: /q/submissionid:25477883-gs-common_bootctrl-aidl Change-Id: Id75467f48ab79b414a27026386255d9aa9a7e50b --- Android.bp | 45 ------------- NOTICE | 190 ----------------------------------------------------- 2 files changed, 235 deletions(-) delete mode 100644 Android.bp delete mode 100644 NOTICE diff --git a/Android.bp b/Android.bp deleted file mode 100644 index 52a1055..0000000 --- a/Android.bp +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright (C) 2023 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 { - default_applicable_licenses: ["device_google_gs-common_license"], -} - -// Added automatically by a large-scale-change that took the approach of -// 'apply every license found to every target'. While this makes sure we respect -// every license restriction, it may not be entirely correct. -// -// e.g. GPL in an MIT project might only apply to the contrib/ directory. -// -// Please consider splitting the single license below into multiple licenses, -// taking care not to lose any license_kind information, and overriding the -// default license using the 'licenses: [...]' property on targets as needed. -// -// For unused files, consider creating a 'fileGroup' with "//visibility:private" -// to attach the license to, and including a comment whether the files may be -// used in the current project. -// See: http://go/android-license-faq -license { - name: "device_google_gs-common_license", - visibility: [":__subpackages__"], - license_kinds: [ - "SPDX-license-identifier-Apache-2.0", - "SPDX-license-identifier-BSD", - ], - license_text: [ - "NOTICE", - ], -} diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 316b4eb..0000000 --- a/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2014, 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. - - 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. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - From b4de8aabdadc8f968bb9927ba6bb840a460ad9d2 Mon Sep 17 00:00:00 2001 From: samou Date: Sat, 2 Dec 2023 06:10:26 +0000 Subject: [PATCH 21/35] bm: Avoid to use CDT number Bug: 313692190 Test: Confirm battery_mitigation does not repeatedly restart Change-Id: I7edaad073b509f163283d4611d987e8982934253 Signed-off-by: samou --- battery_mitigation/battery_mitigation.cpp | 60 +++++++---------------- 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/battery_mitigation/battery_mitigation.cpp b/battery_mitigation/battery_mitigation.cpp index 18bb63d..fb81b20 100644 --- a/battery_mitigation/battery_mitigation.cpp +++ b/battery_mitigation/battery_mitigation.cpp @@ -77,7 +77,6 @@ const struct MitigationConfig::EventThreadConfig eventThreadCfg = { {"cpu0_freq", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"}, {"cpu1_freq", "/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq"}, {"cpu2_freq", "/sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq"}, - {"gpu_freq", "/sys/devices/platform/1f000000.mali/cur_freq"}, {"battery_temp", "/dev/thermal/tz-by-name/battery/temp"}, {"battery_cycle", "/dev/thermal/tz-by-name/battery_cycle/temp"}, {"voltage_now", "/sys/class/power_supply/battery/voltage_now"}, @@ -115,37 +114,24 @@ const struct MitigationConfig::EventThreadConfig eventThreadCfg = { }, }, .PlatformSpecific = { - /* MIN_SUPPORTED_PLATFORM */ - { - .MainPmicName = "s2mpg10-odpm\n", - .SubPmicName = "s2mpg11-odpm\n", - .NumericSysfsStatPaths = { - {"battery_soc", "/sys/class/power_supply/max77759fg/capacity"}, + .NumericSysfsStatPaths = { + { + .name = "battery_soc", + .paths = { + "/sys/class/power_supply/max77759fg/capacity", + "/sys/class/power_supply/max77779fg/capacity", + }, }, - }, - { - .MainPmicName = "s2mpg12-odpm\n", - .SubPmicName = "s2mpg13-odpm\n", - .NumericSysfsStatPaths = { - {"battery_soc", "/sys/class/power_supply/max77759fg/capacity"}, + { + .name = "gpu_freq", + .paths = { + "/sys/devices/platform/1c500000.mali/cur_freq", + "/sys/devices/platform/28000000.mali/cur_freq", + "/sys/devices/platform/1f000000.mali/cur_freq", + }, }, - }, - { - .MainPmicName = "s2mpg14-odpm\n", - .SubPmicName = "s2mpg15-odpm\n", - .NumericSysfsStatPaths = { - {"battery_soc", "/sys/class/power_supply/max77779fg/capacity"}, - }, - }, - /* MAX_SUPPORTED_PLATFORM */ - { - .MainPmicName = "s2mpg14-odpm\n", - .SubPmicName = "s2mpg15-odpm\n", - .NumericSysfsStatPaths = { - {"battery_soc", "/sys/class/power_supply/max77779fg/capacity"}, - }, - }, + }, }, }; @@ -154,29 +140,17 @@ const char kReadyProperty[] = "vendor.brownout.mitigation.ready"; const char kLastMealPath[] = "/data/vendor/mitigation/lastmeal.txt"; const char kBRRequestedProperty[] = "vendor.brownout_reason"; const char kLastMealProperty[] = "vendor.brownout.br.feasible"; -const char kCDTProperty[] = "ro.boot.cdt_hwid"; const std::regex kTimestampRegex("^\\S+\\s[0-9]+:[0-9]+:[0-9]+\\S+$"); -std::string GetSystemProperty(std::string property) { - char value[PROP_VALUE_MAX]; - __system_property_get(property.c_str(), value); - return std::string(value); -} - int main(int argc, char **argv) { - std::string cdt = GetSystemProperty(kCDTProperty); - int platformNum = atoi(cdt.substr(5, 1).c_str()); - batteryMitigationService = new BatteryMitigationService(eventThreadCfg, - platformNum); + batteryMitigationService = new BatteryMitigationService(eventThreadCfg); if (!batteryMitigationService) { return 0; } - bool platformSupported = batteryMitigationService->isPlatformSupported(); bool brownoutStatsBinarySupported = batteryMitigationService->isBrownoutStatsBinarySupported(); if (argc == 2) { if(strcmp(argv[1], "-d") == 0 && - brownoutStatsBinarySupported && - platformSupported) { + brownoutStatsBinarySupported) { /* Create thismeal.txt from thismeal.bin */ batteryMitigationService->genParsedMeal(eventThreadCfg.ParsedThismealPath); } From cfd5dd5de30193df2acf04f8349fea6e2d03835f Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 9 Nov 2023 20:50:57 +0800 Subject: [PATCH 22/35] gs-common: add device_google_gs-common_license reference device/google/zuma Bug: 265063384 Change-Id: I048682438ab98fea16ecbd1e4ebff65bfb7a155c Signed-off-by: Jason Chiu --- Android.bp | 45 +++++++++++++ NOTICE | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 Android.bp create mode 100644 NOTICE diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..52a1055 --- /dev/null +++ b/Android.bp @@ -0,0 +1,45 @@ +// +// Copyright (C) 2023 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 { + default_applicable_licenses: ["device_google_gs-common_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "device_google_gs-common_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-BSD", + ], + license_text: [ + "NOTICE", + ], +} diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..316b4eb --- /dev/null +++ b/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2014, 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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + From 3303171462090b2809e481b682025b7eb197615c Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:52:08 +0800 Subject: [PATCH 23/35] gs-common: move bootctrl hal aidl implementation to gs-common copy from device/google/zuma/interfaces/boot $ git log --oneline -1 interfaces/boot/ 193e5e8 zuma:interfaces:boot: add aidl interface support Bug: 265063384 Change-Id: I9b8318eee17e51f40577d7f4c6514703483b8eaa Signed-off-by: Jason Chiu --- bootctrl/aidl/Android.bp | 71 +++ bootctrl/aidl/BootControl.cpp | 538 ++++++++++++++++++ bootctrl/aidl/BootControl.h | 61 ++ bootctrl/aidl/DevInfo.h | 53 ++ bootctrl/aidl/GptUtils.cpp | 185 ++++++ bootctrl/aidl/GptUtils.h | 71 +++ ...oid.hardware.boot-service.default-pixel.rc | 5 + ...are.boot-service.default_recovery-pixel.rc | 7 + ...re.boot-service.default_recovery-pixel.xml | 6 + bootctrl/aidl/service.cpp | 44 ++ 10 files changed, 1041 insertions(+) create mode 100644 bootctrl/aidl/Android.bp create mode 100644 bootctrl/aidl/BootControl.cpp create mode 100644 bootctrl/aidl/BootControl.h create mode 100644 bootctrl/aidl/DevInfo.h create mode 100644 bootctrl/aidl/GptUtils.cpp create mode 100644 bootctrl/aidl/GptUtils.h create mode 100644 bootctrl/aidl/android.hardware.boot-service.default-pixel.rc create mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc create mode 100644 bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml create mode 100644 bootctrl/aidl/service.cpp diff --git a/bootctrl/aidl/Android.bp b/bootctrl/aidl/Android.bp new file mode 100644 index 0000000..f5ba503 --- /dev/null +++ b/bootctrl/aidl/Android.bp @@ -0,0 +1,71 @@ +// +// Copyright (C) 2023 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. +// + +soong_namespace { + imports: [ + "hardware/google/pixel", + ], +} + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "//device/google/gs-common:device_google_gs-common_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: [ + "//device/google/gs-common:device_google_gs-common_license", + ], +} + +cc_defaults { + name: "android.hardware.boot-service_common-pixel", + relative_install_path: "hw", + defaults: ["libboot_control_defaults"], + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "libz", + "libtrusty", + "android.hardware.boot@1.1", + "android.hardware.boot-V1-ndk", + ], + static_libs: [ + "libboot_control", + "libbootloader_message_vendor", + ], + srcs: [ + "BootControl.cpp", + "GptUtils.cpp", + "service.cpp" + ], +} + +cc_binary { + name: "android.hardware.boot-service.default-pixel", + defaults: ["android.hardware.boot-service_common-pixel"], + init_rc: ["android.hardware.boot-service.default-pixel.rc"], + vendor: true, +} + +cc_binary { + name: "android.hardware.boot-service.default_recovery-pixel", + defaults: ["android.hardware.boot-service_common-pixel"], + vintf_fragments: ["android.hardware.boot-service.default_recovery-pixel.xml"], + init_rc: ["android.hardware.boot-service.default_recovery-pixel.rc"], + recovery: true, +} diff --git a/bootctrl/aidl/BootControl.cpp b/bootctrl/aidl/BootControl.cpp new file mode 100644 index 0000000..941b0d2 --- /dev/null +++ b/bootctrl/aidl/BootControl.cpp @@ -0,0 +1,538 @@ +/* + * Copyright (C) 2023 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 "bootcontrolhal" + +#include "BootControl.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DevInfo.h" +#include "GptUtils.h" + +using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus; +using ndk::ScopedAStatus; + +using android::bootable::GetMiscVirtualAbMergeStatus; +using android::bootable::InitMiscVirtualAbMessageIfNeeded; +using android::bootable::SetMiscVirtualAbMergeStatus; + +namespace aidl::android::hardware::boot { + +namespace { + +// clang-format off + +#define BOOT_A_PATH "/dev/block/by-name/boot_a" +#define BOOT_B_PATH "/dev/block/by-name/boot_b" +#define DEVINFO_PATH "/dev/block/by-name/devinfo" + +// slot flags +#define AB_ATTR_PRIORITY_SHIFT 52 +#define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) +#define AB_ATTR_ACTIVE_SHIFT 54 +#define AB_ATTR_ACTIVE (1UL << AB_ATTR_ACTIVE_SHIFT) +#define AB_ATTR_RETRY_COUNT_SHIFT (55) +#define AB_ATTR_RETRY_COUNT_MASK (7UL << AB_ATTR_RETRY_COUNT_SHIFT) +#define AB_ATTR_SUCCESSFUL (1UL << 58) +#define AB_ATTR_UNBOOTABLE (1UL << 59) + +#define AB_ATTR_MAX_PRIORITY 3UL +#define AB_ATTR_MAX_RETRY_COUNT 3UL + +// clang-format on + +static std::string getDevPath(int32_t in_slot) { + char real_path[PATH_MAX]; + + const char *path = in_slot == 0 ? BOOT_A_PATH : BOOT_B_PATH; + + int ret = readlink(path, real_path, sizeof real_path); + if (ret < 0) { + ALOGE("readlink failed for boot device %s\n", strerror(errno)); + return std::string(); + } + + std::string dp(real_path); + // extract /dev/sda.. part + return dp.substr(0, sizeof "/dev/block/sdX" - 1); +} + +static bool isSlotFlagSet(int32_t in_slot, uint64_t flag) { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", in_slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + return !!(e->attr & flag); +} + +static bool setSlotFlag(int32_t in_slot, uint64_t flag) { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", in_slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + e->attr |= flag; + gpt.Sync(); + + return true; +} + +static bool is_devinfo_valid; +static bool is_devinfo_initialized; +static std::mutex devinfo_lock; +static devinfo_t devinfo; + +static bool isDevInfoValid() { + const std::lock_guard lock(devinfo_lock); + + if (is_devinfo_initialized) { + return is_devinfo_valid; + } + + is_devinfo_initialized = true; + + ::android::base::unique_fd fd(open(DEVINFO_PATH, O_RDONLY)); + ::android::base::ReadFully(fd, &devinfo, sizeof devinfo); + + if (devinfo.magic != DEVINFO_MAGIC) { + return is_devinfo_valid; + } + + uint32_t version = ((uint32_t)devinfo.ver_major << 16) | devinfo.ver_minor; + // only version 3.3+ supports A/B data + if (version >= 0x0003'0003) { + is_devinfo_valid = true; + } + + return is_devinfo_valid; +} + +static bool DevInfoSync() { + if (!isDevInfoValid()) { + return false; + } + + ::android::base::unique_fd fd(open(DEVINFO_PATH, O_WRONLY | O_DSYNC)); + return ::android::base::WriteFully(fd, &devinfo, sizeof devinfo); +} + +static void DevInfoInitSlot(devinfo_ab_slot_data_t &slot_data) { + slot_data.retry_count = AB_ATTR_MAX_RETRY_COUNT; + slot_data.unbootable = 0; + slot_data.successful = 0; + slot_data.active = 1; + slot_data.fastboot_ok = 0; +} + +static int blow_otp_AR(bool secure) { + static const char *dev_name = "/dev/trusty-ipc-dev0"; + static const char *otp_name = "com.android.trusty.otp_manager.tidl"; + int fd = 1, ret = 0; + uint32_t cmd = secure? OTP_CMD_write_antirbk_secure_ap : OTP_CMD_write_antirbk_non_secure_ap; + fd = tipc_connect(dev_name, otp_name); + if (fd < 0) { + ALOGI("Failed to connect to OTP_MGR ns TA - is it missing?\n"); + ret = -1; + return ret; + } + + struct otp_mgr_req_base req = { + .command = cmd, + .resp_payload_size = 0, + }; + struct iovec iov[] = { + { + .iov_base = &req, + .iov_len = sizeof(req), + }, + }; + + size_t rc = tipc_send(fd, iov, 1, NULL, 0); + if (rc != sizeof(req)) { + ALOGI("Send fail! %zx\n", rc); + return rc; + } + + struct otp_mgr_rsp_base resp; + rc = read(fd, &resp, sizeof(resp)); + if (rc < 0) { + ALOGI("Read fail! %zx\n", rc); + return rc; + } + + if (rc < sizeof(resp)) { + ALOGI("Not enough data! %zx\n", rc); + return -EIO; + } + + if (resp.command != (cmd | OTP_RESP_BIT)) { + ALOGI("Wrong command! %x\n", resp.command); + return -EINVAL; + } + + if (resp.result != 0) { + fprintf(stderr, "AR writing error! %x\n", resp.result); + return -EINVAL; + } + + tipc_close(fd); + return 0; +} + +static bool blowAR() { + int ret = blow_otp_AR(true); + if (ret) { + ALOGI("Blow secure anti-rollback OTP failed"); + return false; + } + + ret = blow_otp_AR(false); + if (ret) { + ALOGI("Blow non-secure anti-rollback OTP failed"); + return false; + } + + return true; +} + +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; + } +} + +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; + } +} + +} // namespace + +BootControl::BootControl() { + CHECK(InitMiscVirtualAbMessageIfNeeded()); +} + +ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + *_aidl_return = 0; + return ScopedAStatus::ok(); + } + + if (isDevInfoValid()) { + *_aidl_return = devinfo.ab_data.slots[1].active ? 1 : 0; + return ScopedAStatus::ok(); + } + *_aidl_return = isSlotFlagSet(1, AB_ATTR_ACTIVE) ? 1 : 0; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) { + char suffix[PROPERTY_VALUE_MAX]; + property_get("ro.boot.slot_suffix", suffix, "_a"); + *_aidl_return = std::string(suffix) == "_b" ? 1 : 0; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) { + int32_t slots = 0; + + if (access(BOOT_A_PATH, F_OK) == 0) + slots++; + + if (access(BOOT_B_PATH, F_OK) == 0) + slots++; + + *_aidl_return = slots; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) { + HIDLMergeStatus status; + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (!GetMiscVirtualAbMergeStatus(current_slot, &status)) { + *_aidl_return = MergeStatus::UNKNOWN; + return ScopedAStatus::ok(); + } + *_aidl_return = ToAIDLMergeStatus(status); + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) { + *_aidl_return = in_slot == 0 ? "_a" : in_slot == 1 ? "_b" : ""; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + *_aidl_return = false; + return ScopedAStatus::ok(); + } + if (in_slot >= slots) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + bool unbootable; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + unbootable = !!slot_data.unbootable; + } else { + unbootable = isSlotFlagSet(in_slot, AB_ATTR_UNBOOTABLE); + } + + *_aidl_return = unbootable ? false: true; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + // just return true so that we don't we another call trying to mark it as successful + // when there is no slots + *_aidl_return = true; + return ScopedAStatus::ok(); + } + if (in_slot >= slots) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + bool successful; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + successful = !!slot_data.successful; + } else { + successful = isSlotFlagSet(in_slot, AB_ATTR_SUCCESSFUL); + } + + *_aidl_return = successful ? true : false; + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::markBootSuccessful() { + int32_t slots = 0; + getNumberSlots(&slots); + if (slots == 0) { + // no slots, just return true otherwise Android keeps trying + return ScopedAStatus::ok(); + } + + bool ret; + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (isDevInfoValid()) { + auto const slot = current_slot; + devinfo.ab_data.slots[slot].successful = 1; + ret = DevInfoSync(); + } else { + ret = setSlotFlag(current_slot, AB_ATTR_SUCCESSFUL); + } + + if (!ret) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Failed to set successful flag"); + } + + if (!blowAR()) { + ALOGE("Failed to blow anti-rollback counter"); + // Ignore the error, since ABL will re-trigger it on reboot + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) { + if (in_slot >= 2) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + } + + if (isDevInfoValid()) { + auto &active_slot_data = devinfo.ab_data.slots[in_slot]; + auto &inactive_slot_data = devinfo.ab_data.slots[!in_slot]; + + inactive_slot_data.active = 0; + DevInfoInitSlot(active_slot_data); + + if (!DevInfoSync()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not update DevInfo data"); + } + } else { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not get device path for slot"); + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "failed to load gpt data"); + } + + gpt_entry *active_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_a" : "boot_b"); + gpt_entry *inactive_entry = gpt.GetPartitionEntry(in_slot == 0 ? "boot_b" : "boot_a"); + if (active_entry == nullptr || inactive_entry == nullptr) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "failed to get entries for boot partitions"); + } + + ALOGV("slot active attributes %lx\n", active_entry->attr); + ALOGV("slot inactive attributes %lx\n", inactive_entry->attr); + + // update attributes for active and inactive + inactive_entry->attr &= ~AB_ATTR_ACTIVE; + active_entry->attr = AB_ATTR_ACTIVE | (AB_ATTR_MAX_PRIORITY << AB_ATTR_PRIORITY_SHIFT) | + (AB_ATTR_MAX_RETRY_COUNT << AB_ATTR_RETRY_COUNT_SHIFT); + } + + char boot_dev[PROPERTY_VALUE_MAX]; + property_get("ro.boot.bootdevice", boot_dev, ""); + if (boot_dev[0] == '\0') { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "invalid ro.boot.bootdevice prop"); + } + + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/pixel/boot_lun_enabled"; + int fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + // Try old path for kernels < 5.4 + // TODO: remove once kernel 4.19 support is deprecated + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/attributes/boot_lun_enabled"; + fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "failed to open ufs attr boot_lun_enabled"); + } + } + + // + // bBootLunEn + // 0x1 => Boot LU A = enabled, Boot LU B = disable + // 0x2 => Boot LU A = disable, Boot LU B = enabled + // + int ret = ::android::base::WriteStringToFd(in_slot == 0 ? "1" : "2", fd); + close(fd); + if (ret < 0) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "faied to write boot_lun_enabled attribute"); + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) { + if (in_slot >= 2) + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str()); + + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[in_slot]; + slot_data.unbootable = 1; + if (!DevInfoSync()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not update DevInfo data"); + } + } else { + std::string dev_path = getDevPath(in_slot); + if (dev_path.empty()) { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "Could not get device path for slot"); + } + + GptUtils gpt(dev_path); + gpt.Load(); + + gpt_entry *e = gpt.GetPartitionEntry(in_slot ? "boot_b" : "boot_a"); + e->attr |= AB_ATTR_UNBOOTABLE; + + gpt.Sync(); + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) { + int32_t current_slot = 0; + getCurrentSlot(¤t_slot); + if (!SetMiscVirtualAbMergeStatus(current_slot, ToHIDLMergeStatus(in_status))) + return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED, + "Operation failed"); + return ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::boot diff --git a/bootctrl/aidl/BootControl.h b/bootctrl/aidl/BootControl.h new file mode 100644 index 0000000..a54f66d --- /dev/null +++ b/bootctrl/aidl/BootControl.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2023 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 + +namespace aidl::android::hardware::boot { + +class BootControl final : public BnBootControl { + public: + BootControl(); + ::ndk::ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getNumberSlots(int32_t* _aidl_return) override; + ::ndk::ScopedAStatus getSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override; + ::ndk::ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override; + ::ndk::ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override; + ::ndk::ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override; + ::ndk::ScopedAStatus markBootSuccessful() override; + ::ndk::ScopedAStatus setActiveBootSlot(int32_t in_slot) override; + ::ndk::ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override; + ::ndk::ScopedAStatus setSnapshotMergeStatus( + ::aidl::android::hardware::boot::MergeStatus in_status) override; +}; + +enum otpmgr_command : uint32_t { + OTP_REQ_SHIFT = 1, + OTP_RESP_BIT = 1, + OTP_CMD_write_antirbk_non_secure_ap = (7 << OTP_REQ_SHIFT), + OTP_CMD_write_antirbk_secure_ap = (8 << OTP_REQ_SHIFT), +}; + +struct otp_mgr_req_base { + uint32_t command; + uint32_t resp_payload_size; + uint8_t handle; +}__packed; + +struct otp_mgr_rsp_base { + uint32_t command; + uint32_t resp_payload_size; + int result; +}__packed; + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/DevInfo.h b/bootctrl/aidl/DevInfo.h new file mode 100644 index 0000000..aa5f5d3 --- /dev/null +++ b/bootctrl/aidl/DevInfo.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 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 + +namespace aidl::android::hardware::boot { + +// +// definitions taken from ABL code +// + +constexpr uint32_t DEVINFO_MAGIC = 0x49564544; +constexpr size_t DEVINFO_AB_SLOT_COUNT = 2; + +struct devinfo_ab_slot_data_t { + uint8_t retry_count; + uint8_t unbootable : 1; + uint8_t successful : 1; + uint8_t active : 1; + uint8_t fastboot_ok : 1; + uint8_t : 4; + uint8_t unused[2]; +} __attribute__((packed)); + +typedef struct { + devinfo_ab_slot_data_t slots[DEVINFO_AB_SLOT_COUNT]; +} __attribute__((packed)) devinfo_ab_data_t; + +struct devinfo_t { + uint32_t magic; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t unused[40]; + devinfo_ab_data_t ab_data; + uint8_t unused1[72]; // use remaining up to complete 128 bytes +} __attribute__((packed)); + +static_assert(sizeof(devinfo_t) == 128, "invalid devinfo struct size"); + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.cpp b/bootctrl/aidl/GptUtils.cpp new file mode 100644 index 0000000..34dec11 --- /dev/null +++ b/bootctrl/aidl/GptUtils.cpp @@ -0,0 +1,185 @@ +/* + * 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 "bootcontrolhal" + +#include "GptUtils.h" + +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::boot { + +namespace { + +static int ValidateGptHeader(gpt_header *gpt) { + if (gpt->signature != GPT_SIGNATURE) { + ALOGE("invalid gpt signature 0x%lx\n", gpt->signature); + return -1; + } + + if (gpt->header_size != sizeof(gpt_header)) { + ALOGE("invalid gpt header size %u\n", gpt->header_size); + return -1; + } + + if (gpt->entry_size != sizeof(gpt_entry)) { + ALOGE("invalid gpt entry size %u\n", gpt->entry_size); + return -1; + } + + return 0; +} + +} // namespace + +GptUtils::GptUtils(const std::string dev_path) : dev_path(dev_path), fd(0) {} + +int GptUtils::Load(void) { + fd = open(dev_path.c_str(), O_RDWR); + if (fd < 0) { + ALOGE("failed to open block dev %s, %d\n", dev_path.c_str(), errno); + return -1; + } + + int ret = ioctl(fd, BLKSSZGET, &block_size); + if (ret < 0) { + ALOGE("failed to get block size %d\n", errno); + return -1; + } + + // read primary header + lseek64(fd, block_size, SEEK_SET); + ret = read(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to read gpt primary header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_primary)) { + ALOGE("error validating gpt header\n"); + return -1; + } + + // read partition entries + entry_array.resize(gpt_primary.entry_count); + uint32_t entries_size = gpt_primary.entry_size * gpt_primary.entry_count; + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = read(fd, entry_array.data(), entries_size); + if (ret < 0) { + ALOGE("failed to read gpt partition entries %d\n", errno); + return -1; + } + + // read gpt back header + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = read(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to read gpt backup header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_backup)) { + ALOGW("error validating gpt backup\n"); // just warn about it, not fail + } + + // Create map + auto get_name = [](const uint16_t *efi_name) { + char name[37] = {}; + for (size_t i = 0; efi_name[i] && i < sizeof name - 1; ++i) name[i] = efi_name[i]; + return std::string(name); + }; + + for (auto const &e : entry_array) { + if (e.name[0] == 0) + break; // stop at the first partition with no name + std::string s = get_name(e.name); + entries[s] = const_cast(&e); + } + + return 0; +} + +gpt_entry *GptUtils::GetPartitionEntry(std::string name) { + return entries.find(name) != entries.end() ? entries[name] : nullptr; +} + +int GptUtils::Sync(void) { + if (!fd) + return -1; + + // calculate crc and check if we need to update gpt + gpt_primary.entries_crc32 = crc32(0, reinterpret_cast(entry_array.data()), + entry_array.size() * sizeof(gpt_entry)); + + // save old crc + uint32_t crc = gpt_primary.crc32; + gpt_primary.crc32 = 0; + + gpt_primary.crc32 = crc32(0, reinterpret_cast(&gpt_primary), sizeof gpt_primary); + if (crc == gpt_primary.crc32) + return 0; // nothing to do (no changes) + + ALOGI("updating GPT\n"); + + lseek64(fd, block_size * gpt_primary.current_lba, SEEK_SET); + int ret = write(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to write gpt primary header %d\n", errno); + return -1; + } + + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt partition entries %d\n", errno); + return -1; + } + + // update GPT backup entries and backup + lseek64(fd, block_size * gpt_backup.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt backup partition entries %d\n", errno); + return -1; + } + + gpt_backup.entries_crc32 = gpt_primary.entries_crc32; + gpt_backup.crc32 = 0; + gpt_backup.crc32 = crc32(0, reinterpret_cast(&gpt_backup), sizeof gpt_backup); + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = write(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to write gpt backup header %d\n", errno); + return -1; + } + + fsync(fd); + + return 0; +} + +GptUtils::~GptUtils() { + if (fd) { + Sync(); + close(fd); + } +} + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/GptUtils.h b/bootctrl/aidl/GptUtils.h new file mode 100644 index 0000000..ec68cf6 --- /dev/null +++ b/bootctrl/aidl/GptUtils.h @@ -0,0 +1,71 @@ +/* + * 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 + +namespace aidl::android::hardware::boot { + +#define GPT_SIGNATURE 0x5452415020494645UL + +typedef struct { + uint8_t type_guid[16]; + uint8_t guid[16]; + uint64_t first_lba; + uint64_t last_lba; + uint64_t attr; + uint16_t name[36]; +} __attribute__((packed)) gpt_entry; + +typedef struct { + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t reserved; + uint64_t current_lba; + uint64_t backup_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + uint8_t disk_guid[16]; + uint64_t start_lba; + uint32_t entry_count; + uint32_t entry_size; + uint32_t entries_crc32; +} __attribute__((packed)) gpt_header; + +class GptUtils { + public: + GptUtils(const std::string dev_path); + int Load(void); + gpt_entry *GetPartitionEntry(std::string name); + int Sync(void); + ~GptUtils(); + + private: + std::string dev_path; + int fd; + uint32_t block_size; + gpt_header gpt_primary; + gpt_header gpt_backup; + std::vector entry_array; + std::map entries; +}; + +} // namespace aidl::android::hardware::boot \ No newline at end of file diff --git a/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc new file mode 100644 index 0000000..a9887b9 --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default-pixel.rc @@ -0,0 +1,5 @@ +service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.default-pixel + class early_hal + user root + group root drmrpc + diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc new file mode 100644 index 0000000..e58617e --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.rc @@ -0,0 +1,7 @@ +service vendor.boot-default /system/bin/hw/android.hardware.boot-service.default_recovery-pixel + class early_hal + user root + group root + seclabel u:r:hal_bootctl_default:s0 + interface aidl android.hardware.boot.IBootControl/default + diff --git a/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml new file mode 100644 index 0000000..23ccc4e --- /dev/null +++ b/bootctrl/aidl/android.hardware.boot-service.default_recovery-pixel.xml @@ -0,0 +1,6 @@ + + + android.hardware.boot + IBootControl/default + + diff --git a/bootctrl/aidl/service.cpp b/bootctrl/aidl/service.cpp new file mode 100644 index 0000000..41b6c25 --- /dev/null +++ b/bootctrl/aidl/service.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2023 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 "aidl.android.hardware.boot-service.default" + +#include +#include +#include +#include +#include + +#include "BootControl.h" + +using aidl::android::hardware::boot::BootControl; +using aidl::android::hardware::boot::IBootControl; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; + +int main(int, char* argv[]) { + android::base::InitLogging(argv, android::base::KernelLogger); + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr service = ndk::SharedRefBase::make(); + + const std::string instance = std::string(BootControl::descriptor) + "/default"; + auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str()); + CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status; + LOG(INFO) << "IBootControl AIDL service running..."; + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} From c3102b06fcb95462334e24a9a9a3179ce978c179 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:53:59 +0800 Subject: [PATCH 24/35] gs-common: create bootctrl_aidl.mk and include related modules Bug: 265063384 Change-Id: I9362eb521616c899a14605081fdc10de2a1d5c16 Signed-off-by: Jason Chiu --- bootctrl/bootctrl_aidl.mk | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 bootctrl/bootctrl_aidl.mk diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk new file mode 100644 index 0000000..ca136ba --- /dev/null +++ b/bootctrl/bootctrl_aidl.mk @@ -0,0 +1,5 @@ +PRODUCT_PACKAGES += \ + android.hardware.boot-service.default-pixel \ + android.hardware.boot-service.default_recovery-pixel + +PRODUCT_SOONG_NAMESPACES += device/google/gs-common/bootctrl/aidl From 1473a277b84d1d9a6529163a5065fb534b9c8673 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:58:15 +0800 Subject: [PATCH 25/35] gs-common: move sepolicy related to bootctrl hal aidl to gs-common Bug: 265063384 Change-Id: Id9e1f4f7bc9fc5754f7ebadb97f7443f1117e961 Signed-off-by: Jason Chiu --- bootctrl/bootctrl_aidl.mk | 1 + bootctrl/sepolicy/aidl/device.te | 5 +++++ bootctrl/sepolicy/aidl/file.te | 2 ++ bootctrl/sepolicy/aidl/file_contexts | 1 + bootctrl/sepolicy/aidl/hal_bootctl_default.te | 8 ++++++++ 5 files changed, 17 insertions(+) create mode 100644 bootctrl/sepolicy/aidl/device.te create mode 100644 bootctrl/sepolicy/aidl/file.te create mode 100644 bootctrl/sepolicy/aidl/file_contexts create mode 100644 bootctrl/sepolicy/aidl/hal_bootctl_default.te diff --git a/bootctrl/bootctrl_aidl.mk b/bootctrl/bootctrl_aidl.mk index ca136ba..e9d7051 100644 --- a/bootctrl/bootctrl_aidl.mk +++ b/bootctrl/bootctrl_aidl.mk @@ -3,3 +3,4 @@ PRODUCT_PACKAGES += \ android.hardware.boot-service.default_recovery-pixel PRODUCT_SOONG_NAMESPACES += device/google/gs-common/bootctrl/aidl +BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/bootctrl/sepolicy/aidl diff --git a/bootctrl/sepolicy/aidl/device.te b/bootctrl/sepolicy/aidl/device.te new file mode 100644 index 0000000..4fd0240 --- /dev/null +++ b/bootctrl/sepolicy/aidl/device.te @@ -0,0 +1,5 @@ +# devinfo block device +type devinfo_block_device, dev_type; + +# OTA +type sda_block_device, dev_type; diff --git a/bootctrl/sepolicy/aidl/file.te b/bootctrl/sepolicy/aidl/file.te new file mode 100644 index 0000000..5357fa9 --- /dev/null +++ b/bootctrl/sepolicy/aidl/file.te @@ -0,0 +1,2 @@ +# sysfs +type sysfs_ota, sysfs_type, fs_type; diff --git a/bootctrl/sepolicy/aidl/file_contexts b/bootctrl/sepolicy/aidl/file_contexts new file mode 100644 index 0000000..339896f --- /dev/null +++ b/bootctrl/sepolicy/aidl/file_contexts @@ -0,0 +1 @@ +/vendor/bin/hw/android\.hardware\.boot-service\.default-pixel u:object_r:hal_bootctl_default_exec:s0 diff --git a/bootctrl/sepolicy/aidl/hal_bootctl_default.te b/bootctrl/sepolicy/aidl/hal_bootctl_default.te new file mode 100644 index 0000000..2ffeb27 --- /dev/null +++ b/bootctrl/sepolicy/aidl/hal_bootctl_default.te @@ -0,0 +1,8 @@ +allow hal_bootctl_default devinfo_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sda_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sysfs_ota:file rw_file_perms; +allow hal_bootctl_default tee_device:chr_file rw_file_perms; + +recovery_only(` + allow hal_bootctl_default rootfs:dir r_dir_perms; +') From fd652ae423e4afc3318cd8c955c303c834929c86 Mon Sep 17 00:00:00 2001 From: Carter Hsu Date: Mon, 4 Dec 2023 11:17:34 +0800 Subject: [PATCH 26/35] audio: allow hal_audio_default to allocate graphic buffer 12-04 10:00:07.379 481 481 E SELinux : avc: denied { find } for interface=android.hardware.graphics.mapper::IMapper sid=u:r:hal_audio_default:s0 pid=13283 scontext=u:r:hal_audio_default:s0 tcontext=u:object_r:hal_graphics_mapper_hwservice:s0 tclass=hwservice_manager permissive=0 12-04 10:00:07.409 480 480 E SELinux : avc: denied { find } for pid=13283 uid=1041 name=android.hardware.graphics.allocator.IAllocator/default scontext=u:r:hal_audio_default:s0 tcontext=u:object_r:hal_graphics_allocator_service:s0 tclass=service_manager permissive=0 Bug: 314850759 Test: verified by test build Change-Id: Icb2ecd6d3096455244dc58b5aadf8c562cb02470 Signed-off-by: Carter Hsu --- audio/sepolicy/common/hal_audio_default.te | 2 ++ 1 file changed, 2 insertions(+) diff --git a/audio/sepolicy/common/hal_audio_default.te b/audio/sepolicy/common/hal_audio_default.te index 5cb03ac..c69e339 100644 --- a/audio/sepolicy/common/hal_audio_default.te +++ b/audio/sepolicy/common/hal_audio_default.te @@ -26,6 +26,8 @@ hal_client_domain(hal_audio_default, hal_health); hal_client_domain(hal_audio_default, hal_thermal); allow hal_audio_default fwk_sensor_hwservice:hwservice_manager find; +hal_client_domain(hal_audio_default, hal_graphics_allocator); + userdebug_or_eng(` allow hal_audio_default self:unix_stream_socket create_stream_socket_perms; allow hal_audio_default audio_vendor_data_file:sock_file { create unlink }; From 5d247d17b45466288061b33655d336ad7396efe3 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:42:44 +0800 Subject: [PATCH 27/35] gs-common: move bootctrl hal hidl 1.2 implementation to gs-common copy from device/google/zuma/interfaces/boot $ git log --oneline -1 interfaces/boot/ 193e5e8 zuma:interfaces:boot: add aidl interface support Bug: 265063384 Change-Id: I7b770343096fd113f656c90428f30d80c9341744 Signed-off-by: Jason Chiu --- bootctrl/1.2/Android.bp | 89 ++++ bootctrl/1.2/BootControl.cpp | 501 ++++++++++++++++++ bootctrl/1.2/BootControl.h | 88 +++ bootctrl/1.2/DevInfo.h | 61 +++ bootctrl/1.2/GptUtils.cpp | 193 +++++++ bootctrl/1.2/GptUtils.h | 79 +++ ...android.hardware.boot@1.2-service-pixel.rc | 7 + bootctrl/1.2/service.cpp | 50 ++ 8 files changed, 1068 insertions(+) create mode 100644 bootctrl/1.2/Android.bp create mode 100644 bootctrl/1.2/BootControl.cpp create mode 100644 bootctrl/1.2/BootControl.h create mode 100644 bootctrl/1.2/DevInfo.h create mode 100644 bootctrl/1.2/GptUtils.cpp create mode 100644 bootctrl/1.2/GptUtils.h create mode 100644 bootctrl/1.2/android.hardware.boot@1.2-service-pixel.rc create mode 100644 bootctrl/1.2/service.cpp diff --git a/bootctrl/1.2/Android.bp b/bootctrl/1.2/Android.bp new file mode 100644 index 0000000..ad0b0e1 --- /dev/null +++ b/bootctrl/1.2/Android.bp @@ -0,0 +1,89 @@ +// +// 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. + +soong_namespace { + imports: [ + "hardware/google/pixel", + ], +} + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "//device/google/gs-common:device_google_gs-common_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: [ + "//device/google/gs-common:device_google_gs-common_license", + ], +} + +cc_binary { + name: "android.hardware.boot@1.2-service-pixel", + defaults: ["hidl_defaults"], + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.boot@1.2-service-pixel.rc"], + srcs: [ + "BootControl.cpp", + "GptUtils.cpp", + "service.cpp" + ], + shared_libs: [ + "libbase", + "liblog", + "libhidlbase", + "libutils", + "libcutils", + "libz", + "libtrusty", + "android.hardware.boot@1.0", + "android.hardware.boot@1.1", + "android.hardware.boot@1.2", + ], + static_libs: [ + "libboot_control", + "libbootloader_message_vendor", + "libfstab", + ], +} + +cc_library { + name: "android.hardware.boot@1.2-impl-pixel", + stem: "android.hardware.boot@1.0-impl-1.2-impl-pixel", + recovery: true, + srcs: [ + "BootControl.cpp", + "GptUtils.cpp", + ], + relative_install_path: "hw", + shared_libs: [ + "libbase", + "liblog", + "libhidlbase", + "libutils", + "libcutils", + "libz", + "libtrusty", + "android.hardware.boot@1.0", + "android.hardware.boot@1.1", + "android.hardware.boot@1.2", + ], + static_libs: [ + "libboot_control", + "libbootloader_message_vendor", + "libfstab", + ], +} diff --git a/bootctrl/1.2/BootControl.cpp b/bootctrl/1.2/BootControl.cpp new file mode 100644 index 0000000..7782075 --- /dev/null +++ b/bootctrl/1.2/BootControl.cpp @@ -0,0 +1,501 @@ +/* + * 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 "bootcontrolhal" + +#include "BootControl.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "DevInfo.h" +#include "GptUtils.h" + +namespace android { +namespace hardware { +namespace boot { +namespace V1_2 { +namespace implementation { + +using android::bootable::GetMiscVirtualAbMergeStatus; +using android::bootable::InitMiscVirtualAbMessageIfNeeded; +using android::bootable::SetMiscVirtualAbMergeStatus; +using android::hardware::boot::V1_0::BoolResult; +using android::hardware::boot::V1_0::CommandResult; +using android::hardware::boot::V1_1::MergeStatus; + +namespace { + +// clang-format off + +#define BOOT_A_PATH "/dev/block/by-name/boot_a" +#define BOOT_B_PATH "/dev/block/by-name/boot_b" +#define DEVINFO_PATH "/dev/block/by-name/devinfo" + +// slot flags +#define AB_ATTR_PRIORITY_SHIFT 52 +#define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) +#define AB_ATTR_ACTIVE_SHIFT 54 +#define AB_ATTR_ACTIVE (1UL << AB_ATTR_ACTIVE_SHIFT) +#define AB_ATTR_RETRY_COUNT_SHIFT (55) +#define AB_ATTR_RETRY_COUNT_MASK (7UL << AB_ATTR_RETRY_COUNT_SHIFT) +#define AB_ATTR_SUCCESSFUL (1UL << 58) +#define AB_ATTR_UNBOOTABLE (1UL << 59) + +#define AB_ATTR_MAX_PRIORITY 3UL +#define AB_ATTR_MAX_RETRY_COUNT 3UL + +// clang-format on + +static std::string getDevPath(uint32_t slot) { + char real_path[PATH_MAX]; + + const char *path = slot == 0 ? BOOT_A_PATH : BOOT_B_PATH; + + int ret = readlink(path, real_path, sizeof real_path); + if (ret < 0) { + ALOGE("readlink failed for boot device %s\n", strerror(errno)); + return std::string(); + } + + std::string dp(real_path); + // extract /dev/sda.. part + return dp.substr(0, sizeof "/dev/block/sdX" - 1); +} + +static bool isSlotFlagSet(uint32_t slot, uint64_t flag) { + std::string dev_path = getDevPath(slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + return !!(e->attr & flag); +} + +static bool setSlotFlag(uint32_t slot, uint64_t flag) { + std::string dev_path = getDevPath(slot); + if (dev_path.empty()) { + ALOGI("Could not get device path for slot %d\n", slot); + return false; + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + ALOGI("failed to load gpt data\n"); + return false; + } + + gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a"); + if (e == nullptr) { + ALOGI("failed to get gpt entry\n"); + return false; + } + + e->attr |= flag; + gpt.Sync(); + + return true; +} + +static bool is_devinfo_valid; +static bool is_devinfo_initialized; +static std::mutex devinfo_lock; +static devinfo_t devinfo; + +static bool isDevInfoValid() { + const std::lock_guard lock(devinfo_lock); + + if (is_devinfo_initialized) { + return is_devinfo_valid; + } + + is_devinfo_initialized = true; + + android::base::unique_fd fd(open(DEVINFO_PATH, O_RDONLY)); + android::base::ReadFully(fd, &devinfo, sizeof devinfo); + + if (devinfo.magic != DEVINFO_MAGIC) { + return is_devinfo_valid; + } + + uint32_t version = ((uint32_t)devinfo.ver_major << 16) | devinfo.ver_minor; + // only version 3.3+ supports A/B data + if (version >= 0x0003'0003) { + is_devinfo_valid = true; + } + + return is_devinfo_valid; +} + +static bool DevInfoSync() { + if (!isDevInfoValid()) { + return false; + } + + android::base::unique_fd fd(open(DEVINFO_PATH, O_WRONLY | O_DSYNC)); + return android::base::WriteFully(fd, &devinfo, sizeof devinfo); +} + +static void DevInfoInitSlot(devinfo_ab_slot_data_t &slot_data) { + slot_data.retry_count = AB_ATTR_MAX_RETRY_COUNT; + slot_data.unbootable = 0; + slot_data.successful = 0; + slot_data.active = 1; + slot_data.fastboot_ok = 0; +} + +static int blow_otp_AR(bool secure) { + static const char *dev_name = "/dev/trusty-ipc-dev0"; + static const char *otp_name = "com.android.trusty.otp_manager.tidl"; + int fd = 1, ret = 0; + uint32_t cmd = secure? OTP_CMD_write_antirbk_secure_ap : OTP_CMD_write_antirbk_non_secure_ap; + fd = tipc_connect(dev_name, otp_name); + if (fd < 0) { + ALOGI("Failed to connect to OTP_MGR ns TA - is it missing?\n"); + ret = -1; + return ret; + } + + struct otp_mgr_req_base req = { + .command = cmd, + .resp_payload_size = 0, + }; + struct iovec iov[] = { + { + .iov_base = &req, + .iov_len = sizeof(req), + }, + }; + + int rc = tipc_send(fd, iov, 1, NULL, 0); + if (rc != sizeof(req)) { + ALOGI("Send fail! %x\n", rc); + return rc; + } + + struct otp_mgr_rsp_base resp; + rc = read(fd, &resp, sizeof(resp)); + if (rc < 0) { + ALOGI("Read fail! %x\n", rc); + return rc; + } + + if (rc < sizeof(resp)) { + ALOGI("Not enough data! %x\n", rc); + return -EIO; + } + + if (resp.command != (cmd | OTP_RESP_BIT)) { + ALOGI("Wrong command! %x\n", resp.command); + return -EINVAL; + } + + if (resp.result != 0) { + fprintf(stderr, "AR writing error! %x\n", resp.result); + return -EINVAL; + } + + tipc_close(fd); + return 0; +} + +static bool blowAR() { + int ret = blow_otp_AR(true); + if (ret) { + ALOGI("Blow secure anti-rollback OTP failed"); + return false; + } + + ret = blow_otp_AR(false); + if (ret) { + ALOGI("Blow non-secure anti-rollback OTP failed"); + return false; + } + + return true; +} +} // namespace + +// Methods from ::android::hardware::boot::V1_0::IBootControl follow. +Return BootControl::getNumberSlots() { + uint32_t slots = 0; + + if (access(BOOT_A_PATH, F_OK) == 0) + slots++; + + if (access(BOOT_B_PATH, F_OK) == 0) + slots++; + + return slots; +} + +Return BootControl::getCurrentSlot() { + char suffix[PROPERTY_VALUE_MAX]; + property_get("ro.boot.slot_suffix", suffix, "_a"); + return std::string(suffix) == "_b" ? 1 : 0; +} + +Return BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) { + if (getNumberSlots() == 0) { + // no slots, just return true otherwise Android keeps trying + _hidl_cb({true, ""}); + return Void(); + } + + bool ret; + if (isDevInfoValid()) { + auto const slot = getCurrentSlot(); + devinfo.ab_data.slots[slot].successful = 1; + ret = DevInfoSync(); + } else { + ret = setSlotFlag(getCurrentSlot(), AB_ATTR_SUCCESSFUL); + } + + if (!ret) { + _hidl_cb({false, "Failed to set successful flag"}); + return Void(); + } + + if (!blowAR()) { + ALOGE("Failed to blow anti-rollback counter"); + // Ignore the error, since ABL will re-trigger it on reboot + } + + _hidl_cb({true, ""}); + return Void(); +} + +Return BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) { + if (slot >= 2) { + _hidl_cb({false, "Invalid slot"}); + return Void(); + } + + if (isDevInfoValid()) { + auto &active_slot_data = devinfo.ab_data.slots[slot]; + auto &inactive_slot_data = devinfo.ab_data.slots[!slot]; + + inactive_slot_data.active = 0; + DevInfoInitSlot(active_slot_data); + + if (!DevInfoSync()) { + _hidl_cb({false, "Could not update DevInfo data"}); + return Void(); + } + } else { + std::string dev_path = getDevPath(slot); + if (dev_path.empty()) { + _hidl_cb({false, "Could not get device path for slot"}); + return Void(); + } + + GptUtils gpt(dev_path); + if (gpt.Load()) { + _hidl_cb({false, "failed to load gpt data"}); + return Void(); + } + + gpt_entry *active_entry = gpt.GetPartitionEntry(slot == 0 ? "boot_a" : "boot_b"); + gpt_entry *inactive_entry = gpt.GetPartitionEntry(slot == 0 ? "boot_b" : "boot_a"); + if (active_entry == nullptr || inactive_entry == nullptr) { + _hidl_cb({false, "failed to get entries for boot partitions"}); + return Void(); + } + + ALOGV("slot active attributes %lx\n", active_entry->attr); + ALOGV("slot inactive attributes %lx\n", inactive_entry->attr); + + // update attributes for active and inactive + inactive_entry->attr &= ~AB_ATTR_ACTIVE; + active_entry->attr = AB_ATTR_ACTIVE | (AB_ATTR_MAX_PRIORITY << AB_ATTR_PRIORITY_SHIFT) | + (AB_ATTR_MAX_RETRY_COUNT << AB_ATTR_RETRY_COUNT_SHIFT); + } + + char boot_dev[PROPERTY_VALUE_MAX]; + property_get("ro.boot.bootdevice", boot_dev, ""); + if (boot_dev[0] == '\0') { + _hidl_cb({false, "invalid ro.boot.bootdevice prop"}); + return Void(); + } + + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/pixel/boot_lun_enabled"; + int fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + // Try old path for kernels < 5.4 + // TODO: remove once kernel 4.19 support is deprecated + std::string boot_lun_path = + std::string("/sys/devices/platform/") + boot_dev + "/attributes/boot_lun_enabled"; + fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC); + if (fd < 0) { + _hidl_cb({false, "failed to open ufs attr boot_lun_enabled"}); + return Void(); + } + } + + // + // bBootLunEn + // 0x1 => Boot LU A = enabled, Boot LU B = disable + // 0x2 => Boot LU A = disable, Boot LU B = enabled + // + int ret = android::base::WriteStringToFd(slot == 0 ? "1" : "2", fd); + close(fd); + if (ret < 0) { + _hidl_cb({false, "faied to write boot_lun_enabled attribute"}); + return Void(); + } + + _hidl_cb({true, ""}); + return Void(); +} + +Return BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) { + if (slot >= 2) { + _hidl_cb({false, "Invalid slot"}); + return Void(); + } + + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[slot]; + slot_data.unbootable = 1; + if (!DevInfoSync()) { + _hidl_cb({false, "Could not update DevInfo data"}); + return Void(); + } + } else { + std::string dev_path = getDevPath(slot); + if (dev_path.empty()) { + _hidl_cb({false, "Could not get device path for slot"}); + return Void(); + } + + GptUtils gpt(dev_path); + gpt.Load(); + + gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a"); + e->attr |= AB_ATTR_UNBOOTABLE; + + gpt.Sync(); + } + + _hidl_cb({true, ""}); + return Void(); +} + +Return<::android::hardware::boot::V1_0::BoolResult> BootControl::isSlotBootable(uint32_t slot) { + if (getNumberSlots() == 0) + return BoolResult::FALSE; + if (slot >= getNumberSlots()) + return BoolResult::INVALID_SLOT; + + bool unbootable; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[slot]; + unbootable = !!slot_data.unbootable; + } else { + unbootable = isSlotFlagSet(slot, AB_ATTR_UNBOOTABLE); + } + + return unbootable ? BoolResult::FALSE : BoolResult::TRUE; +} + +Return<::android::hardware::boot::V1_0::BoolResult> BootControl::isSlotMarkedSuccessful( + uint32_t slot) { + if (getNumberSlots() == 0) { + // just return true so that we don't we another call trying to mark it as successful + // when there is no slots + return BoolResult::TRUE; + } + if (slot >= getNumberSlots()) + return BoolResult::INVALID_SLOT; + + bool successful; + if (isDevInfoValid()) { + auto &slot_data = devinfo.ab_data.slots[slot]; + successful = !!slot_data.successful; + } else { + successful = isSlotFlagSet(slot, AB_ATTR_SUCCESSFUL); + } + + return successful ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) { + _hidl_cb(slot == 0 ? "_a" : slot == 1 ? "_b" : ""); + return Void(); +} + +// Methods from ::android::hardware::boot::V1_1::IBootControl follow. +bool BootControl::Init() { + return InitMiscVirtualAbMessageIfNeeded(); +} + +Return BootControl::setSnapshotMergeStatus( + ::android::hardware::boot::V1_1::MergeStatus status) { + return SetMiscVirtualAbMergeStatus(getCurrentSlot(), status); +} + +Return<::android::hardware::boot::V1_1::MergeStatus> BootControl::getSnapshotMergeStatus() { + MergeStatus status; + if (!GetMiscVirtualAbMergeStatus(getCurrentSlot(), &status)) { + return MergeStatus::UNKNOWN; + } + return status; +} + +// Methods from ::android::hardware::boot::V1_2::IBootControl follow. +Return BootControl::getActiveBootSlot() { + if (getNumberSlots() == 0) + return 0; + + if (isDevInfoValid()) + return devinfo.ab_data.slots[1].active ? 1 : 0; + return isSlotFlagSet(1, AB_ATTR_ACTIVE) ? 1 : 0; +} + +// Methods from ::android::hidl::base::V1_0::IBase follow. + +IBootControl *HIDL_FETCH_IBootControl(const char * /* name */) { + auto module = new BootControl(); + + module->Init(); + + return module; +} + +} // namespace implementation +} // namespace V1_2 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.2/BootControl.h b/bootctrl/1.2/BootControl.h new file mode 100644 index 0000000..45b7efa --- /dev/null +++ b/bootctrl/1.2/BootControl.h @@ -0,0 +1,88 @@ +/* + * 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 + +namespace android { +namespace hardware { +namespace boot { +namespace V1_2 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct BootControl : public IBootControl { + 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<::android::hardware::boot::V1_0::BoolResult> isSlotBootable(uint32_t slot) override; + Return<::android::hardware::boot::V1_0::BoolResult> 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( + ::android::hardware::boot::V1_1::MergeStatus status) override; + Return<::android::hardware::boot::V1_1::MergeStatus> getSnapshotMergeStatus() override; + + // Methods from ::android::hardware::boot::V1_2::IBootControl follow. + Return getActiveBootSlot() override; + + // Methods from ::android::hidl::base::V1_0::IBase follow. +}; + +// FIXME: most likely delete, this is only for passthrough implementations +extern "C" IBootControl *HIDL_FETCH_IBootControl(const char *name); + +enum otpmgr_command : uint32_t { + OTP_REQ_SHIFT = 1, + OTP_RESP_BIT = 1, + OTP_CMD_write_antirbk_non_secure_ap = (7 << OTP_REQ_SHIFT), + OTP_CMD_write_antirbk_secure_ap = (8 << OTP_REQ_SHIFT), +}; + +struct otp_mgr_req_base { + uint32_t command; + uint32_t resp_payload_size; + uint8_t handle; +}__packed; + +struct otp_mgr_rsp_base { + uint32_t command; + uint32_t resp_payload_size; + int result; +}__packed; + +} // namespace implementation +} // namespace V1_2 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.2/DevInfo.h b/bootctrl/1.2/DevInfo.h new file mode 100644 index 0000000..a09a83a --- /dev/null +++ b/bootctrl/1.2/DevInfo.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 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 + +namespace android { +namespace hardware { +namespace boot { +namespace V1_2 { +namespace implementation { + +// +// definitions taken from ABL code +// + +constexpr uint32_t DEVINFO_MAGIC = 0x49564544; +constexpr size_t DEVINFO_AB_SLOT_COUNT = 2; + +struct devinfo_ab_slot_data_t { + uint8_t retry_count; + uint8_t unbootable : 1; + uint8_t successful : 1; + uint8_t active : 1; + uint8_t fastboot_ok : 1; + uint8_t : 4; + uint8_t unused[2]; +} __attribute__((packed)); + +typedef struct { + devinfo_ab_slot_data_t slots[DEVINFO_AB_SLOT_COUNT]; +} __attribute__((packed)) devinfo_ab_data_t; + +struct devinfo_t { + uint32_t magic; + uint16_t ver_major; + uint16_t ver_minor; + uint8_t unused[40]; + devinfo_ab_data_t ab_data; + uint8_t unused1[72]; // use remaining up to complete 128 bytes +} __attribute__((packed)); + +static_assert(sizeof(devinfo_t) == 128, "invalid devinfo struct size"); + +} // namespace implementation +} // namespace V1_2 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.2/GptUtils.cpp b/bootctrl/1.2/GptUtils.cpp new file mode 100644 index 0000000..25088e7 --- /dev/null +++ b/bootctrl/1.2/GptUtils.cpp @@ -0,0 +1,193 @@ +/* + * 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 "bootcontrolhal" + +#include "GptUtils.h" + +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace boot { +namespace V1_2 { +namespace implementation { + +namespace { + +static int ValidateGptHeader(gpt_header *gpt) { + if (gpt->signature != GPT_SIGNATURE) { + ALOGE("invalid gpt signature 0x%lx\n", gpt->signature); + return -1; + } + + if (gpt->header_size != sizeof(gpt_header)) { + ALOGE("invalid gpt header size %u\n", gpt->header_size); + return -1; + } + + if (gpt->entry_size != sizeof(gpt_entry)) { + ALOGE("invalid gpt entry size %u\n", gpt->entry_size); + return -1; + } + + return 0; +} + +} // namespace + +GptUtils::GptUtils(const std::string dev_path) : dev_path(dev_path), fd(0) {} + +int GptUtils::Load(void) { + fd = open(dev_path.c_str(), O_RDWR); + if (fd < 0) { + ALOGE("failed to open block dev %s, %d\n", dev_path.c_str(), errno); + return -1; + } + + int ret = ioctl(fd, BLKSSZGET, &block_size); + if (ret < 0) { + ALOGE("failed to get block size %d\n", errno); + return -1; + } + + // read primary header + lseek64(fd, block_size, SEEK_SET); + ret = read(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to read gpt primary header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_primary)) { + ALOGE("error validating gpt header\n"); + return -1; + } + + // read partition entries + entry_array.resize(gpt_primary.entry_count); + uint32_t entries_size = gpt_primary.entry_size * gpt_primary.entry_count; + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = read(fd, entry_array.data(), entries_size); + if (ret < 0) { + ALOGE("failed to read gpt partition entries %d\n", errno); + return -1; + } + + // read gpt back header + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = read(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to read gpt backup header %d\n", errno); + return -1; + } + + if (ValidateGptHeader(&gpt_backup)) { + ALOGW("error validating gpt backup\n"); // just warn about it, not fail + } + + // Create map + auto get_name = [](const uint16_t *efi_name) { + char name[37] = {}; + for (int i = 0; efi_name[i] && i < sizeof name - 1; ++i) name[i] = efi_name[i]; + return std::string(name); + }; + + for (auto const &e : entry_array) { + if (e.name[0] == 0) + break; // stop at the first partition with no name + std::string s = get_name(e.name); + entries[s] = const_cast(&e); + } + + return 0; +} + +gpt_entry *GptUtils::GetPartitionEntry(std::string name) { + return entries.find(name) != entries.end() ? entries[name] : nullptr; +} + +int GptUtils::Sync(void) { + if (!fd) + return -1; + + // calculate crc and check if we need to update gpt + gpt_primary.entries_crc32 = crc32(0, reinterpret_cast(entry_array.data()), + entry_array.size() * sizeof(gpt_entry)); + + // save old crc + uint32_t crc = gpt_primary.crc32; + gpt_primary.crc32 = 0; + + gpt_primary.crc32 = crc32(0, reinterpret_cast(&gpt_primary), sizeof gpt_primary); + if (crc == gpt_primary.crc32) + return 0; // nothing to do (no changes) + + ALOGI("updating GPT\n"); + + lseek64(fd, block_size * gpt_primary.current_lba, SEEK_SET); + int ret = write(fd, &gpt_primary, sizeof gpt_primary); + if (ret < 0) { + ALOGE("failed to write gpt primary header %d\n", errno); + return -1; + } + + lseek64(fd, block_size * gpt_primary.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt partition entries %d\n", errno); + return -1; + } + + // update GPT backup entries and backup + lseek64(fd, block_size * gpt_backup.start_lba, SEEK_SET); + ret = write(fd, entry_array.data(), entry_array.size() * sizeof(gpt_entry)); + if (ret < 0) { + ALOGE("failed to write gpt backup partition entries %d\n", errno); + return -1; + } + + gpt_backup.entries_crc32 = gpt_primary.entries_crc32; + gpt_backup.crc32 = 0; + gpt_backup.crc32 = crc32(0, reinterpret_cast(&gpt_backup), sizeof gpt_backup); + lseek64(fd, block_size * gpt_primary.backup_lba, SEEK_SET); + ret = write(fd, &gpt_backup, sizeof gpt_backup); + if (ret < 0) { + ALOGE("failed to write gpt backup header %d\n", errno); + return -1; + } + + fsync(fd); + + return 0; +} + +GptUtils::~GptUtils() { + if (fd) { + Sync(); + close(fd); + } +} + +} // namespace implementation +} // namespace V1_2 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.2/GptUtils.h b/bootctrl/1.2/GptUtils.h new file mode 100644 index 0000000..a2bed33 --- /dev/null +++ b/bootctrl/1.2/GptUtils.h @@ -0,0 +1,79 @@ +/* + * 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 + +namespace android { +namespace hardware { +namespace boot { +namespace V1_2 { +namespace implementation { + +#define GPT_SIGNATURE 0x5452415020494645UL + +typedef struct { + uint8_t type_guid[16]; + uint8_t guid[16]; + uint64_t first_lba; + uint64_t last_lba; + uint64_t attr; + uint16_t name[36]; +} __attribute__((packed)) gpt_entry; + +typedef struct { + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t crc32; + uint32_t reserved; + uint64_t current_lba; + uint64_t backup_lba; + uint64_t first_usable_lba; + uint64_t last_usable_lba; + uint8_t disk_guid[16]; + uint64_t start_lba; + uint32_t entry_count; + uint32_t entry_size; + uint32_t entries_crc32; +} __attribute__((packed)) gpt_header; + +class GptUtils { + public: + GptUtils(const std::string dev_path); + int Load(void); + gpt_entry *GetPartitionEntry(std::string name); + int Sync(void); + ~GptUtils(); + + private: + std::string dev_path; + int fd; + uint32_t block_size; + gpt_header gpt_primary; + gpt_header gpt_backup; + std::vector entry_array; + std::map entries; +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.2/android.hardware.boot@1.2-service-pixel.rc b/bootctrl/1.2/android.hardware.boot@1.2-service-pixel.rc new file mode 100644 index 0000000..ff7d2f3 --- /dev/null +++ b/bootctrl/1.2/android.hardware.boot@1.2-service-pixel.rc @@ -0,0 +1,7 @@ +service vendor.boot-hal-1-2 /vendor/bin/hw/android.hardware.boot@1.2-service-pixel + 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 drmrpc diff --git a/bootctrl/1.2/service.cpp b/bootctrl/1.2/service.cpp new file mode 100644 index 0000000..f07682e --- /dev/null +++ b/bootctrl/1.2/service.cpp @@ -0,0 +1,50 @@ +/* + * 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 +#include +#include + +#include "BootControl.h" + +using ::android::status_t; + +using ::android::hardware::boot::V1_2::IBootControl; + +using ::android::hardware::boot::V1_2::implementation::BootControl; +// using ::android::hardware::boot::implementation::BootControl; + +int main(int /* argc */, char * /* argv */[]) { + // This function must be called before you join to ensure the proper + // number of threads are created. The threadpool will never exceed + // size one because of this call. + ::android::hardware::configureRpcThreadpool(1 /*threads*/, true /*willJoin*/); + + ::android::sp bootctrl = new BootControl(); + const status_t status = bootctrl->registerAsService(); + if (status != ::android::OK) { + return 1; // or handle error + } + + // Adds this thread to the threadpool, resulting in one total + // thread in the threadpool. We could also do other things, but + // would have to specify 'false' to willJoin in configureRpcThreadpool. + ::android::hardware::joinRpcThreadpool(); + return 1; // joinRpcThreadpool should never return +} From de91ea30a98311f3c1e808ba25fba2981876b70e Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:45:37 +0800 Subject: [PATCH 28/35] gs-common: create bootctrl_hidl_1.2.mk and include related modules Bug: 265063384 Change-Id: I3895946309ff8ee7987c1b0ec0789e95a63f4eae Signed-off-by: Jason Chiu --- bootctrl/bootctrl_hidl_1.2.mk | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 bootctrl/bootctrl_hidl_1.2.mk diff --git a/bootctrl/bootctrl_hidl_1.2.mk b/bootctrl/bootctrl_hidl_1.2.mk new file mode 100644 index 0000000..7b0da0a --- /dev/null +++ b/bootctrl/bootctrl_hidl_1.2.mk @@ -0,0 +1,5 @@ +PRODUCT_PACKAGES += \ + android.hardware.boot@1.2-impl-pixel \ + android.hardware.boot@1.2-service-pixel + +PRODUCT_SOONG_NAMESPACES += device/google/gs-common/bootctrl/1.2 From f4d8fb7ad87375f225eae30bfa5f63fba042e03c Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 27 Nov 2023 16:50:17 +0800 Subject: [PATCH 29/35] gs-common: move sepolicy related to bootctrl hal hidl 1.2 to gs-common Bug: 265063384 Change-Id: I1981edd60a77e4c5aede8649c7b6bc5eacb676ee Signed-off-by: Jason Chiu --- bootctrl/bootctrl_hidl_1.2.mk | 1 + bootctrl/sepolicy/1.2/device.te | 5 +++++ bootctrl/sepolicy/1.2/file.te | 2 ++ bootctrl/sepolicy/1.2/file_contexts | 1 + bootctrl/sepolicy/1.2/hal_bootctl_default.te | 3 +++ 5 files changed, 12 insertions(+) create mode 100644 bootctrl/sepolicy/1.2/device.te create mode 100644 bootctrl/sepolicy/1.2/file.te create mode 100644 bootctrl/sepolicy/1.2/file_contexts create mode 100644 bootctrl/sepolicy/1.2/hal_bootctl_default.te diff --git a/bootctrl/bootctrl_hidl_1.2.mk b/bootctrl/bootctrl_hidl_1.2.mk index 7b0da0a..ef25066 100644 --- a/bootctrl/bootctrl_hidl_1.2.mk +++ b/bootctrl/bootctrl_hidl_1.2.mk @@ -3,3 +3,4 @@ PRODUCT_PACKAGES += \ android.hardware.boot@1.2-service-pixel PRODUCT_SOONG_NAMESPACES += device/google/gs-common/bootctrl/1.2 +BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/bootctrl/sepolicy/1.2 diff --git a/bootctrl/sepolicy/1.2/device.te b/bootctrl/sepolicy/1.2/device.te new file mode 100644 index 0000000..4fd0240 --- /dev/null +++ b/bootctrl/sepolicy/1.2/device.te @@ -0,0 +1,5 @@ +# devinfo block device +type devinfo_block_device, dev_type; + +# OTA +type sda_block_device, dev_type; diff --git a/bootctrl/sepolicy/1.2/file.te b/bootctrl/sepolicy/1.2/file.te new file mode 100644 index 0000000..5357fa9 --- /dev/null +++ b/bootctrl/sepolicy/1.2/file.te @@ -0,0 +1,2 @@ +# sysfs +type sysfs_ota, sysfs_type, fs_type; diff --git a/bootctrl/sepolicy/1.2/file_contexts b/bootctrl/sepolicy/1.2/file_contexts new file mode 100644 index 0000000..c456356 --- /dev/null +++ b/bootctrl/sepolicy/1.2/file_contexts @@ -0,0 +1 @@ +/vendor/bin/hw/android\.hardware\.boot@1\.2-service-pixel u:object_r:hal_bootctl_default_exec:s0 diff --git a/bootctrl/sepolicy/1.2/hal_bootctl_default.te b/bootctrl/sepolicy/1.2/hal_bootctl_default.te new file mode 100644 index 0000000..fe017f9 --- /dev/null +++ b/bootctrl/sepolicy/1.2/hal_bootctl_default.te @@ -0,0 +1,3 @@ +allow hal_bootctl_default devinfo_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sda_block_device:blk_file rw_file_perms; +allow hal_bootctl_default sysfs_ota:file rw_file_perms; From 2a201a74c221ed6bf4adf597d7437b3a724a3898 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Sat, 25 Nov 2023 02:53:02 +0800 Subject: [PATCH 30/35] gs-common: bootctrl: check both properties in setActiveBootSlot properties: ro.boot.bootdevice, ro.boot.boot_devices Bug: 313092597 Change-Id: Ib158c2b2aadf87b2155c4c268264f06bc659b544 Signed-off-by: Jason Chiu --- bootctrl/1.2/BootControl.cpp | 8 ++++++-- bootctrl/aidl/BootControl.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bootctrl/1.2/BootControl.cpp b/bootctrl/1.2/BootControl.cpp index 7782075..4e72805 100644 --- a/bootctrl/1.2/BootControl.cpp +++ b/bootctrl/1.2/BootControl.cpp @@ -345,8 +345,12 @@ Return BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb char boot_dev[PROPERTY_VALUE_MAX]; property_get("ro.boot.bootdevice", boot_dev, ""); if (boot_dev[0] == '\0') { - _hidl_cb({false, "invalid ro.boot.bootdevice prop"}); - return Void(); + ALOGI("failed to get ro.boot.bootdevice. try ro.boot.boot_devices\n"); + property_get("ro.boot.boot_devices", boot_dev, ""); + if (boot_dev[0] == '\0') { + _hidl_cb({false, "invalid ro.boot.bootdevice and ro.boot.boot_devices prop"}); + return Void(); + } } std::string boot_lun_path = diff --git a/bootctrl/aidl/BootControl.cpp b/bootctrl/aidl/BootControl.cpp index 941b0d2..0221514 100644 --- a/bootctrl/aidl/BootControl.cpp +++ b/bootctrl/aidl/BootControl.cpp @@ -461,8 +461,12 @@ ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) { char boot_dev[PROPERTY_VALUE_MAX]; property_get("ro.boot.bootdevice", boot_dev, ""); if (boot_dev[0] == '\0') { - return ScopedAStatus::fromServiceSpecificErrorWithMessage( - COMMAND_FAILED, "invalid ro.boot.bootdevice prop"); + ALOGI("failed to get ro.boot.bootdevice. try ro.boot.boot_devices\n"); + property_get("ro.boot.boot_devices", boot_dev, ""); + if (boot_dev[0] == '\0') { + return ScopedAStatus::fromServiceSpecificErrorWithMessage( + COMMAND_FAILED, "invalid ro.boot.bootdevice and ro.boot.boot_devices prop"); + } } std::string boot_lun_path = From ec2a9a0c7ac5d981862093b47be2d24c36518ecd Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 30 Nov 2023 22:25:57 +0800 Subject: [PATCH 31/35] gs-common: bootctrl: integrate blowAR() for gs101 & zuma Common bootcontrol use zuma version for the base, and blowAR() can't be used by gs101. So we need to port ag/18743149 into common bootcontrol. Bug: 313615120 Change-Id: I25febde96a56279e6592a6d7740be9a2e385543b Signed-off-by: Jason Chiu --- bootctrl/1.2/BootControl.cpp | 23 ++++++++++++++++++++++- bootctrl/aidl/BootControl.cpp | 22 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/bootctrl/1.2/BootControl.cpp b/bootctrl/1.2/BootControl.cpp index 4e72805..ff02013 100644 --- a/bootctrl/1.2/BootControl.cpp +++ b/bootctrl/1.2/BootControl.cpp @@ -50,6 +50,8 @@ namespace { #define BOOT_B_PATH "/dev/block/by-name/boot_b" #define DEVINFO_PATH "/dev/block/by-name/devinfo" +#define BLOW_AR_PATH "/sys/kernel/boot_control/blow_ar" + // slot flags #define AB_ATTR_PRIORITY_SHIFT 52 #define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) @@ -230,7 +232,7 @@ static int blow_otp_AR(bool secure) { return 0; } -static bool blowAR() { +static bool blowAR_zuma() { int ret = blow_otp_AR(true); if (ret) { ALOGI("Blow secure anti-rollback OTP failed"); @@ -245,6 +247,25 @@ static bool blowAR() { return true; } + +static bool blowAR_gs101() { + android::base::unique_fd fd(open(BLOW_AR_PATH, O_WRONLY | O_DSYNC)); + return android::base::WriteStringToFd("1", fd); +} + +static bool blowAR() { + char platform[PROPERTY_VALUE_MAX]; + property_get("ro.boot.hardware.platform", platform, ""); + + if (std::string(platform) == "gs101") { + return blowAR_gs101(); + } else if (std::string(platform) == "gs201" || std::string(platform) == "zuma") { + return blowAR_zuma(); + } + + return true; +} + } // namespace // Methods from ::android::hardware::boot::V1_0::IBootControl follow. diff --git a/bootctrl/aidl/BootControl.cpp b/bootctrl/aidl/BootControl.cpp index 0221514..e771845 100644 --- a/bootctrl/aidl/BootControl.cpp +++ b/bootctrl/aidl/BootControl.cpp @@ -47,6 +47,8 @@ namespace { #define BOOT_B_PATH "/dev/block/by-name/boot_b" #define DEVINFO_PATH "/dev/block/by-name/devinfo" +#define BLOW_AR_PATH "/sys/kernel/boot_control/blow_ar" + // slot flags #define AB_ATTR_PRIORITY_SHIFT 52 #define AB_ATTR_PRIORITY_MASK (3UL << AB_ATTR_PRIORITY_SHIFT) @@ -227,7 +229,7 @@ static int blow_otp_AR(bool secure) { return 0; } -static bool blowAR() { +static bool blowAR_zuma() { int ret = blow_otp_AR(true); if (ret) { ALOGI("Blow secure anti-rollback OTP failed"); @@ -243,6 +245,24 @@ static bool blowAR() { return true; } +static bool blowAR_gs101() { + ::android::base::unique_fd fd(open(BLOW_AR_PATH, O_WRONLY | O_DSYNC)); + return ::android::base::WriteStringToFd("1", fd); +} + +static bool blowAR() { + char platform[PROPERTY_VALUE_MAX]; + property_get("ro.boot.hardware.platform", platform, ""); + + if (std::string(platform) == "gs101") { + return blowAR_gs101(); + } else if (std::string(platform) == "gs201" || std::string(platform) == "zuma") { + return blowAR_zuma(); + } + + return true; +} + static constexpr MergeStatus ToAIDLMergeStatus(HIDLMergeStatus status) { switch (status) { case HIDLMergeStatus::NONE: From cf1faabf1a67fe1e78495e3a6e8c63a08fb5350d Mon Sep 17 00:00:00 2001 From: Raja Ramachandran Date: Wed, 6 Dec 2023 11:18:50 +0800 Subject: [PATCH 32/35] [GABC][FATP] Added ProtoCalibGenerator to PRODUCT_PACKAGES_DEBUG Bug: 284103045 Test: lunch -userdebug && m Change-Id: I4f7f512b6fa6bd5d9aabf998588dc9ad4f54c600 --- camera/lyric.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/camera/lyric.mk b/camera/lyric.mk index b9583ea..e3feab3 100644 --- a/camera/lyric.mk +++ b/camera/lyric.mk @@ -37,6 +37,7 @@ PRODUCT_SOONG_NAMESPACES += \ # Calibration tool for debug builds PRODUCT_PACKAGES_DEBUG += tarasque_test +PRODUCT_PACKAGES_DEBUG += ProtoCalibGenerator endif # vendor/google/camera check From de7a0d5160e8201bd3da2ca0e8452c6c52d74c40 Mon Sep 17 00:00:00 2001 From: Darren Hsu Date: Tue, 12 Dec 2023 23:11:24 +0800 Subject: [PATCH 33/35] powerstats: introduce TpuDvfsStateResidencyDataProvider Bug: 310094590 Test: vts-tradefed run vts -m VtsHalPowerStatsTargetTest Change-Id: Ib09e12bbfd45611e6f98822435b43752d53d7bb0 Signed-off-by: Darren Hsu --- .../TpuDvfsStateResidencyDataProvider.cpp | 105 ++++++++++++++++++ .../TpuDvfsStateResidencyDataProvider.h | 53 +++++++++ 2 files changed, 158 insertions(+) create mode 100644 powerstats/TpuDvfsStateResidencyDataProvider.cpp create mode 100644 powerstats/include/TpuDvfsStateResidencyDataProvider.h diff --git a/powerstats/TpuDvfsStateResidencyDataProvider.cpp b/powerstats/TpuDvfsStateResidencyDataProvider.cpp new file mode 100644 index 0000000..e1ce56c --- /dev/null +++ b/powerstats/TpuDvfsStateResidencyDataProvider.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2023 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 "TpuDvfsStateResidencyDataProvider.h" + +#include + +static const std::string ENTITY_NAME = "TPU-DVFS"; + +namespace aidl { +namespace android { +namespace hardware { +namespace power { +namespace stats { + +TpuDvfsStateResidencyDataProvider::TpuDvfsStateResidencyDataProvider( + const std::string& path, + std::vector frequencies, + uint64_t clockRate) + : mPath(path), mFrequencies(std::move(frequencies)), mClockRate(clockRate) {} + +bool TpuDvfsStateResidencyDataProvider::getStateResidencies( + std::unordered_map> *residencies) { + // Using FILE* instead of std::ifstream for performance reasons + std::unique_ptr fp(fopen(mPath.c_str(), "r"), fclose); + if (!fp) { + PLOG(ERROR) << "Failed to open file " << mPath; + return false; + } + + std::vector stateResidencies; + for (int i = 0; i < mFrequencies.size(); i++) { + StateResidency s = {.id = i, .totalTimeInStateMs = 0}; + stateResidencies.push_back(s); + } + + char *line = nullptr; + size_t len = 0; + std::istringstream ssLine; + std::string split; + int32_t lineIdx = 0; + std::vector stateIdxMap; + int32_t colIdx; + std::vector::const_iterator found; + while (getline(&line, &len, fp.get()) != -1) { + ssLine.clear(); + ssLine.str(line); + colIdx = 0; + for (std::string split; std::getline(ssLine, split, ' ');) { + // Skip first column + if (split.find(':') != std::string::npos) + continue; + + if (lineIdx == 0) { + // Build the state index map by first row + split.erase(split.find_last_not_of(" \n\r\t") + 1); + found = std::find(mFrequencies.begin(), mFrequencies.end(), split); + if (found != mFrequencies.end()) { + stateIdxMap.push_back(found - mFrequencies.begin()); + } else { + PLOG(ERROR) << "TPU frequency " << split << " is not found in " << mPath; + stateIdxMap.push_back(0); + } + } else { + // Add up time in frequency per uid + stateResidencies[stateIdxMap[colIdx]].totalTimeInStateMs += + std::atoll(split.c_str()) / mClockRate; + } + colIdx++; + } + lineIdx++; + } + + residencies->emplace(ENTITY_NAME, stateResidencies); + return true; +} + +std::unordered_map> TpuDvfsStateResidencyDataProvider::getInfo() { + std::vector states; + for (int32_t id = 0; id < mFrequencies.size(); id++) { + State s = + {.id = id, .name = std::to_string(std::atol(mFrequencies[id].c_str()) / 1000) + "MHz"}; + states.push_back(s); + } + + return {{ENTITY_NAME, states}}; +} + +} // namespace stats +} // namespace power +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/powerstats/include/TpuDvfsStateResidencyDataProvider.h b/powerstats/include/TpuDvfsStateResidencyDataProvider.h new file mode 100644 index 0000000..9ce3bd3 --- /dev/null +++ b/powerstats/include/TpuDvfsStateResidencyDataProvider.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 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 + +namespace aidl { +namespace android { +namespace hardware { +namespace power { +namespace stats { + +class TpuDvfsStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider { + public: + TpuDvfsStateResidencyDataProvider( + const std::string& path, std::vector frequencies, uint64_t clockRate); + ~TpuDvfsStateResidencyDataProvider() = default; + + /* + * See IStateResidencyDataProvider::getStateResidencies + */ + bool getStateResidencies( + std::unordered_map> *residencies) override; + + /* + * See IStateResidencyDataProvider::getInfo + */ + std::unordered_map> getInfo() override; + + private: + const std::string mPath; + const std::vector mFrequencies; + const uint64_t mClockRate; +}; + +} // namespace stats +} // namespace power +} // namespace hardware +} // namespace android +} // namespace aidl From 71767237dea8c68f83b73c29b8770902c95af3f3 Mon Sep 17 00:00:00 2001 From: Ken Lin Date: Mon, 11 Dec 2023 07:37:14 +0000 Subject: [PATCH 34/35] dumpstate: add logbuffer support for display Add logbuffer support for display driver to dump DSI cmd Bug: 291441544 Test: adb root; adb shell dumpsys android.hardware.dumpstate.IDumpstateDevice/default dump_display_logbuffer Change-Id: I0c40fa9836851caa5b02528888153bd82e3a9d75 Signed-off-by: Ken Lin --- display_logbuffer/Android.bp | 19 +++++++++++ display_logbuffer/dump.mk | 3 ++ display_logbuffer/dump_display_logbuffer.cpp | 32 +++++++++++++++++++ display_logbuffer/init.display_logbuffer.rc | 3 ++ display_logbuffer/sepolicy/device.te | 1 + .../sepolicy/dump_display_logbuffer.te | 3 ++ display_logbuffer/sepolicy/file_contexts | 4 +++ 7 files changed, 65 insertions(+) create mode 100644 display_logbuffer/Android.bp create mode 100644 display_logbuffer/dump.mk create mode 100644 display_logbuffer/dump_display_logbuffer.cpp create mode 100644 display_logbuffer/init.display_logbuffer.rc create mode 100644 display_logbuffer/sepolicy/device.te create mode 100644 display_logbuffer/sepolicy/dump_display_logbuffer.te create mode 100644 display_logbuffer/sepolicy/file_contexts diff --git a/display_logbuffer/Android.bp b/display_logbuffer/Android.bp new file mode 100644 index 0000000..e2859d9 --- /dev/null +++ b/display_logbuffer/Android.bp @@ -0,0 +1,19 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +cc_binary { + name: "dump_display_logbuffer", + srcs: ["dump_display_logbuffer.cpp"], + init_rc: ["init.display_logbuffer.rc"], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + shared_libs: [ + "libdump", + ], + vendor: true, + relative_install_path: "dump", +} diff --git a/display_logbuffer/dump.mk b/display_logbuffer/dump.mk new file mode 100644 index 0000000..9808c1d --- /dev/null +++ b/display_logbuffer/dump.mk @@ -0,0 +1,3 @@ +BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/display_logbuffer/sepolicy + +PRODUCT_PACKAGES += dump_display_logbuffer diff --git a/display_logbuffer/dump_display_logbuffer.cpp b/display_logbuffer/dump_display_logbuffer.cpp new file mode 100644 index 0000000..7477c8c --- /dev/null +++ b/display_logbuffer/dump_display_logbuffer.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 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. + */ +#include +#include + +const char* logbuffer_paths[][2] = { + {"DSIM0", "/dev/logbuffer_dsim0"}, + {"DSIM1", "/dev/logbuffer_dsim1"}, +}; + +int main() { + for (auto &logbuffer_path : logbuffer_paths) { + if(!access(logbuffer_path[1], R_OK)) { + dumpFileContent(logbuffer_path[0], logbuffer_path[1]); + } + } + + return 0; +} \ No newline at end of file diff --git a/display_logbuffer/init.display_logbuffer.rc b/display_logbuffer/init.display_logbuffer.rc new file mode 100644 index 0000000..2a39ce3 --- /dev/null +++ b/display_logbuffer/init.display_logbuffer.rc @@ -0,0 +1,3 @@ +on property:ro.build.type=userdebug + chown system system /dev/logbuffer_dsim0 + chown system system /dev/logbuffer_dsim1 diff --git a/display_logbuffer/sepolicy/device.te b/display_logbuffer/sepolicy/device.te new file mode 100644 index 0000000..94432f4 --- /dev/null +++ b/display_logbuffer/sepolicy/device.te @@ -0,0 +1 @@ +type display_log_device, dev_type; \ No newline at end of file diff --git a/display_logbuffer/sepolicy/dump_display_logbuffer.te b/display_logbuffer/sepolicy/dump_display_logbuffer.te new file mode 100644 index 0000000..34da48c --- /dev/null +++ b/display_logbuffer/sepolicy/dump_display_logbuffer.te @@ -0,0 +1,3 @@ +pixel_bugreport(dump_display_logbuffer) + +allow dump_display_logbuffer display_log_device:chr_file r_file_perms; \ No newline at end of file diff --git a/display_logbuffer/sepolicy/file_contexts b/display_logbuffer/sepolicy/file_contexts new file mode 100644 index 0000000..7425214 --- /dev/null +++ b/display_logbuffer/sepolicy/file_contexts @@ -0,0 +1,4 @@ +/vendor/bin/dump/dump_display_logbuffer u:object_r:dump_display_logbuffer_exec:s0 + +/dev/logbuffer_dsim0 u:object_r:display_log_device:s0 +/dev/logbuffer_dsim1 u:object_r:display_log_device:s0 From 6461e334288c6b397ff3d422d347eccf8d791417 Mon Sep 17 00:00:00 2001 From: Alex Iacobucci Date: Wed, 13 Dec 2023 19:22:28 +0000 Subject: [PATCH 35/35] aoc: add policy to read system property Solves error: 1 2-13 18:33:15.860000 root 1019 1019 I auditd : type=1400 audit(0.0:7): avc: denied { read } for comm="aocd" name="u:object_r:vendor_rild_prop:s0" dev="tmpfs" ino=404 scontext=u:r:aocd:s0 tcontext=u:object_r:vendor_rild_prop:s0 tclass=file permissive=0 Test: on device Bug: 207711097 Change-Id: Ia28e1622746cca973ca66f437e0e655bbcaf7d66 Signed-off-by: Alex Iacobucci --- aoc/sepolicy/aocd.te | 3 ++- aoc/sepolicy/property.te | 3 ++- aoc/sepolicy/property_contexts | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/aoc/sepolicy/aocd.te b/aoc/sepolicy/aocd.te index b2bfd13..464e46b 100644 --- a/aoc/sepolicy/aocd.te +++ b/aoc/sepolicy/aocd.te @@ -20,4 +20,5 @@ allow aocd device:dir r_dir_perms; # set properties set_prop(aocd, vendor_aoc_prop) -set_prop(aocd, vendor_timeout_aoc_prop) \ No newline at end of file +set_prop(aocd, vendor_timeout_aoc_prop) +get_prop(aocd, vendor_volte_mif_off) \ No newline at end of file diff --git a/aoc/sepolicy/property.te b/aoc/sepolicy/property.te index c2f5695..e6d715b 100644 --- a/aoc/sepolicy/property.te +++ b/aoc/sepolicy/property.te @@ -1,3 +1,4 @@ # AoC vendor_internal_prop(vendor_aoc_prop) -vendor_internal_prop(vendor_timeout_aoc_prop) \ No newline at end of file +vendor_internal_prop(vendor_timeout_aoc_prop) +vendor_internal_prop(vendor_volte_mif_off) diff --git a/aoc/sepolicy/property_contexts b/aoc/sepolicy/property_contexts index 3c2acb6..475272a 100644 --- a/aoc/sepolicy/property_contexts +++ b/aoc/sepolicy/property_contexts @@ -1,3 +1,4 @@ # AoC vendor.aoc.firmware.version u:object_r:vendor_aoc_prop:s0 -persist.vendor.aoc.status_request_timed_out u:object_r:vendor_timeout_aoc_prop:s0 \ No newline at end of file +persist.vendor.aoc.status_request_timed_out u:object_r:vendor_timeout_aoc_prop:s0 +persist.vendor.radio.volte_mif_off u:object_r:vendor_volte_mif_off:s0 \ No newline at end of file