From 5954a237cb085f710c02c8ba938d1eb6d562aed1 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 8 Apr 2019 09:53:18 -0700 Subject: Import translations. DO NOT MERGE Change-Id: I6aff7f01df0c28775a2dbef26ee3476cb5d83060 Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/recovery_l10n/res/values-ja/strings.xml b/tools/recovery_l10n/res/values-ja/strings.xml index 3d6637278..2d6c0abc4 100644 --- a/tools/recovery_l10n/res/values-ja/strings.xml +++ b/tools/recovery_l10n/res/values-ja/strings.xml @@ -6,7 +6,7 @@ "コマンドが指定されていません" "エラーが発生しました。" "セキュリティ アップデートをインストールしています" - "Android システムを読み込めません。データが破損している可能性があります。このメッセージが引き続き表示される場合は、データの初期化を行い、この端末に保存されているすべてのユーザー データを消去することが必要な場合があります。" + "Android システムを読み込めません。データが破損している可能性があります。このメッセージが引き続き表示される場合は、データの初期化を行い、このデバイスに保存されているすべてのユーザー データを消去することが必要な場合があります。" "再試行" "データの初期化" "すべてのユーザー データをワイプしますか?\n\nこの操作は元に戻せません。" -- cgit v1.2.3 From 79c5fb32e8b6eb74dfa64a4f9650ce4fb4034a9c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 11 Apr 2019 16:52:41 -0700 Subject: Import translations. DO NOT MERGE Change-Id: I87585a82fccf625bc05c5805fc90459d572cee10 Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-gl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/recovery_l10n/res/values-gl/strings.xml b/tools/recovery_l10n/res/values-gl/strings.xml index e51b36dfb..e6f2ffd84 100644 --- a/tools/recovery_l10n/res/values-gl/strings.xml +++ b/tools/recovery_l10n/res/values-gl/strings.xml @@ -6,9 +6,9 @@ "Non hai ningún comando" "Erro" "Instalando actualización de seguranza" - "Non se puido cargar o sistema Android. Os teus datos poden estar danados. Se segue aparecendo esta mensaxe, pode ser necesario restablecer os datos de fábrica e borrar todos os datos de usuario almacenados neste dispositivo." + "Non se puido cargar o sistema Android. Os teus datos poden estar danados. Se segue aparecendo esta mensaxe, pode ser necesario restablecer os datos de fábrica e borrar todos os datos do usuario almacenados neste dispositivo." "Tentar de novo" "Restablecemento dos datos de fábrica" - "Queres borrar todos os datos de usuario?\n\n ESTA ACCIÓN NON SE PODE DESFACER." + "Queres borrar todos os datos do usuario?\n\n ESTA ACCIÓN NON SE PODE DESFACER." "Cancelar" -- cgit v1.2.3 From 84efc1ba7d7c2b4cdbc8dc7b154476cd7b50ea40 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 9 May 2019 17:26:20 -0700 Subject: Import translations. DO NOT MERGE Change-Id: Ia35cdac295a1ce6f8b53638c908c0caf2a97477c Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-in/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/recovery_l10n/res/values-in/strings.xml b/tools/recovery_l10n/res/values-in/strings.xml index 15a78ec48..43c9deb94 100644 --- a/tools/recovery_l10n/res/values-in/strings.xml +++ b/tools/recovery_l10n/res/values-in/strings.xml @@ -9,6 +9,6 @@ "Tidak dapat memuat sistem Android. Data Anda mungkin rusak. Jika terus mendapatkan pesan ini, Anda mungkin perlu melakukan reset ke setelan pabrik dan menghapus semua data pengguna yang disimpan di perangkat ini." "Coba lagi" "Reset ke setelan pabrik" - "Wipe semua data pengguna?\n\n TINDAKAN INI TIDAK DAPAT DIURUNGKAN!" + "Hapus total semua data pengguna?\n\n TINDAKAN INI TIDAK DAPAT DIURUNGKAN!" "Batal" -- cgit v1.2.3 From 58a27693b22da9b93c634d053a53deb4c4a71e4e Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Tue, 6 Aug 2019 12:32:05 -0700 Subject: Force package installation with FUSE unless the package stores on device The non-A/B package installation is subject to TOC/TOU flaw if the attacker can switch the package in the middle of installation. And the most pratical case is to store the package on an external device, e.g. a sdcard, and swap the device in the middle. To prevent that, we can adopt the same protection as used in sideloading a package with FUSE. Specifically, when we install the package with FUSE, we read the entire package to cryptographically verify its signature. The hash for each transfer block is recorded in the memory (TOC), and the subsequent reads (TOU) will be rejected upon dectecting a mismatch. This CL forces the package installation with FUSE when the package stays on a removable media. Bug: 136498130 Test: Run bin/recovery --update_package with various paths; and packages are installed from FUSE as expected Change-Id: Ibc9b095036a2fa624e8edf6c347ed4f12aef072f --- Android.bp | 1 + install/include/install/install.h | 4 ++++ install/install.cpp | 47 +++++++++++++++++++++++++++++++++++++++ recovery.cpp | 12 +++++----- tests/Android.bp | 1 + tests/unit/install_test.cpp | 28 +++++++++++++++++++++++ 6 files changed, 86 insertions(+), 7 deletions(-) diff --git a/Android.bp b/Android.bp index 0759e08d1..a9a08a1a9 100644 --- a/Android.bp +++ b/Android.bp @@ -69,6 +69,7 @@ cc_defaults { ], static_libs: [ + "libc++fs", "libinstall", "librecovery_fastboot", "libminui", diff --git a/install/include/install/install.h b/install/include/install/install.h index b4b3a9149..c3331c8bf 100644 --- a/install/include/install/install.h +++ b/install/include/install/install.h @@ -67,3 +67,7 @@ bool verify_package_compatibility(ZipArchiveHandle package_zip); // pre-device and serial number (if presents). A/B OTA specific checks: pre-build version, // fingerprint, timestamp. bool CheckPackageMetadata(const std::map& metadata, OtaType ota_type); + +// Ensures the path to the update package is mounted. Also set the |should_use_fuse| to true if the +// package stays on a removable media. +bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse); diff --git a/install/install.cpp b/install/install.cpp index 9166f9cfb..43916b3d8 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -722,3 +723,49 @@ bool verify_package(Package* package, RecoveryUI* ui) { } return true; } + +bool SetupPackageMount(const std::string& package_path, bool* should_use_fuse) { + CHECK(should_use_fuse != nullptr); + + if (package_path.empty()) { + return false; + } + + *should_use_fuse = true; + if (package_path[0] == '@') { + auto block_map_path = package_path.substr(1); + if (ensure_path_mounted(block_map_path) != 0) { + LOG(ERROR) << "Failed to mount " << block_map_path; + return false; + } + // uncrypt only produces block map only if the package stays on /data. + *should_use_fuse = false; + return true; + } + + // Package is not a block map file. + if (ensure_path_mounted(package_path) != 0) { + LOG(ERROR) << "Failed to mount " << package_path; + return false; + } + + // Reject the package if the input path doesn't equal the canonicalized path. + // e.g. /cache/../sdcard/update_package. + std::error_code ec; + auto canonical_path = std::filesystem::canonical(package_path, ec); + if (ec) { + LOG(ERROR) << "Failed to get canonical of " << package_path << ", " << ec.message(); + return false; + } + if (canonical_path.string() != package_path) { + LOG(ERROR) << "Installation aborts. The canonical path " << canonical_path.string() + << " doesn't equal the original path " << package_path; + return false; + } + + constexpr const char* CACHE_ROOT = "/cache"; + if (android::base::StartsWith(package_path, CACHE_ROOT)) { + *should_use_fuse = false; + } + return true; +} diff --git a/recovery.cpp b/recovery.cpp index 682ddbc4c..8f8f7dc02 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -733,13 +733,11 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector& file_map, int fd, int compression_type) { @@ -595,3 +596,30 @@ TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) { "\n"); TestCheckPackageMetadata(metadata, OtaType::AB, true); } + +TEST(InstallTest, SetupPackageMount_package_path) { + load_volume_table(); + bool install_with_fuse; + + // Setup should fail if the input path doesn't exist. + ASSERT_FALSE(SetupPackageMount("/does_not_exist", &install_with_fuse)); + + // Package should be installed with fuse if it's not in /cache. + TemporaryDir temp_dir; + TemporaryFile update_package(temp_dir.path); + ASSERT_TRUE(SetupPackageMount(update_package.path, &install_with_fuse)); + ASSERT_TRUE(install_with_fuse); + + // Setup should fail if the input path isn't canonicalized. + std::string uncanonical_package_path = android::base::Join( + std::vector{ + temp_dir.path, + "..", + android::base::Basename(temp_dir.path), + android::base::Basename(update_package.path), + }, + '/'); + + ASSERT_EQ(0, access(uncanonical_package_path.c_str(), R_OK)); + ASSERT_FALSE(SetupPackageMount(uncanonical_package_path, &install_with_fuse)); +} -- cgit v1.2.3 From 23f15ec2f26dc5e3d27f8b44cb1a12167d33033e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 21 Jan 2020 09:03:54 -0800 Subject: Import translations. DO NOT MERGE Change-Id: Ie0e80dec4c698c6c6fbf5edd7a434bdcad975951 Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-ky/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/recovery_l10n/res/values-ky/strings.xml b/tools/recovery_l10n/res/values-ky/strings.xml index 1cd69ea84..837cf7d68 100644 --- a/tools/recovery_l10n/res/values-ky/strings.xml +++ b/tools/recovery_l10n/res/values-ky/strings.xml @@ -6,7 +6,7 @@ "Буйрук берилген жок" "Ката!" "Коопсуздук жаңыртуусу орнотулууда" - "Android тутуму жүктөлбөй жатат. Дайындарыңыз бузук болушу мүмкүн. Бул билдирүү дагы деле келе берсе, түзмөктү кайра башынан жөндөп, анда сакталган бардык колдонуучу дайындарын тазалашыңыз керек." + "Android тутуму жүктөлбөй жатат. Дайын-даректериңиз бузук болушу мүмкүн. Бул билдирүү дагы деле келе берсе, түзмөктү кайра башынан жөндөп, анда сакталган бардык колдонуучу дайындарын тазалашыңыз керек." "Кайталоо" "Кайра башынан жөндөө" "Колдонуучу дайындарынын баары жашырылсынбы?\n\n МУНУ АРТКА КАЙТАРУУ МҮМКҮН ЭМЕС!" -- cgit v1.2.3 From 2b9be1f4e385d74de0cc8a0d50ae8d9e9ecd21e4 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 29 Jan 2020 15:36:57 -0800 Subject: Import translations. DO NOT MERGE Change-Id: Id8dd55dd5f36191402ba7f6b44e107f205fbf484 Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml index 2af36d64a..a9cd2d133 100644 --- a/tools/recovery_l10n/res/values-ar/strings.xml +++ b/tools/recovery_l10n/res/values-ar/strings.xml @@ -6,9 +6,9 @@ "ليس هناك أي أمر" "خطأ!" "جارٍ تثبيت تحديث الأمان" - "‏يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط بحسب بيانات المصنع ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز." + "‏يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط على الإعدادات الأصلية ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز." "إعادة المحاولة" - "إعادة الضبط بحسب بيانات المصنع" + "إعادة الضبط على الإعدادات الأصلية" "هل تريد حجب كل بيانات المستخدم؟\n\n لا يمكن التراجع عن هذا الإجراء." "إلغاء" -- cgit v1.2.3 From f5fab11115e07c72e3e7213f5b2bf558f40dbc76 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 18 Feb 2020 06:57:16 -0800 Subject: Import translations. DO NOT MERGE Change-Id: I6b85744c59986965ca016e613974661568b0d182 Auto-generated-cl: translation import --- tools/recovery_l10n/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml index a9cd2d133..69191287d 100644 --- a/tools/recovery_l10n/res/values-ar/strings.xml +++ b/tools/recovery_l10n/res/values-ar/strings.xml @@ -1,11 +1,11 @@ - "جارٍ تثبيت تحديث النظام" + "جارٍ تثبيت إعادة تحميل النظام" "جارٍ محو البيانات" "ليس هناك أي أمر" "خطأ!" - "جارٍ تثبيت تحديث الأمان" + "جارٍ تثبيت إعادة تحميل الأمان" "‏يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط على الإعدادات الأصلية ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز." "إعادة المحاولة" "إعادة الضبط على الإعدادات الأصلية" -- cgit v1.2.3 From 9c8d0f61037307b5f3478fc73a1538d2a0d5885e Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 16 Dec 2019 16:07:27 -0800 Subject: Move libboot_control to boot_control 1.1 It should belong to the default /misc implementation of boot control 1.1. Right now, it's only used by cuttlefish. So move it over to reduce confusion in bootloader_message. Bug: 131775112 Test: build Change-Id: If09bc6f4cc8adf74c8798048c8e54ec94566abaa (cherry picked from commit dc4d2a70db40a302cb7001ddbc41816e7187d5c5) --- boot_control/Android.bp | 61 --- .../include/libboot_control/libboot_control.h | 89 ----- boot_control/legacy_boot_control.cpp | 115 ------ boot_control/libboot_control.cpp | 424 --------------------- .../bootloader_message/bootloader_message.h | 102 ----- 5 files changed, 791 deletions(-) delete mode 100644 boot_control/Android.bp delete mode 100644 boot_control/include/libboot_control/libboot_control.h delete mode 100644 boot_control/legacy_boot_control.cpp delete mode 100644 boot_control/libboot_control.cpp diff --git a/boot_control/Android.bp b/boot_control/Android.bp deleted file mode 100644 index b2e68dfd4..000000000 --- a/boot_control/Android.bp +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -cc_defaults { - name: "libboot_control_defaults", - vendor: true, - recovery_available: true, - relative_install_path: "hw", - - cflags: [ - "-D_FILE_OFFSET_BITS=64", - "-Werror", - "-Wall", - "-Wextra", - ], - - shared_libs: [ - "android.hardware.boot@1.1", - "libbase", - "liblog", - ], - static_libs: [ - "libbootloader_message_vendor", - "libfstab", - ], -} - -cc_library_static { - name: "libboot_control", - defaults: ["libboot_control_defaults"], - export_include_dirs: ["include"], - - srcs: ["libboot_control.cpp"], -} - -cc_library_shared { - name: "bootctrl.default", - defaults: ["libboot_control_defaults"], - - srcs: ["legacy_boot_control.cpp"], - - static_libs: [ - "libboot_control", - ], - shared_libs: [ - "libhardware", - ], -} diff --git a/boot_control/include/libboot_control/libboot_control.h b/boot_control/include/libboot_control/libboot_control.h deleted file mode 100644 index 546865887..000000000 --- a/boot_control/include/libboot_control/libboot_control.h +++ /dev/null @@ -1,89 +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 - -namespace android { -namespace bootable { - -// Helper library to implement the IBootControl HAL using the misc partition. -class BootControl { - using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus; - - public: - bool Init(); - unsigned int GetNumberSlots(); - unsigned int GetCurrentSlot(); - bool MarkBootSuccessful(); - bool SetActiveBootSlot(unsigned int slot); - bool SetSlotAsUnbootable(unsigned int slot); - bool SetSlotBootable(unsigned int slot); - bool IsSlotBootable(unsigned int slot); - const char* GetSuffix(unsigned int slot); - bool IsSlotMarkedSuccessful(unsigned int slot); - bool SetSnapshotMergeStatus(MergeStatus status); - MergeStatus GetSnapshotMergeStatus(); - - bool IsValidSlot(unsigned int slot); - - const std::string& misc_device() const { - return misc_device_; - } - - private: - // Whether this object was initialized with data from the bootloader message - // that doesn't change until next reboot. - bool initialized_ = false; - - // The path to the misc_device as reported in the fstab. - std::string misc_device_; - - // The number of slots present on the device. - unsigned int num_slots_ = 0; - - // The slot where we are running from. - unsigned int current_slot_ = 0; -}; - -// Helper functions to write the Virtual A/B merge status message. These are -// separate because BootControl uses bootloader_control_ab in vendor space, -// whereas the Virtual A/B merge status is in system space. A HAL might not -// use bootloader_control_ab, but may want to use the AOSP method of maintaining -// the merge status. - -// If the Virtual A/B message has not yet been initialized, then initialize it. -// This should be called when the BootControl HAL first loads. -// -// If the Virtual A/B message in misc was already initialized, true is returned. -// If initialization was attempted, but failed, false is returned, and the HAL -// should fail to load. -bool InitMiscVirtualAbMessageIfNeeded(); - -// Save the current merge status as well as the current slot. -bool SetMiscVirtualAbMergeStatus(unsigned int current_slot, - android::hardware::boot::V1_1::MergeStatus status); - -// Return the current merge status. If the saved status is SNAPSHOTTED but the -// slot hasn't changed, the status returned will be NONE. -bool GetMiscVirtualAbMergeStatus(unsigned int current_slot, - android::hardware::boot::V1_1::MergeStatus* status); - -} // namespace bootable -} // namespace android diff --git a/boot_control/legacy_boot_control.cpp b/boot_control/legacy_boot_control.cpp deleted file mode 100644 index 73d3a5841..000000000 --- a/boot_control/legacy_boot_control.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2015 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 -#include - -#include - -using android::bootable::BootControl; - -struct boot_control_private_t { - // The base struct needs to be first in the list. - boot_control_module_t base; - - BootControl impl; -}; - -namespace { - -void BootControl_init(boot_control_module_t* module) { - auto& impl = reinterpret_cast(module)->impl; - impl.Init(); -} - -unsigned int BootControl_getNumberSlots(boot_control_module_t* module) { - auto& impl = reinterpret_cast(module)->impl; - return impl.GetNumberSlots(); -} - -unsigned int BootControl_getCurrentSlot(boot_control_module_t* module) { - auto& impl = reinterpret_cast(module)->impl; - return impl.GetCurrentSlot(); -} - -int BootControl_markBootSuccessful(boot_control_module_t* module) { - auto& impl = reinterpret_cast(module)->impl; - return impl.MarkBootSuccessful() ? 0 : -1; -} - -int BootControl_setActiveBootSlot(boot_control_module_t* module, unsigned int slot) { - auto& impl = reinterpret_cast(module)->impl; - return impl.SetActiveBootSlot(slot) ? 0 : -1; -} - -int BootControl_setSlotAsUnbootable(struct boot_control_module* module, unsigned int slot) { - auto& impl = reinterpret_cast(module)->impl; - return impl.SetSlotAsUnbootable(slot) ? 0 : -1; -} - -int BootControl_isSlotBootable(struct boot_control_module* module, unsigned int slot) { - auto& impl = reinterpret_cast(module)->impl; - return impl.IsSlotBootable(slot) ? 0 : -1; -} - -int BootControl_isSlotMarkedSuccessful(struct boot_control_module* module, unsigned int slot) { - auto& impl = reinterpret_cast(module)->impl; - return impl.IsSlotMarkedSuccessful(slot) ? 0 : -1; -} - -const char* BootControl_getSuffix(boot_control_module_t* module, unsigned int slot) { - auto& impl = reinterpret_cast(module)->impl; - return impl.GetSuffix(slot); -} - -static int BootControl_open(const hw_module_t* module __unused, const char* id __unused, - hw_device_t** device __unused) { - /* Nothing to do currently. */ - return 0; -} - -struct hw_module_methods_t BootControl_methods = { - .open = BootControl_open, -}; - -} // namespace - -boot_control_private_t HAL_MODULE_INFO_SYM = { - .base = - { - .common = - { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = BOOT_CONTROL_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = BOOT_CONTROL_HARDWARE_MODULE_ID, - .name = "AOSP reference bootctrl HAL", - .author = "The Android Open Source Project", - .methods = &BootControl_methods, - }, - .init = BootControl_init, - .getNumberSlots = BootControl_getNumberSlots, - .getCurrentSlot = BootControl_getCurrentSlot, - .markBootSuccessful = BootControl_markBootSuccessful, - .setActiveBootSlot = BootControl_setActiveBootSlot, - .setSlotAsUnbootable = BootControl_setSlotAsUnbootable, - .isSlotBootable = BootControl_isSlotBootable, - .getSuffix = BootControl_getSuffix, - .isSlotMarkedSuccessful = BootControl_isSlotMarkedSuccessful, - }, -}; diff --git a/boot_control/libboot_control.cpp b/boot_control/libboot_control.cpp deleted file mode 100644 index ab9ce971b..000000000 --- a/boot_control/libboot_control.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 2015 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 -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -namespace android { -namespace bootable { - -using ::android::hardware::boot::V1_1::MergeStatus; - -// The number of boot attempts that should be made from a new slot before -// rolling back to the previous slot. -constexpr unsigned int kDefaultBootAttempts = 7; -static_assert(kDefaultBootAttempts < 8, "tries_remaining field only has 3 bits"); - -constexpr unsigned int kMaxNumSlots = - sizeof(bootloader_control::slot_info) / sizeof(bootloader_control::slot_info[0]); -constexpr const char* kSlotSuffixes[kMaxNumSlots] = { "_a", "_b", "_c", "_d" }; -constexpr off_t kBootloaderControlOffset = offsetof(bootloader_message_ab, slot_suffix); - -static uint32_t CRC32(const uint8_t* buf, size_t size) { - static uint32_t crc_table[256]; - - // Compute the CRC-32 table only once. - if (!crc_table[1]) { - for (uint32_t i = 0; i < 256; ++i) { - uint32_t crc = i; - for (uint32_t j = 0; j < 8; ++j) { - uint32_t mask = -(crc & 1); - crc = (crc >> 1) ^ (0xEDB88320 & mask); - } - crc_table[i] = crc; - } - } - - uint32_t ret = -1; - for (size_t i = 0; i < size; ++i) { - ret = (ret >> 8) ^ crc_table[(ret ^ buf[i]) & 0xFF]; - } - - return ~ret; -} - -// Return the little-endian representation of the CRC-32 of the first fields -// in |boot_ctrl| up to the crc32_le field. -uint32_t BootloaderControlLECRC(const bootloader_control* boot_ctrl) { - return htole32( - CRC32(reinterpret_cast(boot_ctrl), offsetof(bootloader_control, crc32_le))); -} - -bool LoadBootloaderControl(const std::string& misc_device, bootloader_control* buffer) { - android::base::unique_fd fd(open(misc_device.c_str(), O_RDONLY)); - if (fd.get() == -1) { - PLOG(ERROR) << "failed to open " << misc_device; - return false; - } - if (lseek(fd, kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) { - PLOG(ERROR) << "failed to lseek " << misc_device; - return false; - } - if (!android::base::ReadFully(fd.get(), buffer, sizeof(bootloader_control))) { - PLOG(ERROR) << "failed to read " << misc_device; - return false; - } - return true; -} - -bool UpdateAndSaveBootloaderControl(const std::string& misc_device, bootloader_control* buffer) { - buffer->crc32_le = BootloaderControlLECRC(buffer); - android::base::unique_fd fd(open(misc_device.c_str(), O_WRONLY | O_SYNC)); - if (fd.get() == -1) { - PLOG(ERROR) << "failed to open " << misc_device; - return false; - } - if (lseek(fd.get(), kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) { - PLOG(ERROR) << "failed to lseek " << misc_device; - return false; - } - if (!android::base::WriteFully(fd.get(), buffer, sizeof(bootloader_control))) { - PLOG(ERROR) << "failed to write " << misc_device; - return false; - } - return true; -} - -void InitDefaultBootloaderControl(BootControl* control, bootloader_control* boot_ctrl) { - memset(boot_ctrl, 0, sizeof(*boot_ctrl)); - - unsigned int current_slot = control->GetCurrentSlot(); - if (current_slot < kMaxNumSlots) { - strlcpy(boot_ctrl->slot_suffix, kSlotSuffixes[current_slot], sizeof(boot_ctrl->slot_suffix)); - } - boot_ctrl->magic = BOOT_CTRL_MAGIC; - boot_ctrl->version = BOOT_CTRL_VERSION; - - // Figure out the number of slots by checking if the partitions exist, - // otherwise assume the maximum supported by the header. - boot_ctrl->nb_slot = kMaxNumSlots; - std::string base_path = control->misc_device(); - size_t last_path_sep = base_path.rfind('/'); - if (last_path_sep != std::string::npos) { - // We test the existence of the "boot" partition on each possible slot, - // which is a partition required by Android Bootloader Requirements. - base_path = base_path.substr(0, last_path_sep + 1) + "boot"; - int last_existing_slot = -1; - int first_missing_slot = -1; - for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { - std::string partition_path = base_path + kSlotSuffixes[slot]; - struct stat part_stat; - int err = stat(partition_path.c_str(), &part_stat); - if (!err) { - last_existing_slot = slot; - LOG(INFO) << "Found slot: " << kSlotSuffixes[slot]; - } else if (err < 0 && errno == ENOENT && first_missing_slot == -1) { - first_missing_slot = slot; - } - } - // We only declare that we found the actual number of slots if we found all - // the boot partitions up to the number of slots, and no boot partition - // after that. Not finding any of the boot partitions implies a problem so - // we just leave the number of slots in the maximum value. - if ((last_existing_slot != -1 && last_existing_slot + 1 == first_missing_slot) || - (first_missing_slot == -1 && last_existing_slot + 1 == kMaxNumSlots)) { - boot_ctrl->nb_slot = last_existing_slot + 1; - LOG(INFO) << "Found a system with " << last_existing_slot + 1 << " slots."; - } - } - - for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { - slot_metadata entry = {}; - - if (slot < boot_ctrl->nb_slot) { - entry.priority = 7; - entry.tries_remaining = kDefaultBootAttempts; - entry.successful_boot = 0; - } else { - entry.priority = 0; // Unbootable - } - - // When the boot_control stored on disk is invalid, we assume that the - // current slot is successful. The bootloader should repair this situation - // before booting and write a valid boot_control slot, so if we reach this - // stage it means that the misc partition was corrupted since boot. - if (current_slot == slot) { - entry.successful_boot = 1; - } - - boot_ctrl->slot_info[slot] = entry; - } - boot_ctrl->recovery_tries_remaining = 0; - - boot_ctrl->crc32_le = BootloaderControlLECRC(boot_ctrl); -} - -// Return the index of the slot suffix passed or -1 if not a valid slot suffix. -int SlotSuffixToIndex(const char* suffix) { - for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) { - if (!strcmp(kSlotSuffixes[slot], suffix)) return slot; - } - return -1; -} - -// Initialize the boot_control_private struct with the information from -// the bootloader_message buffer stored in |boot_ctrl|. Returns whether the -// initialization succeeded. -bool BootControl::Init() { - if (initialized_) return true; - - // Initialize the current_slot from the read-only property. If the property - // was not set (from either the command line or the device tree), we can later - // initialize it from the bootloader_control struct. - std::string suffix_prop = android::base::GetProperty("ro.boot.slot_suffix", ""); - if (suffix_prop.empty()) { - LOG(ERROR) << "Slot suffix property is not set"; - return false; - } - current_slot_ = SlotSuffixToIndex(suffix_prop.c_str()); - - std::string err; - std::string device = get_bootloader_message_blk_device(&err); - if (device.empty()) { - LOG(ERROR) << "Could not find bootloader message block device: " << err; - return false; - } - - bootloader_control boot_ctrl; - if (!LoadBootloaderControl(device.c_str(), &boot_ctrl)) { - LOG(ERROR) << "Failed to load bootloader control block"; - return false; - } - - // Note that since there isn't a module unload function this memory is leaked. - // We use `device` below sometimes, so it's not moved out of here. - misc_device_ = device; - initialized_ = true; - - // Validate the loaded data, otherwise we will destroy it and re-initialize it - // with the current information. - uint32_t computed_crc32 = BootloaderControlLECRC(&boot_ctrl); - if (boot_ctrl.crc32_le != computed_crc32) { - LOG(WARNING) << "Invalid boot control found, expected CRC-32 0x" << std::hex << computed_crc32 - << " but found 0x" << std::hex << boot_ctrl.crc32_le << ". Re-initializing."; - InitDefaultBootloaderControl(this, &boot_ctrl); - UpdateAndSaveBootloaderControl(device.c_str(), &boot_ctrl); - } - - if (!InitMiscVirtualAbMessageIfNeeded()) { - return false; - } - - num_slots_ = boot_ctrl.nb_slot; - return true; -} - -unsigned int BootControl::GetNumberSlots() { - return num_slots_; -} - -unsigned int BootControl::GetCurrentSlot() { - return current_slot_; -} - -bool BootControl::MarkBootSuccessful() { - bootloader_control bootctrl; - if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false; - - bootctrl.slot_info[current_slot_].successful_boot = 1; - // tries_remaining == 0 means that the slot is not bootable anymore, make - // sure we mark the current slot as bootable if it succeeds in the last - // attempt. - bootctrl.slot_info[current_slot_].tries_remaining = 1; - return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl); -} - -bool BootControl::SetActiveBootSlot(unsigned int slot) { - if (slot >= kMaxNumSlots || slot >= num_slots_) { - // Invalid slot number. - return false; - } - - bootloader_control bootctrl; - if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false; - - // Set every other slot with a lower priority than the new "active" slot. - const unsigned int kActivePriority = 15; - const unsigned int kActiveTries = 6; - for (unsigned int i = 0; i < num_slots_; ++i) { - if (i != slot) { - if (bootctrl.slot_info[i].priority >= kActivePriority) - bootctrl.slot_info[i].priority = kActivePriority - 1; - } - } - - // Note that setting a slot as active doesn't change the successful bit. - // The successful bit will only be changed by setSlotAsUnbootable(). - bootctrl.slot_info[slot].priority = kActivePriority; - bootctrl.slot_info[slot].tries_remaining = kActiveTries; - - // Setting the current slot as active is a way to revert the operation that - // set *another* slot as active at the end of an updater. This is commonly - // used to cancel the pending update. We should only reset the verity_corrpted - // bit when attempting a new slot, otherwise the verity bit on the current - // slot would be flip. - if (slot != current_slot_) bootctrl.slot_info[slot].verity_corrupted = 0; - - return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl); -} - -bool BootControl::SetSlotAsUnbootable(unsigned int slot) { - if (slot >= kMaxNumSlots || slot >= num_slots_) { - // Invalid slot number. - return false; - } - - bootloader_control bootctrl; - if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false; - - // The only way to mark a slot as unbootable, regardless of the priority is to - // set the tries_remaining to 0. - bootctrl.slot_info[slot].successful_boot = 0; - bootctrl.slot_info[slot].tries_remaining = 0; - return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl); -} - -bool BootControl::IsSlotBootable(unsigned int slot) { - if (slot >= kMaxNumSlots || slot >= num_slots_) { - // Invalid slot number. - return false; - } - - bootloader_control bootctrl; - if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false; - - return bootctrl.slot_info[slot].tries_remaining != 0; -} - -bool BootControl::IsSlotMarkedSuccessful(unsigned int slot) { - if (slot >= kMaxNumSlots || slot >= num_slots_) { - // Invalid slot number. - return false; - } - - bootloader_control bootctrl; - if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false; - - return bootctrl.slot_info[slot].successful_boot && bootctrl.slot_info[slot].tries_remaining; -} - -bool BootControl::IsValidSlot(unsigned int slot) { - return slot < kMaxNumSlots && slot < num_slots_; -} - -bool BootControl::SetSnapshotMergeStatus(MergeStatus status) { - return SetMiscVirtualAbMergeStatus(current_slot_, status); -} - -MergeStatus BootControl::GetSnapshotMergeStatus() { - MergeStatus status; - if (!GetMiscVirtualAbMergeStatus(current_slot_, &status)) { - return MergeStatus::UNKNOWN; - } - return status; -} - -const char* BootControl::GetSuffix(unsigned int slot) { - if (slot >= kMaxNumSlots || slot >= num_slots_) { - return nullptr; - } - return kSlotSuffixes[slot]; -} - -bool InitMiscVirtualAbMessageIfNeeded() { - std::string err; - misc_virtual_ab_message message; - if (!ReadMiscVirtualAbMessage(&message, &err)) { - LOG(ERROR) << "Could not read merge status: " << err; - return false; - } - - if (message.version == MISC_VIRTUAL_AB_MESSAGE_VERSION && - message.magic == MISC_VIRTUAL_AB_MAGIC_HEADER) { - // Already initialized. - return true; - } - - message = {}; - message.version = MISC_VIRTUAL_AB_MESSAGE_VERSION; - message.magic = MISC_VIRTUAL_AB_MAGIC_HEADER; - if (!WriteMiscVirtualAbMessage(message, &err)) { - LOG(ERROR) << "Could not write merge status: " << err; - return false; - } - return true; -} - -bool SetMiscVirtualAbMergeStatus(unsigned int current_slot, - android::hardware::boot::V1_1::MergeStatus status) { - std::string err; - misc_virtual_ab_message message; - - if (!ReadMiscVirtualAbMessage(&message, &err)) { - LOG(ERROR) << "Could not read merge status: " << err; - return false; - } - - message.merge_status = static_cast(status); - message.source_slot = current_slot; - if (!WriteMiscVirtualAbMessage(message, &err)) { - LOG(ERROR) << "Could not write merge status: " << err; - return false; - } - return true; -} - -bool GetMiscVirtualAbMergeStatus(unsigned int current_slot, - android::hardware::boot::V1_1::MergeStatus* status) { - std::string err; - misc_virtual_ab_message message; - - if (!ReadMiscVirtualAbMessage(&message, &err)) { - LOG(ERROR) << "Could not read merge status: " << err; - return false; - } - - // If the slot reverted after having created a snapshot, then the snapshot will - // be thrown away at boot. Thus we don't count this as being in a snapshotted - // state. - *status = static_cast(message.merge_status); - if (*status == MergeStatus::SNAPSHOTTED && current_slot == message.source_slot) { - *status = MergeStatus::NONE; - } - return true; -} - -} // namespace bootable -} // namespace android diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h index 9a482d423..e4cf09b22 100644 --- a/bootloader_message/include/bootloader_message/bootloader_message.h +++ b/bootloader_message/include/bootloader_message/bootloader_message.h @@ -83,108 +83,6 @@ struct bootloader_message { char reserved[1184]; }; -/** - * We must be cautious when changing the bootloader_message struct size, - * because A/B-specific fields may end up with different offsets. - */ -#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) -static_assert(sizeof(struct bootloader_message) == 2048, - "struct bootloader_message size changes, which may break A/B devices"); -#endif - -/** - * The A/B-specific bootloader message structure (4-KiB). - * - * We separate A/B boot control metadata from the regular bootloader - * message struct and keep it here. Everything that's A/B-specific - * stays after struct bootloader_message, which should be managed by - * the A/B-bootloader or boot control HAL. - * - * The slot_suffix field is used for A/B implementations where the - * bootloader does not set the androidboot.ro.boot.slot_suffix kernel - * commandline parameter. This is used by fs_mgr to mount /system and - * other partitions with the slotselect flag set in fstab. A/B - * implementations are free to use all 32 bytes and may store private - * data past the first NUL-byte in this field. It is encouraged, but - * not mandatory, to use 'struct bootloader_control' described below. - * - * The update_channel field is used to store the Omaha update channel - * if update_engine is compiled with Omaha support. - */ -struct bootloader_message_ab { - struct bootloader_message message; - char slot_suffix[32]; - char update_channel[128]; - - // Round up the entire struct to 4096-byte. - char reserved[1888]; -}; - -/** - * Be cautious about the struct size change, in case we put anything post - * bootloader_message_ab struct (b/29159185). - */ -#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) -static_assert(sizeof(struct bootloader_message_ab) == 4096, - "struct bootloader_message_ab size changes"); -#endif - -#define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */ -#define BOOT_CTRL_VERSION 1 - -struct slot_metadata { - // Slot priority with 15 meaning highest priority, 1 lowest - // priority and 0 the slot is unbootable. - uint8_t priority : 4; - // Number of times left attempting to boot this slot. - uint8_t tries_remaining : 3; - // 1 if this slot has booted successfully, 0 otherwise. - uint8_t successful_boot : 1; - // 1 if this slot is corrupted from a dm-verity corruption, 0 - // otherwise. - uint8_t verity_corrupted : 1; - // Reserved for further use. - uint8_t reserved : 7; -} __attribute__((packed)); - -/* Bootloader Control AB - * - * This struct can be used to manage A/B metadata. It is designed to - * be put in the 'slot_suffix' field of the 'bootloader_message' - * structure described above. It is encouraged to use the - * 'bootloader_control' structure to store the A/B metadata, but not - * mandatory. - */ -struct bootloader_control { - // NUL terminated active slot suffix. - char slot_suffix[4]; - // Bootloader Control AB magic number (see BOOT_CTRL_MAGIC). - uint32_t magic; - // Version of struct being used (see BOOT_CTRL_VERSION). - uint8_t version; - // Number of slots being managed. - uint8_t nb_slot : 3; - // Number of times left attempting to boot recovery. - uint8_t recovery_tries_remaining : 3; - // Status of any pending snapshot merge of dynamic partitions. - uint8_t merge_status : 3; - // Ensure 4-bytes alignment for slot_info field. - uint8_t reserved0[1]; - // Per-slot information. Up to 4 slots. - struct slot_metadata slot_info[4]; - // Reserved for further use. - uint8_t reserved1[8]; - // CRC32 of all 28 bytes preceding this field (little endian - // format). - uint32_t crc32_le; -} __attribute__((packed)); - -#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus) -static_assert(sizeof(struct bootloader_control) == - sizeof(((struct bootloader_message_ab *)0)->slot_suffix), - "struct bootloader_control has wrong size"); -#endif - // Holds Virtual A/B merge status information. Current version is 1. New fields // must be added to the end. struct misc_virtual_ab_message { -- cgit v1.2.3 From cbb0b54b1253bcf5d29fb0b29441f8f821a061b6 Mon Sep 17 00:00:00 2001 From: Marek Z Jeziorek Date: Sat, 22 Feb 2020 21:43:12 +0000 Subject: New priority scripts + critical updates to fonts. Author: Marek Z. Jeziorek Needs to be submitted with https://googleplex-android-review.git.corp.google.com/c/platform/frameworks/base/+/10280447 BUGANIZER BUGS Addressed ======================== BUG: 149257053 CHANGES ======= Remove font files no longer required deleted: other/NotoSansAdlam-Regular.ttf deleted: other/NotoSansGeorgian-Bold.otf deleted: other/NotoSansGeorgian-Medium.otf deleted: other/NotoSansGeorgian-Regular.otf deleted: other/NotoSansJavanese-Regular.ttf deleted: other/NotoSansTifinagh-Regular.ttf deleted: other/NotoSerifGeorgian-Bold.otf deleted: other/NotoSerifGeorgian-Regular.otf modified: fonts.mk modified: other/Android.bp Replacements for the above deleted files: new file: other/NotoSansAdlam-VF.ttf new file: other/NotoSansGeorgian-VF.ttf new file: other/NotoSansJavanese-Regular.otf new file: other/NotoSansTifinagh-Regular.otf new file: other/NotoSerifGeorgian-VF.ttf New additions to Android fonts (living/revival languages): new file: other/NotoSansGunjalaGondi-Regular.otf new file: other/NotoSansHanifiRohingya-Regular.otf new file: other/NotoSansKhojki-Regular.otf new file: other/NotoSansMasaramGondi-Regular.otf new file: other/NotoSansWancho-Regular.otf new file: other/NotoSansWarangCiti-Regular.otf Test: =================================================== Test: on Android (click on a link within a browser): Test: Adlam https://en.wikipedia.org/wiki/Adlam_(Unicode_block) Test: Georgian https://en.wikipedia.org/wiki/Georgian_(Unicode_block) Test: Georgian https://en.wikipedia.org/wiki/Georgian_Extended Test: Gunjala Gondi https://en.wikipedia.org/wiki/Gunjala_Gondi_(Unicode_block) Test: Hanifi Rohingya https://en.wikipedia.org/wiki/Hanifi_Rohingya_(Unicode_block) Test: Javanese https://en.wikipedia.org/wiki/Javanese_(Unicode_block) Test: Khojki https://en.wikipedia.org/wiki/Khojki_(Unicode_block) Test: Masaram Gondi https://en.wikipedia.org/wiki/Masaram_Gondi_(Unicode_block) Test: Tifinagh https://en.wikipedia.org/wiki/Tifinagh_(Unicode_block) Test: Wancho https://en.wikipedia.org/wiki/Wancho_(Unicode_block) Test: Warang Citi https://en.wikipedia.org/wiki/Warang_Citi_(Unicode_block) Test: =================================================== Test: on Android (click on a link within a browser): Test: udhr Adlam https://unicode.org/udhr/d/udhr_fuf_adlm.html Test: udhr Georgian https://unicode.org/udhr/d/udhr_kat.html Test: udhr Gunjala Gondi NA (Not Available) Test: udhr Hanifi Rohingya NA (Not Available) Test: udhr Javanese https://unicode.org/udhr/d/udhr_jav_java.html Test: udhr Khojki NA (Not Available) Test: udhr Masaram Gondi NA (Not Available) Test: udhr Tifinagh https://unicode.org/udhr/d/udhr_tzm_tfng.html Test: udhr Wancho NA (Not Available) Test: udhr Warang Citi NA (Not Available) Test: =================================== Test: on Android (comparing two systems - before/after) Test: Georgian: Systems settings menus compared side by side Test: =================================== Test: on Mac (comparing the existing Android fonts with the new font Test: using diffenator - https://github.com/googlefonts/fontdiffenator) Test: =================================== Test: SansAdlam-VF: VALIDATED Test: SansGeorgian-VF: VALIDATED Test: SansGunjalaGondi: NEW (No Applicable) Test: SansHanifiRohingya: NEW (No Applicable) Test: SansJavanese: VALIDATED Test: SansKhojki: NEW (No Applicable) Test: SansMasaramGondi: NEW (No Applicable) Test: SansTifinagh: VALIDATED Test: SansWancho: NEW (No Applicable) Test: SansWarangCiti: NEW (No Applicable) Test: SerifGeorgian-VF: VALIDATED Change-Id: I41e030b63f83ec243ae6f174c061faa5298bd6dc Signed-off-by: Marek Z Jeziorek (cherry picked from commit f165b9c886476889d99edad8d3e43b2980b855a1) --- tools/image_generator/ImageGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/image_generator/ImageGenerator.java b/tools/image_generator/ImageGenerator.java index fd8e54295..1da43e5c6 100644 --- a/tools/image_generator/ImageGenerator.java +++ b/tools/image_generator/ImageGenerator.java @@ -123,7 +123,7 @@ public class ImageGenerator { put("hy", "NotoSansArmenian-Regular"); put("iw", "NotoSansHebrew-Regular"); put("ja", "NotoSansCJK-Regular"); - put("ka", "NotoSansGeorgian-Regular"); + put("ka", "NotoSansGeorgian-VF"); put("ko", "NotoSansCJK-Regular"); put("km", "NotoSansKhmerUI-Regular"); put("kn", "NotoSansKannadaUI-Regular"); -- cgit v1.2.3 From b37d794351e3718683cd13238972cf79da7f6cdd Mon Sep 17 00:00:00 2001 From: Hongguang Chen Date: Sun, 15 Mar 2020 21:09:21 -0700 Subject: Add more mounting options to updater mount function. If enabling the oem partition, it will be mounted by updater before reading product properties from it. To be safety, we want to enable AVB to this oem partition. But this means the oem partition can never be mounted to writable. Otherwise, that partition will be corrupted to AVB verifying. This change follows fs_mgr to allow to pass more mounting options to the updater. BUG: 150156957 Test: make ota package which mounts AVB oem partition to read only and run OTA. Change-Id: I2ebbe3c8ac53c70112f3fed2703fcba9170405a6 --- updater/updater_runtime.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/updater/updater_runtime.cpp b/updater/updater_runtime.cpp index c4222a56e..b1b8863fd 100644 --- a/updater/updater_runtime.cpp +++ b/updater/updater_runtime.cpp @@ -43,10 +43,62 @@ std::string UpdaterRuntime::FindBlockDeviceName(const std::string_view name) con return std::string(name); } +static struct { + const char* name; + unsigned flag; +} mount_flags_list[] = { + { "noatime", MS_NOATIME }, + { "noexec", MS_NOEXEC }, + { "nosuid", MS_NOSUID }, + { "nodev", MS_NODEV }, + { "nodiratime", MS_NODIRATIME }, + { "ro", MS_RDONLY }, + { "rw", 0 }, + { "remount", MS_REMOUNT }, + { "bind", MS_BIND }, + { "rec", MS_REC }, + { "unbindable", MS_UNBINDABLE }, + { "private", MS_PRIVATE }, + { "slave", MS_SLAVE }, + { "shared", MS_SHARED }, + { "defaults", 0 }, + { 0, 0 }, +}; + +static bool setMountFlag(const std::string& flag, unsigned* mount_flags) { + for (const auto& [name, value] : mount_flags_list) { + if (flag == name) { + *mount_flags |= value; + return true; + } + } + return false; +} + +static bool parseMountFlags(const std::string& flags, unsigned* mount_flags, + std::string* fs_options) { + bool is_flag_set = false; + std::vector flag_list; + for (const auto& flag : android::base::Split(flags, ",")) { + if (!setMountFlag(flag, mount_flags)) { + // Unknown flag, so it must be a filesystem specific option. + flag_list.push_back(flag); + } else { + is_flag_set = true; + } + } + *fs_options = android::base::Join(flag_list, ','); + return is_flag_set; +} + int UpdaterRuntime::Mount(const std::string_view location, const std::string_view mount_point, const std::string_view fs_type, const std::string_view mount_options) { std::string mount_point_string(mount_point); + std::string mount_options_string(mount_options); char* secontext = nullptr; + unsigned mount_flags = 0; + std::string fs_options; + if (sehandle_) { selabel_lookup(sehandle_, &secontext, mount_point_string.c_str(), 0755); setfscreatecon(secontext); @@ -59,9 +111,13 @@ int UpdaterRuntime::Mount(const std::string_view location, const std::string_vie setfscreatecon(nullptr); } + if (!parseMountFlags(mount_options_string, &mount_flags, &fs_options)) { + // Fall back to default + mount_flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME; + } + return mount(std::string(location).c_str(), mount_point_string.c_str(), - std::string(fs_type).c_str(), MS_NOATIME | MS_NODEV | MS_NODIRATIME, - std::string(mount_options).c_str()); + std::string(fs_type).c_str(), mount_flags, fs_options.c_str()); } bool UpdaterRuntime::IsMounted(const std::string_view mount_point) const { -- cgit v1.2.3 From e8ca1b86347992d3c92db8e7a25ee77a6280787b Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Fri, 13 Mar 2020 14:25:02 -0700 Subject: Consolidate the wait in recovery's reboot After a reboot function call, we should always wait for it to finish without executing other instructions. Bug: 151110322 Test: build Change-Id: I1dda291a0835ff96df7eaf42eba1a38267a3beeb (cherry picked from commit 00c4aba9bf428717fc00e26a03e97401eca76ee8) --- otautil/include/otautil/sysutil.h | 2 +- otautil/sysutil.cpp | 8 ++++++-- recovery.cpp | 8 +------- recovery_ui/ui.cpp | 3 --- updater/install.cpp | 1 - 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/otautil/include/otautil/sysutil.h b/otautil/include/otautil/sysutil.h index 326db8644..d0d2e67d7 100644 --- a/otautil/include/otautil/sysutil.h +++ b/otautil/include/otautil/sysutil.h @@ -103,7 +103,7 @@ class MemMapping { // Reboots the device into the specified target, by additionally handling quiescent reboot mode. // All unknown targets reboot into Android. -bool Reboot(std::string_view target); +[[noreturn]] void Reboot(std::string_view target); // Triggers a shutdown. bool Shutdown(std::string_view target); diff --git a/otautil/sysutil.cpp b/otautil/sysutil.cpp index 6cd46c6a9..b3ead9736 100644 --- a/otautil/sysutil.cpp +++ b/otautil/sysutil.cpp @@ -219,14 +219,18 @@ MemMapping::~MemMapping() { ranges_.clear(); } -bool Reboot(std::string_view target) { +void Reboot(std::string_view target) { std::string cmd = "reboot," + std::string(target); // Honor the quiescent mode if applicable. if (target != "bootloader" && target != "fastboot" && android::base::GetBoolProperty("ro.boot.quiescent", false)) { cmd += ",quiescent"; } - return android::base::SetProperty(ANDROID_RB_PROPERTY, cmd); + if (!android::base::SetProperty(ANDROID_RB_PROPERTY, cmd)) { + LOG(FATAL) << "Reboot failed"; + } + + while (true) pause(); } bool Shutdown(std::string_view target) { diff --git a/recovery.cpp b/recovery.cpp index 0382697ab..7675121d4 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -781,13 +781,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vectorPrint("Retry attempt %d\n", retry_count); // Reboot back into recovery to retry the update. - if (!Reboot("recovery")) { - ui->Print("Reboot failed\n"); - } else { - while (true) { - pause(); - } - } + Reboot("recovery"); } // If this is an eng or userdebug build, then automatically // turn the text display on if the script fails so the error diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp index 6f5cbbca6..330721773 100644 --- a/recovery_ui/ui.cpp +++ b/recovery_ui/ui.cpp @@ -375,9 +375,6 @@ void RecoveryUI::ProcessKey(int key_code, int updown) { case RecoveryUI::REBOOT: if (reboot_enabled) { Reboot("userrequested,recovery,ui"); - while (true) { - pause(); - } } break; diff --git a/updater/install.cpp b/updater/install.cpp index 62ff87e76..7608dc3cd 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -733,7 +733,6 @@ Value* RebootNowFn(const char* name, State* state, const std::vector Date: Fri, 22 Nov 2019 13:46:19 -0800 Subject: Add libavb as a dependency It's needed by libfec Bug: 144388532 Test: mma Change-Id: Ic82671f6506e7718afa965a511261b1b329ea38f (cherry picked from commit 2bb374a86d0161700f01b68433063b0b13adc86a) --- updater/Android.bp | 1 + updater/Android.mk | 1 + 2 files changed, 2 insertions(+) diff --git a/updater/Android.bp b/updater/Android.bp index cbef43099..f00a192b9 100644 --- a/updater/Android.bp +++ b/updater/Android.bp @@ -25,6 +25,7 @@ cc_defaults { "libdm", "libfec", "libfec_rs", + "libavb", "libverity_tree", "libgtest_prod", "liblog", diff --git a/updater/Android.mk b/updater/Android.mk index 8a4cd86d9..46300d974 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -32,6 +32,7 @@ updater_common_static_libraries := \ libdm \ libfec \ libfec_rs \ + libavb \ libverity_tree \ libgtest_prod \ liblog \ -- cgit v1.2.3 From c054f231ae94ff14fc1cebe632d98597a153c884 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 25 Mar 2020 10:29:41 -0700 Subject: Import translations. DO NOT MERGE Auto-generated-cl: translation import Change-Id: Ia3393b1e62f0af1661cbc7b2c0b19e0a52631c4c --- tools/recovery_l10n/res/values-ar/strings.xml | 4 ++-- tools/recovery_l10n/res/values-hy/strings.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml index 69191287d..a9cd2d133 100644 --- a/tools/recovery_l10n/res/values-ar/strings.xml +++ b/tools/recovery_l10n/res/values-ar/strings.xml @@ -1,11 +1,11 @@ - "جارٍ تثبيت إعادة تحميل النظام" + "جارٍ تثبيت تحديث النظام" "جارٍ محو البيانات" "ليس هناك أي أمر" "خطأ!" - "جارٍ تثبيت إعادة تحميل الأمان" + "جارٍ تثبيت تحديث الأمان" "‏يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط على الإعدادات الأصلية ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز." "إعادة المحاولة" "إعادة الضبط على الإعدادات الأصلية" diff --git a/tools/recovery_l10n/res/values-hy/strings.xml b/tools/recovery_l10n/res/values-hy/strings.xml index 35a0ab113..76c28a707 100644 --- a/tools/recovery_l10n/res/values-hy/strings.xml +++ b/tools/recovery_l10n/res/values-hy/strings.xml @@ -9,6 +9,6 @@ "Չհաջողվեց բեռնել Android համակարգը։ Հնարավոր է՝ ձեր տվյալները վնասված են։ Եթե նորից տեսնեք այս հաղորդագրությունը, փորձեք վերակայել սարքի կարգավորումները և ջնջել օգտատիրոջ բոլոր տվյալները։" "Նորից փորձել" "Վերակայել բոլոր տվյալները" - "Մաքրե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ" + "Ջնջե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ" "Չեղարկել" -- cgit v1.2.3 From 22beef1b282301d69987e7bc9144c82f397586b5 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Fri, 27 Mar 2020 20:37:07 -0700 Subject: minadbd: statically link libadbd. Reduce the amount of wasted space on the recovery image by statically linking all of the adb libraries into minadbd. Bug: http://b/150317254 Test: booted aosp_walleye-eng into recovery Change-Id: I5233b1a23c14f9d478bb77c25ebdbb0ce45bcc5a Merged-In: I5233b1a23c14f9d478bb77c25ebdbb0ce45bcc5a (cherry picked from commit 5ee3eba34f0ddf478f53ac4d0774c1ee423a5182) --- minadbd/Android.bp | 12 +++++++++--- minadbd/minadbd_services.cpp | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/minadbd/Android.bp b/minadbd/Android.bp index c39c73443..793680f33 100644 --- a/minadbd/Android.bp +++ b/minadbd/Android.bp @@ -34,7 +34,7 @@ cc_defaults { // `libminadbd_services` is analogous to the `libadbd_services` for regular `adbd`, but providing // the sideload service only. -cc_library { +cc_library_static { name: "libminadbd_services", recovery_available: true, @@ -79,6 +79,8 @@ cc_binary { defaults: [ "minadbd_defaults", + "libadbd_binary_dependencies", + "librecovery_utils_defaults", ], srcs: [ @@ -86,10 +88,14 @@ cc_binary { ], shared_libs: [ - "libadbd", "libbase", "libcrypto", + ], + + static_libs: [ "libminadbd_services", + "libfusesideload", + "librecovery_utils", ], required: [ @@ -104,6 +110,7 @@ cc_test { defaults: [ "minadbd_defaults", "librecovery_utils_defaults", + "libadbd_binary_dependencies", ], srcs: [ @@ -116,7 +123,6 @@ cc_test { "libfusesideload", "librecovery_utils", "libotautil", - "libadbd", ], shared_libs: [ diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp index eb91fb3e4..ff91ba931 100644 --- a/minadbd/minadbd_services.cpp +++ b/minadbd/minadbd_services.cpp @@ -266,6 +266,10 @@ static void WipeDeviceService(unique_fd fd, const std::string& args) { } } +asocket* daemon_service_to_socket(std::string_view) { + return nullptr; +} + unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport */) { // Common services that are supported both in sideload and rescue modes. if (android::base::ConsumePrefix(&name, "reboot:")) { -- cgit v1.2.3 From 94abf26ba2ae26a37b44a4de4cc949bbf26f762e Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Wed, 15 Apr 2020 11:52:21 +0200 Subject: Rename external storage properties. According to property naming guidelines. Bug: 152170470 Bug: 153525566 Test: N/A Change-Id: I64c6d8ca49fbd72f923a8794df0929bd500dd8e9 Merged-In: I64c6d8ca49fbd72f923a8794df0929bd500dd8e9 --- recovery_utils/roots.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recovery_utils/roots.cpp b/recovery_utils/roots.cpp index 58a313973..99f3c5dc9 100644 --- a/recovery_utils/roots.cpp +++ b/recovery_utils/roots.cpp @@ -157,8 +157,8 @@ int format_volume(const std::string& volume, const std::string& directory) { bool needs_projid = false; if (volume == "/data") { - needs_casefold = android::base::GetBoolProperty("ro.emulated_storage.casefold", false); - needs_projid = android::base::GetBoolProperty("ro.emulated_storage.projid", false); + needs_casefold = android::base::GetBoolProperty("external_storage.casefold.enabled", false); + needs_projid = android::base::GetBoolProperty("external_storage.projid.enabled", false); } // If there's a key_loc that looks like a path, it should be a block device for storing encryption -- cgit v1.2.3 From 2a4afd29a15522ccf3d8ca902214e68445bcac81 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Mon, 27 Apr 2020 20:16:18 -0700 Subject: Detect non-A/B vs. A/B packages correctly. Check the package metadata to determine whether this is an A/B or non-A/B update package. This is more accurate. Also checks ro.virtual_ab.allow_non_ab flag. This is useful for continuously supporting (and testing) non-A/B. Bug: 153581609 Test: apply non-A/B update on cuttlefish Change-Id: I629a533a67966d46d9cd87a59c6b9af26daf1667 --- install/install.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/install/install.cpp b/install/install.cpp index 1c9bf2fd2..d404997dc 100644 --- a/install/install.cpp +++ b/install/install.cpp @@ -331,15 +331,25 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, return INSTALL_CORRUPT; } - bool is_ab = android::base::GetBoolProperty("ro.build.ab_update", false); - if (is_ab) { + bool package_is_ab = get_value(metadata, "ota-type") == OtaTypeToString(OtaType::AB); + bool device_supports_ab = android::base::GetBoolProperty("ro.build.ab_update", false); + bool ab_device_supports_nonab = + android::base::GetBoolProperty("ro.virtual_ab.allow_non_ab", false); + bool device_only_supports_ab = device_supports_ab && !ab_device_supports_nonab; + + if (package_is_ab) { CHECK(package->GetType() == PackageType::kFile); } - // Verify against the metadata in the package first. - if (is_ab && !CheckPackageMetadata(metadata, OtaType::AB)) { - log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure)); - return INSTALL_ERROR; + // Verify against the metadata in the package first. Expects A/B metadata if: + // Package declares itself as an A/B package + // Package does not declare itself as an A/B package, but device only supports A/B; + // still calls CheckPackageMetadata to get a meaningful error message. + if (package_is_ab || device_only_supports_ab) { + if (!CheckPackageMetadata(metadata, OtaType::AB)) { + log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure)); + return INSTALL_ERROR; + } } ReadSourceTargetBuild(metadata, log_buffer); @@ -389,8 +399,9 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache, std::vector args; if (auto setup_result = - is_ab ? SetUpAbUpdateCommands(package_path, zip, pipe_write.get(), &args) - : SetUpNonAbUpdateCommands(package_path, zip, retry_count, pipe_write.get(), &args); + package_is_ab + ? SetUpAbUpdateCommands(package_path, zip, pipe_write.get(), &args) + : SetUpNonAbUpdateCommands(package_path, zip, retry_count, pipe_write.get(), &args); !setup_result) { log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure)); return INSTALL_CORRUPT; -- cgit v1.2.3 From bc7e1db2118feba14d2efe19651d40df7cf202be Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Tue, 28 Apr 2020 13:26:33 -0700 Subject: Add slot suffix to DAP ops If device supports both A/B and non-A/B, when applying a non-A/B package, add current slot suffix and apply the update to the partition at current slot. This includes: - (un)map_partition in edify script. For example, map_partition("system") will automatically append slot suffix to "system" before calling CreateLogicalPartition. - All operations in dynamic_partitions_op_list. For example, add foo group_foo will automatically append slot suffix to foo and group_foo before editing the super partition metadata. Test: apply update Bug: 153581609 Change-Id: Idbd0bfea142529a33dddb4d2debfc74513290730 --- updater/updater_runtime_dynamic_partitions.cpp | 127 ++++++++++++++----------- 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/updater/updater_runtime_dynamic_partitions.cpp b/updater/updater_runtime_dynamic_partitions.cpp index be9250a81..6570cfffd 100644 --- a/updater/updater_runtime_dynamic_partitions.cpp +++ b/updater/updater_runtime_dynamic_partitions.cpp @@ -41,6 +41,7 @@ using android::fs_mgr::LpMetadata; using android::fs_mgr::MetadataBuilder; using android::fs_mgr::Partition; using android::fs_mgr::PartitionOpener; +using android::fs_mgr::SlotNumberForSlotSuffix; static constexpr std::chrono::milliseconds kMapTimeout{ 1000 }; @@ -48,13 +49,17 @@ static std::string GetSuperDevice() { return "/dev/block/by-name/" + fs_mgr_get_super_partition_name(); } -static bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) { - auto state = DeviceMapper::Instance().GetState(partition_name); +static std::string AddSlotSuffix(const std::string& partition_name) { + return partition_name + fs_mgr_get_slot_suffix(); +} + +static bool UnmapPartitionWithSuffixOnDeviceMapper(const std::string& partition_name_suffix) { + auto state = DeviceMapper::Instance().GetState(partition_name_suffix); if (state == DmDeviceState::INVALID) { return true; } if (state == DmDeviceState::ACTIVE) { - return DestroyLogicalPartition(partition_name); + return DestroyLogicalPartition(partition_name_suffix); } LOG(ERROR) << "Unknown device mapper state: " << static_cast>(state); @@ -63,12 +68,17 @@ static bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) { bool UpdaterRuntime::MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) { - auto state = DeviceMapper::Instance().GetState(partition_name); + auto partition_name_suffix = AddSlotSuffix(partition_name); + auto state = DeviceMapper::Instance().GetState(partition_name_suffix); if (state == DmDeviceState::INVALID) { CreateLogicalPartitionParams params = { .block_device = GetSuperDevice(), - .metadata_slot = 0, - .partition_name = partition_name, + // If device supports A/B, apply non-A/B update to the partition at current slot. Otherwise, + // SlotNumberForSlotSuffix("") returns 0. + .metadata_slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix()), + // If device supports A/B, apply non-A/B update to the partition at current slot. Otherwise, + // fs_mgr_get_slot_suffix() returns empty string. + .partition_name = partition_name_suffix, .force_writable = true, .timeout_ms = kMapTimeout, }; @@ -76,7 +86,7 @@ bool UpdaterRuntime::MapPartitionOnDeviceMapper(const std::string& partition_nam } if (state == DmDeviceState::ACTIVE) { - return DeviceMapper::Instance().GetDmDevicePathByName(partition_name, path); + return DeviceMapper::Instance().GetDmDevicePathByName(partition_name_suffix, path); } LOG(ERROR) << "Unknown device mapper state: " << static_cast>(state); @@ -84,7 +94,7 @@ bool UpdaterRuntime::MapPartitionOnDeviceMapper(const std::string& partition_nam } bool UpdaterRuntime::UnmapPartitionOnDeviceMapper(const std::string& partition_name) { - return ::UnmapPartitionOnDeviceMapper(partition_name); + return ::UnmapPartitionWithSuffixOnDeviceMapper(AddSlotSuffix(partition_name)); } namespace { // Ops @@ -126,22 +136,23 @@ using OpMap = std::map; bool PerformOpResize(const OpParameters& params) { if (!params.ExpectArgSize(2)) return false; - const auto& partition_name = params.arg(0); + const auto& partition_name_suffix = AddSlotSuffix(params.arg(0)); auto size = params.uint_arg(1, "size"); if (!size.has_value()) return false; - auto partition = params.builder->FindPartition(partition_name); + auto partition = params.builder->FindPartition(partition_name_suffix); if (partition == nullptr) { - LOG(ERROR) << "Failed to find partition " << partition_name + LOG(ERROR) << "Failed to find partition " << partition_name_suffix << " in dynamic partition metadata."; return false; } - if (!UnmapPartitionOnDeviceMapper(partition_name)) { - LOG(ERROR) << "Cannot unmap " << partition_name << " before resizing."; + if (!UnmapPartitionWithSuffixOnDeviceMapper(partition_name_suffix)) { + LOG(ERROR) << "Cannot unmap " << partition_name_suffix << " before resizing."; return false; } if (!params.builder->ResizePartition(partition, size.value())) { - LOG(ERROR) << "Failed to resize partition " << partition_name << " to size " << *size << "."; + LOG(ERROR) << "Failed to resize partition " << partition_name_suffix << " to size " << *size + << "."; return false; } return true; @@ -149,24 +160,25 @@ bool PerformOpResize(const OpParameters& params) { bool PerformOpRemove(const OpParameters& params) { if (!params.ExpectArgSize(1)) return false; - const auto& partition_name = params.arg(0); + const auto& partition_name_suffix = AddSlotSuffix(params.arg(0)); - if (!UnmapPartitionOnDeviceMapper(partition_name)) { - LOG(ERROR) << "Cannot unmap " << partition_name << " before removing."; + if (!UnmapPartitionWithSuffixOnDeviceMapper(partition_name_suffix)) { + LOG(ERROR) << "Cannot unmap " << partition_name_suffix << " before removing."; return false; } - params.builder->RemovePartition(partition_name); + params.builder->RemovePartition(partition_name_suffix); return true; } bool PerformOpAdd(const OpParameters& params) { if (!params.ExpectArgSize(2)) return false; - const auto& partition_name = params.arg(0); - const auto& group_name = params.arg(1); + const auto& partition_name_suffix = AddSlotSuffix(params.arg(0)); + const auto& group_name_suffix = AddSlotSuffix(params.arg(1)); - if (params.builder->AddPartition(partition_name, group_name, LP_PARTITION_ATTR_READONLY) == - nullptr) { - LOG(ERROR) << "Failed to add partition " << partition_name << " to group " << group_name << "."; + if (params.builder->AddPartition(partition_name_suffix, group_name_suffix, + LP_PARTITION_ATTR_READONLY) == nullptr) { + LOG(ERROR) << "Failed to add partition " << partition_name_suffix << " to group " + << group_name_suffix << "."; return false; } return true; @@ -174,21 +186,21 @@ bool PerformOpAdd(const OpParameters& params) { bool PerformOpMove(const OpParameters& params) { if (!params.ExpectArgSize(2)) return false; - const auto& partition_name = params.arg(0); - const auto& new_group = params.arg(1); + const auto& partition_name_suffix = AddSlotSuffix(params.arg(0)); + const auto& new_group_name_suffix = AddSlotSuffix(params.arg(1)); - auto partition = params.builder->FindPartition(partition_name); + auto partition = params.builder->FindPartition(partition_name_suffix); if (partition == nullptr) { - LOG(ERROR) << "Cannot move partition " << partition_name << " to group " << new_group - << " because it is not found."; + LOG(ERROR) << "Cannot move partition " << partition_name_suffix << " to group " + << new_group_name_suffix << " because it is not found."; return false; } - auto old_group = partition->group_name(); - if (old_group != new_group) { - if (!params.builder->ChangePartitionGroup(partition, new_group)) { - LOG(ERROR) << "Cannot move partition " << partition_name << " from group " << old_group - << " to group " << new_group << "."; + auto old_group_name_suffix = partition->group_name(); + if (old_group_name_suffix != new_group_name_suffix) { + if (!params.builder->ChangePartitionGroup(partition, new_group_name_suffix)) { + LOG(ERROR) << "Cannot move partition " << partition_name_suffix << " from group " + << old_group_name_suffix << " to group " << new_group_name_suffix << "."; return false; } } @@ -197,22 +209,22 @@ bool PerformOpMove(const OpParameters& params) { bool PerformOpAddGroup(const OpParameters& params) { if (!params.ExpectArgSize(2)) return false; - const auto& group_name = params.arg(0); + const auto& group_name_suffix = AddSlotSuffix(params.arg(0)); auto maximum_size = params.uint_arg(1, "maximum_size"); if (!maximum_size.has_value()) return false; - auto group = params.builder->FindGroup(group_name); + auto group = params.builder->FindGroup(group_name_suffix); if (group != nullptr) { - LOG(ERROR) << "Cannot add group " << group_name << " because it already exists."; + LOG(ERROR) << "Cannot add group " << group_name_suffix << " because it already exists."; return false; } if (maximum_size.value() == 0) { - LOG(WARNING) << "Adding group " << group_name << " with no size limits."; + LOG(WARNING) << "Adding group " << group_name_suffix << " with no size limits."; } - if (!params.builder->AddGroup(group_name, maximum_size.value())) { - LOG(ERROR) << "Failed to add group " << group_name << " with maximum size " + if (!params.builder->AddGroup(group_name_suffix, maximum_size.value())) { + LOG(ERROR) << "Failed to add group " << group_name_suffix << " with maximum size " << maximum_size.value() << "."; return false; } @@ -221,20 +233,20 @@ bool PerformOpAddGroup(const OpParameters& params) { bool PerformOpResizeGroup(const OpParameters& params) { if (!params.ExpectArgSize(2)) return false; - const auto& group_name = params.arg(0); + const auto& group_name_suffix = AddSlotSuffix(params.arg(0)); auto new_size = params.uint_arg(1, "maximum_size"); if (!new_size.has_value()) return false; - auto group = params.builder->FindGroup(group_name); + auto group = params.builder->FindGroup(group_name_suffix); if (group == nullptr) { - LOG(ERROR) << "Cannot resize group " << group_name << " because it is not found."; + LOG(ERROR) << "Cannot resize group " << group_name_suffix << " because it is not found."; return false; } auto old_size = group->maximum_size(); if (old_size != new_size.value()) { - if (!params.builder->ChangeGroupSize(group_name, new_size.value())) { - LOG(ERROR) << "Cannot resize group " << group_name << " from " << old_size << " to " + if (!params.builder->ChangeGroupSize(group_name_suffix, new_size.value())) { + LOG(ERROR) << "Cannot resize group " << group_name_suffix << " from " << old_size << " to " << new_size.value() << "."; return false; } @@ -243,8 +255,8 @@ bool PerformOpResizeGroup(const OpParameters& params) { } std::vector ListPartitionNamesInGroup(MetadataBuilder* builder, - const std::string& group_name) { - auto partitions = builder->ListPartitionsInGroup(group_name); + const std::string& group_name_suffix) { + auto partitions = builder->ListPartitionsInGroup(group_name_suffix); std::vector partition_names; std::transform(partitions.begin(), partitions.end(), std::back_inserter(partition_names), [](Partition* partition) { return partition->name(); }); @@ -253,15 +265,16 @@ std::vector ListPartitionNamesInGroup(MetadataBuilder* builder, bool PerformOpRemoveGroup(const OpParameters& params) { if (!params.ExpectArgSize(1)) return false; - const auto& group_name = params.arg(0); + const auto& group_name_suffix = AddSlotSuffix(params.arg(0)); - auto partition_names = ListPartitionNamesInGroup(params.builder, group_name); + auto partition_names = ListPartitionNamesInGroup(params.builder, group_name_suffix); if (!partition_names.empty()) { - LOG(ERROR) << "Cannot remove group " << group_name << " because it still contains partitions [" + LOG(ERROR) << "Cannot remove group " << group_name_suffix + << " because it still contains partitions [" << android::base::Join(partition_names, ", ") << "]"; return false; } - params.builder->RemoveGroupAndPartitions(group_name); + params.builder->RemoveGroupAndPartitions(group_name_suffix); return true; } @@ -269,16 +282,16 @@ bool PerformOpRemoveAllGroups(const OpParameters& params) { if (!params.ExpectArgSize(0)) return false; auto group_names = params.builder->ListGroups(); - for (const auto& group_name : group_names) { - auto partition_names = ListPartitionNamesInGroup(params.builder, group_name); - for (const auto& partition_name : partition_names) { - if (!UnmapPartitionOnDeviceMapper(partition_name)) { - LOG(ERROR) << "Cannot unmap " << partition_name << " before removing group " << group_name - << "."; + for (const auto& group_name_suffix : group_names) { + auto partition_names = ListPartitionNamesInGroup(params.builder, group_name_suffix); + for (const auto& partition_name_suffix : partition_names) { + if (!UnmapPartitionWithSuffixOnDeviceMapper(partition_name_suffix)) { + LOG(ERROR) << "Cannot unmap " << partition_name_suffix << " before removing group " + << group_name_suffix << "."; return false; } } - params.builder->RemoveGroupAndPartitions(group_name); + params.builder->RemoveGroupAndPartitions(group_name_suffix); } return true; } -- cgit v1.2.3 From dff80042750992ed635056cd9719481a14f93007 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Tue, 28 Apr 2020 13:31:11 -0700 Subject: Add add_slot_suffix function. This function appends androidboot.slot_suffix to the value of the argument. Test: apply update Bug: 153581609 Change-Id: I28a4047b5f2051acc039084f65a71deb492d9dcb --- .clang-format | 1 + edify/include/edify/updater_runtime_interface.h | 3 +++ updater/include/updater/simulator_runtime.h | 1 + updater/include/updater/updater_runtime.h | 1 + updater/install.cpp | 16 ++++++++++++++++ updater/simulator_runtime.cpp | 5 +++++ updater/updater_runtime.cpp | 5 +++++ 7 files changed, 32 insertions(+) diff --git a/.clang-format b/.clang-format index 4a3bd2fc3..6fa717cfb 100644 --- a/.clang-format +++ b/.clang-format @@ -36,6 +36,7 @@ AllowShortIfStatementsOnASingleLine: true ColumnLimit: 100 CommentPragmas: NOLINT:.* DerivePointerAlignment: false +IncludeBlocks: Preserve IndentWidth: 2 PointerAlignment: Left TabWidth: 2 diff --git a/edify/include/edify/updater_runtime_interface.h b/edify/include/edify/updater_runtime_interface.h index d3d26da64..bdd6aecc8 100644 --- a/edify/include/edify/updater_runtime_interface.h +++ b/edify/include/edify/updater_runtime_interface.h @@ -71,4 +71,7 @@ class UpdaterRuntimeInterface { virtual bool MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) = 0; virtual bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) = 0; virtual bool UpdateDynamicPartitions(const std::string_view op_list_value) = 0; + + // On devices supports A/B, add current slot suffix to arg. Otherwise, return |arg| as is. + virtual std::string AddSlotSuffix(const std::string_view arg) const = 0; }; diff --git a/updater/include/updater/simulator_runtime.h b/updater/include/updater/simulator_runtime.h index 9f7847b4f..fa878db33 100644 --- a/updater/include/updater/simulator_runtime.h +++ b/updater/include/updater/simulator_runtime.h @@ -53,6 +53,7 @@ class SimulatorRuntime : public UpdaterRuntimeInterface { bool MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) override; bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) override; bool UpdateDynamicPartitions(const std::string_view op_list_value) override; + std::string AddSlotSuffix(const std::string_view arg) const override; private: std::string FindBlockDeviceName(const std::string_view name) const override; diff --git a/updater/include/updater/updater_runtime.h b/updater/include/updater/updater_runtime.h index 8fc066f6a..b943dfcf1 100644 --- a/updater/include/updater/updater_runtime.h +++ b/updater/include/updater/updater_runtime.h @@ -56,6 +56,7 @@ class UpdaterRuntime : public UpdaterRuntimeInterface { bool MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) override; bool UnmapPartitionOnDeviceMapper(const std::string& partition_name) override; bool UpdateDynamicPartitions(const std::string_view op_list_value) override; + std::string AddSlotSuffix(const std::string_view arg) const override; private: struct selabel_handle* sehandle_{ nullptr }; diff --git a/updater/install.cpp b/updater/install.cpp index 7608dc3cd..afa5195d0 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -852,6 +852,20 @@ Value* Tune2FsFn(const char* name, State* state, const std::vector>& argv) { + if (argv.size() != 1) { + return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size()); + } + std::vector args; + if (!ReadArgs(state, argv, &args)) { + return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name); + } + const std::string& arg = args[0]; + auto updater_runtime = state->updater->GetRuntime(); + return StringValue(updater_runtime->AddSlotSuffix(arg)); +} + void RegisterInstallFunctions() { RegisterFunction("mount", MountFn); RegisterFunction("is_mounted", IsMountedFn); @@ -885,4 +899,6 @@ void RegisterInstallFunctions() { RegisterFunction("enable_reboot", EnableRebootFn); RegisterFunction("tune2fs", Tune2FsFn); + + RegisterFunction("add_slot_suffix", AddSlotSuffixFn); } diff --git a/updater/simulator_runtime.cpp b/updater/simulator_runtime.cpp index 3ed7bf337..57dfb32d4 100644 --- a/updater/simulator_runtime.cpp +++ b/updater/simulator_runtime.cpp @@ -130,3 +130,8 @@ bool SimulatorRuntime::UpdateDynamicPartitions(const std::string_view op_list_va } return true; } + +std::string SimulatorRuntime::AddSlotSuffix(const std::string_view arg) const { + LOG(INFO) << "Skip adding slot suffix to " << arg; + return std::string(arg); +} diff --git a/updater/updater_runtime.cpp b/updater/updater_runtime.cpp index b1b8863fd..e93830505 100644 --- a/updater/updater_runtime.cpp +++ b/updater/updater_runtime.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -186,3 +187,7 @@ int UpdaterRuntime::Tune2Fs(const std::vector& args) const { // tune2fs changes the filesystem parameters on an ext2 filesystem; it returns 0 on success. return tune2fs_main(tune2fs_args.size() - 1, tune2fs_args.data()); } + +std::string UpdaterRuntime::AddSlotSuffix(const std::string_view arg) const { + return std::string(arg) + fs_mgr_get_slot_suffix(); +} -- cgit v1.2.3 From 4d0df88d88db381422ee912f2609258d72eca4cf Mon Sep 17 00:00:00 2001 From: Hongguang Chen Date: Tue, 21 Apr 2020 20:58:04 -0700 Subject: Add EthernetDevice to manage ethernet connection. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current fastbootd only supports USB protocol. But some Android TV devices are built without USB port. The fastbootd cannot be used on those ATV devices due to it. aosp/1295566 enables fastbootd over ethernet. This change adds an EthernetDevice to manage ethernet connection and set fastbootd protcol property fastbootd.protocol to enable fastbootd over ethernet in recovery mode. It uses IPv6 link-local address to not expose the devices out of the network segment. The devices who want to use this EthernetDevice should add “TARGET_RECOVERY_UI_LIB := librecovery_ui_ethernet” into BoardConfig.mk. BUG: 152544169 BUG: 155198345 Test: Enter and exit fastboot mode and check eth0 IPv6 link-local address on screen UI. Change-Id: I73fe44be3790bdba5a6059fbba3f7264b21eed99 Merged-In: I73fe44be3790bdba5a6059fbba3f7264b21eed99 --- Android.mk | 6 +- fastboot/fastboot.cpp | 1 + recovery_main.cpp | 5 + recovery_ui/Android.bp | 21 ++++ recovery_ui/ethernet_device.cpp | 136 ++++++++++++++++++++++++++ recovery_ui/ethernet_ui.cpp | 32 ++++++ recovery_ui/include/recovery_ui/device.h | 12 +++ recovery_ui/include/recovery_ui/ethernet_ui.h | 34 +++++++ 8 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 recovery_ui/ethernet_device.cpp create mode 100644 recovery_ui/ethernet_ui.cpp create mode 100644 recovery_ui/include/recovery_ui/ethernet_ui.h diff --git a/Android.mk b/Android.mk index 9806d1091..9f691531c 100644 --- a/Android.mk +++ b/Android.mk @@ -18,9 +18,9 @@ LOCAL_PATH := $(call my-dir) RECOVERY_API_VERSION := 3 RECOVERY_FSTAB_VERSION := 2 -# TARGET_RECOVERY_UI_LIB should be one of librecovery_ui_{default,wear,vr} or a device-specific -# module that defines make_device() and the exact RecoveryUI class for the target. It defaults to -# librecovery_ui_default, which uses ScreenRecoveryUI. +# TARGET_RECOVERY_UI_LIB should be one of librecovery_ui_{default,wear,vr,ethernet} or a +# device-specific module that defines make_device() and the exact RecoveryUI class for the +# target. It defaults to librecovery_ui_default, which uses ScreenRecoveryUI. TARGET_RECOVERY_UI_LIB ?= librecovery_ui_default # librecovery_ui_ext (shared library) diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 202334997..a0930087c 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -52,6 +52,7 @@ Device::BuiltinAction StartFastboot(Device* device, const std::vectorResetKeyInterruptStatus(); ui->SetTitle(title_lines); ui->ShowText(true); + device->StartFastboot(); // Reset to normal system boot so recovery won't cycle indefinitely. // TODO(b/112277594) Clear only if 'recovery' field of BCB is empty. If not, diff --git a/recovery_main.cpp b/recovery_main.cpp index 30a1fc0a4..80cba61d3 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -471,6 +471,11 @@ int main(int argc, char** argv) { std::string usb_config = fastboot ? "fastboot" : IsRoDebuggable() || IsDeviceUnlocked() ? "adb" : "none"; std::string usb_state = android::base::GetProperty("sys.usb.state", "none"); + if (fastboot) { + device->PreFastboot(); + } else { + device->PreRecovery(); + } if (usb_config != usb_state) { if (!SetUsbConfig("none")) { LOG(ERROR) << "Failed to clear USB config"; diff --git a/recovery_ui/Android.bp b/recovery_ui/Android.bp index 149ef8acc..9dfee5fd5 100644 --- a/recovery_ui/Android.bp +++ b/recovery_ui/Android.bp @@ -22,6 +22,7 @@ cc_library { srcs: [ "device.cpp", + "ethernet_ui.cpp", "screen_ui.cpp", "stub_ui.cpp", "ui.cpp", @@ -90,3 +91,23 @@ cc_library_static { export_include_dirs: ["include"], } + +// The default device that uses EthernetRecoveryUI. +cc_library_static { + name: "librecovery_ui_ethernet", + recovery_available: true, + + defaults: [ + "recovery_defaults", + ], + + srcs: [ + "ethernet_device.cpp", + ], + + shared_libs: [ + "libbase", + ], + + export_include_dirs: ["include"], +} diff --git a/recovery_ui/ethernet_device.cpp b/recovery_ui/ethernet_device.cpp new file mode 100644 index 000000000..39ec65dc4 --- /dev/null +++ b/recovery_ui/ethernet_device.cpp @@ -0,0 +1,136 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "recovery_ui/device.h" +#include "recovery_ui/ethernet_ui.h" + +class EthernetDevice : public Device { + public: + explicit EthernetDevice(EthernetRecoveryUI* ui); + + void PreRecovery() override; + void PreFastboot() override; + + private: + int SetInterfaceFlags(const unsigned set, const unsigned clr); + void SetTitleIPv6LinkLocalAddress(const bool interface_up); + + android::base::unique_fd ctl_sock_; + static const std::string interface; +}; + +const std::string EthernetDevice::interface = "eth0"; + +EthernetDevice::EthernetDevice(EthernetRecoveryUI* ui) + : Device(ui), ctl_sock_(socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) { + if (ctl_sock_ < 0) { + PLOG(ERROR) << "Failed to open socket"; + } +} + +void EthernetDevice::PreRecovery() { + SetInterfaceFlags(0, IFF_UP); + SetTitleIPv6LinkLocalAddress(false); +} + +void EthernetDevice::PreFastboot() { + android::base::SetProperty("fastbootd.protocol", "tcp"); + + if (SetInterfaceFlags(IFF_UP, 0) < 0) { + LOG(ERROR) << "Failed to bring up interface"; + return; + } + + SetTitleIPv6LinkLocalAddress(true); +} + +int EthernetDevice::SetInterfaceFlags(const unsigned set, const unsigned clr) { + struct ifreq ifr; + + if (ctl_sock_ < 0) { + return -1; + } + + memset(&ifr, 0, sizeof(struct ifreq)); + strncpy(ifr.ifr_name, interface.c_str(), IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = 0; + + if (ioctl(ctl_sock_, SIOCGIFFLAGS, &ifr) < 0) { + PLOG(ERROR) << "Failed to get interface active flags"; + return -1; + } + ifr.ifr_flags = (ifr.ifr_flags & (~clr)) | set; + + if (ioctl(ctl_sock_, SIOCSIFFLAGS, &ifr) < 0) { + PLOG(ERROR) << "Failed to set interface active flags"; + return -1; + } + + return 0; +} + +void EthernetDevice::SetTitleIPv6LinkLocalAddress(const bool interface_up) { + auto recovery_ui = reinterpret_cast(GetUI()); + if (!interface_up) { + recovery_ui->SetIPv6LinkLocalAddress(); + return; + } + + struct ifaddrs* ifaddr; + if (getifaddrs(&ifaddr) == -1) { + PLOG(ERROR) << "Failed to get interface addresses"; + recovery_ui->SetIPv6LinkLocalAddress(); + return; + } + + std::unique_ptr guard{ ifaddr, freeifaddrs }; + for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family != AF_INET6 || interface != ifa->ifa_name) { + continue; + } + + auto current_addr = reinterpret_cast(ifa->ifa_addr); + if (!IN6_IS_ADDR_LINKLOCAL(&(current_addr->sin6_addr))) { + continue; + } + + char addrstr[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, reinterpret_cast(¤t_addr->sin6_addr), addrstr, + INET6_ADDRSTRLEN); + LOG(INFO) << "Our IPv6 link-local address is " << addrstr; + recovery_ui->SetIPv6LinkLocalAddress(addrstr); + return; + } + + recovery_ui->SetIPv6LinkLocalAddress(); +} + +// ----------------------------------------------------------------------------------------- +Device* make_device() { + return new EthernetDevice(new EthernetRecoveryUI); +} diff --git a/recovery_ui/ethernet_ui.cpp b/recovery_ui/ethernet_ui.cpp new file mode 100644 index 000000000..535d407f9 --- /dev/null +++ b/recovery_ui/ethernet_ui.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#include "recovery_ui/ethernet_ui.h" + +#include + +void EthernetRecoveryUI::SetTitle(const std::vector& lines) { + ScreenRecoveryUI::SetTitle(lines); + + // Append IP address, if any + if (!address_.empty()) { + title_lines_.push_back("IPv6 link-local address - " + address_); + } +} + +void EthernetRecoveryUI::SetIPv6LinkLocalAddress(const std::string& address) { + address_ = address; +} diff --git a/recovery_ui/include/recovery_ui/device.h b/recovery_ui/include/recovery_ui/device.h index f4f993638..76166f09d 100644 --- a/recovery_ui/include/recovery_ui/device.h +++ b/recovery_ui/include/recovery_ui/device.h @@ -79,10 +79,22 @@ class Device { ui_.reset(ui); } + // Called before recovery mode started up, to perform whatever device-specific recovery mode + // preparation as needed. + virtual void PreRecovery() {} + // Called when recovery starts up (after the UI has been obtained and initialized and after the // arguments have been parsed, but before anything else). virtual void StartRecovery() {} + // Called before fastboot mode is started up, to perform whatever device-specific fastboot mode + // preparation as needed. + virtual void PreFastboot() {} + + // Called when fastboot starts up (after the UI has been obtained and initialized and after the + // arguments have been parsed, but before anything else). + virtual void StartFastboot() {} + // Called from the main thread when recovery is at the main menu and waiting for input, and a key // is pressed. (Note that "at" the main menu does not necessarily mean the menu is visible; // recovery will be at the main menu with it invisible after an unsuccessful operation, such as diff --git a/recovery_ui/include/recovery_ui/ethernet_ui.h b/recovery_ui/include/recovery_ui/ethernet_ui.h new file mode 100644 index 000000000..f40c73f69 --- /dev/null +++ b/recovery_ui/include/recovery_ui/ethernet_ui.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#ifndef RECOVERY_ETHERNET_UI_H +#define RECOVERY_ETHERNET_UI_H + +#include "screen_ui.h" + +class EthernetRecoveryUI : public ScreenRecoveryUI { + public: + EthernetRecoveryUI() {} + void SetTitle(const std::vector& lines) override; + + // For EthernetDevice + void SetIPv6LinkLocalAddress(const std::string& address = ""); + + private: + std::string address_; +}; + +#endif // RECOVERY_ETHERNET_UI_H -- cgit v1.2.3 From 4473e1689fc7bb788749b4d5e143eafa82b6f473 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Mon, 1 Jun 2020 18:58:57 -0700 Subject: Track rename of adbd_system_binaries. Bug: http://b/157709367 Test: treehugger Change-Id: Ic205acc56a763c38ba689b2b895609b5e878d813 (cherry picked from commit d4a964f121ec03124a599eeed13a334677e942e9) --- minadbd/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minadbd/Android.bp b/minadbd/Android.bp index 793680f33..4cdcac6d9 100644 --- a/minadbd/Android.bp +++ b/minadbd/Android.bp @@ -99,7 +99,7 @@ cc_binary { ], required: [ - "adbd_system_binaries_recovery", + "adbd_system_api_recovery", ] } -- cgit v1.2.3 From fd33b4992dd454b6512bb92c97550c9822acfc4c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 17 Jul 2020 17:40:48 -0700 Subject: Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Id59b183068ff2cdf8c58f42b9b7c8406cc04b8f2 --- tools/recovery_l10n/res/values-ur/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/recovery_l10n/res/values-ur/strings.xml b/tools/recovery_l10n/res/values-ur/strings.xml index da03f1972..13dc6b37d 100644 --- a/tools/recovery_l10n/res/values-ur/strings.xml +++ b/tools/recovery_l10n/res/values-ur/strings.xml @@ -6,9 +6,9 @@ "کوئی کمانڈ نہیں ہے" "خرابی!" "سیکیورٹی اپ ڈیٹ انسٹال ہو رہی ہے" - "‏Android سسٹم لوڈ نہیں کیا جا سکتا۔ آپ کا ڈیٹا خراب ہو سکتا ہے۔ اگر آپ کو مستقل یہ پیغام موصول ہوتا ہے تو آپ کو فیکٹری ڈیٹا کی دوبارہ ترتیب انجام دینے اور اس آلہ پر اسٹور کردہ سبھی صارف ڈیٹا کو مٹانے کی ضرورت پڑ سکتی ہے۔" + "‏Android سسٹم لوڈ نہیں کیا جا سکتا۔ آپ کا ڈیٹا خراب ہو سکتا ہے۔ اگر آپ کو مستقل یہ پیغام موصول ہوتا ہے تو آپ کو فیکٹری ڈیٹا ری سیٹ انجام دینے اور اس آلہ پر اسٹور کردہ سبھی صارف ڈیٹا کو مٹانے کی ضرورت پڑ سکتی ہے۔" "دوبارہ کوشش کریں" - "فیکٹری ڈیٹا کی دوبارہ ترتیب" + "فیکٹری ڈیٹا ری سیٹ" "سبھی صارف ڈیٹا صاف کریں؟\n\n اسے کالعدم نہیں کیا جا سکتا!" "منسوخ کریں" -- cgit v1.2.3 From de521d2b0d5f73da289198d2cf7a3298746d51b0 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 2 Sep 2020 06:36:09 +0000 Subject: Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ia586562662d1a1a833301a19db5cac66e39a689b --- tools/recovery_l10n/res/values-ar/strings.xml | 4 ++-- tools/recovery_l10n/res/values-hy/strings.xml | 2 +- tools/recovery_l10n/res/values-ur/strings.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml index 69191287d..a9cd2d133 100644 --- a/tools/recovery_l10n/res/values-ar/strings.xml +++ b/tools/recovery_l10n/res/values-ar/strings.xml @@ -1,11 +1,11 @@ - "جارٍ تثبيت إعادة تحميل النظام" + "جارٍ تثبيت تحديث النظام" "جارٍ محو البيانات" "ليس هناك أي أمر" "خطأ!" - "جارٍ تثبيت إعادة تحميل الأمان" + "جارٍ تثبيت تحديث الأمان" "‏يتعذَّر تحميل نظام Android، حيث قد تكون بياناتك تالفة. وإذا استمر ظهور هذه الرسالة، قد يتعيَّن عليك إجراء إعادة الضبط على الإعدادات الأصلية ومحو جميع بيانات المستخدم المُخزَّنة على هذا الجهاز." "إعادة المحاولة" "إعادة الضبط على الإعدادات الأصلية" diff --git a/tools/recovery_l10n/res/values-hy/strings.xml b/tools/recovery_l10n/res/values-hy/strings.xml index 35a0ab113..76c28a707 100644 --- a/tools/recovery_l10n/res/values-hy/strings.xml +++ b/tools/recovery_l10n/res/values-hy/strings.xml @@ -9,6 +9,6 @@ "Չհաջողվեց բեռնել Android համակարգը։ Հնարավոր է՝ ձեր տվյալները վնասված են։ Եթե նորից տեսնեք այս հաղորդագրությունը, փորձեք վերակայել սարքի կարգավորումները և ջնջել օգտատիրոջ բոլոր տվյալները։" "Նորից փորձել" "Վերակայել բոլոր տվյալները" - "Մաքրե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ" + "Ջնջե՞լ օգտատիրոջ բոլոր տվյալները։\n\n ԱՅՍ ԳՈՐԾՈՂՈՒԹՅՈՒՆԸ ՀՆԱՐԱՎՈՐ ՉԻ ԼԻՆԻ ՀԵՏԱՐԿԵԼ" "Չեղարկել" diff --git a/tools/recovery_l10n/res/values-ur/strings.xml b/tools/recovery_l10n/res/values-ur/strings.xml index da03f1972..13dc6b37d 100644 --- a/tools/recovery_l10n/res/values-ur/strings.xml +++ b/tools/recovery_l10n/res/values-ur/strings.xml @@ -6,9 +6,9 @@ "کوئی کمانڈ نہیں ہے" "خرابی!" "سیکیورٹی اپ ڈیٹ انسٹال ہو رہی ہے" - "‏Android سسٹم لوڈ نہیں کیا جا سکتا۔ آپ کا ڈیٹا خراب ہو سکتا ہے۔ اگر آپ کو مستقل یہ پیغام موصول ہوتا ہے تو آپ کو فیکٹری ڈیٹا کی دوبارہ ترتیب انجام دینے اور اس آلہ پر اسٹور کردہ سبھی صارف ڈیٹا کو مٹانے کی ضرورت پڑ سکتی ہے۔" + "‏Android سسٹم لوڈ نہیں کیا جا سکتا۔ آپ کا ڈیٹا خراب ہو سکتا ہے۔ اگر آپ کو مستقل یہ پیغام موصول ہوتا ہے تو آپ کو فیکٹری ڈیٹا ری سیٹ انجام دینے اور اس آلہ پر اسٹور کردہ سبھی صارف ڈیٹا کو مٹانے کی ضرورت پڑ سکتی ہے۔" "دوبارہ کوشش کریں" - "فیکٹری ڈیٹا کی دوبارہ ترتیب" + "فیکٹری ڈیٹا ری سیٹ" "سبھی صارف ڈیٹا صاف کریں؟\n\n اسے کالعدم نہیں کیا جا سکتا!" "منسوخ کریں" -- cgit v1.2.3