summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp168
-rw-r--r--Android.mk171
-rw-r--r--boot_control/Android.bp37
-rw-r--r--boot_control/Android.mk33
-rw-r--r--device.cpp1
-rw-r--r--device.h2
-rw-r--r--etc/init.rc105
-rw-r--r--fastboot/fastboot.cpp82
-rw-r--r--fastboot/fastboot.h24
-rw-r--r--fuse_sideload/Android.bp5
-rw-r--r--install.cpp2
-rw-r--r--minadbd/Android.bp19
-rw-r--r--minui/Android.bp3
-rw-r--r--minui/graphics_drm.cpp10
-rw-r--r--otautil/Android.bp17
-rw-r--r--recovery.cpp82
-rw-r--r--recovery_main.cpp124
-rw-r--r--roots.cpp1
-rw-r--r--tests/Android.bp218
-rw-r--r--tests/Android.mk230
-rw-r--r--tests/component/install_test.cpp2
-rw-r--r--tests/component/resources_test.cpp8
-rw-r--r--tests/unit/commands_test.cpp20
-rw-r--r--tools/recovery_l10n/res/values-as/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-en-rCA/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-en-rXC/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-or/strings.xml9
-rw-r--r--updater/Android.bp80
-rw-r--r--updater/Android.mk35
-rw-r--r--updater/commands.cpp42
-rw-r--r--updater/include/private/commands.h52
-rw-r--r--updater/install.cpp10
-rw-r--r--updater_sample/Android.bp33
-rw-r--r--updater_sample/Android.mk35
-rw-r--r--updater_sample/README.md2
-rw-r--r--updater_sample/tests/Android.bp40
-rw-r--r--updater_sample/tests/Android.mk36
37 files changed, 1123 insertions, 642 deletions
diff --git a/Android.bp b/Android.bp
index 22c90bd3e..53b74dca5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,14 +16,48 @@ cc_defaults {
name: "recovery_defaults",
cflags: [
+ "-D_FILE_OFFSET_BITS=64",
+
+ // Must be the same as RECOVERY_API_VERSION.
+ "-DRECOVERY_API_VERSION=3",
+
"-Wall",
"-Werror",
],
}
+cc_library {
+ name: "librecovery_ui",
+ recovery_available: true,
+
+ defaults: [
+ "recovery_defaults",
+ ],
+
+ srcs: [
+ "device.cpp",
+ "screen_ui.cpp",
+ "ui.cpp",
+ "vr_ui.cpp",
+ "wear_ui.cpp"
+ ],
+
+ static_libs: [
+ "libminui",
+ "libotautil",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libpng",
+ "libz",
+ ],
+}
+
// Generic device that uses ScreenRecoveryUI.
cc_library_static {
name: "librecovery_ui_default",
+ recovery_available: true,
defaults: [
"recovery_defaults",
@@ -37,6 +71,7 @@ cc_library_static {
// The default wear device that uses WearRecoveryUI.
cc_library_static {
name: "librecovery_ui_wear",
+ recovery_available: true,
defaults: [
"recovery_defaults",
@@ -50,6 +85,7 @@ cc_library_static {
// The default VR device that uses VrRecoveryUI.
cc_library_static {
name: "librecovery_ui_vr",
+ recovery_available: true,
defaults: [
"recovery_defaults",
@@ -61,7 +97,94 @@ cc_library_static {
}
cc_library_static {
+ name: "librecovery_fastboot",
+ recovery_available: true,
+ defaults: [
+ "recovery_defaults",
+ ],
+
+ srcs: [
+ "fastboot/fastboot.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libbootloader_message",
+ "libcutils",
+ "liblog",
+ ],
+
+ static_libs: [
+ "librecovery_ui_default",
+ ],
+}
+
+cc_defaults {
+ name: "librecovery_defaults",
+
+ defaults: [
+ "recovery_defaults",
+ ],
+
+ shared_libs: [
+ "android.hardware.health@2.0",
+ "libbase",
+ "libbootloader_message",
+ "libcrypto",
+ "libcutils",
+ "libext4_utils",
+ "libfs_mgr",
+ "libfusesideload",
+ "libhidl-gen-utils",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libpng",
+ "libselinux",
+ "libtinyxml2",
+ "libutils",
+ "libz",
+ "libziparchive",
+ ],
+
+ static_libs: [
+ "librecovery_fastboot",
+ "libminui",
+ "libverifier",
+ "libotautil",
+
+ // external dependencies
+ "libhealthhalutils",
+ "libvintf_recovery",
+ "libvintf",
+ ],
+}
+
+cc_library_static {
+ name: "librecovery",
+ recovery_available: true,
+
+ defaults: [
+ "librecovery_defaults",
+ ],
+
+ srcs: [
+ "adb_install.cpp",
+ "fsck_unshare_blocks.cpp",
+ "fuse_sdcard_provider.cpp",
+ "install.cpp",
+ "recovery.cpp",
+ "roots.cpp",
+ ],
+
+ include_dirs: [
+ "system/vold",
+ ],
+}
+
+cc_library_static {
name: "libverifier",
+ recovery_available: true,
defaults: [
"recovery_defaults",
@@ -72,14 +195,49 @@ cc_library_static {
"verifier.cpp",
],
- static_libs: [
+ shared_libs: [
"libbase",
"libcrypto",
"libcrypto_utils",
+ ],
+
+ static_libs: [
"libotautil",
],
}
+cc_binary {
+ name: "recovery",
+ recovery: true,
+
+ defaults: [
+ "librecovery_defaults",
+ ],
+
+ srcs: [
+ "logging.cpp",
+ "recovery_main.cpp",
+ ],
+
+ shared_libs: [
+ "libminadbd_services",
+ "librecovery_ui",
+ ],
+
+ static_libs: [
+ "librecovery",
+ "librecovery_ui_default",
+ ],
+
+ required: [
+ "e2fsdroid.recovery",
+ "librecovery_ui_ext",
+ "mke2fs.conf",
+ "mke2fs.recovery",
+ "recovery_deps",
+ ],
+}
+
// The dynamic executable that runs after /data mounts.
cc_binary {
name: "recovery-persist",
@@ -133,3 +291,11 @@ cc_binary {
"recovery-refresh.rc",
],
}
+
+filegroup {
+ name: "res-testdata",
+
+ srcs: [
+ "res-*/images/*_text.png",
+ ],
+}
diff --git a/Android.mk b/Android.mk
index 9542080ca..80d107dc4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,7 +14,7 @@
LOCAL_PATH := $(call my-dir)
-# Needed by build/make/core/Makefile.
+# Needed by build/make/core/Makefile. Must be consistent with the value in Android.bp.
RECOVERY_API_VERSION := 3
RECOVERY_FSTAB_VERSION := 2
@@ -23,11 +23,6 @@ RECOVERY_FSTAB_VERSION := 2
# librecovery_ui_default, which uses ScreenRecoveryUI.
TARGET_RECOVERY_UI_LIB ?= librecovery_ui_default
-recovery_common_cflags := \
- -Wall \
- -Werror \
- -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
-
# librecovery_ui_ext (shared library)
# ===================================
include $(CLEAR_VARS)
@@ -49,151 +44,16 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
libbase \
liblog \
- librecovery_ui
-
-include $(BUILD_SHARED_LIBRARY)
-
-# librecovery_ui (shared library)
-# ===============================
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- device.cpp \
- screen_ui.cpp \
- ui.cpp \
- vr_ui.cpp \
- wear_ui.cpp
-
-LOCAL_MODULE := librecovery_ui
-
-LOCAL_CFLAGS := $(recovery_common_cflags)
-
-LOCAL_MULTILIB := first
-
-ifeq ($(TARGET_IS_64_BIT),true)
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib64
-else
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/lib
-endif
-
-LOCAL_STATIC_LIBRARIES := \
- libminui \
- libotautil \
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libpng \
- libz \
+ librecovery_ui.recovery
include $(BUILD_SHARED_LIBRARY)
-# librecovery_ui (static library)
-# ===============================
+# recovery_deps: A phony target that's depended on by `recovery`, which
+# builds additional modules conditionally based on Makefile variables.
+# ======================================================================
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- device.cpp \
- screen_ui.cpp \
- ui.cpp \
- vr_ui.cpp \
- wear_ui.cpp
-
-LOCAL_MODULE := librecovery_ui
-LOCAL_CFLAGS := $(recovery_common_cflags)
-
-LOCAL_STATIC_LIBRARIES := \
- libminui \
- libotautil \
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libpng \
- libz \
-
-include $(BUILD_STATIC_LIBRARY)
-
-librecovery_static_libraries := \
- libbootloader_message \
- libfusesideload \
- libminadbd \
- libminui \
- libverifier \
- libotautil \
- libasyncio \
- libbatterymonitor \
- libcrypto_utils \
- libcrypto \
- libext4_utils \
- libfs_mgr \
- libpng \
- libsparse \
- libvintf_recovery \
- libvintf \
- libhidl-gen-utils \
- libtinyxml2 \
- libziparchive \
- libbase \
- libutils \
- libcutils \
- liblog \
- libselinux \
- libz \
-
-# librecovery (static library)
-# ===============================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- adb_install.cpp \
- fsck_unshare_blocks.cpp \
- fuse_sdcard_provider.cpp \
- install.cpp \
- recovery.cpp \
- roots.cpp \
-
-LOCAL_C_INCLUDES := \
- system/vold \
-
-LOCAL_CFLAGS := $(recovery_common_cflags)
-
-LOCAL_MODULE := librecovery
-
-LOCAL_STATIC_LIBRARIES := \
- $(librecovery_static_libraries)
-
-include $(BUILD_STATIC_LIBRARY)
-
-# recovery (static executable)
-# ===============================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- logging.cpp \
- recovery_main.cpp \
-
-LOCAL_MODULE := recovery
-
-LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/system/bin
-
-# Cannot link with LLD: undefined symbol: UsbNoPermissionsLongHelpText
-# http://b/77543887, lld does not handle -Wl,--gc-sections as well as ld.
-LOCAL_USE_CLANG_LLD := false
-
-LOCAL_CFLAGS := $(recovery_common_cflags)
-
-LOCAL_STATIC_LIBRARIES := \
- librecovery \
- librecovery_ui_default \
- $(librecovery_static_libraries)
-
-LOCAL_SHARED_LIBRARIES := \
- librecovery_ui \
-
-LOCAL_HAL_STATIC_LIBRARIES := libhealthd
-
-LOCAL_REQUIRED_MODULES := \
- e2fsdroid.recovery \
- mke2fs.recovery \
- mke2fs.conf
+LOCAL_MODULE := recovery_deps
ifeq ($(TARGET_USERIMAGES_USE_F2FS),true)
ifeq ($(HOST_OS),linux)
@@ -206,7 +66,8 @@ endif
# e2fsck is needed for adb remount -R.
ifeq ($(BOARD_EXT4_SHARE_DUP_BLOCKS),true)
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-LOCAL_REQUIRED_MODULES += e2fsck_static
+LOCAL_REQUIRED_MODULES += \
+ e2fsck_static
endif
endif
@@ -216,21 +77,7 @@ LOCAL_REQUIRED_MODULES += \
recovery-refresh
endif
-LOCAL_REQUIRED_MODULES += \
- librecovery_ui_ext
-
-# TODO(b/110380063): Explicitly install the following shared libraries to recovery, until `recovery`
-# module is built with Soong (with `recovery: true` flag).
-LOCAL_REQUIRED_MODULES += \
- libbase.recovery \
- liblog.recovery \
- libpng.recovery \
- libz.recovery \
-
-include $(BUILD_EXECUTABLE)
+include $(BUILD_PHONY_PACKAGE)
include \
- $(LOCAL_PATH)/boot_control/Android.mk \
- $(LOCAL_PATH)/tests/Android.mk \
$(LOCAL_PATH)/updater/Android.mk \
- $(LOCAL_PATH)/updater_sample/Android.mk \
diff --git a/boot_control/Android.bp b/boot_control/Android.bp
new file mode 100644
index 000000000..7720ead50
--- /dev/null
+++ b/boot_control/Android.bp
@@ -0,0 +1,37 @@
+//
+// 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_library_shared {
+ name: "bootctrl.default",
+ recovery_available: true,
+ relative_install_path: "hw",
+
+ srcs: ["boot_control.cpp"],
+
+ cflags: [
+ "-D_FILE_OFFSET_BITS=64",
+ "-Werror",
+ "-Wall",
+ "-Wextra",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libbootloader_message",
+ "libfs_mgr",
+ "liblog",
+ ],
+}
diff --git a/boot_control/Android.mk b/boot_control/Android.mk
deleted file mode 100644
index 9814d7122..000000000
--- a/boot_control/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (C) 2017 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.
-#
-
-LOCAL_PATH := $(my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := bootctrl.bcb
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := boot_control.cpp
-LOCAL_CFLAGS := \
- -D_FILE_OFFSET_BITS=64 \
- -Werror \
- -Wall \
- -Wextra
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_STATIC_LIBRARIES := libbootloader_message libfs_mgr libbase
-LOCAL_POST_INSTALL_CMD := \
- $(hide) mkdir -p $(TARGET_OUT_SHARED_LIBRARIES)/hw && \
- ln -sf bootctrl.bcb.so $(TARGET_OUT_SHARED_LIBRARIES)/hw/bootctrl.default.so
-include $(BUILD_SHARED_LIBRARY)
diff --git a/device.cpp b/device.cpp
index 3c6334e5c..eec1932c2 100644
--- a/device.cpp
+++ b/device.cpp
@@ -28,6 +28,7 @@
static std::vector<std::pair<std::string, Device::BuiltinAction>> g_menu_actions{
{ "Reboot system now", Device::REBOOT },
{ "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
+ { "Enter fastboot", Device::ENTER_FASTBOOT },
{ "Apply update from ADB", Device::APPLY_ADB_SIDELOAD },
{ "Apply update from SD card", Device::APPLY_SDCARD },
{ "Wipe data/factory reset", Device::WIPE_DATA },
diff --git a/device.h b/device.h
index a6ad62788..6a8daf83e 100644
--- a/device.h
+++ b/device.h
@@ -48,6 +48,8 @@ class Device {
RUN_GRAPHICS_TEST = 11,
RUN_LOCALE_TEST = 12,
KEY_INTERRUPTED = 13,
+ ENTER_FASTBOOT = 14,
+ ENTER_RECOVERY = 15,
};
explicit Device(RecoveryUI* ui);
diff --git a/etc/init.rc b/etc/init.rc
index 8e18438b5..9add2494a 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -6,6 +6,8 @@ on early-init
start ueventd
+ setprop sys.usb.configfs 0
+
on init
export ANDROID_ROOT /system
export ANDROID_DATA /data
@@ -31,20 +33,6 @@ on init
write /proc/sys/kernel/panic_on_oops 1
write /proc/sys/vm/max_map_count 1000000
-on fs
- write /sys/class/android_usb/android0/f_ffs/aliases adb
- mkdir /dev/usb-ffs 0770 shell shell
- mkdir /dev/usb-ffs/adb 0770 shell shell
- mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
-
- write /sys/class/android_usb/android0/enable 0
- write /sys/class/android_usb/android0/idVendor 18D1
- write /sys/class/android_usb/android0/idProduct D001
- write /sys/class/android_usb/android0/functions adb
- write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
- write /sys/class/android_usb/android0/iProduct ${ro.product.model}
- write /sys/class/android_usb/android0/iSerial ${ro.serialno}
-
on boot
ifup lo
hostname localhost
@@ -77,7 +65,7 @@ on late-init
trigger early-boot
trigger boot
-service ueventd /sbin/ueventd
+service ueventd /system/bin/ueventd
critical
seclabel u:r:ueventd:s0
@@ -86,6 +74,7 @@ service charger /charger -r
seclabel u:r:charger:s0
service recovery /system/bin/recovery
+ socket recovery stream 422 system system
seclabel u:r:recovery:s0
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
@@ -93,13 +82,89 @@ service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
socket adbd stream 660 system system
seclabel u:r:adbd:s0
-# Always start adbd on userdebug and eng builds
-on property:ro.debuggable=1
- write /sys/class/android_usb/android0/enable 1
- start adbd
+service fastbootd /system/bin/fastbootd
+ disabled
+ group system
+ seclabel u:r:fastbootd:s0
# Restart adbd so it can run as root
on property:service.adb.root=1
- write /sys/class/android_usb/android0/enable 0
restart adbd
+
+# Always start adbd on userdebug and eng builds
+on fs && property:ro.debuggable=1
+ setprop sys.usb.config adb
+
+on fs && property:sys.usb.configfs=1
+ mount configfs none /config
+ mkdir /config/usb_gadget/g1 0770 shell shell
+ write /config/usb_gadget/g1/idVendor 0x18D1
+ mkdir /config/usb_gadget/g1/strings/0x409 0770
+ write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
+ write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
+ write /config/usb_gadget/g1/strings/0x409/product ${ro.product.model}
+ mkdir /config/usb_gadget/g1/functions/ffs.adb
+ mkdir /config/usb_gadget/g1/functions/ffs.fastboot
+ mkdir /config/usb_gadget/g1/configs/b.1 0777 shell shell
+ mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell
+
+on fs && property:sys.usb.configfs=0
+ write /sys/class/android_usb/android0/f_ffs/aliases adb,fastboot
+ write /sys/class/android_usb/android0/idVendor 18D1
+ write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
+ write /sys/class/android_usb/android0/iProduct ${ro.product.model}
+ write /sys/class/android_usb/android0/iSerial ${ro.serialno}
+
+on fs
+ mkdir /dev/usb-ffs 0775 shell shell
+ mkdir /dev/usb-ffs/adb 0770 shell shell
+ mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000
+ mkdir /dev/usb-ffs/fastboot 0770 system system
+ mount functionfs fastboot /dev/usb-ffs/fastboot rmode=0770,fmode=0660,uid=1000,gid=1000
+
+on property:sys.usb.config=adb
+ start adbd
+
+on property:sys.usb.config=fastboot
+ start fastbootd
+
+on property:sys.usb.config=none
+ stop adbd
+ stop fastbootd
+
+on property:sys.usb.config=none && property:sys.usb.configfs=0
+ write /sys/class/android_usb/android0/enable 0
+ setprop sys.usb.state ${sys.usb.config}
+
+on property:sys.usb.config=adb && property:sys.usb.configfs=0
+ write /sys/class/android_usb/android0/idProduct D001
+ write /sys/class/android_usb/android0/functions adb
+ write /sys/class/android_usb/android0/enable 1
+ setprop sys.usb.state ${sys.usb.config}
+
+on property:sys.usb.config=fastboot && property:sys.usb.configfs=0
+ write /sys/class/android_usb/android0/idProduct 4EE0
+ write /sys/class/android_usb/android0/functions fastboot
write /sys/class/android_usb/android0/enable 1
+ setprop sys.usb.state ${sys.usb.config}
+
+# Configfs triggers
+on property:sys.usb.config=none && property:sys.usb.configfs=1
+ write /config/usb_gadget/g1/UDC "none"
+ setprop sys.usb.ffs.ready 0
+ rm /config/usb_gadget/g1/configs/b.1/f1
+ setprop sys.usb.state ${sys.usb.config}
+
+on property:sys.usb.config=adb && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
+ write /config/usb_gadget/g1/idProduct 0xD001
+ write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
+ symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
+ write /config/usb_gadget/g1/UDC ${sys.usb.controller}
+ setprop sys.usb.state ${sys.usb.config}
+
+on property:sys.usb.config=fastboot && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1
+ write /config/usb_gadget/g1/idProduct 0x4EE0
+ write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "fastboot"
+ symlink /config/usb_gadget/g1/functions/ffs.fastboot /config/usb_gadget/g1/configs/b.1/f1
+ write /config/usb_gadget/g1/UDC ${sys.usb.controller}
+ setprop sys.usb.state ${sys.usb.config}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
new file mode 100644
index 000000000..8458c99dd
--- /dev/null
+++ b/fastboot/fastboot.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#include "fastboot.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <bootloader_message/bootloader_message.h>
+
+#include "device.h"
+#include "ui.h"
+
+static const std::vector<std::pair<std::string, Device::BuiltinAction>> kFastbootMenuActions{
+ { "Reboot system now", Device::REBOOT },
+ { "Enter recovery", Device::ENTER_RECOVERY },
+ { "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
+ { "Power off", Device::SHUTDOWN },
+};
+
+Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& /* args */) {
+ RecoveryUI* ui = device->GetUI();
+
+ std::vector<std::string> title_lines = { "Android Fastboot" };
+ title_lines.push_back("Product name - " + android::base::GetProperty("ro.product.device", ""));
+ title_lines.push_back("Bootloader version - " + android::base::GetProperty("ro.bootloader", ""));
+ title_lines.push_back("Baseband version - " +
+ android::base::GetProperty("ro.build.expect.baseband", ""));
+ title_lines.push_back("Serial number - " + android::base::GetProperty("ro.serialno", ""));
+ title_lines.push_back(std::string("Secure boot - ") +
+ ((android::base::GetProperty("ro.secure", "") == "1") ? "yes" : "no"));
+ title_lines.push_back("HW version - " + android::base::GetProperty("ro.revision", ""));
+
+ ui->ResetKeyInterruptStatus();
+ ui->SetTitle(title_lines);
+ ui->ShowText(true);
+
+ // 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,
+ // set the 'command' field of BCB to 'boot-recovery' so the next boot is into recovery
+ // to finish any interrupted tasks.
+ std::string err;
+ if (!clear_bootloader_message(&err)) {
+ LOG(ERROR) << "Failed to clear BCB message: " << err;
+ }
+
+ std::vector<std::string> fastboot_menu_items;
+ std::transform(kFastbootMenuActions.cbegin(), kFastbootMenuActions.cend(),
+ std::back_inserter(fastboot_menu_items),
+ [](const auto& entry) { return entry.first; });
+
+ auto chosen_item = ui->ShowMenu(
+ {}, fastboot_menu_items, 0, false,
+ std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
+
+ if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED)) {
+ return Device::KEY_INTERRUPTED;
+ }
+ if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT)) {
+ return Device::BuiltinAction::NO_ACTION;
+ }
+ return kFastbootMenuActions[chosen_item].second;
+}
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
new file mode 100644
index 000000000..53a2adcae
--- /dev/null
+++ b/fastboot/fastboot.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "device.h"
+
+Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& args);
diff --git a/fuse_sideload/Android.bp b/fuse_sideload/Android.bp
index 76bc16df9..90c4c22c3 100644
--- a/fuse_sideload/Android.bp
+++ b/fuse_sideload/Android.bp
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_library_static {
+cc_library {
name: "libfusesideload",
+ recovery_available: true,
cflags: [
"-D_XOPEN_SOURCE",
@@ -30,7 +31,7 @@ cc_library_static {
"include",
],
- static_libs: [
+ shared_libs: [
"libbase",
"libcrypto",
],
diff --git a/install.cpp b/install.cpp
index 800847fdb..e379ef307 100644
--- a/install.cpp
+++ b/install.cpp
@@ -248,7 +248,7 @@ int SetUpAbUpdateCommands(const std::string& package, ZipArchiveHandle zip, int
}
long payload_offset = payload_entry.offset;
*cmd = {
- "/sbin/update_engine_sideload",
+ "/system/bin/update_engine_sideload",
"--payload=file://" + package,
android::base::StringPrintf("--offset=%ld", payload_offset),
"--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
diff --git a/minadbd/Android.bp b/minadbd/Android.bp
index 432b2f0f5..00244ee7e 100644
--- a/minadbd/Android.bp
+++ b/minadbd/Android.bp
@@ -26,8 +26,11 @@ cc_defaults {
],
}
-cc_library_static {
- name: "libminadbd",
+// `libminadbd_services` is analogous to the `libadbd_services` for regular `adbd`, but providing
+// the sideload service only.
+cc_library {
+ name: "libminadbd_services",
+ recovery_available: true,
defaults: [
"minadbd_defaults",
@@ -39,14 +42,11 @@ cc_library_static {
"minadbd_services.cpp",
],
- static_libs: [
- "libfusesideload",
+ shared_libs: [
+ "libadbd",
"libbase",
"libcrypto",
- ],
-
- whole_static_libs: [
- "libadbd",
+ "libfusesideload",
],
}
@@ -62,8 +62,9 @@ cc_test {
],
static_libs: [
+ "libminadbd_services",
+ "libadbd",
"libBionicGtestMain",
- "libminadbd",
],
shared_libs: [
diff --git a/minui/Android.bp b/minui/Android.bp
index 19d28be62..fff3a8ec9 100644
--- a/minui/Android.bp
+++ b/minui/Android.bp
@@ -14,6 +14,7 @@
cc_library {
name: "libminui",
+ recovery_available: true,
defaults: [
"recovery_defaults",
@@ -35,7 +36,7 @@ cc_library {
whole_static_libs: [
"libadf",
"libdrm",
- "libsync_recovery",
+ "libsync",
],
shared_libs: [
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
index 9336a1e63..630b80180 100644
--- a/minui/graphics_drm.cpp
+++ b/minui/graphics_drm.cpp
@@ -117,12 +117,16 @@ GRSurfaceDrm* MinuiBackendDrm::DrmCreateSurface(int width, int height) {
uint32_t format;
PixelFormat pixel_format = gr_pixel_format();
+ // PixelFormat comes in byte order, whereas DRM_FORMAT_* uses little-endian
+ // (external/libdrm/include/drm/drm_fourcc.h). Note that although drm_fourcc.h also defines a
+ // macro of DRM_FORMAT_BIG_ENDIAN, it doesn't seem to be actually supported (see the discussion
+ // in https://lists.freedesktop.org/archives/amd-gfx/2017-May/008560.html).
if (pixel_format == PixelFormat::ABGR) {
- format = DRM_FORMAT_ABGR8888;
+ format = DRM_FORMAT_RGBA8888;
} else if (pixel_format == PixelFormat::BGRA) {
- format = DRM_FORMAT_BGRA8888;
+ format = DRM_FORMAT_ARGB8888;
} else if (pixel_format == PixelFormat::RGBX) {
- format = DRM_FORMAT_RGBX8888;
+ format = DRM_FORMAT_XBGR8888;
} else {
format = DRM_FORMAT_RGB565;
}
diff --git a/otautil/Android.bp b/otautil/Android.bp
index b058f7b35..56c7c9e89 100644
--- a/otautil/Android.bp
+++ b/otautil/Android.bp
@@ -16,6 +16,11 @@ cc_library_static {
name: "libotautil",
host_supported: true,
+ recovery_available: true,
+
+ defaults: [
+ "recovery_defaults",
+ ],
// Minimal set of files to support host build.
srcs: [
@@ -23,16 +28,10 @@ cc_library_static {
"rangeset.cpp",
],
- static_libs: [
+ shared_libs: [
"libbase",
],
- cflags: [
- "-D_FILE_OFFSET_BITS=64",
- "-Werror",
- "-Wall",
- ],
-
export_include_dirs: [
"include",
],
@@ -46,9 +45,9 @@ cc_library_static {
"thermalutil.cpp",
],
- static_libs: [
- "libselinux",
+ shared_libs: [
"libcutils",
+ "libselinux",
],
},
},
diff --git a/recovery.cpp b/recovery.cpp
index 3828e29b3..01bd83b5e 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -49,7 +49,7 @@
#include <android-base/unique_fd.h>
#include <bootloader_message/bootloader_message.h>
#include <cutils/properties.h> /* for property_list */
-#include <healthd/BatteryMonitor.h>
+#include <healthhalutils/HealthHalUtils.h>
#include <ziparchive/zip_archive.h>
#include "adb_install.h"
@@ -779,6 +779,8 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) {
case Device::REBOOT:
case Device::SHUTDOWN:
case Device::REBOOT_BOOTLOADER:
+ case Device::ENTER_FASTBOOT:
+ case Device::ENTER_RECOVERY:
return chosen_action;
case Device::WIPE_DATA:
@@ -876,54 +878,63 @@ void ui_print(const char* format, ...) {
}
static bool is_battery_ok(int* required_battery_level) {
- struct healthd_config healthd_config = {
- .batteryStatusPath = android::String8(android::String8::kEmptyString),
- .batteryHealthPath = android::String8(android::String8::kEmptyString),
- .batteryPresentPath = android::String8(android::String8::kEmptyString),
- .batteryCapacityPath = android::String8(android::String8::kEmptyString),
- .batteryVoltagePath = android::String8(android::String8::kEmptyString),
- .batteryTemperaturePath = android::String8(android::String8::kEmptyString),
- .batteryTechnologyPath = android::String8(android::String8::kEmptyString),
- .batteryCurrentNowPath = android::String8(android::String8::kEmptyString),
- .batteryCurrentAvgPath = android::String8(android::String8::kEmptyString),
- .batteryChargeCounterPath = android::String8(android::String8::kEmptyString),
- .batteryFullChargePath = android::String8(android::String8::kEmptyString),
- .batteryCycleCountPath = android::String8(android::String8::kEmptyString),
- .energyCounter = nullptr,
- .boot_min_cap = 0,
- .screen_on = nullptr
- };
- healthd_board_init(&healthd_config);
+ using android::hardware::health::V1_0::BatteryStatus;
+ using android::hardware::health::V2_0::get_health_service;
+ using android::hardware::health::V2_0::IHealth;
+ using android::hardware::health::V2_0::Result;
+ using android::hardware::health::V2_0::toString;
- android::BatteryMonitor monitor;
- monitor.init(&healthd_config);
+ android::sp<IHealth> health = get_health_service();
static constexpr int BATTERY_READ_TIMEOUT_IN_SEC = 10;
int wait_second = 0;
while (true) {
- int charge_status = monitor.getChargeStatus();
+ auto charge_status = BatteryStatus::UNKNOWN;
+
+ if (health == nullptr) {
+ LOG(WARNING) << "no health implementation is found, assuming defaults";
+ } else {
+ health
+ ->getChargeStatus([&charge_status](auto res, auto out_status) {
+ if (res == Result::SUCCESS) {
+ charge_status = out_status;
+ }
+ })
+ .isOk(); // should not have transport error
+ }
+
// Treat unknown status as charged.
- bool charged = (charge_status != android::BATTERY_STATUS_DISCHARGING &&
- charge_status != android::BATTERY_STATUS_NOT_CHARGING);
- android::BatteryProperty capacity;
- android::status_t status = monitor.getProperty(android::BATTERY_PROP_CAPACITY, &capacity);
- ui_print("charge_status %d, charged %d, status %d, capacity %" PRId64 "\n", charge_status,
- charged, status, capacity.valueInt64);
+ bool charged = (charge_status != BatteryStatus::DISCHARGING &&
+ charge_status != BatteryStatus::NOT_CHARGING);
+
+ Result res = Result::UNKNOWN;
+ int32_t capacity = INT32_MIN;
+ if (health != nullptr) {
+ health
+ ->getCapacity([&res, &capacity](auto out_res, auto out_capacity) {
+ res = out_res;
+ capacity = out_capacity;
+ })
+ .isOk(); // should not have transport error
+ }
+
+ LOG(INFO) << "charge_status " << toString(charge_status) << ", charged " << charged
+ << ", status " << toString(res) << ", capacity " << capacity;
// At startup, the battery drivers in devices like N5X/N6P take some time to load
// the battery profile. Before the load finishes, it reports value 50 as a fake
// capacity. BATTERY_READ_TIMEOUT_IN_SEC is set that the battery drivers are expected
// to finish loading the battery profile earlier than 10 seconds after kernel startup.
- if (status == 0 && capacity.valueInt64 == 50) {
+ if (res == Result::SUCCESS && capacity == 50) {
if (wait_second < BATTERY_READ_TIMEOUT_IN_SEC) {
sleep(1);
wait_second++;
continue;
}
}
- // If we can't read battery percentage, it may be a device without battery. In this situation,
- // use 100 as a fake battery percentage.
- if (status != 0) {
- capacity.valueInt64 = 100;
+ // If we can't read battery percentage, it may be a device without battery. In this
+ // situation, use 100 as a fake battery percentage.
+ if (res != Result::SUCCESS) {
+ capacity = 100;
}
// GmsCore enters recovery mode to install package when having enough battery percentage.
@@ -932,7 +943,7 @@ static bool is_battery_ok(int* required_battery_level) {
static constexpr int BATTERY_OK_PERCENTAGE = 20;
static constexpr int BATTERY_WITH_CHARGER_OK_PERCENTAGE = 15;
*required_battery_level = charged ? BATTERY_WITH_CHARGER_OK_PERCENTAGE : BATTERY_OK_PERCENTAGE;
- return capacity.valueInt64 >= *required_battery_level;
+ return capacity >= *required_battery_level;
}
}
@@ -986,6 +997,7 @@ static void log_failure_code(ErrorCode code, const std::string& update_package)
Device::BuiltinAction start_recovery(Device* device, const std::vector<std::string>& args) {
static constexpr struct option OPTIONS[] = {
+ { "fastboot", no_argument, nullptr, 0 },
{ "fsck_unshare_blocks", no_argument, nullptr, 0 },
{ "just_exit", no_argument, nullptr, 'x' },
{ "locale", required_argument, nullptr, 0 },
@@ -1040,7 +1052,7 @@ Device::BuiltinAction start_recovery(Device* device, const std::vector<std::stri
std::string option = OPTIONS[option_index].name;
if (option == "fsck_unshare_blocks") {
fsck_unshare_blocks = true;
- } else if (option == "locale") {
+ } else if (option == "locale" || option == "fastboot") {
// Handled in recovery_main.cpp
} else if (option == "prompt_and_wipe_data") {
should_prompt_and_wipe_data = true;
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 9a9890de0..99f965098 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -30,15 +30,19 @@
#include <time.h>
#include <unistd.h>
+#include <atomic>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <bootloader_message/bootloader_message.h>
#include <cutils/android_reboot.h>
+#include <cutils/sockets.h>
#include <private/android_logger.h> /* private pmsg functions */
#include <selinux/android.h>
#include <selinux/label.h>
@@ -46,6 +50,7 @@
#include "common.h"
#include "device.h"
+#include "fastboot/fastboot.h"
#include "logging.h"
#include "minadbd/minadbd.h"
#include "otautil/paths.h"
@@ -162,6 +167,44 @@ static std::string load_locale_from_cache() {
return android::base::Trim(content);
}
+static void ListenRecoverySocket(RecoveryUI* ui, std::atomic<Device::BuiltinAction>& action) {
+ android::base::unique_fd sock_fd(android_get_control_socket("recovery"));
+ if (sock_fd < 0) {
+ PLOG(ERROR) << "Failed to open recovery socket";
+ return;
+ }
+ listen(sock_fd, 4);
+
+ while (true) {
+ android::base::unique_fd connection_fd;
+ connection_fd.reset(accept(sock_fd, nullptr, nullptr));
+ if (connection_fd < 0) {
+ PLOG(ERROR) << "Failed to accept socket connection";
+ continue;
+ }
+ char msg;
+ constexpr char kSwitchToFastboot = 'f';
+ constexpr char kSwitchToRecovery = 'r';
+ ssize_t ret = TEMP_FAILURE_RETRY(read(connection_fd, &msg, sizeof(msg)));
+ if (ret != sizeof(msg)) {
+ PLOG(ERROR) << "Couldn't read from socket";
+ continue;
+ }
+ switch (msg) {
+ case kSwitchToRecovery:
+ action = Device::BuiltinAction::ENTER_RECOVERY;
+ break;
+ case kSwitchToFastboot:
+ action = Device::BuiltinAction::ENTER_FASTBOOT;
+ break;
+ default:
+ LOG(ERROR) << "Unrecognized char from socket " << msg;
+ continue;
+ }
+ ui->InterruptKey();
+ }
+}
+
static void redirect_stdio(const char* filename) {
int pipefd[2];
if (pipe(pipefd) == -1) {
@@ -251,6 +294,11 @@ static void redirect_stdio(const char* filename) {
}
}
+static bool SetUsbConfig(const std::string& state) {
+ android::base::SetProperty("sys.usb.config", state);
+ return android::base::WaitForProperty("sys.usb.state", state);
+}
+
int main(int argc, char** argv) {
// We don't have logcat yet under recovery; so we'll print error on screen and log to stdout
// (which is redirected to recovery.log) as we used to do.
@@ -281,8 +329,6 @@ int main(int argc, char** argv) {
// instances with different timestamps.
redirect_stdio(Paths::Get().temporary_log_file().c_str());
- printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));
-
load_volume_table();
has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
@@ -290,12 +336,14 @@ int main(int argc, char** argv) {
auto args_to_parse = StringVectorToNullTerminatedArray(args);
static constexpr struct option OPTIONS[] = {
+ { "fastboot", no_argument, nullptr, 0 },
{ "locale", required_argument, nullptr, 0 },
{ "show_text", no_argument, nullptr, 't' },
{ nullptr, 0, nullptr, 0 },
};
bool show_text = false;
+ bool fastboot = false;
std::string locale;
int arg;
@@ -310,6 +358,8 @@ int main(int argc, char** argv) {
std::string option = OPTIONS[option_index].name;
if (option == "locale") {
locale = optarg;
+ } else if (option == "fastboot") {
+ fastboot = true;
}
break;
}
@@ -328,8 +378,6 @@ int main(int argc, char** argv) {
}
}
- printf("locale is [%s]\n", locale.c_str());
-
static constexpr const char* kDefaultLibRecoveryUIExt = "librecovery_ui_ext.so";
// Intentionally not calling dlclose(3) to avoid potential gotchas (e.g. `make_device` may have
// handed out pointers to code or static [or thread-local] data and doesn't collect them all back
@@ -374,33 +422,67 @@ int main(int argc, char** argv) {
ui->SetBackground(RecoveryUI::NONE);
if (show_text) ui->ShowText(true);
+ LOG(INFO) << "Starting recovery (pid " << getpid() << ") on " << ctime(&start);
+ LOG(INFO) << "locale is [" << locale << "]";
+
sehandle = selinux_android_file_context_handle();
selinux_android_set_sehandle(sehandle);
if (!sehandle) {
ui->Print("Warning: No file_contexts\n");
}
- Device::BuiltinAction after = start_recovery(device, args);
+ std::atomic<Device::BuiltinAction> action;
+ std::thread listener_thread(ListenRecoverySocket, ui, std::ref(action));
+ listener_thread.detach();
+
+ while (true) {
+ std::string usb_config = fastboot ? "fastboot" : is_ro_debuggable() ? "adb" : "none";
+ std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
+ if (usb_config != usb_state) {
+ if (!SetUsbConfig("none")) {
+ LOG(ERROR) << "Failed to clear USB config";
+ }
+ if (!SetUsbConfig(usb_config)) {
+ LOG(ERROR) << "Failed to set USB config to " << usb_config;
+ }
+ }
- switch (after) {
- case Device::SHUTDOWN:
- ui->Print("Shutting down...\n");
- android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
- break;
+ auto ret = fastboot ? StartFastboot(device, args) : start_recovery(device, args);
- case Device::REBOOT_BOOTLOADER:
- ui->Print("Rebooting to bootloader...\n");
- android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
- break;
+ if (ret == Device::KEY_INTERRUPTED) {
+ ret = action.exchange(ret);
+ if (ret == Device::NO_ACTION) {
+ continue;
+ }
+ }
+ switch (ret) {
+ case Device::SHUTDOWN:
+ ui->Print("Shutting down...\n");
+ android::base::SetProperty(ANDROID_RB_PROPERTY, "shutdown,");
+ break;
- default:
- ui->Print("Rebooting...\n");
- reboot("reboot,");
- break;
- }
- while (true) {
- pause();
+ case Device::REBOOT_BOOTLOADER:
+ ui->Print("Rebooting to bootloader...\n");
+ android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,bootloader");
+ break;
+
+ case Device::ENTER_FASTBOOT:
+ LOG(INFO) << "Entering fastboot";
+ fastboot = true;
+ break;
+
+ case Device::ENTER_RECOVERY:
+ LOG(INFO) << "Entering recovery";
+ fastboot = false;
+ break;
+
+ default:
+ ui->Print("Rebooting...\n");
+ reboot("reboot,");
+ break;
+ }
}
+
// Should be unreachable.
return EXIT_SUCCESS;
}
diff --git a/roots.cpp b/roots.cpp
index 2b26bf43e..06a77c186 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -327,6 +327,7 @@ int format_volume(const char* volume, const char* directory) {
"-f",
"-O", "encrypt",
"-O", "quota",
+ "-O", "verity",
"-w", std::to_string(kSectorSize),
v->blk_device,
};
diff --git a/tests/Android.bp b/tests/Android.bp
new file mode 100644
index 000000000..d305e2560
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,218 @@
+// 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: "recovery_test_defaults",
+
+ defaults: [
+ "recovery_defaults",
+ ],
+
+ include_dirs: [
+ "bootable/recovery",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libcrypto",
+ "libcutils",
+ "liblog",
+ "libpng",
+ "libselinux",
+ "libz",
+ "libziparchive",
+ ],
+
+ target: {
+ android: {
+ shared_libs: [
+ "libutils",
+ ],
+ },
+
+ host: {
+ static_libs: [
+ "libutils",
+ ],
+ }
+ },
+}
+
+// libapplypatch, libapplypatch_modes, libimgdiff, libimgpatch
+libapplypatch_static_libs = [
+ "libapplypatch_modes",
+ "libapplypatch",
+ "libedify",
+ "libimgdiff",
+ "libimgpatch",
+ "libotafault",
+ "libotautil",
+ "libbsdiff",
+ "libbspatch",
+ "libdivsufsort",
+ "libdivsufsort64",
+ "libutils",
+ "libbase",
+ "libbrotli",
+ "libbz",
+ "libcrypto",
+ "libz",
+ "libziparchive",
+]
+
+// librecovery_defaults uses many shared libs that we want to avoid using in tests (e.g. we don't
+// have 32-bit android.hardware.health@2.0.so or libbootloader_message.so on marlin).
+librecovery_static_libs = [
+ "librecovery",
+ "librecovery_fastboot",
+ "libminui",
+ "libverifier",
+ "libotautil",
+
+ "libhealthhalutils",
+ "libvintf_recovery",
+ "libvintf",
+
+ "android.hardware.health@2.0",
+ "android.hardware.health@1.0",
+ "libbootloader_message",
+ "libext4_utils",
+ "libfs_mgr",
+ "libfusesideload",
+ "libhidl-gen-utils",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "libvndksupport",
+ "libtinyxml2",
+]
+
+cc_test {
+ name: "recovery_unit_test",
+
+ defaults: [
+ "recovery_test_defaults",
+ ],
+
+ test_suites: ["device-tests"],
+
+ srcs: [
+ "unit/asn1_decoder_test.cpp",
+ "unit/applypatch_test.cpp",
+ "unit/commands_test.cpp",
+ "unit/dirutil_test.cpp",
+ "unit/locale_test.cpp",
+ "unit/rangeset_test.cpp",
+ "unit/screen_ui_test.cpp",
+ "unit/sysutil_test.cpp",
+ "unit/zip_test.cpp",
+ ],
+
+ static_libs: libapplypatch_static_libs + [
+ "librecovery_ui",
+ "libminui",
+ "libverifier",
+ "libotautil",
+ "libupdater",
+ "libgtest_prod",
+ "libBionicGtestMain",
+ ],
+
+ data: ["testdata/*"],
+}
+
+cc_test {
+ name: "recovery_manual_test",
+
+ defaults: [
+ "recovery_test_defaults",
+ ],
+
+ test_suites: ["device-tests"],
+
+ srcs: [
+ "manual/recovery_test.cpp",
+ ],
+
+ static_libs: [
+ "libBionicGtestMain",
+ ],
+}
+
+cc_test {
+ name: "recovery_component_test",
+
+ defaults: [
+ "recovery_test_defaults",
+ "libupdater_defaults",
+ ],
+
+ test_suites: ["device-tests"],
+
+ srcs: [
+ "component/bootloader_message_test.cpp",
+ "component/edify_test.cpp",
+ "component/imgdiff_test.cpp",
+ "component/install_test.cpp",
+ "component/resources_test.cpp",
+ "component/sideload_test.cpp",
+ "component/uncrypt_test.cpp",
+ "component/updater_test.cpp",
+ "component/update_verifier_test.cpp",
+ "component/verifier_test.cpp",
+ ],
+
+ static_libs: libapplypatch_static_libs + librecovery_static_libs + [
+ "libupdater",
+ "libupdate_verifier",
+ "libprotobuf-cpp-lite",
+ "libBionicGtestMain",
+ ],
+
+ data: [
+ "testdata/*",
+ ":res-testdata",
+ ],
+}
+
+cc_test_host {
+ name: "recovery_host_test",
+
+ defaults: [
+ "recovery_test_defaults",
+ ],
+
+ srcs: [
+ "component/imgdiff_test.cpp",
+ ],
+
+ static_libs: [
+ "libimgdiff",
+ "libimgpatch",
+ "libotautil",
+ "libbsdiff",
+ "libbspatch",
+ "libziparchive",
+ "libutils",
+ "libcrypto",
+ "libbrotli",
+ "libbz",
+ "libdivsufsort64",
+ "libdivsufsort",
+ "libz",
+ "libBionicGtestMain",
+ ],
+
+ data: ["testdata/*"],
+}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index daf4853b9..000000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,230 +0,0 @@
-#
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-# libapplypatch, libapplypatch_modes, libimgdiff, libimgpatch.
-libapplypatch_static_libraries := \
- libapplypatch_modes \
- libapplypatch \
- libedify \
- libimgdiff \
- libimgpatch \
- libotafault \
- libotautil \
- libbsdiff \
- libbspatch \
- libdivsufsort \
- libdivsufsort64 \
- libutils \
- libbase \
- libbrotli \
- libbz \
- libcrypto \
- libz \
- libziparchive \
-
-# Unit tests
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_MODULE := recovery_unit_test
-LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_STATIC_LIBRARIES := \
- $(libapplypatch_static_libraries) \
- libverifier \
- librecovery_ui \
- libminui \
- libotautil \
- libupdater \
- libgtest_prod \
- libpng \
- libziparchive \
- libutils \
- libz \
- libselinux \
- libbase \
- libBionicGtestMain
-
-LOCAL_SRC_FILES := \
- unit/applypatch_test.cpp \
- unit/asn1_decoder_test.cpp \
- unit/commands_test.cpp \
- unit/dirutil_test.cpp \
- unit/locale_test.cpp \
- unit/rangeset_test.cpp \
- unit/screen_ui_test.cpp \
- unit/sysutil_test.cpp \
- unit/zip_test.cpp
-
-LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_TEST_DATA := \
- $(call find-test-data-in-subdirs, $(LOCAL_PATH), "*", testdata)
-include $(BUILD_NATIVE_TEST)
-
-# Manual tests
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_MODULE := recovery_manual_test
-LOCAL_STATIC_LIBRARIES := \
- libbase \
- libBionicGtestMain
-
-LOCAL_SRC_FILES := manual/recovery_test.cpp
-LOCAL_SHARED_LIBRARIES := \
- liblog
-
-include $(BUILD_NATIVE_TEST)
-
-# Component tests
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := \
- -Wall \
- -Werror \
- -D_FILE_OFFSET_BITS=64
-
-LOCAL_MODULE := recovery_component_test
-LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_SRC_FILES := \
- component/applypatch_modes_test.cpp \
- component/bootloader_message_test.cpp \
- component/edify_test.cpp \
- component/imgdiff_test.cpp \
- component/install_test.cpp \
- component/resources_test.cpp \
- component/sideload_test.cpp \
- component/uncrypt_test.cpp \
- component/updater_test.cpp \
- component/update_verifier_test.cpp \
- component/verifier_test.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libhidlbase \
- libprotobuf-cpp-lite
-
-tune2fs_static_libraries := \
- libext2_com_err \
- libext2_blkid \
- libext2_quota \
- libext2_uuid \
- libext2_e2p \
- libext2fs
-
-libupdater_static_libraries := \
- libupdater \
- libapplypatch \
- libbspatch \
- libedify \
- libziparchive \
- libotautil \
- libbootloader_message \
- libutils \
- libotafault \
- libext4_utils \
- libfec \
- libfec_rs \
- libverity_tree \
- libfs_mgr \
- libgtest_prod \
- liblog \
- libselinux \
- libsparse \
- libsquashfs_utils \
- libbz \
- libz \
- libbase \
- libcrypto \
- libcrypto_utils \
- libcutils \
- libtune2fs \
- libbrotli \
- $(tune2fs_static_libraries)
-
-librecovery_static_libraries := \
- librecovery \
- libbootloader_message \
- libfusesideload \
- libminadbd \
- librecovery_ui_default \
- librecovery_ui \
- libminui \
- libverifier \
- libotautil \
- libasyncio \
- libbatterymonitor \
- libcrypto_utils \
- libcrypto \
- libext4_utils \
- libfs_mgr \
- libpng \
- libsparse \
- libvintf_recovery \
- libvintf \
- libhidl-gen-utils \
- libtinyxml2 \
- libziparchive \
- libbase \
- libutils \
- libcutils \
- liblog \
- libselinux \
- libz \
-
-libupdate_verifier_static_libraries := \
- libupdate_verifier \
-
-LOCAL_STATIC_LIBRARIES := \
- $(libapplypatch_static_libraries) \
- $(librecovery_static_libraries) \
- $(libupdate_verifier_static_libraries) \
- $(libupdater_static_libraries) \
- libBionicGtestMain
-
-LOCAL_TEST_DATA := \
- $(call find-test-data-in-subdirs, $(LOCAL_PATH), "*", testdata) \
- $(call find-test-data-in-subdirs, bootable/recovery, "*_text.png", res-*)
-include $(BUILD_NATIVE_TEST)
-
-# Host tests
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_MODULE := recovery_host_test
-LOCAL_MODULE_HOST_OS := linux
-LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_SRC_FILES := \
- component/imgdiff_test.cpp
-LOCAL_STATIC_LIBRARIES := \
- libimgdiff \
- libimgpatch \
- libotautil \
- libbsdiff \
- libbspatch \
- libziparchive \
- libutils \
- libbase \
- libcrypto \
- libbrotli \
- libbz \
- libdivsufsort64 \
- libdivsufsort \
- libz \
- libBionicGtestMain
-LOCAL_SHARED_LIBRARIES := \
- liblog
-LOCAL_TEST_DATA := \
- $(call find-test-data-in-subdirs, $(LOCAL_PATH), "*", testdata)
-include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/component/install_test.cpp b/tests/component/install_test.cpp
index b9af0b18b..08b429000 100644
--- a/tests/component/install_test.cpp
+++ b/tests/component/install_test.cpp
@@ -305,7 +305,7 @@ static void VerifyAbUpdateCommands(const std::string& serialno, bool success = t
if (success) {
ASSERT_EQ(0, SetUpAbUpdateCommands(package, zip, status_fd, &cmd));
ASSERT_EQ(5U, cmd.size());
- ASSERT_EQ("/sbin/update_engine_sideload", cmd[0]);
+ ASSERT_EQ("/system/bin/update_engine_sideload", cmd[0]);
ASSERT_EQ("--payload=file://" + package, cmd[1]);
ASSERT_EQ("--offset=" + std::to_string(payload_entry.offset), cmd[2]);
ASSERT_EQ("--headers=" + properties, cmd[3]);
diff --git a/tests/component/resources_test.cpp b/tests/component/resources_test.cpp
index 618d5a4dd..54329db22 100644
--- a/tests/component/resources_test.cpp
+++ b/tests/component/resources_test.cpp
@@ -32,10 +32,10 @@
static const std::string kLocale = "zu";
-static const std::vector<std::string> kResourceImagesDirs{ "res-mdpi/images/", "res-hdpi/images/",
- "res-xhdpi/images/",
- "res-xxhdpi/images/",
- "res-xxxhdpi/images/" };
+static const std::vector<std::string> kResourceImagesDirs{
+ "res-mdpi/images/", "res-hdpi/images/", "res-xhdpi/images/",
+ "res-xxhdpi/images/", "res-xxxhdpi/images/",
+};
static int png_filter(const dirent* de) {
if (de->d_type != DT_REG || !android::base::EndsWith(de->d_name, "_text.png")) {
diff --git a/tests/unit/commands_test.cpp b/tests/unit/commands_test.cpp
index 9679a9e73..19841d676 100644
--- a/tests/unit/commands_test.cpp
+++ b/tests/unit/commands_test.cpp
@@ -333,6 +333,25 @@ TEST(CommandsTest, Parse_ZERO) {
ASSERT_EQ(PatchInfo(), command.patch());
}
+TEST(CommandsTest, Parse_COMPUTE_HASH_TREE) {
+ const std::string input{ "compute_hash_tree 2,0,1 2,3,4 sha1 unknown-salt unknown-root-hash" };
+ std::string err;
+ Command command = Command::Parse(input, 9, &err);
+ ASSERT_TRUE(command);
+
+ ASSERT_EQ(Command::Type::COMPUTE_HASH_TREE, command.type());
+ ASSERT_EQ(9, command.index());
+ ASSERT_EQ(input, command.cmdline());
+
+ HashTreeInfo expected_info(RangeSet({ { 0, 1 } }), RangeSet({ { 3, 4 } }), "sha1", "unknown-salt",
+ "unknown-root-hash");
+ ASSERT_EQ(expected_info, command.hash_tree_info());
+ ASSERT_EQ(TargetInfo(), command.target());
+ ASSERT_EQ(SourceInfo(), command.source());
+ ASSERT_EQ(StashInfo(), command.stash());
+ ASSERT_EQ(PatchInfo(), command.patch());
+}
+
TEST(CommandsTest, Parse_InvalidNumberOfArgs) {
Command::abort_allowed_ = true;
@@ -341,6 +360,7 @@ TEST(CommandsTest, Parse_InvalidNumberOfArgs) {
std::vector<std::string> inputs{
"abort foo",
"bsdiff",
+ "compute_hash_tree, 2,0,1 2,0,1 unknown-algorithm unknown-salt",
"erase",
"erase 4,3,5,10,12 hash1",
"free",
diff --git a/tools/recovery_l10n/res/values-as/strings.xml b/tools/recovery_l10n/res/values-as/strings.xml
new file mode 100644
index 000000000..2624cebe4
--- /dev/null
+++ b/tools/recovery_l10n/res/values-as/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recovery_installing" msgid="2013591905463558223">"আপডেইট ইনষ্টল কৰি থকা হৈছে"</string>
+ <string name="recovery_erasing" msgid="7334826894904037088">"মচি থকা হৈছে"</string>
+ <string name="recovery_no_command" msgid="4465476568623024327">"কোনো আদেশ নাই"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"ত্ৰুটি!"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"সুৰক্ষা আপডেইট ইনষ্টল কৰি থকা হৈছে"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-en-rCA/strings.xml b/tools/recovery_l10n/res/values-en-rCA/strings.xml
new file mode 100644
index 000000000..dc75c2374
--- /dev/null
+++ b/tools/recovery_l10n/res/values-en-rCA/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recovery_installing" msgid="2013591905463558223">"Installing system update"</string>
+ <string name="recovery_erasing" msgid="7334826894904037088">"Erasing"</string>
+ <string name="recovery_no_command" msgid="4465476568623024327">"No command"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"Error!"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"Installing security update"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-en-rXC/strings.xml b/tools/recovery_l10n/res/values-en-rXC/strings.xml
new file mode 100644
index 000000000..2d528b3fb
--- /dev/null
+++ b/tools/recovery_l10n/res/values-en-rXC/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recovery_installing" msgid="2013591905463558223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎Installing system update‎‏‎‎‏‎"</string>
+ <string name="recovery_erasing" msgid="7334826894904037088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎Erasing‎‏‎‎‏‎"</string>
+ <string name="recovery_no_command" msgid="4465476568623024327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎No command‎‏‎‎‏‎"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎Error!‎‏‎‎‏‎"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎Installing security update‎‏‎‎‏‎"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-or/strings.xml b/tools/recovery_l10n/res/values-or/strings.xml
new file mode 100644
index 000000000..2b0851cdd
--- /dev/null
+++ b/tools/recovery_l10n/res/values-or/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recovery_installing" msgid="2013591905463558223">"ସିଷ୍ଟମ ଅପଡେଟ ଇନଷ୍ଟଲ କରୁଛି"</string>
+ <string name="recovery_erasing" msgid="7334826894904037088">"ଲିଭାଉଛି"</string>
+ <string name="recovery_no_command" msgid="4465476568623024327">"କୌଣସି କମାଣ୍ଡ ନାହିଁ"</string>
+ <string name="recovery_error" msgid="5748178989622716736">"ତ୍ରୁଟି!"</string>
+ <string name="recovery_installing_security" msgid="9184031299717114342">"ସୁରକ୍ଷା ଅପ୍‌ଡେଟ୍‌ ଇନ୍‌ଷ୍ଟଲ୍‌ କରୁଛି"</string>
+</resources>
diff --git a/updater/Android.bp b/updater/Android.bp
new file mode 100644
index 000000000..c77bac8fb
--- /dev/null
+++ b/updater/Android.bp
@@ -0,0 +1,80 @@
+// 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: "libupdater_defaults",
+
+ defaults: [
+ "recovery_defaults",
+ ],
+
+ static_libs: [
+ "libapplypatch",
+ "libbootloader_message",
+ "libbspatch",
+ "libedify",
+ "libotafault",
+ "libotautil",
+ "libext4_utils",
+ "libfec",
+ "libfec_rs",
+ "libverity_tree",
+ "libfs_mgr",
+ "libgtest_prod",
+ "liblog",
+ "libselinux",
+ "libsparse",
+ "libsquashfs_utils",
+ "libbrotli",
+ "libbz",
+ "libziparchive",
+ "libz",
+ "libbase",
+ "libcrypto",
+ "libcrypto_utils",
+ "libcutils",
+ "libutils",
+ "libtune2fs",
+
+ "libext2_com_err",
+ "libext2_blkid",
+ "libext2_quota",
+ "libext2_uuid",
+ "libext2_e2p",
+ "libext2fs",
+ ],
+}
+
+cc_library_static {
+ name: "libupdater",
+
+ defaults: [
+ "recovery_defaults",
+ "libupdater_defaults",
+ ],
+
+ srcs: [
+ "blockimg.cpp",
+ "commands.cpp",
+ "install.cpp",
+ ],
+
+ include_dirs: [
+ "external/e2fsprogs/misc",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+}
diff --git a/updater/Android.mk b/updater/Android.mk
index 78d0bd451..5478a7df6 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -25,12 +25,10 @@ tune2fs_static_libraries := \
updater_common_static_libraries := \
libapplypatch \
libbootloader_message \
+ libbspatch \
libedify \
libotafault \
libotautil \
- libbspatch \
- libziparchive \
- libutils \
libext4_utils \
libfec \
libfec_rs \
@@ -41,43 +39,18 @@ updater_common_static_libraries := \
libselinux \
libsparse \
libsquashfs_utils \
+ libbrotli \
libbz \
+ libziparchive \
libz \
libbase \
libcrypto \
libcrypto_utils \
libcutils \
+ libutils \
libtune2fs \
- libbrotli \
$(tune2fs_static_libraries)
-# libupdater (static library)
-# ===============================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libupdater
-
-LOCAL_SRC_FILES := \
- commands.cpp \
- install.cpp \
- blockimg.cpp
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/include \
- external/e2fsprogs/misc
-
-LOCAL_CFLAGS := \
- -Wall \
- -Werror
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
- $(LOCAL_PATH)/include
-
-LOCAL_STATIC_LIBRARIES := \
- $(updater_common_static_libraries)
-
-include $(BUILD_STATIC_LIBRARY)
-
# updater (static executable)
# ===============================
include $(CLEAR_VARS)
diff --git a/updater/commands.cpp b/updater/commands.cpp
index 15a787c51..4a90ea873 100644
--- a/updater/commands.cpp
+++ b/updater/commands.cpp
@@ -31,6 +31,14 @@ using namespace std::string_literals;
bool Command::abort_allowed_ = false;
+Command::Command(Type type, size_t index, std::string cmdline, HashTreeInfo hash_tree_info)
+ : type_(type),
+ index_(index),
+ cmdline_(std::move(cmdline)),
+ hash_tree_info_(std::move(hash_tree_info)) {
+ CHECK(type == Type::COMPUTE_HASH_TREE);
+}
+
Command::Type Command::ParseType(const std::string& type_str) {
if (type_str == "abort") {
if (!abort_allowed_) {
@@ -177,7 +185,6 @@ Command Command::Parse(const std::string& line, size_t index, std::string* err)
SourceInfo source_info;
StashInfo stash_info;
- // TODO(xunchang) add the parse code of compute_hash_tree
if (op == Type::ZERO || op == Type::NEW || op == Type::ERASE) {
// zero/new/erase <rangeset>
if (pos + 1 != tokens.size()) {
@@ -255,6 +262,39 @@ Command Command::Parse(const std::string& line, size_t index, std::string* err)
tokens.size() - pos);
return {};
}
+ } else if (op == Type::COMPUTE_HASH_TREE) {
+ // <hash_tree_ranges> <source_ranges> <hash_algorithm> <salt_hex> <root_hash>
+ if (pos + 5 != tokens.size()) {
+ *err = android::base::StringPrintf("invalid number of args: %zu (expected 5)",
+ tokens.size() - pos);
+ return {};
+ }
+
+ // Expects the hash_tree data to be contiguous.
+ RangeSet hash_tree_ranges = RangeSet::Parse(tokens[pos++]);
+ if (!hash_tree_ranges || hash_tree_ranges.size() != 1) {
+ *err = "invalid hash tree ranges in: " + line;
+ return {};
+ }
+
+ RangeSet source_ranges = RangeSet::Parse(tokens[pos++]);
+ if (!source_ranges) {
+ *err = "invalid source ranges in: " + line;
+ return {};
+ }
+
+ std::string hash_algorithm = tokens[pos++];
+ std::string salt_hex = tokens[pos++];
+ std::string root_hash = tokens[pos++];
+ if (hash_algorithm.empty() || salt_hex.empty() || root_hash.empty()) {
+ *err = "invalid hash tree arguments in " + line;
+ return {};
+ }
+
+ HashTreeInfo hash_tree_info(std::move(hash_tree_ranges), std::move(source_ranges),
+ std::move(hash_algorithm), std::move(salt_hex),
+ std::move(root_hash));
+ return Command(op, index, line, std::move(hash_tree_info));
} else {
*err = "invalid op";
return {};
diff --git a/updater/include/private/commands.h b/updater/include/private/commands.h
index 7f9dc79f4..85b52883b 100644
--- a/updater/include/private/commands.h
+++ b/updater/include/private/commands.h
@@ -166,6 +166,50 @@ class PatchInfo {
size_t length_{ 0 };
};
+// The arguments to build a hash tree from blocks on the block device.
+class HashTreeInfo {
+ public:
+ HashTreeInfo() = default;
+
+ HashTreeInfo(RangeSet hash_tree_ranges, RangeSet source_ranges, std::string hash_algorithm,
+ std::string salt_hex, std::string root_hash)
+ : hash_tree_ranges_(std::move(hash_tree_ranges)),
+ source_ranges_(std::move(source_ranges)),
+ hash_algorithm_(std::move(hash_algorithm)),
+ salt_hex_(std::move(salt_hex)),
+ root_hash_(std::move(root_hash)) {}
+
+ const RangeSet& hash_tree_ranges() const {
+ return hash_tree_ranges_;
+ }
+ const RangeSet& source_ranges() const {
+ return source_ranges_;
+ }
+
+ const std::string& hash_algorithm() const {
+ return hash_algorithm_;
+ }
+ const std::string& salt_hex() const {
+ return salt_hex_;
+ }
+ const std::string& root_hash() const {
+ return root_hash_;
+ }
+
+ bool operator==(const HashTreeInfo& other) const {
+ return hash_tree_ranges_ == other.hash_tree_ranges_ && source_ranges_ == other.source_ranges_ &&
+ hash_algorithm_ == other.hash_algorithm_ && salt_hex_ == other.salt_hex_ &&
+ root_hash_ == other.root_hash_;
+ }
+
+ private:
+ RangeSet hash_tree_ranges_;
+ RangeSet source_ranges_;
+ std::string hash_algorithm_;
+ std::string salt_hex_;
+ std::string root_hash_;
+};
+
// Command class holds the info for an update command that performs block-based OTA (BBOTA). Each
// command consists of one or several args, namely TargetInfo, SourceInfo, StashInfo and PatchInfo.
// The currently used BBOTA version is v4.
@@ -248,6 +292,8 @@ class Command {
source_(std::move(source)),
stash_(std::move(stash)) {}
+ Command(Type type, size_t index, std::string cmdline, HashTreeInfo hash_tree_info);
+
// Parses the given command 'line' into a Command object and returns it. The 'index' is specified
// by the caller to index the object. On parsing error, it returns an empty Command object that
// evaluates to false, and the specific error message will be set in 'err'.
@@ -284,6 +330,10 @@ class Command {
return stash_;
}
+ const HashTreeInfo& hash_tree_info() const {
+ return hash_tree_info_;
+ }
+
constexpr explicit operator bool() const {
return type_ != Type::LAST;
}
@@ -325,6 +375,8 @@ class Command {
// The stash info. Only meaningful for STASH and FREE commands. Note that although SourceInfo may
// also load data from stash, such info will be owned and managed by SourceInfo (i.e. in source_).
StashInfo stash_;
+ // The hash_tree info. Only meaningful for COMPUTE_HASH_TREE.
+ HashTreeInfo hash_tree_info_;
};
std::ostream& operator<<(std::ostream& os, const Command& command);
diff --git a/updater/install.cpp b/updater/install.cpp
index 088d24b31..f9333459b 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -497,12 +497,10 @@ Value* FormatFn(const char* name, State* state, const std::vector<std::unique_pt
const char* f2fs_argv[] = { "mkfs.f2fs",
"-d1",
"-f",
- "-O",
- "encrypt",
- "-O",
- "quota",
- "-w",
- "512",
+ "-O", "encrypt",
+ "-O", "quota",
+ "-O", "verity",
+ "-w", "512",
location.c_str(),
(size < 512) ? nullptr : num_sectors.c_str(),
nullptr };
diff --git a/updater_sample/Android.bp b/updater_sample/Android.bp
new file mode 100644
index 000000000..845e07b70
--- /dev/null
+++ b/updater_sample/Android.bp
@@ -0,0 +1,33 @@
+// 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.
+
+android_app {
+ name: "SystemUpdaterSample",
+ sdk_version: "system_current",
+ privileged: true,
+
+ srcs: ["src/**/*.java"],
+
+ static_libs: [
+ "guava",
+ ],
+
+ optimize: {
+ proguard_flags_files: [
+ "proguard.flags",
+ ],
+ },
+
+ resource_dirs: ["res"],
+}
diff --git a/updater_sample/Android.mk b/updater_sample/Android.mk
deleted file mode 100644
index cff5b0c1f..000000000
--- a/updater_sample/Android.mk
+++ /dev/null
@@ -1,35 +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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := SystemUpdaterSample
-LOCAL_SDK_VERSION := system_current
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES += guava
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/updater_sample/README.md b/updater_sample/README.md
index 306e71e5b..69e8e244f 100644
--- a/updater_sample/README.md
+++ b/updater_sample/README.md
@@ -227,7 +227,7 @@ privileged system app, so it's granted the required permissions to access
1. Build `mmma bootable/recovery/updater_sample/`
2. Install app
- `adb install $OUT/system/app/SystemUpdaterSample/SystemUpdaterSample.apk`
+ `adb install $OUT/system/priv-app/SystemUpdaterSample/SystemUpdaterSample.apk`
3. Install tests
`adb install $OUT/testcases/SystemUpdaterSampleTests/SystemUpdaterSampleTests.apk`
4. Run tests
diff --git a/updater_sample/tests/Android.bp b/updater_sample/tests/Android.bp
new file mode 100644
index 000000000..c2783ef88
--- /dev/null
+++ b/updater_sample/tests/Android.bp
@@ -0,0 +1,40 @@
+// 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.
+
+android_test {
+ name: "SystemUpdaterSampleTests",
+ sdk_version: "system_current",
+
+ libs: [
+ "android.test.base.stubs",
+ "android.test.runner.stubs",
+ "SystemUpdaterSample",
+ ],
+
+ static_libs: [
+ "android-support-test",
+ "mockito-target-minus-junit4",
+ "guava",
+ ],
+
+ instrumentation_for: "com.example.android.systemupdatersample",
+
+ optimize: {
+ enabled: false,
+ },
+
+ resource_dirs: ["res"],
+
+ srcs: ["src/**/*.java"],
+}
diff --git a/updater_sample/tests/Android.mk b/updater_sample/tests/Android.mk
deleted file mode 100644
index 415760454..000000000
--- a/updater_sample/tests/Android.mk
+++ /dev/null
@@ -1,36 +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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := SystemUpdaterSampleTests
-LOCAL_SDK_VERSION := system_current
-LOCAL_MODULE_TAGS := tests
-LOCAL_JAVA_LIBRARIES := \
- android.test.base.stubs \
- android.test.runner.stubs
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test \
- mockito-target-minus-junit4 \
- guava
-LOCAL_INSTRUMENTATION_FOR := SystemUpdaterSample
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-include $(BUILD_PACKAGE)