summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk38
-rw-r--r--adb_install.cpp30
-rw-r--r--applypatch/Android.mk75
-rw-r--r--applypatch/Makefile33
-rw-r--r--applypatch/applypatch.cpp316
-rw-r--r--applypatch/bsdiff.cpp410
-rw-r--r--applypatch/bspatch.cpp3
-rw-r--r--applypatch/freecache.cpp2
-rw-r--r--applypatch/imgdiff.cpp41
-rw-r--r--applypatch/imgpatch.cpp12
-rw-r--r--applypatch/include/applypatch/applypatch.h (renamed from applypatch/applypatch.h)1
-rw-r--r--applypatch/libimgpatch.pc6
-rw-r--r--applypatch/main.cpp10
-rw-r--r--applypatch/utils.cpp20
-rw-r--r--applypatch/utils.h5
-rw-r--r--bootloader_message/include/bootloader_message/bootloader_message.h122
-rw-r--r--device.cpp32
-rw-r--r--device.h2
-rw-r--r--edify/expr.cpp7
-rw-r--r--etc/META-INF/com/google/android/update-script8
-rw-r--r--etc/init.rc3
-rw-r--r--install.cpp202
-rw-r--r--minadbd/Android.mk4
-rw-r--r--minadbd/adb_main.cpp2
-rw-r--r--minadbd/fuse_adb_provider.cpp2
-rw-r--r--minadbd/minadbd_services.cpp (renamed from minadbd/services.cpp)5
-rw-r--r--minui/Android.mk1
-rw-r--r--minui/events.cpp17
-rw-r--r--minui/graphics_adf.cpp38
-rw-r--r--minui/minui.h6
-rw-r--r--minui/resources.cpp28
-rw-r--r--minzip/Android.mk2
-rw-r--r--minzip/DirUtil.cpp (renamed from minzip/DirUtil.c)66
-rw-r--r--minzip/DirUtil.h3
-rw-r--r--minzip/Zip.c26
-rw-r--r--minzip/Zip.h13
-rw-r--r--mounts.cpp89
-rw-r--r--mounts.h (renamed from mtdutils/mounts.h)25
-rw-r--r--mtdutils/Android.mk20
-rw-r--r--mtdutils/flash_image.c143
-rw-r--r--mtdutils/mounts.c161
-rw-r--r--mtdutils/mtdutils.c561
-rw-r--r--mtdutils/mtdutils.h62
-rw-r--r--otafault/Android.mk2
-rw-r--r--otafault/ota_io.cpp3
-rw-r--r--recovery-refresh.cpp4
-rw-r--r--recovery.cpp136
-rw-r--r--res-hdpi/images/erasing_text.pngbin55181 -> 50373 bytes
-rw-r--r--res-hdpi/images/error_text.pngbin39052 -> 35720 bytes
-rw-r--r--res-hdpi/images/installing_security_text.pngbin122186 -> 111582 bytes
-rw-r--r--res-hdpi/images/installing_text.pngbin113078 -> 102734 bytes
-rw-r--r--res-hdpi/images/no_command_text.pngbin67427 -> 61665 bytes
-rw-r--r--res-mdpi/images/erasing_text.pngbin31323 -> 29558 bytes
-rw-r--r--res-mdpi/images/error_text.pngbin22467 -> 20926 bytes
-rw-r--r--res-mdpi/images/installing_security_text.pngbin74376 -> 69709 bytes
-rw-r--r--res-mdpi/images/installing_text.pngbin66242 -> 61548 bytes
-rw-r--r--res-mdpi/images/no_command_text.pngbin36416 -> 34232 bytes
-rw-r--r--res-xhdpi/images/erasing_text.pngbin80047 -> 72595 bytes
-rw-r--r--res-xhdpi/images/error_text.pngbin57974 -> 51739 bytes
-rw-r--r--res-xhdpi/images/installing_security_text.pngbin212335 -> 195507 bytes
-rw-r--r--res-xhdpi/images/installing_text.pngbin191771 -> 174877 bytes
-rw-r--r--res-xhdpi/images/no_command_text.pngbin94944 -> 85999 bytes
-rw-r--r--res-xxhdpi/images/erasing_text.pngbin136033 -> 119060 bytes
-rw-r--r--res-xxhdpi/images/error_text.pngbin96714 -> 84432 bytes
-rw-r--r--res-xxhdpi/images/installing_security_text.pngbin484913 -> 447442 bytes
-rw-r--r--res-xxhdpi/images/installing_text.pngbin455797 -> 416541 bytes
-rw-r--r--res-xxhdpi/images/no_command_text.pngbin266239 -> 243828 bytes
-rw-r--r--res-xxxhdpi/images/erasing_text.pngbin297262 -> 264753 bytes
-rw-r--r--res-xxxhdpi/images/error_text.pngbin199691 -> 178491 bytes
-rw-r--r--res-xxxhdpi/images/installing_security_text.pngbin676381 -> 611664 bytes
-rw-r--r--res-xxxhdpi/images/installing_text.pngbin637038 -> 569291 bytes
-rw-r--r--res-xxxhdpi/images/no_command_text.pngbin372530 -> 333053 bytes
-rw-r--r--roots.cpp78
-rw-r--r--screen_ui.cpp10
-rw-r--r--tests/Android.mk4
-rw-r--r--tests/component/verifier_test.cpp86
-rw-r--r--tests/testdata/otasigned_v1.zip (renamed from tests/testdata/otasigned.zip)bin4009 -> 4009 bytes
-rw-r--r--tests/testdata/otasigned_v2.zip (renamed from tests/testdata/otasigned_f4.zip)bin5195 -> 5195 bytes
-rw-r--r--tests/testdata/otasigned_v3.zip (renamed from tests/testdata/otasigned_sha256.zip)bin5326 -> 5326 bytes
-rw-r--r--tests/testdata/otasigned_v4.zip (renamed from tests/testdata/otasigned_f4_sha256.zip)bin5319 -> 5319 bytes
-rw-r--r--tests/testdata/otasigned_v5.zip (renamed from tests/testdata/otasigned_ecdsa_sha256.zip)bin3085 -> 3085 bytes
-rw-r--r--tests/testdata/testkey_v1.pk8 (renamed from tests/testdata/testkey.pk8)bin1217 -> 1217 bytes
-rw-r--r--tests/testdata/testkey_v1.txt (renamed from tests/testdata/test_key_e3.txt)0
-rw-r--r--tests/testdata/testkey_v1.x509.pem (renamed from tests/testdata/testkey.x509.pem)0
-rw-r--r--tests/testdata/testkey_v2.pk8 (renamed from tests/testdata/test_f4.pk8)bin1217 -> 1217 bytes
-rw-r--r--tests/testdata/testkey_v2.txt (renamed from tests/testdata/test_key_f4.txt)0
-rw-r--r--tests/testdata/testkey_v2.x509.pem (renamed from tests/testdata/test_f4.x509.pem)0
l---------tests/testdata/testkey_v3.pk81
-rw-r--r--tests/testdata/testkey_v3.txt1
-rw-r--r--tests/testdata/testkey_v3.x509.pem (renamed from tests/testdata/testkey_sha256.x509.pem)0
l---------tests/testdata/testkey_v4.pk81
-rw-r--r--tests/testdata/testkey_v4.txt1
-rw-r--r--tests/testdata/testkey_v4.x509.pem (renamed from tests/testdata/test_f4_sha256.x509.pem)0
-rw-r--r--tests/testdata/testkey_v5.pk8 (renamed from tests/testdata/testkey_ecdsa.pk8)bin138 -> 138 bytes
-rw-r--r--tests/testdata/testkey_v5.txt (renamed from tests/testdata/test_key_ec.txt)0
-rw-r--r--tests/testdata/testkey_v5.x509.pem (renamed from tests/testdata/testkey_ecdsa.x509.pem)0
-rw-r--r--tools/dumpkey/Android.mk (renamed from tools/ota/Android.mk)21
-rw-r--r--tools/dumpkey/DumpPublicKey.java270
-rw-r--r--tools/dumpkey/DumpPublicKey.mf1
-rw-r--r--tools/ota/add-property-tag.c141
-rw-r--r--tools/ota/check-lost+found.c145
-rw-r--r--tools/ota/convert-to-bmp.py79
-rw-r--r--tools/recovery_l10n/README.md33
-rw-r--r--tools/recovery_l10n/res/values-af/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-am/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ar/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-az-rAZ/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-b+sr+Latn/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-be-rBY/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-bg/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-bn-rBD/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-bs-rBA/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ca/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-cs/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-da/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-de/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-el/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-en-rAU/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-en-rGB/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-en-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-es-rUS/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-es/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-et-rEE/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-eu-rES/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-fa/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-fi/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-fr-rCA/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-fr/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-gl-rES/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-gu-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-hi/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-hr/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-hu/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-hy-rAM/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-in/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-is-rIS/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-it/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-iw/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ja/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ka-rGE/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-kk-rKZ/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-km-rKH/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-kn-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ko/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ky-rKG/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-lo-rLA/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-lt/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-lv/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-mk-rMK/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ml-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-mn-rMN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-mr-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ms-rMY/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-my-rMM/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-nb/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ne-rNP/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-nl/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-pa-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-pl/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-pt-rBR/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-pt-rPT/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-pt/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ro/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ru/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-si-rLK/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sk/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sl/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sq-rAL/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sr/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sv/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-sw/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ta-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-te-rIN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-th/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-tl/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-tr/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-uk/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-ur-rPK/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-uz-rUZ/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-vi/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-zh-rCN/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-zh-rHK/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-zh-rTW/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values-zu/strings.xml9
-rw-r--r--tools/recovery_l10n/res/values/strings.xml1
-rw-r--r--tools/recovery_l10n/src/com/android/recovery_l10n/Main.java1
-rw-r--r--uncrypt/uncrypt.cpp82
-rw-r--r--unique_fd.h62
-rw-r--r--updater/Android.mk70
-rw-r--r--updater/blockimg.cpp42
-rw-r--r--updater/install.cpp206
-rw-r--r--updater/install.h4
-rw-r--r--updater/updater.cpp3
-rw-r--r--updater/updater.h4
-rw-r--r--verifier.cpp1
-rw-r--r--wear_ui.cpp10
196 files changed, 1686 insertions, 3198 deletions
diff --git a/Android.mk b/Android.mk
index 589bff41f..6aa29c141 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,18 +14,28 @@
LOCAL_PATH := $(call my-dir)
+# libfusesideload (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_SRC_FILES := fuse_sideload.cpp
LOCAL_CLANG := true
-LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
+LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter -Werror
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-
LOCAL_MODULE := libfusesideload
+LOCAL_STATIC_LIBRARIES := libcutils libc libcrypto
+include $(BUILD_STATIC_LIBRARY)
-LOCAL_STATIC_LIBRARIES := libcutils libc libcrypto_static
+# libmounts (static library)
+# ===============================
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := mounts.cpp
+LOCAL_CLANG := true
+LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
+LOCAL_MODULE := libmounts
include $(BUILD_STATIC_LIBRARY)
+# recovery (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
@@ -69,14 +79,15 @@ LOCAL_STATIC_LIBRARIES := \
libext4_utils_static \
libsparse_static \
libminzip \
+ libmounts \
libz \
- libmtdutils \
libminadbd \
libfusesideload \
libminui \
libpng \
libfs_mgr \
- libcrypto_static \
+ libcrypto_utils \
+ libcrypto \
libbase \
libcutils \
libutils \
@@ -87,11 +98,8 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_HAL_STATIC_LIBRARIES := libhealthd
-ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
- LOCAL_CFLAGS += -DUSE_EXT4
- LOCAL_C_INCLUDES += system/extras/ext4_utils
- LOCAL_STATIC_LIBRARIES += libext4_utils_static libz
-endif
+LOCAL_C_INCLUDES += system/extras/ext4_utils
+LOCAL_STATIC_LIBRARIES += libext4_utils_static libz
ifeq ($(AB_OTA_UPDATER),true)
LOCAL_CFLAGS += -DAB_OTA_UPDATER=1
@@ -131,7 +139,8 @@ LOCAL_CFLAGS := -Werror
LOCAL_INIT_RC := recovery-refresh.rc
include $(BUILD_EXECUTABLE)
-# All the APIs for testing
+# libverifier (static library)
+# ===============================
include $(CLEAR_VARS)
LOCAL_CLANG := true
LOCAL_MODULE := libverifier
@@ -140,17 +149,16 @@ LOCAL_SRC_FILES := \
asn1_decoder.cpp \
verifier.cpp \
ui.cpp
-LOCAL_STATIC_LIBRARIES := libcrypto_static
+LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto
include $(BUILD_STATIC_LIBRARY)
include \
$(LOCAL_PATH)/applypatch/Android.mk \
$(LOCAL_PATH)/bootloader_message/Android.mk \
$(LOCAL_PATH)/edify/Android.mk \
+ $(LOCAL_PATH)/minadbd/Android.mk \
$(LOCAL_PATH)/minui/Android.mk \
$(LOCAL_PATH)/minzip/Android.mk \
- $(LOCAL_PATH)/minadbd/Android.mk \
- $(LOCAL_PATH)/mtdutils/Android.mk \
$(LOCAL_PATH)/otafault/Android.mk \
$(LOCAL_PATH)/tests/Android.mk \
$(LOCAL_PATH)/tools/Android.mk \
diff --git a/adb_install.cpp b/adb_install.cpp
index 4aed9d4b1..b05fda13a 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -33,10 +33,7 @@
#include "minadbd/fuse_adb_provider.h"
#include "fuse_sideload.h"
-static RecoveryUI* ui = NULL;
-
-static void
-set_usb_driver(bool enabled) {
+static void set_usb_driver(RecoveryUI* ui, bool enabled) {
int fd = open("/sys/class/android_usb/android0/enable", O_WRONLY);
if (fd < 0) {
ui->Print("failed to open driver control: %s\n", strerror(errno));
@@ -50,18 +47,16 @@ set_usb_driver(bool enabled) {
}
}
-static void
-stop_adbd() {
+static void stop_adbd(RecoveryUI* ui) {
+ ui->Print("Stopping adbd...\n");
property_set("ctl.stop", "adbd");
- set_usb_driver(false);
+ set_usb_driver(ui, false);
}
-
-static void
-maybe_restart_adbd() {
+static void maybe_restart_adbd(RecoveryUI* ui) {
if (is_ro_debuggable()) {
ui->Print("Restarting adbd...\n");
- set_usb_driver(true);
+ set_usb_driver(ui, true);
property_set("ctl.start", "adbd");
}
}
@@ -70,14 +65,11 @@ maybe_restart_adbd() {
// package, before timing out.
#define ADB_INSTALL_TIMEOUT 300
-int
-apply_from_adb(RecoveryUI* ui_, bool* wipe_cache, const char* install_file) {
+int apply_from_adb(RecoveryUI* ui, bool* wipe_cache, const char* install_file) {
modified_flash = true;
- ui = ui_;
-
- stop_adbd();
- set_usb_driver(true);
+ stop_adbd(ui);
+ set_usb_driver(ui, true);
ui->Print("\n\nNow send the package you want to apply\n"
"to the device with \"adb sideload <filename>\"...\n");
@@ -137,8 +129,8 @@ apply_from_adb(RecoveryUI* ui_, bool* wipe_cache, const char* install_file) {
}
}
- set_usb_driver(false);
- maybe_restart_adbd();
+ set_usb_driver(ui, false);
+ maybe_restart_adbd(ui);
return result;
}
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 887a570db..604787e78 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -14,61 +14,86 @@
LOCAL_PATH := $(call my-dir)
+# libapplypatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
-LOCAL_SRC_FILES := applypatch.cpp bspatch.cpp freecache.cpp imgpatch.cpp utils.cpp
+LOCAL_SRC_FILES := \
+ applypatch.cpp \
+ bspatch.cpp \
+ freecache.cpp \
+ imgpatch.cpp \
+ utils.cpp
LOCAL_MODULE := libapplypatch
LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libbase libotafault libmtdutils libcrypto_static libbz libz
-
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES += \
+ libotafault \
+ libbase \
+ libcrypto \
+ libbz \
+ libz
include $(BUILD_STATIC_LIBRARY)
+# libimgpatch (static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
+LOCAL_STATIC_LIBRARIES += libcrypto libbz libz
include $(BUILD_STATIC_LIBRARY)
-ifeq ($(HOST_OS),linux)
+# libimgpatch (host static library)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include \
+ bootable/recovery
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
+LOCAL_STATIC_LIBRARIES += libcrypto libbz libz
include $(BUILD_HOST_STATIC_LIBRARY)
-endif # HOST_OS == linux
+# applypatch (executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
LOCAL_SRC_FILES := main.cpp
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libmtdutils libcrypto_static libbz \
- libedify \
-
+LOCAL_STATIC_LIBRARIES += \
+ libapplypatch \
+ libbase \
+ libedify \
+ libotafault \
+ libminzip \
+ libcrypto \
+ libbz
LOCAL_SHARED_LIBRARIES += libz libcutils libc
-
include $(BUILD_EXECUTABLE)
+# imgdiff (host static executable)
+# ===============================
include $(CLEAR_VARS)
-
LOCAL_CLANG := true
-LOCAL_SRC_FILES := imgdiff.cpp utils.cpp bsdiff.cpp
+LOCAL_SRC_FILES := imgdiff.cpp utils.cpp
LOCAL_MODULE := imgdiff
+LOCAL_STATIC_LIBRARIES += \
+ libbsdiff \
+ libbz \
+ libdivsufsort64 \
+ libdivsufsort \
+ libz
LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_C_INCLUDES += external/zlib external/bzip2
-LOCAL_STATIC_LIBRARIES += libz libbz
-
include $(BUILD_HOST_EXECUTABLE)
diff --git a/applypatch/Makefile b/applypatch/Makefile
new file mode 100644
index 000000000..fb4984303
--- /dev/null
+++ b/applypatch/Makefile
@@ -0,0 +1,33 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file is for building imgdiff in Chrome OS.
+
+CPPFLAGS += -iquote.. -Iinclude
+CXXFLAGS += -std=c++11 -O3 -Wall -Werror
+LDLIBS += -lbz2 -lz
+
+.PHONY: all clean
+
+all: imgdiff libimgpatch.a
+
+clean:
+ rm -f *.o imgdiff libimgpatch.a
+
+imgdiff: imgdiff.o bsdiff.o utils.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDLIBS) -o $@ $^
+
+libimgpatch.a utils.o: CXXFLAGS += -fPIC
+libimgpatch.a: imgpatch.o bspatch.o utils.o
+ ${AR} rcs $@ $^
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 7985fc0c6..02a3c6e41 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -31,8 +31,7 @@
#include <android-base/strings.h>
#include "openssl/sha.h"
-#include "applypatch.h"
-#include "mtdutils/mtdutils.h"
+#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "ota_io.h"
#include "print_sha1.h"
@@ -49,17 +48,14 @@ static int GenerateTarget(FileContents* source_file,
size_t target_size,
const Value* bonus_data);
-static bool mtd_partitions_scanned = false;
-
// Read a file into memory; store the file contents and associated
// metadata in *file.
//
// Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file) {
- // A special 'filename' beginning with "MTD:" or "EMMC:" means to
+ // A special 'filename' beginning with "EMMC:" means to
// load the contents of a partition.
- if (strncmp(filename, "MTD:", 4) == 0 ||
- strncmp(filename, "EMMC:", 5) == 0) {
+ if (strncmp(filename, "EMMC:", 5) == 0) {
return LoadPartitionContents(filename, file);
}
@@ -77,7 +73,7 @@ int LoadFileContents(const char* filename, FileContents* file) {
size_t bytes_read = ota_fread(data.data(), 1, data.size(), f);
if (bytes_read != data.size()) {
- printf("short read of \"%s\" (%zu bytes of %zd)\n", filename, bytes_read, data.size());
+ printf("short read of \"%s\" (%zu bytes of %zu)\n", filename, bytes_read, data.size());
ota_fclose(f);
return -1;
}
@@ -87,10 +83,9 @@ int LoadFileContents(const char* filename, FileContents* file) {
return 0;
}
-// Load the contents of an MTD or EMMC partition into the provided
+// Load the contents of an EMMC partition into the provided
// FileContents. filename should be a string of the form
-// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:..." (or
-// "EMMC:<partition_device>:..."). The smallest size_n bytes for
+// "EMMC:<partition_device>:...". The smallest size_n bytes for
// which that prefix of the partition contents has the corresponding
// sha1 hash will be loaded. It is acceptable for a size value to be
// repeated with different sha1s. Will return 0 on success.
@@ -102,8 +97,6 @@ int LoadFileContents(const char* filename, FileContents* file) {
// "end-of-file" marker), so the caller must specify the possible
// lengths and the hash of the data, and we'll do the load expecting
// to find one of those hashes.
-enum PartitionType { MTD, EMMC };
-
static int LoadPartitionContents(const char* filename, FileContents* file) {
std::string copy(filename);
std::vector<std::string> pieces = android::base::Split(copy, ":");
@@ -112,12 +105,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
return -1;
}
- enum PartitionType type;
- if (pieces[0] == "MTD") {
- type = MTD;
- } else if (pieces[0] == "EMMC") {
- type = EMMC;
- } else {
+ if (pieces[0] != "EMMC") {
printf("LoadPartitionContents called with bad filename (%s)\n", filename);
return -1;
}
@@ -145,36 +133,10 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
}
);
- MtdReadContext* ctx = NULL;
- FILE* dev = NULL;
-
- switch (type) {
- case MTD: {
- if (!mtd_partitions_scanned) {
- mtd_scan_partitions();
- mtd_partitions_scanned = true;
- }
-
- const MtdPartition* mtd = mtd_find_partition_by_name(partition);
- if (mtd == NULL) {
- printf("mtd partition \"%s\" not found (loading %s)\n", partition, filename);
- return -1;
- }
-
- ctx = mtd_read_partition(mtd);
- if (ctx == NULL) {
- printf("failed to initialize read of mtd partition \"%s\"\n", partition);
- return -1;
- }
- break;
- }
-
- case EMMC:
- dev = ota_fopen(partition, "rb");
- if (dev == NULL) {
- printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno));
- return -1;
- }
+ FILE* dev = ota_fopen(partition, "rb");
+ if (dev == NULL) {
+ printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno));
+ return -1;
}
SHA_CTX sha_ctx;
@@ -192,16 +154,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
// we're trying the possibilities in order of increasing size).
size_t next = size[index[i]] - data_size;
if (next > 0) {
- size_t read = 0;
- switch (type) {
- case MTD:
- read = mtd_read_data(ctx, p, next);
- break;
-
- case EMMC:
- read = ota_fread(p, 1, next, dev);
- break;
- }
+ size_t read = ota_fread(p, 1, next, dev);
if (next != read) {
printf("short read (%zu bytes of %zu) for partition \"%s\"\n",
read, next, partition);
@@ -234,16 +187,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
}
}
- switch (type) {
- case MTD:
- mtd_read_close(ctx);
- break;
-
- case EMMC:
- ota_fclose(dev);
- break;
- }
-
+ ota_fclose(dev);
if (!found) {
// Ran off the end of the list of (size,sha1) pairs without finding a match.
@@ -302,7 +246,7 @@ int SaveFileContents(const char* filename, const FileContents* file) {
}
// Write a memory buffer to 'target' partition, a string of the form
-// "MTD:<partition>[:...]" or "EMMC:<partition_device>[:...]". The target name
+// "EMMC:<partition_device>[:...]". The target name
// might contain multiple colons, but WriteToPartition() only uses the first
// two and ignores the rest. Return 0 on success.
int WriteToPartition(const unsigned char* data, size_t len, const char* target) {
@@ -314,165 +258,117 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
return -1;
}
- enum PartitionType type;
- if (pieces[0] == "MTD") {
- type = MTD;
- } else if (pieces[0] == "EMMC") {
- type = EMMC;
- } else {
+ if (pieces[0] != "EMMC") {
printf("WriteToPartition called with bad target (%s)\n", target);
return -1;
}
const char* partition = pieces[1].c_str();
- switch (type) {
- case MTD: {
- if (!mtd_partitions_scanned) {
- mtd_scan_partitions();
- mtd_partitions_scanned = true;
- }
-
- const MtdPartition* mtd = mtd_find_partition_by_name(partition);
- if (mtd == NULL) {
- printf("mtd partition \"%s\" not found for writing\n", partition);
- return -1;
- }
-
- MtdWriteContext* ctx = mtd_write_partition(mtd);
- if (ctx == NULL) {
- printf("failed to init mtd partition \"%s\" for writing\n", partition);
- return -1;
- }
+ size_t start = 0;
+ bool success = false;
+ int fd = ota_open(partition, O_RDWR | O_SYNC);
+ if (fd < 0) {
+ printf("failed to open %s: %s\n", partition, strerror(errno));
+ return -1;
+ }
- size_t written = mtd_write_data(ctx, reinterpret_cast<const char*>(data), len);
- if (written != len) {
- printf("only wrote %zu of %zu bytes to MTD %s\n", written, len, partition);
- mtd_write_close(ctx);
- return -1;
- }
+ for (size_t attempt = 0; attempt < 2; ++attempt) {
+ if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) {
+ printf("failed seek on %s: %s\n", partition, strerror(errno));
+ return -1;
+ }
+ while (start < len) {
+ size_t to_write = len - start;
+ if (to_write > 1<<20) to_write = 1<<20;
- if (mtd_erase_blocks(ctx, -1) < 0) {
- printf("error finishing mtd write of %s\n", partition);
- mtd_write_close(ctx);
+ ssize_t written = TEMP_FAILURE_RETRY(ota_write(fd, data+start, to_write));
+ if (written == -1) {
+ printf("failed write writing to %s: %s\n", partition, strerror(errno));
return -1;
}
+ start += written;
+ }
+ if (ota_fsync(fd) != 0) {
+ printf("failed to sync to %s (%s)\n", partition, strerror(errno));
+ return -1;
+ }
+ if (ota_close(fd) != 0) {
+ printf("failed to close %s (%s)\n", partition, strerror(errno));
+ return -1;
+ }
+ fd = ota_open(partition, O_RDONLY);
+ if (fd < 0) {
+ printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno));
+ return -1;
+ }
- if (mtd_write_close(ctx)) {
- printf("error closing mtd write of %s\n", partition);
- return -1;
- }
- break;
+ // Drop caches so our subsequent verification read
+ // won't just be reading the cache.
+ sync();
+ int dc = ota_open("/proc/sys/vm/drop_caches", O_WRONLY);
+ if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) {
+ printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno));
+ } else {
+ printf(" caches dropped\n");
}
+ ota_close(dc);
+ sleep(1);
- case EMMC: {
- size_t start = 0;
- bool success = false;
- int fd = ota_open(partition, O_RDWR | O_SYNC);
- if (fd < 0) {
- printf("failed to open %s: %s\n", partition, strerror(errno));
- return -1;
+ // verify
+ if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) {
+ printf("failed to seek back to beginning of %s: %s\n",
+ partition, strerror(errno));
+ return -1;
+ }
+ unsigned char buffer[4096];
+ start = len;
+ for (size_t p = 0; p < len; p += sizeof(buffer)) {
+ size_t to_read = len - p;
+ if (to_read > sizeof(buffer)) {
+ to_read = sizeof(buffer);
}
- for (size_t attempt = 0; attempt < 2; ++attempt) {
- if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) {
- printf("failed seek on %s: %s\n", partition, strerror(errno));
+ size_t so_far = 0;
+ while (so_far < to_read) {
+ ssize_t read_count =
+ TEMP_FAILURE_RETRY(ota_read(fd, buffer+so_far, to_read-so_far));
+ if (read_count == -1) {
+ printf("verify read error %s at %zu: %s\n",
+ partition, p, strerror(errno));
return -1;
}
- while (start < len) {
- size_t to_write = len - start;
- if (to_write > 1<<20) to_write = 1<<20;
-
- ssize_t written = TEMP_FAILURE_RETRY(ota_write(fd, data+start, to_write));
- if (written == -1) {
- printf("failed write writing to %s: %s\n", partition, strerror(errno));
- return -1;
- }
- start += written;
- }
- if (ota_fsync(fd) != 0) {
- printf("failed to sync to %s (%s)\n", partition, strerror(errno));
- return -1;
- }
- if (ota_close(fd) != 0) {
- printf("failed to close %s (%s)\n", partition, strerror(errno));
- return -1;
- }
- fd = ota_open(partition, O_RDONLY);
- if (fd < 0) {
- printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno));
- return -1;
- }
-
- // Drop caches so our subsequent verification read
- // won't just be reading the cache.
- sync();
- int dc = ota_open("/proc/sys/vm/drop_caches", O_WRONLY);
- if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) {
- printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno));
- } else {
- printf(" caches dropped\n");
- }
- ota_close(dc);
- sleep(1);
-
- // verify
- if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) {
- printf("failed to seek back to beginning of %s: %s\n",
- partition, strerror(errno));
- return -1;
- }
- unsigned char buffer[4096];
- start = len;
- for (size_t p = 0; p < len; p += sizeof(buffer)) {
- size_t to_read = len - p;
- if (to_read > sizeof(buffer)) {
- to_read = sizeof(buffer);
- }
-
- size_t so_far = 0;
- while (so_far < to_read) {
- ssize_t read_count =
- TEMP_FAILURE_RETRY(ota_read(fd, buffer+so_far, to_read-so_far));
- if (read_count == -1) {
- printf("verify read error %s at %zu: %s\n",
- partition, p, strerror(errno));
- return -1;
- }
- if (static_cast<size_t>(read_count) < to_read) {
- printf("short verify read %s at %zu: %zd %zu %s\n",
- partition, p, read_count, to_read, strerror(errno));
- }
- so_far += read_count;
- }
-
- if (memcmp(buffer, data+p, to_read) != 0) {
- printf("verification failed starting at %zu\n", p);
- start = p;
- break;
- }
- }
-
- if (start == len) {
- printf("verification read succeeded (attempt %zu)\n", attempt+1);
- success = true;
- break;
+ if (static_cast<size_t>(read_count) < to_read) {
+ printf("short verify read %s at %zu: %zd %zu %s\n",
+ partition, p, read_count, to_read, strerror(errno));
}
+ so_far += read_count;
}
- if (!success) {
- printf("failed to verify after all attempts\n");
- return -1;
+ if (memcmp(buffer, data+p, to_read) != 0) {
+ printf("verification failed starting at %zu\n", p);
+ start = p;
+ break;
}
+ }
- if (ota_close(fd) != 0) {
- printf("error closing %s (%s)\n", partition, strerror(errno));
- return -1;
- }
- sync();
+ if (start == len) {
+ printf("verification read succeeded (attempt %zu)\n", attempt+1);
+ success = true;
break;
}
}
+ if (!success) {
+ printf("failed to verify after all attempts\n");
+ return -1;
+ }
+
+ if (ota_close(fd) != 0) {
+ printf("error closing %s (%s)\n", partition, strerror(errno));
+ return -1;
+ }
+ sync();
+
return 0;
}
@@ -596,7 +492,7 @@ size_t FreeSpaceForFile(const char* filename) {
int CacheSizeCheck(size_t bytes) {
if (MakeFreeSpaceOnCache(bytes) < 0) {
- printf("unable to make %ld bytes available on /cache\n", (long)bytes);
+ printf("unable to make %zu bytes available on /cache\n", bytes);
return 1;
} else {
return 0;
@@ -729,7 +625,7 @@ int applypatch_flash(const char* source_filename, const char* target_filename,
std::string target_str(target_filename);
std::vector<std::string> pieces = android::base::Split(target_str, ":");
- if (pieces.size() != 2 || (pieces[0] != "MTD" && pieces[0] != "EMMC")) {
+ if (pieces.size() != 2 || pieces[0] != "EMMC") {
printf("invalid target name \"%s\"", target_filename);
return 1;
}
@@ -778,8 +674,7 @@ static int GenerateTarget(FileContents* source_file,
FileContents* source_to_use;
int made_copy = 0;
- bool target_is_partition = (strncmp(target_filename, "MTD:", 4) == 0 ||
- strncmp(target_filename, "EMMC:", 5) == 0);
+ bool target_is_partition = (strncmp(target_filename, "EMMC:", 5) == 0);
const std::string tmp_target_filename = std::string(target_filename) + ".patch";
// assume that target_filename (eg "/system/app/Foo.apk") is located
@@ -860,8 +755,7 @@ static int GenerateTarget(FileContents* source_file,
// copy the source file to cache, then delete it from the original
// location.
- if (strncmp(source_filename, "MTD:", 4) == 0 ||
- strncmp(source_filename, "EMMC:", 5) == 0) {
+ if (strncmp(source_filename, "EMMC:", 5) == 0) {
// It's impossible to free space on the target filesystem by
// deleting the source if the source is a partition. If
// we're ever in a state where we need to do this, fail.
@@ -897,7 +791,7 @@ static int GenerateTarget(FileContents* source_file,
} else {
// We write the decoded output to "<tgt-file>.patch".
output_fd = ota_open(tmp_target_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC,
- S_IRUSR | S_IWUSR);
+ S_IRUSR | S_IWUSR);
if (output_fd < 0) {
printf("failed to open output file %s: %s\n", tmp_target_filename.c_str(),
strerror(errno));
diff --git a/applypatch/bsdiff.cpp b/applypatch/bsdiff.cpp
deleted file mode 100644
index 55dbe5cf1..000000000
--- a/applypatch/bsdiff.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-/*
- * Most of this code comes from bsdiff.c from the bsdiff-4.3
- * distribution, which is:
- */
-
-/*-
- * Copyright 2003-2005 Colin Percival
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted providing that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <bzlib.h>
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define MIN(x,y) (((x)<(y)) ? (x) : (y))
-
-static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
-{
- off_t i,j,k,x,tmp,jj,kk;
-
- if(len<16) {
- for(k=start;k<start+len;k+=j) {
- j=1;x=V[I[k]+h];
- for(i=1;k+i<start+len;i++) {
- if(V[I[k+i]+h]<x) {
- x=V[I[k+i]+h];
- j=0;
- };
- if(V[I[k+i]+h]==x) {
- tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
- j++;
- };
- };
- for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
- if(j==1) I[k]=-1;
- };
- return;
- };
-
- x=V[I[start+len/2]+h];
- jj=0;kk=0;
- for(i=start;i<start+len;i++) {
- if(V[I[i]+h]<x) jj++;
- if(V[I[i]+h]==x) kk++;
- };
- jj+=start;kk+=jj;
-
- i=start;j=0;k=0;
- while(i<jj) {
- if(V[I[i]+h]<x) {
- i++;
- } else if(V[I[i]+h]==x) {
- tmp=I[i];I[i]=I[jj+j];I[jj+j]=tmp;
- j++;
- } else {
- tmp=I[i];I[i]=I[kk+k];I[kk+k]=tmp;
- k++;
- };
- };
-
- while(jj+j<kk) {
- if(V[I[jj+j]+h]==x) {
- j++;
- } else {
- tmp=I[jj+j];I[jj+j]=I[kk+k];I[kk+k]=tmp;
- k++;
- };
- };
-
- if(jj>start) split(I,V,start,jj-start,h);
-
- for(i=0;i<kk-jj;i++) V[I[jj+i]]=kk-1;
- if(jj==kk-1) I[jj]=-1;
-
- if(start+len>kk) split(I,V,kk,start+len-kk,h);
-}
-
-static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
-{
- off_t buckets[256];
- off_t i,h,len;
-
- for(i=0;i<256;i++) buckets[i]=0;
- for(i=0;i<oldsize;i++) buckets[old[i]]++;
- for(i=1;i<256;i++) buckets[i]+=buckets[i-1];
- for(i=255;i>0;i--) buckets[i]=buckets[i-1];
- buckets[0]=0;
-
- for(i=0;i<oldsize;i++) I[++buckets[old[i]]]=i;
- I[0]=oldsize;
- for(i=0;i<oldsize;i++) V[i]=buckets[old[i]];
- V[oldsize]=0;
- for(i=1;i<256;i++) if(buckets[i]==buckets[i-1]+1) I[buckets[i]]=-1;
- I[0]=-1;
-
- for(h=1;I[0]!=-(oldsize+1);h+=h) {
- len=0;
- for(i=0;i<oldsize+1;) {
- if(I[i]<0) {
- len-=I[i];
- i-=I[i];
- } else {
- if(len) I[i-len]=-len;
- len=V[I[i]]+1-i;
- split(I,V,i,len,h);
- i+=len;
- len=0;
- };
- };
- if(len) I[i-len]=-len;
- };
-
- for(i=0;i<oldsize+1;i++) I[V[i]]=i;
-}
-
-static off_t matchlen(u_char *olddata,off_t oldsize,u_char *newdata,off_t newsize)
-{
- off_t i;
-
- for(i=0;(i<oldsize)&&(i<newsize);i++)
- if(olddata[i]!=newdata[i]) break;
-
- return i;
-}
-
-static off_t search(off_t *I,u_char *old,off_t oldsize,
- u_char *newdata,off_t newsize,off_t st,off_t en,off_t *pos)
-{
- off_t x,y;
-
- if(en-st<2) {
- x=matchlen(old+I[st],oldsize-I[st],newdata,newsize);
- y=matchlen(old+I[en],oldsize-I[en],newdata,newsize);
-
- if(x>y) {
- *pos=I[st];
- return x;
- } else {
- *pos=I[en];
- return y;
- }
- };
-
- x=st+(en-st)/2;
- if(memcmp(old+I[x],newdata,MIN(oldsize-I[x],newsize))<0) {
- return search(I,old,oldsize,newdata,newsize,x,en,pos);
- } else {
- return search(I,old,oldsize,newdata,newsize,st,x,pos);
- };
-}
-
-static void offtout(off_t x,u_char *buf)
-{
- off_t y;
-
- if(x<0) y=-x; else y=x;
-
- buf[0]=y%256;y-=buf[0];
- y=y/256;buf[1]=y%256;y-=buf[1];
- y=y/256;buf[2]=y%256;y-=buf[2];
- y=y/256;buf[3]=y%256;y-=buf[3];
- y=y/256;buf[4]=y%256;y-=buf[4];
- y=y/256;buf[5]=y%256;y-=buf[5];
- y=y/256;buf[6]=y%256;y-=buf[6];
- y=y/256;buf[7]=y%256;
-
- if(x<0) buf[7]|=0x80;
-}
-
-// This is main() from bsdiff.c, with the following changes:
-//
-// - old, oldsize, newdata, newsize are arguments; we don't load this
-// data from files. old and newdata are owned by the caller; we
-// don't free them at the end.
-//
-// - the "I" block of memory is owned by the caller, who passes a
-// pointer to *I, which can be NULL. This way if we call
-// bsdiff() multiple times with the same 'old' data, we only do
-// the qsufsort() step the first time.
-//
-int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize,
- const char* patch_filename)
-{
- int fd;
- off_t *I;
- off_t scan,pos,len;
- off_t lastscan,lastpos,lastoffset;
- off_t oldscore,scsc;
- off_t s,Sf,lenf,Sb,lenb;
- off_t overlap,Ss,lens;
- off_t i;
- off_t dblen,eblen;
- u_char *db,*eb;
- u_char buf[8];
- u_char header[32];
- FILE * pf;
- BZFILE * pfbz2;
- int bz2err;
-
- if (*IP == NULL) {
- off_t* V;
- *IP = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t)));
- V = reinterpret_cast<off_t*>(malloc((oldsize+1) * sizeof(off_t)));
- qsufsort(*IP, V, old, oldsize);
- free(V);
- }
- I = *IP;
-
- if(((db=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL) ||
- ((eb=reinterpret_cast<u_char*>(malloc(newsize+1)))==NULL)) err(1,NULL);
- dblen=0;
- eblen=0;
-
- /* Create the patch file */
- if ((pf = fopen(patch_filename, "w")) == NULL)
- err(1, "%s", patch_filename);
-
- /* Header is
- 0 8 "BSDIFF40"
- 8 8 length of bzip2ed ctrl block
- 16 8 length of bzip2ed diff block
- 24 8 length of new file */
- /* File is
- 0 32 Header
- 32 ?? Bzip2ed ctrl block
- ?? ?? Bzip2ed diff block
- ?? ?? Bzip2ed extra block */
- memcpy(header,"BSDIFF40",8);
- offtout(0, header + 8);
- offtout(0, header + 16);
- offtout(newsize, header + 24);
- if (fwrite(header, 32, 1, pf) != 1)
- err(1, "fwrite(%s)", patch_filename);
-
- /* Compute the differences, writing ctrl as we go */
- if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
- errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
- scan=0;len=0;
- lastscan=0;lastpos=0;lastoffset=0;
- while(scan<newsize) {
- oldscore=0;
-
- for(scsc=scan+=len;scan<newsize;scan++) {
- len=search(I,old,oldsize,newdata+scan,newsize-scan,
- 0,oldsize,&pos);
-
- for(;scsc<scan+len;scsc++)
- if((scsc+lastoffset<oldsize) &&
- (old[scsc+lastoffset] == newdata[scsc]))
- oldscore++;
-
- if(((len==oldscore) && (len!=0)) ||
- (len>oldscore+8)) break;
-
- if((scan+lastoffset<oldsize) &&
- (old[scan+lastoffset] == newdata[scan]))
- oldscore--;
- };
-
- if((len!=oldscore) || (scan==newsize)) {
- s=0;Sf=0;lenf=0;
- for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
- if(old[lastpos+i]==newdata[lastscan+i]) s++;
- i++;
- if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
- };
-
- lenb=0;
- if(scan<newsize) {
- s=0;Sb=0;
- for(i=1;(scan>=lastscan+i)&&(pos>=i);i++) {
- if(old[pos-i]==newdata[scan-i]) s++;
- if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
- };
- };
-
- if(lastscan+lenf>scan-lenb) {
- overlap=(lastscan+lenf)-(scan-lenb);
- s=0;Ss=0;lens=0;
- for(i=0;i<overlap;i++) {
- if(newdata[lastscan+lenf-overlap+i]==
- old[lastpos+lenf-overlap+i]) s++;
- if(newdata[scan-lenb+i]==
- old[pos-lenb+i]) s--;
- if(s>Ss) { Ss=s; lens=i+1; };
- };
-
- lenf+=lens-overlap;
- lenb-=lens;
- };
-
- for(i=0;i<lenf;i++)
- db[dblen+i]=newdata[lastscan+i]-old[lastpos+i];
- for(i=0;i<(scan-lenb)-(lastscan+lenf);i++)
- eb[eblen+i]=newdata[lastscan+lenf+i];
-
- dblen+=lenf;
- eblen+=(scan-lenb)-(lastscan+lenf);
-
- offtout(lenf,buf);
- BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
- offtout((scan-lenb)-(lastscan+lenf),buf);
- BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
- offtout((pos-lenb)-(lastpos+lenf),buf);
- BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
-
- lastscan=scan-lenb;
- lastpos=pos-lenb;
- lastoffset=pos-scan;
- };
- };
- BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
- /* Compute size of compressed ctrl data */
- if ((len = ftello(pf)) == -1)
- err(1, "ftello");
- offtout(len-32, header + 8);
-
- /* Write compressed diff data */
- if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
- errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
- BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
- BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
- /* Compute size of compressed diff data */
- if ((newsize = ftello(pf)) == -1)
- err(1, "ftello");
- offtout(newsize - len, header + 16);
-
- /* Write compressed extra data */
- if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL)
- errx(1, "BZ2_bzWriteOpen, bz2err = %d", bz2err);
- BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWrite, bz2err = %d", bz2err);
- BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL);
- if (bz2err != BZ_OK)
- errx(1, "BZ2_bzWriteClose, bz2err = %d", bz2err);
-
- /* Seek to the beginning, write the header, and close the file */
- if (fseeko(pf, 0, SEEK_SET))
- err(1, "fseeko");
- if (fwrite(header, 32, 1, pf) != 1)
- err(1, "fwrite(%s)", patch_filename);
- if (fclose(pf))
- err(1, "fclose");
-
- /* Free the memory we used */
- free(db);
- free(eb);
-
- return 0;
-}
diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp
index ebb55f1d1..a4945da28 100644
--- a/applypatch/bspatch.cpp
+++ b/applypatch/bspatch.cpp
@@ -30,7 +30,7 @@
#include <bzlib.h>
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
void ShowBSDiffLicense() {
puts("The bsdiff library used herein is:\n"
@@ -182,7 +182,6 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size,
off_t oldpos = 0, newpos = 0;
off_t ctrl[3];
- off_t len_read;
int i;
unsigned char buf[24];
while (newpos < new_size) {
diff --git a/applypatch/freecache.cpp b/applypatch/freecache.cpp
index c84f42797..331cae265 100644
--- a/applypatch/freecache.cpp
+++ b/applypatch/freecache.cpp
@@ -32,7 +32,7 @@
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
static int EliminateOpenFiles(std::set<std::string>* files) {
std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir);
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index f22502e38..7c5bb866d 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -130,6 +130,8 @@
#include <unistd.h>
#include <sys/types.h>
+#include <bsdiff.h>
+
#include "zlib.h"
#include "imgdiff.h"
#include "utils.h"
@@ -144,8 +146,6 @@ typedef struct {
size_t source_start;
size_t source_len;
- off_t* I; // used by bsdiff
-
// --- for CHUNK_DEFLATE chunks only: ---
// original (compressed) deflate data
@@ -179,10 +179,6 @@ static int fileentry_compare(const void* a, const void* b) {
}
}
-// from bsdiff.c
-int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* newdata, off_t newsize,
- const char* patch_filename);
-
unsigned char* ReadZip(const char* filename,
int* num_chunks, ImageChunk** chunks,
int include_pseudo_chunk) {
@@ -296,7 +292,6 @@ unsigned char* ReadZip(const char* filename,
curr->len = st.st_size;
curr->data = img;
curr->filename = NULL;
- curr->I = NULL;
++curr;
++*num_chunks;
}
@@ -311,7 +306,6 @@ unsigned char* ReadZip(const char* filename,
curr->deflate_len = temp_entries[nextentry].deflate_len;
curr->deflate_data = img + pos;
curr->filename = temp_entries[nextentry].filename;
- curr->I = NULL;
curr->len = temp_entries[nextentry].uncomp_len;
curr->data = reinterpret_cast<unsigned char*>(malloc(curr->len));
@@ -356,7 +350,6 @@ unsigned char* ReadZip(const char* filename,
}
curr->data = img + pos;
curr->filename = NULL;
- curr->I = NULL;
pos += curr->len;
++*num_chunks;
@@ -407,7 +400,6 @@ unsigned char* ReadImage(const char* filename,
while (pos < sz) {
unsigned char* p = img+pos;
- bool processed_deflate = false;
if (sz - pos >= 4 &&
p[0] == 0x1f && p[1] == 0x8b &&
p[2] == 0x08 && // deflate compression
@@ -425,7 +417,6 @@ unsigned char* ReadImage(const char* filename,
curr->type = CHUNK_NORMAL;
curr->len = GZIP_HEADER_LEN;
curr->data = p;
- curr->I = NULL;
pos += curr->len;
p += curr->len;
@@ -433,7 +424,6 @@ unsigned char* ReadImage(const char* filename,
curr->type = CHUNK_DEFLATE;
curr->filename = NULL;
- curr->I = NULL;
// We must decompress this chunk in order to discover where it
// ends, and so we can put the uncompressed data and its length
@@ -461,28 +451,27 @@ unsigned char* ReadImage(const char* filename,
strm.next_out = curr->data + curr->len;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret < 0) {
- if (!processed_deflate) {
- // This is the first chunk, assume that it's just a spurious
- // gzip header instead of a real one.
- break;
- }
- printf("Error: inflate failed [%s] at file offset [%zu]\n"
- "imgdiff only supports gzip kernel compression,"
- " did you try CONFIG_KERNEL_LZO?\n",
+ printf("Warning: inflate failed [%s] at offset [%zu],"
+ " treating as a normal chunk\n",
strm.msg, chunk_offset);
- free(img);
- return NULL;
+ break;
}
curr->len = allocated - strm.avail_out;
if (strm.avail_out == 0) {
allocated *= 2;
curr->data = reinterpret_cast<unsigned char*>(realloc(curr->data, allocated));
}
- processed_deflate = true;
} while (ret != Z_STREAM_END);
curr->deflate_len = sz - strm.avail_in - pos;
inflateEnd(&strm);
+
+ if (ret < 0) {
+ free(curr->data);
+ *num_chunks -= 2;
+ continue;
+ }
+
pos += curr->deflate_len;
p += curr->deflate_len;
++curr;
@@ -493,7 +482,6 @@ unsigned char* ReadImage(const char* filename,
curr->start = pos;
curr->len = GZIP_FOOTER_LEN;
curr->data = img+pos;
- curr->I = NULL;
pos += curr->len;
p += curr->len;
@@ -517,7 +505,6 @@ unsigned char* ReadImage(const char* filename,
*chunks = reinterpret_cast<ImageChunk*>(realloc(*chunks, *num_chunks * sizeof(ImageChunk)));
ImageChunk* curr = *chunks + (*num_chunks-1);
curr->start = pos;
- curr->I = NULL;
// 'pos' is not the offset of the start of a gzip chunk, so scan
// forward until we find a gzip header.
@@ -598,7 +585,6 @@ int ReconstructDeflateChunk(ImageChunk* chunk) {
return -1;
}
- size_t p = 0;
unsigned char* out = reinterpret_cast<unsigned char*>(malloc(BUFFER_SIZE));
// We only check two combinations of encoder parameters: level 6
@@ -645,7 +631,7 @@ unsigned char* MakePatch(ImageChunk* src, ImageChunk* tgt, size_t* size) {
close(fd); // temporary file is created and we don't need its file
// descriptor
- int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp);
+ int r = bsdiff::bsdiff(src->data, src->len, tgt->data, tgt->len, ptemp);
if (r != 0) {
printf("bsdiff() failed: %d\n", r);
return NULL;
@@ -844,7 +830,6 @@ int main(int argc, char** argv) {
}
if (argc != 4) {
- usage:
printf("usage: %s [-z] [-b <bonus-file>] <src-img> <tgt-img> <patch-file>\n",
argv[0]);
return 2;
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp
index d175d6385..0c06d6b1e 100644
--- a/applypatch/imgpatch.cpp
+++ b/applypatch/imgpatch.cpp
@@ -28,7 +28,7 @@
#include "zlib.h"
#include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "imgdiff.h"
#include "utils.h"
@@ -130,6 +130,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
size_t src_len = Read8(deflate_header+8);
size_t patch_offset = Read8(deflate_header+16);
size_t expanded_len = Read8(deflate_header+24);
+ size_t target_len = Read8(deflate_header+32);
int level = Read4(deflate_header+40);
int method = Read4(deflate_header+44);
int windowBits = Read4(deflate_header+48);
@@ -200,6 +201,11 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
&uncompressed_target_data) != 0) {
return -1;
}
+ if (uncompressed_target_data.size() != target_len) {
+ printf("expected target len to be %zu, but it's %zu\n",
+ target_len, uncompressed_target_data.size());
+ return -1;
+ }
// Now compress the target data and append it to the output.
@@ -231,8 +237,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
ssize_t have = temp_data.size() - strm.avail_out;
if (sink(temp_data.data(), have, token) != have) {
- printf("failed to write %ld compressed bytes to output\n",
- (long)have);
+ printf("failed to write %zd compressed bytes to output\n",
+ have);
return -1;
}
if (ctx) SHA1_Update(ctx, temp_data.data(), have);
diff --git a/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h
index f392c5534..9ee39d293 100644
--- a/applypatch/applypatch.h
+++ b/applypatch/include/applypatch/applypatch.h
@@ -17,6 +17,7 @@
#ifndef _APPLYPATCH_H
#define _APPLYPATCH_H
+#include <stdint.h>
#include <sys/stat.h>
#include <vector>
diff --git a/applypatch/libimgpatch.pc b/applypatch/libimgpatch.pc
new file mode 100644
index 000000000..e5002934f
--- /dev/null
+++ b/applypatch/libimgpatch.pc
@@ -0,0 +1,6 @@
+# This file is for libimgpatch in Chrome OS.
+
+Name: libimgpatch
+Description: Apply imgdiff patch
+Version: 0.0.1
+Libs: -limgpatch -lbz2 -lz
diff --git a/applypatch/main.cpp b/applypatch/main.cpp
index 9013760c4..1968ae48f 100644
--- a/applypatch/main.cpp
+++ b/applypatch/main.cpp
@@ -22,7 +22,7 @@
#include <memory>
#include <vector>
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "openssl/sha.h"
@@ -160,9 +160,9 @@ static int PatchMode(int argc, char** argv) {
// - otherwise, or if any error is encountered, exits with non-zero
// status.
//
-// <src-file> (or <file> in check mode) may refer to an MTD partition
+// <src-file> (or <file> in check mode) may refer to an EMMC partition
// to read the source data. See the comments for the
-// LoadMTDContents() function above for the format of such a filename.
+// LoadPartitionContents() function for the format of such a filename.
int main(int argc, char** argv) {
if (argc < 2) {
@@ -175,8 +175,8 @@ int main(int argc, char** argv) {
" or %s -l\n"
"\n"
"Filenames may be of the form\n"
- " MTD:<partition>:<len_1>:<sha1_1>:<len_2>:<sha1_2>:...\n"
- "to specify reading from or writing to an MTD partition.\n\n",
+ " EMMC:<partition>:<len_1>:<sha1_1>:<len_2>:<sha1_2>:...\n"
+ "to specify reading from or writing to an EMMC partition.\n\n",
argv[0], argv[0], argv[0], argv[0]);
return 2;
}
diff --git a/applypatch/utils.cpp b/applypatch/utils.cpp
index 4a80be75f..fef250f01 100644
--- a/applypatch/utils.cpp
+++ b/applypatch/utils.cpp
@@ -27,7 +27,7 @@ void Write4(int value, FILE* f) {
}
/** Write an 8-byte value to f in little-endian order. */
-void Write8(long long value, FILE* f) {
+void Write8(int64_t value, FILE* f) {
fputc(value & 0xff, f);
fputc((value >> 8) & 0xff, f);
fputc((value >> 16) & 0xff, f);
@@ -52,14 +52,14 @@ int Read4(void* pv) {
(unsigned int)p[0]);
}
-long long Read8(void* pv) {
+int64_t Read8(void* pv) {
unsigned char* p = reinterpret_cast<unsigned char*>(pv);
- return (long long)(((unsigned long long)p[7] << 56) |
- ((unsigned long long)p[6] << 48) |
- ((unsigned long long)p[5] << 40) |
- ((unsigned long long)p[4] << 32) |
- ((unsigned long long)p[3] << 24) |
- ((unsigned long long)p[2] << 16) |
- ((unsigned long long)p[1] << 8) |
- (unsigned long long)p[0]);
+ return (int64_t)(((uint64_t)p[7] << 56) |
+ ((uint64_t)p[6] << 48) |
+ ((uint64_t)p[5] << 40) |
+ ((uint64_t)p[4] << 32) |
+ ((uint64_t)p[3] << 24) |
+ ((uint64_t)p[2] << 16) |
+ ((uint64_t)p[1] << 8) |
+ (uint64_t)p[0]);
}
diff --git a/applypatch/utils.h b/applypatch/utils.h
index bc97f1720..1c34edd97 100644
--- a/applypatch/utils.h
+++ b/applypatch/utils.h
@@ -17,14 +17,15 @@
#ifndef _BUILD_TOOLS_APPLYPATCH_UTILS_H
#define _BUILD_TOOLS_APPLYPATCH_UTILS_H
+#include <inttypes.h>
#include <stdio.h>
// Read and write little-endian values of various sizes.
void Write4(int value, FILE* f);
-void Write8(long long value, FILE* f);
+void Write8(int64_t value, FILE* f);
int Read2(void* p);
int Read4(void* p);
-long long Read8(void* p);
+int64_t Read8(void* p);
#endif // _BUILD_TOOLS_APPLYPATCH_UTILS_H
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index c63aeca6f..f343c64ac 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -17,18 +17,21 @@
#ifndef _BOOTLOADER_MESSAGE_H
#define _BOOTLOADER_MESSAGE_H
+#include <assert.h>
#include <stddef.h>
+#include <stdint.h>
// Spaces used by misc partition are as below:
-// 0 - 2K Bootloader Message
-// 2K - 16K Used by Vendor's bootloader
+// 0 - 2K For bootloader_message
+// 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
+// as bootloader_message_ab struct)
// 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
// Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
// are not configurable without changing all of them.
static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
-/* Bootloader Message
+/* Bootloader Message (2-KiB)
*
* This structure describes the content of a block in flash
* that is used for recovery and the bootloader to talk to
@@ -51,12 +54,10 @@ static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
* package it is. If the value is of the format "#/#" (eg, "1/3"),
* the UI will add a simple indicator of that status.
*
- * 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.
+ * We used to have slot_suffix field for A/B boot control metadata in
+ * this struct, which gets unintentionally cleared by recovery or
+ * uncrypt. Move it into struct bootloader_message_ab to avoid the
+ * issue.
*/
struct bootloader_message {
char command[32];
@@ -69,10 +70,110 @@ struct bootloader_message {
// stage string (for multistage packages) and possible future
// expansion.
char stage[32];
+
+ // The 'reserved' field used to be 224 bytes when it was initially
+ // carved off from the 1024-byte recovery field. Bump it up to
+ // 1184-byte so that the entire bootloader_message struct rounds up
+ // to 2048-byte.
+ 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.
+ */
+struct bootloader_message_ab {
+ struct bootloader_message message;
char slot_suffix[32];
- char reserved[192];
+
+ // Round up the entire struct to 4096-byte.
+ char reserved[2016];
};
+/**
+ * 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;
+ // Ensure 4-bytes alignment for slot_info field.
+ uint8_t reserved0[2];
+ // 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
+
#ifdef __cplusplus
#include <string>
@@ -86,7 +187,6 @@ bool clear_bootloader_message(std::string* err);
bool read_wipe_package(std::string* package_data, size_t size, std::string* err);
bool write_wipe_package(const std::string& package_data, std::string* err);
-
#else
#include <stdbool.h>
diff --git a/device.cpp b/device.cpp
index f8fbb8a49..e717dddf7 100644
--- a/device.cpp
+++ b/device.cpp
@@ -16,36 +16,15 @@
#include "device.h"
-#if defined(AB_OTA_UPDATER)
-
-static const char* MENU_ITEMS[] = {
- "Reboot system now",
- "Reboot to bootloader",
- "Wipe data/factory reset",
- "Mount /system",
- "Run graphics test",
- "Power off",
- NULL,
-};
-
-static const Device::BuiltinAction MENU_ACTIONS[] = {
- Device::REBOOT,
- Device::REBOOT_BOOTLOADER,
- Device::WIPE_DATA,
- Device::MOUNT_SYSTEM,
- Device::RUN_GRAPHICS_TEST,
- Device::SHUTDOWN,
-};
-
-#else
-
static const char* MENU_ITEMS[] = {
"Reboot system now",
"Reboot to bootloader",
"Apply update from ADB",
"Apply update from SD card",
"Wipe data/factory reset",
+#ifndef AB_OTA_UPDATER
"Wipe cache partition",
+#endif // !AB_OTA_UPDATER
"Mount /system",
"View recovery logs",
"Run graphics test",
@@ -59,14 +38,19 @@ static const Device::BuiltinAction MENU_ACTIONS[] = {
Device::APPLY_ADB_SIDELOAD,
Device::APPLY_SDCARD,
Device::WIPE_DATA,
+#ifndef AB_OTA_UPDATER
Device::WIPE_CACHE,
+#endif // !AB_OTA_UPDATER
Device::MOUNT_SYSTEM,
Device::VIEW_RECOVERY_LOGS,
Device::RUN_GRAPHICS_TEST,
Device::SHUTDOWN,
};
-#endif
+static_assert(sizeof(MENU_ITEMS) / sizeof(MENU_ITEMS[0]) ==
+ sizeof(MENU_ACTIONS) / sizeof(MENU_ACTIONS[0]) + 1,
+ "MENU_ITEMS and MENU_ACTIONS should have the same length, "
+ "except for the extra NULL entry in MENU_ITEMS.");
const char* const* Device::GetMenuItems() {
return MENU_ITEMS;
diff --git a/device.h b/device.h
index 5017782e6..08dfcdff4 100644
--- a/device.h
+++ b/device.h
@@ -21,7 +21,7 @@
class Device {
public:
- Device(RecoveryUI* ui) : ui_(ui) { }
+ explicit Device(RecoveryUI* ui) : ui_(ui) { }
virtual ~Device() { }
// Called to obtain the UI object that should be used to display
diff --git a/edify/expr.cpp b/edify/expr.cpp
index cc14fbe93..ecb1bea1a 100644
--- a/edify/expr.cpp
+++ b/edify/expr.cpp
@@ -291,13 +291,14 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) {
bool result = false;
char* end;
- long l_int = strtol(left, &end, 10);
+ // Parse up to at least long long or 64-bit integers.
+ int64_t l_int = static_cast<int64_t>(strtoll(left, &end, 10));
if (left[0] == '\0' || *end != '\0') {
goto done;
}
- long r_int;
- r_int = strtol(right, &end, 10);
+ int64_t r_int;
+ r_int = static_cast<int64_t>(strtoll(right, &end, 10));
if (right[0] == '\0' || *end != '\0') {
goto done;
}
diff --git a/etc/META-INF/com/google/android/update-script b/etc/META-INF/com/google/android/update-script
deleted file mode 100644
index b091b1927..000000000
--- a/etc/META-INF/com/google/android/update-script
+++ /dev/null
@@ -1,8 +0,0 @@
-assert compatible_with("0.1") == "true"
-assert file_contains("SYSTEM:build.prop", "ro.product.device=dream") == "true" || file_contains("SYSTEM:build.prop", "ro.build.product=dream") == "true"
-assert file_contains("RECOVERY:default.prop", "ro.product.device=dream") == "true" || file_contains("RECOVERY:default.prop", "ro.build.product=dream") == "true"
-assert getprop("ro.product.device") == "dream"
-format BOOT:
-format SYSTEM:
-copy_dir PACKAGE:system SYSTEM:
-write_raw_image PACKAGE:boot.img BOOT:
diff --git a/etc/init.rc b/etc/init.rc
index 5915b8d80..29b088d14 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -14,6 +14,9 @@ on init
symlink /system/etc /etc
+ mount cgroup none /acct cpuacct
+ mkdir /acct/uid
+
mkdir /sdcard
mkdir /system
mkdir /data
diff --git a/install.cpp b/install.cpp
index 518337fef..38e89fde6 100644
--- a/install.cpp
+++ b/install.cpp
@@ -17,6 +17,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
@@ -24,12 +25,15 @@
#include <unistd.h>
#include <chrono>
+#include <limits>
+#include <map>
#include <string>
#include <vector>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <cutils/properties.h>
#include "common.h"
#include "error_code.h"
@@ -37,8 +41,6 @@
#include "minui/minui.h"
#include "minzip/SysUtil.h"
#include "minzip/Zip.h"
-#include "mtdutils/mounts.h"
-#include "mtdutils/mtdutils.h"
#include "roots.h"
#include "ui.h"
#include "verifier.h"
@@ -46,6 +48,8 @@
extern RecoveryUI* ui;
#define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary"
+static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
+static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
#define PUBLIC_KEYS_FILE "/res/keys"
static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
@@ -113,17 +117,152 @@ static void read_source_target_build(ZipArchive* zip, std::vector<std::string>&
}
}
-// If the package contains an update binary, extract it and run it.
+// Extract the update binary from the open zip archive |zip| located at |path|
+// and store into |cmd| the command line that should be called. The |status_fd|
+// is the file descriptor the child process should use to report back the
+// progress of the update.
static int
-try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
- std::vector<std::string>& log_buffer, int retry_count)
+update_binary_command(const char* path, ZipArchive* zip, int retry_count,
+ int status_fd, std::vector<std::string>* cmd);
+
+#ifdef AB_OTA_UPDATER
+
+// Parses the metadata of the OTA package in |zip| and checks whether we are
+// allowed to accept this A/B package. Downgrading is not allowed unless
+// explicitly enabled in the package and only for incremental packages.
+static int check_newer_ab_build(ZipArchive* zip)
{
- read_source_target_build(zip, log_buffer);
+ std::string metadata_str;
+ if (!read_metadata_from_package(zip, &metadata_str)) {
+ return INSTALL_CORRUPT;
+ }
+ std::map<std::string, std::string> metadata;
+ for (const std::string& line : android::base::Split(metadata_str, "\n")) {
+ size_t eq = line.find('=');
+ if (eq != std::string::npos) {
+ metadata[line.substr(0, eq)] = line.substr(eq + 1);
+ }
+ }
+ char value[PROPERTY_VALUE_MAX];
+
+ property_get("ro.product.device", value, "");
+ const std::string& pkg_device = metadata["pre-device"];
+ if (pkg_device != value || pkg_device.empty()) {
+ LOGE("Package is for product %s but expected %s\n",
+ pkg_device.c_str(), value);
+ return INSTALL_ERROR;
+ }
+
+ // We allow the package to not have any serialno, but if it has a non-empty
+ // value it should match.
+ property_get("ro.serialno", value, "");
+ const std::string& pkg_serial_no = metadata["serialno"];
+ if (!pkg_serial_no.empty() && pkg_serial_no != value) {
+ LOGE("Package is for serial %s\n", pkg_serial_no.c_str());
+ return INSTALL_ERROR;
+ }
+ if (metadata["ota-type"] != "AB") {
+ LOGE("Package is not A/B\n");
+ return INSTALL_ERROR;
+ }
+
+ // Incremental updates should match the current build.
+ property_get("ro.build.version.incremental", value, "");
+ const std::string& pkg_pre_build = metadata["pre-build-incremental"];
+ if (!pkg_pre_build.empty() && pkg_pre_build != value) {
+ LOGE("Package is for source build %s but expected %s\n",
+ pkg_pre_build.c_str(), value);
+ return INSTALL_ERROR;
+ }
+ property_get("ro.build.fingerprint", value, "");
+ const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
+ if (!pkg_pre_build_fingerprint.empty() &&
+ pkg_pre_build_fingerprint != value) {
+ LOGE("Package is for source build %s but expected %s\n",
+ pkg_pre_build_fingerprint.c_str(), value);
+ return INSTALL_ERROR;
+ }
+
+ // Check for downgrade version.
+ int64_t build_timestampt = property_get_int64(
+ "ro.build.date.utc", std::numeric_limits<int64_t>::max());
+ int64_t pkg_post_timespampt = 0;
+ // We allow to full update to the same version we are running, in case there
+ // is a problem with the current copy of that version.
+ if (metadata["post-timestamp"].empty() ||
+ !android::base::ParseInt(metadata["post-timestamp"].c_str(),
+ &pkg_post_timespampt) ||
+ pkg_post_timespampt < build_timestampt) {
+ if (metadata["ota-downgrade"] != "yes") {
+ LOGE("Update package is older than the current build, expected a "
+ "build newer than timestamp %" PRIu64 " but package has "
+ "timestamp %" PRIu64 " and downgrade not allowed.\n",
+ build_timestampt, pkg_post_timespampt);
+ return INSTALL_ERROR;
+ }
+ if (pkg_pre_build_fingerprint.empty()) {
+ LOGE("Downgrade package must have a pre-build version set, not "
+ "allowed.\n");
+ return INSTALL_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+static int
+update_binary_command(const char* path, ZipArchive* zip, int retry_count,
+ int status_fd, std::vector<std::string>* cmd)
+{
+ int ret = check_newer_ab_build(zip);
+ if (ret) {
+ return ret;
+ }
+
+ // For A/B updates we extract the payload properties to a buffer and obtain
+ // the RAW payload offset in the zip file.
+ const ZipEntry* properties_entry =
+ mzFindZipEntry(zip, AB_OTA_PAYLOAD_PROPERTIES);
+ if (!properties_entry) {
+ LOGE("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+ return INSTALL_CORRUPT;
+ }
+ std::vector<unsigned char> payload_properties(
+ mzGetZipEntryUncompLen(properties_entry));
+ if (!mzExtractZipEntryToBuffer(zip, properties_entry,
+ payload_properties.data())) {
+ LOGE("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES);
+ return INSTALL_CORRUPT;
+ }
+
+ const ZipEntry* payload_entry = mzFindZipEntry(zip, AB_OTA_PAYLOAD);
+ if (!payload_entry) {
+ LOGE("Can't find %s\n", AB_OTA_PAYLOAD);
+ return INSTALL_CORRUPT;
+ }
+ long payload_offset = mzGetZipEntryOffset(payload_entry);
+ *cmd = {
+ "/sbin/update_engine_sideload",
+ android::base::StringPrintf("--payload=file://%s", path),
+ android::base::StringPrintf("--offset=%ld", payload_offset),
+ "--headers=" + std::string(payload_properties.begin(),
+ payload_properties.end()),
+ android::base::StringPrintf("--status_fd=%d", status_fd),
+ };
+ return 0;
+}
+
+#else // !AB_OTA_UPDATER
+
+static int
+update_binary_command(const char* path, ZipArchive* zip, int retry_count,
+ int status_fd, std::vector<std::string>* cmd)
+{
+ // On traditional updates we extract the update binary from the package.
const ZipEntry* binary_entry =
mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
if (binary_entry == NULL) {
- mzCloseZipArchive(zip);
return INSTALL_CORRUPT;
}
@@ -131,22 +270,48 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
unlink(binary);
int fd = creat(binary, 0755);
if (fd < 0) {
- mzCloseZipArchive(zip);
LOGE("Can't make %s\n", binary);
return INSTALL_ERROR;
}
bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
close(fd);
- mzCloseZipArchive(zip);
if (!ok) {
LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
return INSTALL_ERROR;
}
+ *cmd = {
+ binary,
+ EXPAND(RECOVERY_API_VERSION), // defined in Android.mk
+ std::to_string(status_fd),
+ path,
+ };
+ if (retry_count > 0)
+ cmd->push_back("retry");
+ return 0;
+}
+#endif // !AB_OTA_UPDATER
+
+// If the package contains an update binary, extract it and run it.
+static int
+try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
+ std::vector<std::string>& log_buffer, int retry_count)
+{
+ read_source_target_build(zip, log_buffer);
+
int pipefd[2];
pipe(pipefd);
+ std::vector<std::string> args;
+ int ret = update_binary_command(path, zip, retry_count, pipefd[1], &args);
+ mzCloseZipArchive(zip);
+ if (ret) {
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return ret;
+ }
+
// When executing the update binary contained in the package, the
// arguments passed are:
//
@@ -196,22 +361,19 @@ try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
// update attempt.
//
- const char** args = (const char**)malloc(sizeof(char*) * 6);
- args[0] = binary;
- args[1] = EXPAND(RECOVERY_API_VERSION); // defined in Android.mk
- char* temp = (char*)malloc(10);
- sprintf(temp, "%d", pipefd[1]);
- args[2] = temp;
- args[3] = (char*)path;
- args[4] = retry_count > 0 ? "retry" : NULL;
- args[5] = NULL;
+ // Convert the vector to a NULL-terminated char* array suitable for execv.
+ const char* chr_args[args.size() + 1];
+ chr_args[args.size()] = NULL;
+ for (size_t i = 0; i < args.size(); i++) {
+ chr_args[i] = args[i].c_str();
+ }
pid_t pid = fork();
if (pid == 0) {
umask(022);
close(pipefd[0]);
- execv(binary, (char* const*)args);
- fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
+ execv(chr_args[0], const_cast<char**>(chr_args));
+ fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
_exit(-1);
}
close(pipefd[1]);
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index 3db3b4114..34631a944 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -13,7 +13,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
adb_main.cpp \
fuse_adb_provider.cpp \
- services.cpp \
+ minadbd_services.cpp \
LOCAL_CLANG := true
LOCAL_MODULE := libminadbd
@@ -21,7 +21,7 @@ LOCAL_CFLAGS := $(minadbd_cflags)
LOCAL_CONLY_FLAGS := -Wimplicit-function-declaration
LOCAL_C_INCLUDES := bootable/recovery system/core/adb
LOCAL_WHOLE_STATIC_LIBRARIES := libadbd
-LOCAL_STATIC_LIBRARIES := libbase
+LOCAL_STATIC_LIBRARIES := libcrypto libbase
include $(BUILD_STATIC_LIBRARY)
diff --git a/minadbd/adb_main.cpp b/minadbd/adb_main.cpp
index 0694280cb..8e581c2a9 100644
--- a/minadbd/adb_main.cpp
+++ b/minadbd/adb_main.cpp
@@ -19,8 +19,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include "sysdeps.h"
-
#include "adb.h"
#include "adb_auth.h"
#include "transport.h"
diff --git a/minadbd/fuse_adb_provider.cpp b/minadbd/fuse_adb_provider.cpp
index d71807dfb..0f4c2563d 100644
--- a/minadbd/fuse_adb_provider.cpp
+++ b/minadbd/fuse_adb_provider.cpp
@@ -19,8 +19,6 @@
#include <string.h>
#include <errno.h>
-#include "sysdeps.h"
-
#include "adb.h"
#include "adb_io.h"
#include "fuse_adb_provider.h"
diff --git a/minadbd/services.cpp b/minadbd/minadbd_services.cpp
index 658a43f36..003b51913 100644
--- a/minadbd/services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -21,11 +21,10 @@
#include <string.h>
#include <unistd.h>
-#include "sysdeps.h"
-
#include "adb.h"
#include "fdevent.h"
#include "fuse_adb_provider.h"
+#include "sysdeps.h"
typedef struct stinfo stinfo;
@@ -62,7 +61,7 @@ static void sideload_host_service(int sfd, void* data) {
static int create_service_thread(void (*func)(int, void *), void *cookie) {
int s[2];
- if(adb_socketpair(s)) {
+ if (adb_socketpair(s)) {
printf("cannot create service socket pair\n");
return -1;
}
diff --git a/minui/Android.mk b/minui/Android.mk
index 3057f452c..380ec2bfd 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -11,6 +11,7 @@ LOCAL_SRC_FILES := \
LOCAL_WHOLE_STATIC_LIBRARIES += libadf
LOCAL_WHOLE_STATIC_LIBRARIES += libdrm
+LOCAL_WHOLE_STATIC_LIBRARIES += libsync_recovery
LOCAL_STATIC_LIBRARIES += libpng
LOCAL_MODULE := libminui
diff --git a/minui/events.cpp b/minui/events.cpp
index 3b2262a4b..e6e7bd28c 100644
--- a/minui/events.cpp
+++ b/minui/events.cpp
@@ -49,7 +49,7 @@ static unsigned ev_count = 0;
static unsigned ev_dev_count = 0;
static unsigned ev_misc_count = 0;
-static bool test_bit(size_t bit, unsigned long* array) {
+static bool test_bit(size_t bit, unsigned long* array) { // NOLINT
return (array[bit/BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
}
@@ -65,7 +65,8 @@ int ev_init(ev_callback input_cb, void* data) {
if (dir != NULL) {
dirent* de;
while ((de = readdir(dir))) {
- unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
+ // Use unsigned long to match ioctl's parameter type.
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
// fprintf(stderr,"/dev/input/%s\n", de->d_name);
if (strncmp(de->d_name, "event", 5)) continue;
@@ -175,8 +176,9 @@ int ev_get_input(int fd, uint32_t epevents, input_event* ev) {
}
int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data) {
- unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
- unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];
+ // Use unsigned long to match ioctl's parameter type.
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
+ unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
for (size_t i = 0; i < ev_dev_count; ++i) {
memset(ev_bits, 0, sizeof(ev_bits));
@@ -202,9 +204,10 @@ int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data) {
return 0;
}
-void ev_iterate_available_keys(std::function<void(int)> f) {
- unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
- unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];
+void ev_iterate_available_keys(const std::function<void(int)>& f) {
+ // Use unsigned long to match ioctl's parameter type.
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)]; // NOLINT
+ unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)]; // NOLINT
for (size_t i = 0; i < ev_dev_count; ++i) {
memset(ev_bits, 0, sizeof(ev_bits));
diff --git a/minui/graphics_adf.cpp b/minui/graphics_adf.cpp
index 5d0867f58..3c3541094 100644
--- a/minui/graphics_adf.cpp
+++ b/minui/graphics_adf.cpp
@@ -26,11 +26,13 @@
#include <sys/mman.h>
#include <adf/adf.h>
+#include <sync/sync.h>
#include "graphics.h"
struct adf_surface_pdata {
GRSurface base;
+ int fence_fd;
int fd;
__u32 offset;
__u32 pitch;
@@ -42,6 +44,8 @@ struct adf_pdata {
adf_id_t eng_id;
__u32 format;
+ adf_device dev;
+
unsigned int current_surface;
unsigned int n_surfaces;
adf_surface_pdata surfaces[2];
@@ -53,6 +57,7 @@ static void adf_blank(minui_backend *backend, bool blank);
static int adf_surface_init(adf_pdata *pdata, drm_mode_modeinfo *mode, adf_surface_pdata *surf) {
memset(surf, 0, sizeof(*surf));
+ surf->fence_fd = -1;
surf->fd = adf_interface_simple_buffer_alloc(pdata->intf_fd, mode->hdisplay,
mode->vdisplay, pdata->format, &surf->offset, &surf->pitch);
if (surf->fd < 0)
@@ -163,21 +168,20 @@ static GRSurface* adf_init(minui_backend *backend)
pdata->intf_fd = -1;
for (i = 0; i < n_dev_ids && pdata->intf_fd < 0; i++) {
- adf_device dev;
- int err = adf_device_open(dev_ids[i], O_RDWR, &dev);
+ int err = adf_device_open(dev_ids[i], O_RDWR, &pdata->dev);
if (err < 0) {
fprintf(stderr, "opening adf device %u failed: %s\n", dev_ids[i],
strerror(-err));
continue;
}
- err = adf_device_init(pdata, &dev);
- if (err < 0)
+ err = adf_device_init(pdata, &pdata->dev);
+ if (err < 0) {
fprintf(stderr, "initializing adf device %u failed: %s\n",
dev_ids[i], strerror(-err));
-
- adf_device_close(&dev);
+ adf_device_close(&pdata->dev);
+ }
}
free(dev_ids);
@@ -193,6 +197,23 @@ static GRSurface* adf_init(minui_backend *backend)
return ret;
}
+static void adf_sync(adf_surface_pdata *surf)
+{
+ unsigned int warningTimeout = 3000;
+
+ if (surf == NULL)
+ return;
+
+ if (surf->fence_fd >= 0){
+ int err = sync_wait(surf->fence_fd, warningTimeout);
+ if (err < 0)
+ perror("adf sync fence wait error\n");
+
+ close(surf->fence_fd);
+ surf->fence_fd = -1;
+ }
+}
+
static GRSurface* adf_flip(minui_backend *backend)
{
adf_pdata *pdata = (adf_pdata *)backend;
@@ -202,9 +223,10 @@ static GRSurface* adf_flip(minui_backend *backend)
surf->base.width, surf->base.height, pdata->format, surf->fd,
surf->offset, surf->pitch, -1);
if (fence_fd >= 0)
- close(fence_fd);
+ surf->fence_fd = fence_fd;
pdata->current_surface = (pdata->current_surface + 1) % pdata->n_surfaces;
+ adf_sync(&pdata->surfaces[pdata->current_surface]);
return &pdata->surfaces[pdata->current_surface].base;
}
@@ -218,6 +240,7 @@ static void adf_blank(minui_backend *backend, bool blank)
static void adf_surface_destroy(adf_surface_pdata *surf)
{
munmap(surf->base.data, surf->pitch * surf->base.height);
+ close(surf->fence_fd);
close(surf->fd);
}
@@ -226,6 +249,7 @@ static void adf_exit(minui_backend *backend)
adf_pdata *pdata = (adf_pdata *)backend;
unsigned int i;
+ adf_device_close(&pdata->dev);
for (i = 0; i < pdata->n_surfaces; i++)
adf_surface_destroy(&pdata->surfaces[i]);
if (pdata->intf_fd >= 0)
diff --git a/minui/minui.h b/minui/minui.h
index 23156b6f1..f6b42c628 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -77,7 +77,7 @@ typedef int (*ev_set_key_callback)(int code, int value, void* data);
int ev_init(ev_callback input_cb, void* data);
void ev_exit();
int ev_add_fd(int fd, ev_callback cb, void* data);
-void ev_iterate_available_keys(std::function<void(int)> f);
+void ev_iterate_available_keys(const std::function<void(int)>& f);
int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data);
// 'timeout' has the same semantics as poll(2).
@@ -123,8 +123,8 @@ int res_create_alpha_surface(const char* name, GRSurface** pSurface);
// given locale. The image is expected to be a composite of multiple
// translations of the same text, with special added rows that encode
// the subimages' size and intended locale in the pixel data. See
-// development/tools/recovery_l10n for an app that will generate these
-// specialized images from Android resources.
+// bootable/recovery/tools/recovery_l10n for an app that will generate
+// these specialized images from Android resources.
int res_create_localized_alpha_surface(const char* name, const char* locale,
GRSurface** pSurface);
diff --git a/minui/resources.cpp b/minui/resources.cpp
index 40d3c2c88..730b05f13 100644
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -28,6 +28,7 @@
#include <linux/fb.h>
#include <linux/kd.h>
+#include <vector>
#include <png.h>
#include "minui.h"
@@ -280,7 +281,7 @@ int res_create_multi_display_surface(const char* name, int* frames, int* fps,
goto exit;
}
- surface = reinterpret_cast<GRSurface**>(malloc(*frames * sizeof(GRSurface*)));
+ surface = reinterpret_cast<GRSurface**>(calloc(*frames, sizeof(GRSurface*)));
if (surface == NULL) {
result = -8;
goto exit;
@@ -315,7 +316,7 @@ exit:
if (result < 0) {
if (surface) {
for (int i = 0; i < *frames; ++i) {
- if (surface[i]) free(surface[i]);
+ free(surface[i]);
}
free(surface);
}
@@ -391,18 +392,13 @@ int res_create_localized_alpha_surface(const char* name,
png_infop info_ptr = NULL;
png_uint_32 width, height;
png_byte channels;
- unsigned char* row;
png_uint_32 y;
+ std::vector<unsigned char> row;
*pSurface = NULL;
if (locale == NULL) {
- surface = malloc_surface(0);
- surface->width = 0;
- surface->height = 0;
- surface->row_bytes = 0;
- surface->pixel_bytes = 1;
- goto exit;
+ return result;
}
result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
@@ -413,13 +409,13 @@ int res_create_localized_alpha_surface(const char* name,
goto exit;
}
- row = reinterpret_cast<unsigned char*>(malloc(width));
+ row.resize(width);
for (y = 0; y < height; ++y) {
- png_read_row(png_ptr, row, NULL);
+ png_read_row(png_ptr, row.data(), NULL);
int w = (row[1] << 8) | row[0];
int h = (row[3] << 8) | row[2];
- int len = row[4];
- char* loc = (char*)row+5;
+ __unused int len = row[4];
+ char* loc = reinterpret_cast<char*>(&row[5]);
if (y+1+h >= height || matches_locale(loc, locale)) {
printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
@@ -436,8 +432,8 @@ int res_create_localized_alpha_surface(const char* name,
int i;
for (i = 0; i < h; ++i, ++y) {
- png_read_row(png_ptr, row, NULL);
- memcpy(surface->data + i*w, row, w);
+ png_read_row(png_ptr, row.data(), NULL);
+ memcpy(surface->data + i*w, row.data(), w);
}
*pSurface = reinterpret_cast<GRSurface*>(surface);
@@ -445,7 +441,7 @@ int res_create_localized_alpha_surface(const char* name,
} else {
int i;
for (i = 0; i < h; ++i, ++y) {
- png_read_row(png_ptr, row, NULL);
+ png_read_row(png_ptr, row.data(), NULL);
}
}
}
diff --git a/minzip/Android.mk b/minzip/Android.mk
index 22eabfbb1..3d36fd64e 100644
--- a/minzip/Android.mk
+++ b/minzip/Android.mk
@@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
Hash.c \
SysUtil.c \
- DirUtil.c \
+ DirUtil.cpp \
Inlines.c \
Zip.c
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.cpp
index 97cb2e0ee..e08e360c0 100644
--- a/minzip/DirUtil.c
+++ b/minzip/DirUtil.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "DirUtil.h"
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -24,7 +26,10 @@
#include <dirent.h>
#include <limits.h>
-#include "DirUtil.h"
+#include <string>
+
+#include <selinux/label.h>
+#include <selinux/selinux.h>
typedef enum { DMISSING, DDIR, DILLEGAL } DirStatus;
@@ -66,43 +71,25 @@ dirCreateHierarchy(const char *path, int mode,
errno = ENOENT;
return -1;
}
-
- /* Allocate a path that we can modify; stick a slash on
- * the end to make things easier.
- */
- size_t pathLen = strlen(path);
- char *cpath = (char *)malloc(pathLen + 2);
- if (cpath == NULL) {
- errno = ENOMEM;
- return -1;
- }
- memcpy(cpath, path, pathLen);
+ // Allocate a path that we can modify; stick a slash on
+ // the end to make things easier.
+ std::string cpath = path;
if (stripFileName) {
- /* Strip everything after the last slash.
- */
- char *c = cpath + pathLen - 1;
- while (c != cpath && *c != '/') {
- c--;
- }
- if (c == cpath) {
- //xxx test this path
- /* No directory component. Act like the path was empty.
- */
+ // Strip everything after the last slash.
+ size_t pos = cpath.rfind('/');
+ if (pos == std::string::npos) {
errno = ENOENT;
- free(cpath);
return -1;
}
- c[1] = '\0'; // Terminate after the slash we found.
+ cpath.resize(pos + 1);
} else {
- /* Make sure that the path ends in a slash.
- */
- cpath[pathLen] = '/';
- cpath[pathLen + 1] = '\0';
+ // Make sure that the path ends in a slash.
+ cpath.push_back('/');
}
/* See if it already exists.
*/
- ds = getPathDirStatus(cpath);
+ ds = getPathDirStatus(cpath.c_str());
if (ds == DDIR) {
return 0;
} else if (ds == DILLEGAL) {
@@ -112,7 +99,8 @@ dirCreateHierarchy(const char *path, int mode,
/* Walk up the path from the root and make each level.
* If a directory already exists, no big deal.
*/
- char *p = cpath;
+ const char *path_start = &cpath[0];
+ char *p = &cpath[0];
while (*p != '\0') {
/* Skip any slashes, watching out for the end of the string.
*/
@@ -135,12 +123,11 @@ dirCreateHierarchy(const char *path, int mode,
/* Check this part of the path and make a new directory
* if necessary.
*/
- ds = getPathDirStatus(cpath);
+ ds = getPathDirStatus(path_start);
if (ds == DILLEGAL) {
/* Could happen if some other process/thread is
* messing with the filesystem.
*/
- free(cpath);
return -1;
} else if (ds == DMISSING) {
int err;
@@ -148,11 +135,11 @@ dirCreateHierarchy(const char *path, int mode,
char *secontext = NULL;
if (sehnd) {
- selabel_lookup(sehnd, &secontext, cpath, mode);
+ selabel_lookup(sehnd, &secontext, path_start, mode);
setfscreatecon(secontext);
}
- err = mkdir(cpath, mode);
+ err = mkdir(path_start, mode);
if (secontext) {
freecon(secontext);
@@ -160,22 +147,17 @@ dirCreateHierarchy(const char *path, int mode,
}
if (err != 0) {
- free(cpath);
return -1;
}
- if (timestamp != NULL && utime(cpath, timestamp)) {
- free(cpath);
+ if (timestamp != NULL && utime(path_start, timestamp)) {
return -1;
}
}
// else, this directory already exists.
-
- /* Repair the path and continue.
- */
+
+ // Repair the path and continue.
*p = '/';
}
- free(cpath);
-
return 0;
}
diff --git a/minzip/DirUtil.h b/minzip/DirUtil.h
index 85a00128b..85b83c387 100644
--- a/minzip/DirUtil.h
+++ b/minzip/DirUtil.h
@@ -24,8 +24,7 @@
extern "C" {
#endif
-#include <selinux/selinux.h>
-#include <selinux/label.h>
+struct selabel_handle;
/* Like "mkdir -p", try to guarantee that all directories
* specified in path are present, creating as many directories
diff --git a/minzip/Zip.c b/minzip/Zip.c
index bdb565c64..d557daa7f 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -23,6 +23,9 @@
#undef NDEBUG // do this after including Log.h
#include <assert.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+
#define SORT_ENTRIES 1
/*
@@ -91,7 +94,7 @@ enum {
static void dumpEntry(const ZipEntry* pEntry)
{
LOGI(" %p '%.*s'\n", pEntry->fileName,pEntry->fileNameLen,pEntry->fileName);
- LOGI(" off=%ld comp=%ld uncomp=%ld how=%d\n", pEntry->offset,
+ LOGI(" off=%u comp=%u uncomp=%u how=%d\n", pEntry->offset,
pEntry->compLen, pEntry->uncompLen, pEntry->compression);
}
#endif
@@ -505,13 +508,11 @@ static bool processDeflatedEntry(const ZipArchive *pArchive,
const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
void *cookie)
{
- long result = -1;
+ bool success = false;
+ unsigned long totalOut = 0;
unsigned char procBuf[32 * 1024];
z_stream zstream;
int zerr;
- long compRemaining;
-
- compRemaining = pEntry->compLen;
/*
* Initialize the zlib stream.
@@ -572,16 +573,17 @@ static bool processDeflatedEntry(const ZipArchive *pArchive,
assert(zerr == Z_STREAM_END); /* other errors should've been caught */
// success!
- result = zstream.total_out;
+ totalOut = zstream.total_out;
+ success = true;
z_bail:
inflateEnd(&zstream); /* free up any allocated structures */
bail:
- if (result != pEntry->uncompLen) {
- if (result != -1) // error already shown?
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- result, pEntry->uncompLen);
+ if (totalOut != pEntry->uncompLen) {
+ if (success) { // error already shown?
+ LOGW("Size mismatch on inflated file (%lu vs %u)\n", totalOut, pEntry->uncompLen);
+ }
return false;
}
return true;
@@ -759,7 +761,7 @@ static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry)
*/
needLen = helper->targetDirLen + 1 +
pEntry->fileNameLen - helper->zipDirLen + 1;
- if (needLen > helper->bufLen) {
+ if (firstTime || needLen > helper->bufLen) {
char *newBuf;
needLen *= 2;
@@ -966,7 +968,7 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
setfscreatecon(secontext);
}
- int fd = open(targetFile, O_CREAT|O_WRONLY|O_TRUNC|O_SYNC,
+ int fd = open(targetFile, O_CREAT|O_WRONLY|O_TRUNC,
UNZIP_FILEMODE);
if (secontext) {
diff --git a/minzip/Zip.h b/minzip/Zip.h
index 86d8db597..c932c1178 100644
--- a/minzip/Zip.h
+++ b/minzip/Zip.h
@@ -18,8 +18,7 @@
extern "C" {
#endif
-#include <selinux/selinux.h>
-#include <selinux/label.h>
+struct selabel_handle;
/*
* One entry in the Zip archive. Treat this as opaque -- use accessors below.
@@ -32,9 +31,9 @@ extern "C" {
typedef struct ZipEntry {
unsigned int fileNameLen;
const char* fileName; // not null-terminated
- long offset;
- long compLen;
- long uncompLen;
+ uint32_t offset;
+ uint32_t compLen;
+ uint32_t uncompLen;
int compression;
long modTime;
long crc32;
@@ -85,10 +84,10 @@ void mzCloseZipArchive(ZipArchive* pArchive);
const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
const char* entryName);
-INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
+INLINE uint32_t mzGetZipEntryOffset(const ZipEntry* pEntry) {
return pEntry->offset;
}
-INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
+INLINE uint32_t mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
return pEntry->uncompLen;
}
diff --git a/mounts.cpp b/mounts.cpp
new file mode 100644
index 000000000..f23376b06
--- /dev/null
+++ b/mounts.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 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 "mounts.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+
+#include <string>
+#include <vector>
+
+struct MountedVolume {
+ std::string device;
+ std::string mount_point;
+ std::string filesystem;
+ std::string flags;
+};
+
+std::vector<MountedVolume*> g_mounts_state;
+
+bool scan_mounted_volumes() {
+ for (size_t i = 0; i < g_mounts_state.size(); ++i) {
+ delete g_mounts_state[i];
+ }
+ g_mounts_state.clear();
+
+ // Open and read mount table entries.
+ FILE* fp = setmntent("/proc/mounts", "re");
+ if (fp == NULL) {
+ return false;
+ }
+ mntent* e;
+ while ((e = getmntent(fp)) != NULL) {
+ MountedVolume* v = new MountedVolume;
+ v->device = e->mnt_fsname;
+ v->mount_point = e->mnt_dir;
+ v->filesystem = e->mnt_type;
+ v->flags = e->mnt_opts;
+ g_mounts_state.push_back(v);
+ }
+ endmntent(fp);
+ return true;
+}
+
+MountedVolume* find_mounted_volume_by_device(const char* device) {
+ for (size_t i = 0; i < g_mounts_state.size(); ++i) {
+ if (g_mounts_state[i]->device == device) return g_mounts_state[i];
+ }
+ return nullptr;
+}
+
+MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point) {
+ for (size_t i = 0; i < g_mounts_state.size(); ++i) {
+ if (g_mounts_state[i]->mount_point == mount_point) return g_mounts_state[i];
+ }
+ return nullptr;
+}
+
+int unmount_mounted_volume(MountedVolume* volume) {
+ // Intentionally pass the empty string to umount if the caller tries
+ // to unmount a volume they already unmounted using this
+ // function.
+ std::string mount_point = volume->mount_point;
+ volume->mount_point.clear();
+ return umount(mount_point.c_str());
+}
+
+int remount_read_only(MountedVolume* volume) {
+ return mount(volume->device.c_str(), volume->mount_point.c_str(), volume->filesystem.c_str(),
+ MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY | MS_REMOUNT, 0);
+}
diff --git a/mtdutils/mounts.h b/mounts.h
index d721355b8..1b7670329 100644
--- a/mtdutils/mounts.h
+++ b/mounts.h
@@ -14,28 +14,19 @@
* limitations under the License.
*/
-#ifndef MTDUTILS_MOUNTS_H_
-#define MTDUTILS_MOUNTS_H_
+#ifndef MOUNTS_H_
+#define MOUNTS_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct MountedVolume MountedVolume;
+struct MountedVolume;
-int scan_mounted_volumes(void);
+bool scan_mounted_volumes();
-const MountedVolume *find_mounted_volume_by_device(const char *device);
+MountedVolume* find_mounted_volume_by_device(const char* device);
-const MountedVolume *
-find_mounted_volume_by_mount_point(const char *mount_point);
+MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point);
-int unmount_mounted_volume(const MountedVolume *volume);
+int unmount_mounted_volume(MountedVolume* volume);
-int remount_read_only(const MountedVolume* volume);
+int remount_read_only(MountedVolume* volume);
-#ifdef __cplusplus
-}
#endif
-
-#endif // MTDUTILS_MOUNTS_H_
diff --git a/mtdutils/Android.mk b/mtdutils/Android.mk
deleted file mode 100644
index b7d35c27a..000000000
--- a/mtdutils/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- mtdutils.c \
- mounts.c
-
-LOCAL_MODULE := libmtdutils
-LOCAL_CLANG := true
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_CLANG := true
-LOCAL_SRC_FILES := flash_image.c
-LOCAL_MODULE := flash_image
-LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES := libmtdutils
-LOCAL_SHARED_LIBRARIES := libcutils liblog libc
-include $(BUILD_EXECUTABLE)
diff --git a/mtdutils/flash_image.c b/mtdutils/flash_image.c
deleted file mode 100644
index 36ffa1314..000000000
--- a/mtdutils/flash_image.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 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 <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "cutils/log.h"
-#include "mtdutils.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "flash_image"
-
-#define HEADER_SIZE 2048 // size of header to compare for equality
-
-void die(const char *msg, ...) {
- int err = errno;
- va_list args;
- va_start(args, msg);
- char buf[1024];
- vsnprintf(buf, sizeof(buf), msg, args);
- va_end(args);
-
- if (err != 0) {
- strlcat(buf, ": ", sizeof(buf));
- strlcat(buf, strerror(err), sizeof(buf));
- }
-
- fprintf(stderr, "%s\n", buf);
- ALOGE("%s\n", buf);
- exit(1);
-}
-
-/* Read an image file and write it to a flash partition. */
-
-int main(int argc, char **argv) {
- const MtdPartition *ptn;
- MtdWriteContext *write;
- void *data;
- unsigned sz;
-
- if (argc != 3) {
- fprintf(stderr, "usage: %s partition file.img\n", argv[0]);
- return 2;
- }
-
- if (mtd_scan_partitions() <= 0) die("error scanning partitions");
- const MtdPartition *partition = mtd_find_partition_by_name(argv[1]);
- if (partition == NULL) die("can't find %s partition", argv[1]);
-
- // If the first part of the file matches the partition, skip writing
-
- int fd = open(argv[2], O_RDONLY);
- if (fd < 0) die("error opening %s", argv[2]);
-
- char header[HEADER_SIZE];
- int headerlen = TEMP_FAILURE_RETRY(read(fd, header, sizeof(header)));
- if (headerlen <= 0) die("error reading %s header", argv[2]);
-
- MtdReadContext *in = mtd_read_partition(partition);
- if (in == NULL) {
- ALOGW("error opening %s: %s\n", argv[1], strerror(errno));
- // just assume it needs re-writing
- } else {
- char check[HEADER_SIZE];
- int checklen = mtd_read_data(in, check, sizeof(check));
- if (checklen <= 0) {
- ALOGW("error reading %s: %s\n", argv[1], strerror(errno));
- // just assume it needs re-writing
- } else if (checklen == headerlen && !memcmp(header, check, headerlen)) {
- ALOGI("header is the same, not flashing %s\n", argv[1]);
- return 0;
- }
- mtd_read_close(in);
- }
-
- // Skip the header (we'll come back to it), write everything else
- ALOGI("flashing %s from %s\n", argv[1], argv[2]);
-
- MtdWriteContext *out = mtd_write_partition(partition);
- if (out == NULL) die("error writing %s", argv[1]);
-
- char buf[HEADER_SIZE];
- memset(buf, 0, headerlen);
- int wrote = mtd_write_data(out, buf, headerlen);
- if (wrote != headerlen) die("error writing %s", argv[1]);
-
- int len;
- while ((len = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf)))) > 0) {
- wrote = mtd_write_data(out, buf, len);
- if (wrote != len) die("error writing %s", argv[1]);
- }
- if (len < 0) die("error reading %s", argv[2]);
-
- if (mtd_write_close(out)) die("error closing %s", argv[1]);
-
- // Now come back and write the header last
-
- out = mtd_write_partition(partition);
- if (out == NULL) die("error re-opening %s", argv[1]);
-
- wrote = mtd_write_data(out, header, headerlen);
- if (wrote != headerlen) die("error re-writing %s", argv[1]);
-
- // Need to write a complete block, so write the rest of the first block
- size_t block_size;
- if (mtd_partition_info(partition, NULL, &block_size, NULL))
- die("error getting %s block size", argv[1]);
-
- if (TEMP_FAILURE_RETRY(lseek(fd, headerlen, SEEK_SET)) != headerlen)
- die("error rewinding %s", argv[2]);
-
- int left = block_size - headerlen;
- while (left < 0) left += block_size;
- while (left > 0) {
- len = TEMP_FAILURE_RETRY(read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left));
- if (len <= 0) die("error reading %s", argv[2]);
- if (mtd_write_data(out, buf, len) != len)
- die("error writing %s", argv[1]);
- left -= len;
- }
-
- if (mtd_write_close(out)) die("error closing %s", argv[1]);
- return 0;
-}
diff --git a/mtdutils/mounts.c b/mtdutils/mounts.c
deleted file mode 100644
index 6a9b03d30..000000000
--- a/mtdutils/mounts.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2007 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 <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mount.h>
-
-#include "mounts.h"
-
-struct MountedVolume {
- const char *device;
- const char *mount_point;
- const char *filesystem;
- const char *flags;
-};
-
-typedef struct {
- MountedVolume *volumes;
- int volumes_allocd;
- int volume_count;
-} MountsState;
-
-static MountsState g_mounts_state = {
- NULL, // volumes
- 0, // volumes_allocd
- 0 // volume_count
-};
-
-static inline void
-free_volume_internals(const MountedVolume *volume, int zero)
-{
- free((char *)volume->device);
- free((char *)volume->mount_point);
- free((char *)volume->filesystem);
- free((char *)volume->flags);
- if (zero) {
- memset((void *)volume, 0, sizeof(*volume));
- }
-}
-
-#define PROC_MOUNTS_FILENAME "/proc/mounts"
-
-int
-scan_mounted_volumes()
-{
- FILE* fp;
- struct mntent* mentry;
-
- if (g_mounts_state.volumes == NULL) {
- const int numv = 32;
- MountedVolume *volumes = malloc(numv * sizeof(*volumes));
- if (volumes == NULL) {
- errno = ENOMEM;
- return -1;
- }
- g_mounts_state.volumes = volumes;
- g_mounts_state.volumes_allocd = numv;
- memset(volumes, 0, numv * sizeof(*volumes));
- } else {
- /* Free the old volume strings.
- */
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- free_volume_internals(&g_mounts_state.volumes[i], 1);
- }
- }
- g_mounts_state.volume_count = 0;
-
- /* Open and read mount table entries. */
- fp = setmntent(PROC_MOUNTS_FILENAME, "r");
- if (fp == NULL) {
- return -1;
- }
- while ((mentry = getmntent(fp)) != NULL) {
- MountedVolume* v = &g_mounts_state.volumes[g_mounts_state.volume_count++];
- v->device = strdup(mentry->mnt_fsname);
- v->mount_point = strdup(mentry->mnt_dir);
- v->filesystem = strdup(mentry->mnt_type);
- v->flags = strdup(mentry->mnt_opts);
- }
- endmntent(fp);
- return 0;
-}
-
-const MountedVolume *
-find_mounted_volume_by_device(const char *device)
-{
- if (g_mounts_state.volumes != NULL) {
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- MountedVolume *v = &g_mounts_state.volumes[i];
- /* May be null if it was unmounted and we haven't rescanned.
- */
- if (v->device != NULL) {
- if (strcmp(v->device, device) == 0) {
- return v;
- }
- }
- }
- }
- return NULL;
-}
-
-const MountedVolume *
-find_mounted_volume_by_mount_point(const char *mount_point)
-{
- if (g_mounts_state.volumes != NULL) {
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- MountedVolume *v = &g_mounts_state.volumes[i];
- /* May be null if it was unmounted and we haven't rescanned.
- */
- if (v->mount_point != NULL) {
- if (strcmp(v->mount_point, mount_point) == 0) {
- return v;
- }
- }
- }
- }
- return NULL;
-}
-
-int
-unmount_mounted_volume(const MountedVolume *volume)
-{
- /* Intentionally pass NULL to umount if the caller tries
- * to unmount a volume they already unmounted using this
- * function.
- */
- int ret = umount(volume->mount_point);
- if (ret == 0) {
- free_volume_internals(volume, 1);
- return 0;
- }
- return ret;
-}
-
-int
-remount_read_only(const MountedVolume* volume)
-{
- return mount(volume->device, volume->mount_point, volume->filesystem,
- MS_NOATIME | MS_NODEV | MS_NODIRATIME |
- MS_RDONLY | MS_REMOUNT, 0);
-}
diff --git a/mtdutils/mtdutils.c b/mtdutils/mtdutils.c
deleted file mode 100644
index cd4f52cd5..000000000
--- a/mtdutils/mtdutils.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright (C) 2007 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mount.h> // for _IOW, _IOR, mount()
-#include <sys/stat.h>
-#include <mtd/mtd-user.h>
-#undef NDEBUG
-#include <assert.h>
-
-#include "mtdutils.h"
-
-struct MtdPartition {
- int device_index;
- unsigned int size;
- unsigned int erase_size;
- char *name;
-};
-
-struct MtdReadContext {
- const MtdPartition *partition;
- char *buffer;
- size_t consumed;
- int fd;
-};
-
-struct MtdWriteContext {
- const MtdPartition *partition;
- char *buffer;
- size_t stored;
- int fd;
-
- off_t* bad_block_offsets;
- int bad_block_alloc;
- int bad_block_count;
-};
-
-typedef struct {
- MtdPartition *partitions;
- int partitions_allocd;
- int partition_count;
-} MtdState;
-
-static MtdState g_mtd_state = {
- NULL, // partitions
- 0, // partitions_allocd
- -1 // partition_count
-};
-
-#define MTD_PROC_FILENAME "/proc/mtd"
-
-int
-mtd_scan_partitions()
-{
- char buf[2048];
- const char *bufp;
- int fd;
- int i;
- ssize_t nbytes;
-
- if (g_mtd_state.partitions == NULL) {
- const int nump = 32;
- MtdPartition *partitions = malloc(nump * sizeof(*partitions));
- if (partitions == NULL) {
- errno = ENOMEM;
- return -1;
- }
- g_mtd_state.partitions = partitions;
- g_mtd_state.partitions_allocd = nump;
- memset(partitions, 0, nump * sizeof(*partitions));
- }
- g_mtd_state.partition_count = 0;
-
- /* Initialize all of the entries to make things easier later.
- * (Lets us handle sparsely-numbered partitions, which
- * may not even be possible.)
- */
- for (i = 0; i < g_mtd_state.partitions_allocd; i++) {
- MtdPartition *p = &g_mtd_state.partitions[i];
- if (p->name != NULL) {
- free(p->name);
- p->name = NULL;
- }
- p->device_index = -1;
- }
-
- /* Open and read the file contents.
- */
- fd = open(MTD_PROC_FILENAME, O_RDONLY);
- if (fd < 0) {
- goto bail;
- }
- nbytes = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf) - 1));
- close(fd);
- if (nbytes < 0) {
- goto bail;
- }
- buf[nbytes] = '\0';
-
- /* Parse the contents of the file, which looks like:
- *
- * # cat /proc/mtd
- * dev: size erasesize name
- * mtd0: 00080000 00020000 "bootloader"
- * mtd1: 00400000 00020000 "mfg_and_gsm"
- * mtd2: 00400000 00020000 "0000000c"
- * mtd3: 00200000 00020000 "0000000d"
- * mtd4: 04000000 00020000 "system"
- * mtd5: 03280000 00020000 "userdata"
- */
- bufp = buf;
- while (nbytes > 0) {
- int mtdnum, mtdsize, mtderasesize;
- int matches;
- char mtdname[64];
- mtdname[0] = '\0';
- mtdnum = -1;
-
- matches = sscanf(bufp, "mtd%d: %x %x \"%63[^\"]",
- &mtdnum, &mtdsize, &mtderasesize, mtdname);
- /* This will fail on the first line, which just contains
- * column headers.
- */
- if (matches == 4) {
- MtdPartition *p = &g_mtd_state.partitions[mtdnum];
- p->device_index = mtdnum;
- p->size = mtdsize;
- p->erase_size = mtderasesize;
- p->name = strdup(mtdname);
- if (p->name == NULL) {
- errno = ENOMEM;
- goto bail;
- }
- g_mtd_state.partition_count++;
- }
-
- /* Eat the line.
- */
- while (nbytes > 0 && *bufp != '\n') {
- bufp++;
- nbytes--;
- }
- if (nbytes > 0) {
- bufp++;
- nbytes--;
- }
- }
-
- return g_mtd_state.partition_count;
-
-bail:
- // keep "partitions" around so we can free the names on a rescan.
- g_mtd_state.partition_count = -1;
- return -1;
-}
-
-const MtdPartition *
-mtd_find_partition_by_name(const char *name)
-{
- if (g_mtd_state.partitions != NULL) {
- int i;
- for (i = 0; i < g_mtd_state.partitions_allocd; i++) {
- MtdPartition *p = &g_mtd_state.partitions[i];
- if (p->device_index >= 0 && p->name != NULL) {
- if (strcmp(p->name, name) == 0) {
- return p;
- }
- }
- }
- }
- return NULL;
-}
-
-int
-mtd_mount_partition(const MtdPartition *partition, const char *mount_point,
- const char *filesystem, int read_only)
-{
- const unsigned long flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
- char devname[64];
- int rv = -1;
-
- sprintf(devname, "/dev/block/mtdblock%d", partition->device_index);
- if (!read_only) {
- rv = mount(devname, mount_point, filesystem, flags, NULL);
- }
- if (read_only || rv < 0) {
- rv = mount(devname, mount_point, filesystem, flags | MS_RDONLY, 0);
- if (rv < 0) {
- printf("Failed to mount %s on %s: %s\n",
- devname, mount_point, strerror(errno));
- } else {
- printf("Mount %s on %s read-only\n", devname, mount_point);
- }
- }
-#if 1 //TODO: figure out why this is happening; remove include of stat.h
- if (rv >= 0) {
- /* For some reason, the x bits sometimes aren't set on the root
- * of mounted volumes.
- */
- struct stat st;
- rv = stat(mount_point, &st);
- if (rv < 0) {
- return rv;
- }
- mode_t new_mode = st.st_mode | S_IXUSR | S_IXGRP | S_IXOTH;
- if (new_mode != st.st_mode) {
-printf("Fixing execute permissions for %s\n", mount_point);
- rv = chmod(mount_point, new_mode);
- if (rv < 0) {
- printf("Couldn't fix permissions for %s: %s\n",
- mount_point, strerror(errno));
- }
- }
- }
-#endif
- return rv;
-}
-
-int
-mtd_partition_info(const MtdPartition *partition,
- size_t *total_size, size_t *erase_size, size_t *write_size)
-{
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- int fd = open(mtddevname, O_RDONLY);
- if (fd < 0) return -1;
-
- struct mtd_info_user mtd_info;
- int ret = ioctl(fd, MEMGETINFO, &mtd_info);
- close(fd);
- if (ret < 0) return -1;
-
- if (total_size != NULL) *total_size = mtd_info.size;
- if (erase_size != NULL) *erase_size = mtd_info.erasesize;
- if (write_size != NULL) *write_size = mtd_info.writesize;
- return 0;
-}
-
-MtdReadContext *mtd_read_partition(const MtdPartition *partition)
-{
- MtdReadContext *ctx = (MtdReadContext*) malloc(sizeof(MtdReadContext));
- if (ctx == NULL) return NULL;
-
- ctx->buffer = malloc(partition->erase_size);
- if (ctx->buffer == NULL) {
- free(ctx);
- return NULL;
- }
-
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- ctx->fd = open(mtddevname, O_RDONLY);
- if (ctx->fd < 0) {
- free(ctx->buffer);
- free(ctx);
- return NULL;
- }
-
- ctx->partition = partition;
- ctx->consumed = partition->erase_size;
- return ctx;
-}
-
-static int read_block(const MtdPartition *partition, int fd, char *data)
-{
- struct mtd_ecc_stats before, after;
- if (ioctl(fd, ECCGETSTATS, &before)) {
- printf("mtd: ECCGETSTATS error (%s)\n", strerror(errno));
- return -1;
- }
-
- loff_t pos = TEMP_FAILURE_RETRY(lseek64(fd, 0, SEEK_CUR));
- if (pos == -1) {
- printf("mtd: read_block: couldn't SEEK_CUR: %s\n", strerror(errno));
- return -1;
- }
-
- ssize_t size = partition->erase_size;
- int mgbb;
-
- while (pos + size <= (int) partition->size) {
- if (TEMP_FAILURE_RETRY(lseek64(fd, pos, SEEK_SET)) != pos ||
- TEMP_FAILURE_RETRY(read(fd, data, size)) != size) {
- printf("mtd: read error at 0x%08llx (%s)\n",
- (long long)pos, strerror(errno));
- } else if (ioctl(fd, ECCGETSTATS, &after)) {
- printf("mtd: ECCGETSTATS error (%s)\n", strerror(errno));
- return -1;
- } else if (after.failed != before.failed) {
- printf("mtd: ECC errors (%d soft, %d hard) at 0x%08llx\n",
- after.corrected - before.corrected,
- after.failed - before.failed, (long long)pos);
- // copy the comparison baseline for the next read.
- memcpy(&before, &after, sizeof(struct mtd_ecc_stats));
- } else if ((mgbb = ioctl(fd, MEMGETBADBLOCK, &pos))) {
- fprintf(stderr,
- "mtd: MEMGETBADBLOCK returned %d at 0x%08llx: %s\n",
- mgbb, (long long)pos, strerror(errno));
- } else {
- return 0; // Success!
- }
-
- pos += partition->erase_size;
- }
-
- errno = ENOSPC;
- return -1;
-}
-
-ssize_t mtd_read_data(MtdReadContext *ctx, char *data, size_t len)
-{
- size_t read = 0;
- while (read < len) {
- if (ctx->consumed < ctx->partition->erase_size) {
- size_t avail = ctx->partition->erase_size - ctx->consumed;
- size_t copy = len - read < avail ? len - read : avail;
- memcpy(data + read, ctx->buffer + ctx->consumed, copy);
- ctx->consumed += copy;
- read += copy;
- }
-
- // Read complete blocks directly into the user's buffer
- while (ctx->consumed == ctx->partition->erase_size &&
- len - read >= ctx->partition->erase_size) {
- if (read_block(ctx->partition, ctx->fd, data + read)) return -1;
- read += ctx->partition->erase_size;
- }
-
- if (read >= len) {
- return read;
- }
-
- // Read the next block into the buffer
- if (ctx->consumed == ctx->partition->erase_size && read < len) {
- if (read_block(ctx->partition, ctx->fd, ctx->buffer)) return -1;
- ctx->consumed = 0;
- }
- }
-
- return read;
-}
-
-void mtd_read_close(MtdReadContext *ctx)
-{
- close(ctx->fd);
- free(ctx->buffer);
- free(ctx);
-}
-
-MtdWriteContext *mtd_write_partition(const MtdPartition *partition)
-{
- MtdWriteContext *ctx = (MtdWriteContext*) malloc(sizeof(MtdWriteContext));
- if (ctx == NULL) return NULL;
-
- ctx->bad_block_offsets = NULL;
- ctx->bad_block_alloc = 0;
- ctx->bad_block_count = 0;
-
- ctx->buffer = malloc(partition->erase_size);
- if (ctx->buffer == NULL) {
- free(ctx);
- return NULL;
- }
-
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- ctx->fd = open(mtddevname, O_RDWR);
- if (ctx->fd < 0) {
- free(ctx->buffer);
- free(ctx);
- return NULL;
- }
-
- ctx->partition = partition;
- ctx->stored = 0;
- return ctx;
-}
-
-static void add_bad_block_offset(MtdWriteContext *ctx, off_t pos) {
- if (ctx->bad_block_count + 1 > ctx->bad_block_alloc) {
- ctx->bad_block_alloc = (ctx->bad_block_alloc*2) + 1;
- ctx->bad_block_offsets = realloc(ctx->bad_block_offsets,
- ctx->bad_block_alloc * sizeof(off_t));
- }
- ctx->bad_block_offsets[ctx->bad_block_count++] = pos;
-}
-
-static int write_block(MtdWriteContext *ctx, const char *data)
-{
- const MtdPartition *partition = ctx->partition;
- int fd = ctx->fd;
-
- off_t pos = TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_CUR));
- if (pos == (off_t) -1) {
- printf("mtd: write_block: couldn't SEEK_CUR: %s\n", strerror(errno));
- return -1;
- }
-
- ssize_t size = partition->erase_size;
- while (pos + size <= (int) partition->size) {
- loff_t bpos = pos;
- int ret = ioctl(fd, MEMGETBADBLOCK, &bpos);
- if (ret != 0 && !(ret == -1 && errno == EOPNOTSUPP)) {
- add_bad_block_offset(ctx, pos);
- fprintf(stderr,
- "mtd: not writing bad block at 0x%08lx (ret %d): %s\n",
- pos, ret, strerror(errno));
- pos += partition->erase_size;
- continue; // Don't try to erase known factory-bad blocks.
- }
-
- struct erase_info_user erase_info;
- erase_info.start = pos;
- erase_info.length = size;
- int retry;
- for (retry = 0; retry < 2; ++retry) {
- if (ioctl(fd, MEMERASE, &erase_info) < 0) {
- printf("mtd: erase failure at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
- if (TEMP_FAILURE_RETRY(lseek(fd, pos, SEEK_SET)) != pos ||
- TEMP_FAILURE_RETRY(write(fd, data, size)) != size) {
- printf("mtd: write error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- }
-
- char verify[size];
- if (TEMP_FAILURE_RETRY(lseek(fd, pos, SEEK_SET)) != pos ||
- TEMP_FAILURE_RETRY(read(fd, verify, size)) != size) {
- printf("mtd: re-read error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
- if (memcmp(data, verify, size) != 0) {
- printf("mtd: verification error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
-
- if (retry > 0) {
- printf("mtd: wrote block after %d retries\n", retry);
- }
- printf("mtd: successfully wrote block at %lx\n", pos);
- return 0; // Success!
- }
-
- // Try to erase it once more as we give up on this block
- add_bad_block_offset(ctx, pos);
- printf("mtd: skipping write block at 0x%08lx\n", pos);
- ioctl(fd, MEMERASE, &erase_info);
- pos += partition->erase_size;
- }
-
- // Ran out of space on the device
- errno = ENOSPC;
- return -1;
-}
-
-ssize_t mtd_write_data(MtdWriteContext *ctx, const char *data, size_t len)
-{
- size_t wrote = 0;
- while (wrote < len) {
- // Coalesce partial writes into complete blocks
- if (ctx->stored > 0 || len - wrote < ctx->partition->erase_size) {
- size_t avail = ctx->partition->erase_size - ctx->stored;
- size_t copy = len - wrote < avail ? len - wrote : avail;
- memcpy(ctx->buffer + ctx->stored, data + wrote, copy);
- ctx->stored += copy;
- wrote += copy;
- }
-
- // If a complete block was accumulated, write it
- if (ctx->stored == ctx->partition->erase_size) {
- if (write_block(ctx, ctx->buffer)) return -1;
- ctx->stored = 0;
- }
-
- // Write complete blocks directly from the user's buffer
- while (ctx->stored == 0 && len - wrote >= ctx->partition->erase_size) {
- if (write_block(ctx, data + wrote)) return -1;
- wrote += ctx->partition->erase_size;
- }
- }
-
- return wrote;
-}
-
-off_t mtd_erase_blocks(MtdWriteContext *ctx, int blocks)
-{
- // Zero-pad and write any pending data to get us to a block boundary
- if (ctx->stored > 0) {
- size_t zero = ctx->partition->erase_size - ctx->stored;
- memset(ctx->buffer + ctx->stored, 0, zero);
- if (write_block(ctx, ctx->buffer)) return -1;
- ctx->stored = 0;
- }
-
- off_t pos = TEMP_FAILURE_RETRY(lseek(ctx->fd, 0, SEEK_CUR));
- if ((off_t) pos == (off_t) -1) {
- printf("mtd_erase_blocks: couldn't SEEK_CUR: %s\n", strerror(errno));
- return -1;
- }
-
- const int total = (ctx->partition->size - pos) / ctx->partition->erase_size;
- if (blocks < 0) blocks = total;
- if (blocks > total) {
- errno = ENOSPC;
- return -1;
- }
-
- // Erase the specified number of blocks
- while (blocks-- > 0) {
- loff_t bpos = pos;
- if (ioctl(ctx->fd, MEMGETBADBLOCK, &bpos) > 0) {
- printf("mtd: not erasing bad block at 0x%08lx\n", pos);
- pos += ctx->partition->erase_size;
- continue; // Don't try to erase known factory-bad blocks.
- }
-
- struct erase_info_user erase_info;
- erase_info.start = pos;
- erase_info.length = ctx->partition->erase_size;
- if (ioctl(ctx->fd, MEMERASE, &erase_info) < 0) {
- printf("mtd: erase failure at 0x%08lx\n", pos);
- }
- pos += ctx->partition->erase_size;
- }
-
- return pos;
-}
-
-int mtd_write_close(MtdWriteContext *ctx)
-{
- int r = 0;
- // Make sure any pending data gets written
- if (mtd_erase_blocks(ctx, 0) == (off_t) -1) r = -1;
- if (close(ctx->fd)) r = -1;
- free(ctx->bad_block_offsets);
- free(ctx->buffer);
- free(ctx);
- return r;
-}
diff --git a/mtdutils/mtdutils.h b/mtdutils/mtdutils.h
deleted file mode 100644
index 8059d6a4d..000000000
--- a/mtdutils/mtdutils.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 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 MTDUTILS_H_
-#define MTDUTILS_H_
-
-#include <sys/types.h> // for size_t, etc.
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct MtdPartition MtdPartition;
-
-int mtd_scan_partitions(void);
-
-const MtdPartition *mtd_find_partition_by_name(const char *name);
-
-/* mount_point is like "/system"
- * filesystem is like "yaffs2"
- */
-int mtd_mount_partition(const MtdPartition *partition, const char *mount_point,
- const char *filesystem, int read_only);
-
-/* get the partition and the minimum erase/write block size. NULL is ok.
- */
-int mtd_partition_info(const MtdPartition *partition,
- size_t *total_size, size_t *erase_size, size_t *write_size);
-
-/* read or write raw data from a partition, starting at the beginning.
- * skips bad blocks as best we can.
- */
-typedef struct MtdReadContext MtdReadContext;
-typedef struct MtdWriteContext MtdWriteContext;
-
-MtdReadContext *mtd_read_partition(const MtdPartition *);
-ssize_t mtd_read_data(MtdReadContext *, char *data, size_t data_len);
-void mtd_read_close(MtdReadContext *);
-
-MtdWriteContext *mtd_write_partition(const MtdPartition *);
-ssize_t mtd_write_data(MtdWriteContext *, const char *data, size_t data_len);
-off_t mtd_erase_blocks(MtdWriteContext *, int blocks); /* 0 ok, -1 for all */
-int mtd_write_close(MtdWriteContext *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // MTDUTILS_H_
diff --git a/otafault/Android.mk b/otafault/Android.mk
index ba7add855..d0b1174a4 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -32,6 +32,8 @@ LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs)
include $(BUILD_STATIC_LIBRARY)
+# otafault_test (static executable)
+# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp
index 04458537b..2efd3004a 100644
--- a/otafault/ota_io.cpp
+++ b/otafault/ota_io.cpp
@@ -30,7 +30,7 @@ static std::string read_fault_file_name = "";
static std::string write_fault_file_name = "";
static std::string fsync_fault_file_name = "";
-static bool get_hit_file(const char* cached_path, std::string ffn) {
+static bool get_hit_file(const char* cached_path, const std::string& ffn) {
return should_hit_cache()
? !strncmp(cached_path, OTAIO_CACHE_FNAME, strlen(cached_path))
: !strncmp(cached_path, ffn.c_str(), strlen(cached_path));
@@ -92,6 +92,7 @@ size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
}
}
size_t status = fread(ptr, size, nitems, stream);
+ // If I/O error occurs, set the retry-update flag.
if (status != nitems && errno == EIO) {
have_eio_error = true;
}
diff --git a/recovery-refresh.cpp b/recovery-refresh.cpp
index 70adc70ee..b75c91538 100644
--- a/recovery-refresh.cpp
+++ b/recovery-refresh.cpp
@@ -76,7 +76,7 @@ static ssize_t logrotate(
}
std::string name(filename);
- size_t dot = name.find_last_of(".");
+ size_t dot = name.find_last_of('.');
std::string sub = name.substr(0, dot);
if (!strstr(LAST_KMSG_FILE, sub.c_str()) &&
@@ -92,7 +92,7 @@ static ssize_t logrotate(
if (!isdigit(number.data()[0])) {
name += ".1";
} else {
- unsigned long long i = std::stoull(number);
+ auto i = std::stoull(number);
name = sub + "." + std::to_string(i + 1);
}
}
diff --git a/recovery.cpp b/recovery.cpp
index cd4f361fe..6989fe00d 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -44,13 +44,15 @@
#include <android-base/parseint.h>
#include <android-base/stringprintf.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/properties.h>
+#include <healthd/BatteryMonitor.h>
#include <log/logger.h> /* Android Log packet format */
#include <private/android_logger.h> /* private pmsg functions */
-
-#include <healthd/BatteryMonitor.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
#include "adb_install.h"
#include "common.h"
@@ -64,13 +66,11 @@
#include "minzip/Zip.h"
#include "roots.h"
#include "ui.h"
-#include "unique_fd.h"
#include "screen_ui.h"
struct selabel_handle *sehandle;
static const struct option OPTIONS[] = {
- { "send_intent", required_argument, NULL, 'i' },
{ "update_package", required_argument, NULL, 'u' },
{ "retry_count", required_argument, NULL, 'n' },
{ "wipe_data", no_argument, NULL, 'w' },
@@ -97,7 +97,6 @@ static const std::vector<std::string> bootreason_blacklist {
static const char *CACHE_LOG_DIR = "/cache/recovery";
static const char *COMMAND_FILE = "/cache/recovery/command";
-static const char *INTENT_FILE = "/cache/recovery/intent";
static const char *LOG_FILE = "/cache/recovery/log";
static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
static const char *LOCALE_FILE = "/cache/recovery/last_locale";
@@ -132,10 +131,8 @@ static bool has_cache = false;
* The recovery tool communicates with the main system through /cache files.
* /cache/recovery/command - INPUT - command line for tool, one arg per line
* /cache/recovery/log - OUTPUT - combined log file from recovery run(s)
- * /cache/recovery/intent - OUTPUT - intent that was passed in
*
* The arguments which may be supplied in the recovery.command file:
- * --send_intent=anystring - write the text out to recovery.intent
* --update_package=path - verify install an OTA package file
* --wipe_data - erase user data (and cache), then reboot
* --wipe_cache - wipe cache (but not user data), then reboot
@@ -424,7 +421,7 @@ static void copy_log_file_to_pmsg(const char* source, const char* destination) {
}
// How much of the temp log we have copied to the copy in cache.
-static long tmplog_offset = 0;
+static off_t tmplog_offset = 0;
static void copy_log_file(const char* source, const char* destination, bool append) {
FILE* dest_fp = fopen_path(destination, append ? "a" : "w");
@@ -434,7 +431,7 @@ static void copy_log_file(const char* source, const char* destination, bool appe
FILE* source_fp = fopen(source, "r");
if (source_fp != nullptr) {
if (append) {
- fseek(source_fp, tmplog_offset, SEEK_SET); // Since last write
+ fseeko(source_fp, tmplog_offset, SEEK_SET); // Since last write
}
char buf[4096];
size_t bytes;
@@ -442,7 +439,7 @@ static void copy_log_file(const char* source, const char* destination, bool appe
fwrite(buf, 1, bytes, dest_fp);
}
if (append) {
- tmplog_offset = ftell(source_fp);
+ tmplog_offset = ftello(source_fp);
}
check_and_fclose(source_fp, source);
}
@@ -516,22 +513,10 @@ static void copy_logs() {
}
// clear the recovery command and prepare to boot a (hopefully working) system,
-// copy our log file to cache as well (for the system to read), and
-// record any intent we were asked to communicate back to the system.
-// this function is idempotent: call it as many times as you like.
+// copy our log file to cache as well (for the system to read). This function is
+// idempotent: call it as many times as you like.
static void
-finish_recovery(const char *send_intent) {
- // By this point, we're ready to return to the main system...
- if (send_intent != NULL && has_cache) {
- FILE *fp = fopen_path(INTENT_FILE, "w");
- if (fp == NULL) {
- LOGE("Can't open %s\n", INTENT_FILE);
- } else {
- fputs(send_intent, fp);
- check_and_fclose(fp, INTENT_FILE);
- }
- }
-
+finish_recovery() {
// Save the locale to cache, so if recovery is next started up
// without a --locale argument (eg, directly from the bootloader)
// it will use the last-known locale.
@@ -541,10 +526,12 @@ finish_recovery(const char *send_intent) {
if (has_cache) {
LOGI("Saving locale \"%s\"\n", locale);
FILE* fp = fopen_path(LOCALE_FILE, "w");
- fwrite(locale, 1, len, fp);
- fflush(fp);
- fsync(fileno(fp));
- check_and_fclose(fp, LOCALE_FILE);
+ if (fp != NULL) {
+ fwrite(locale, 1, len, fp);
+ fflush(fp);
+ fsync(fileno(fp));
+ check_and_fclose(fp, LOCALE_FILE);
+ }
}
}
@@ -884,14 +871,14 @@ static bool wipe_cache(bool should_confirm, Device* device) {
// Otherwise, it goes with BLKDISCARD (if device supports BLKDISCARDZEROES) or
// BLKZEROOUT.
static bool secure_wipe_partition(const std::string& partition) {
- unique_fd fd(TEMP_FAILURE_RETRY(open(partition.c_str(), O_WRONLY)));
- if (fd.get() == -1) {
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(partition.c_str(), O_WRONLY)));
+ if (fd == -1) {
LOGE("failed to open \"%s\": %s\n", partition.c_str(), strerror(errno));
return false;
}
uint64_t range[2] = {0, 0};
- if (ioctl(fd.get(), BLKGETSIZE64, &range[1]) == -1 || range[1] == 0) {
+ if (ioctl(fd, BLKGETSIZE64, &range[1]) == -1 || range[1] == 0) {
LOGE("failed to get partition size: %s\n", strerror(errno));
return false;
}
@@ -899,20 +886,20 @@ static bool secure_wipe_partition(const std::string& partition) {
partition.c_str(), range[0], range[1]);
printf("Trying BLKSECDISCARD...\t");
- if (ioctl(fd.get(), BLKSECDISCARD, &range) == -1) {
+ if (ioctl(fd, BLKSECDISCARD, &range) == -1) {
printf("failed: %s\n", strerror(errno));
// Use BLKDISCARD if it zeroes out blocks, otherwise use BLKZEROOUT.
unsigned int zeroes;
- if (ioctl(fd.get(), BLKDISCARDZEROES, &zeroes) == 0 && zeroes != 0) {
+ if (ioctl(fd, BLKDISCARDZEROES, &zeroes) == 0 && zeroes != 0) {
printf("Trying BLKDISCARD...\t");
- if (ioctl(fd.get(), BLKDISCARD, &range) == -1) {
+ if (ioctl(fd, BLKDISCARD, &range) == -1) {
printf("failed: %s\n", strerror(errno));
return false;
}
} else {
printf("Trying BLKZEROOUT...\t");
- if (ioctl(fd.get(), BLKZEROOUT, &range) == -1) {
+ if (ioctl(fd, BLKZEROOUT, &range) == -1) {
printf("failed: %s\n", strerror(errno));
return false;
}
@@ -1014,45 +1001,50 @@ static bool wipe_ab_device(size_t wipe_package_size) {
}
static void choose_recovery_file(Device* device) {
- if (!has_cache) {
- ui->Print("No /cache partition found.\n");
- return;
- }
-
// "Back" + KEEP_LOG_COUNT * 2 + terminating nullptr entry
char* entries[1 + KEEP_LOG_COUNT * 2 + 1];
memset(entries, 0, sizeof(entries));
unsigned int n = 0;
- // Add LAST_LOG_FILE + LAST_LOG_FILE.x
- // Add LAST_KMSG_FILE + LAST_KMSG_FILE.x
- for (int i = 0; i < KEEP_LOG_COUNT; i++) {
- char* log_file;
- int ret;
- ret = (i == 0) ? asprintf(&log_file, "%s", LAST_LOG_FILE) :
- asprintf(&log_file, "%s.%d", LAST_LOG_FILE, i);
- if (ret == -1) {
- // memory allocation failure - return early. Should never happen.
- return;
- }
- if ((ensure_path_mounted(log_file) != 0) || (access(log_file, R_OK) == -1)) {
- free(log_file);
- } else {
- entries[n++] = log_file;
- }
+ if (has_cache) {
+ // Add LAST_LOG_FILE + LAST_LOG_FILE.x
+ // Add LAST_KMSG_FILE + LAST_KMSG_FILE.x
+ for (int i = 0; i < KEEP_LOG_COUNT; i++) {
+ char* log_file;
+ int ret;
+ ret = (i == 0) ? asprintf(&log_file, "%s", LAST_LOG_FILE) :
+ asprintf(&log_file, "%s.%d", LAST_LOG_FILE, i);
+ if (ret == -1) {
+ // memory allocation failure - return early. Should never happen.
+ return;
+ }
+ if ((ensure_path_mounted(log_file) != 0) || (access(log_file, R_OK) == -1)) {
+ free(log_file);
+ } else {
+ entries[n++] = log_file;
+ }
- char* kmsg_file;
- ret = (i == 0) ? asprintf(&kmsg_file, "%s", LAST_KMSG_FILE) :
- asprintf(&kmsg_file, "%s.%d", LAST_KMSG_FILE, i);
- if (ret == -1) {
- // memory allocation failure - return early. Should never happen.
- return;
+ char* kmsg_file;
+ ret = (i == 0) ? asprintf(&kmsg_file, "%s", LAST_KMSG_FILE) :
+ asprintf(&kmsg_file, "%s.%d", LAST_KMSG_FILE, i);
+ if (ret == -1) {
+ // memory allocation failure - return early. Should never happen.
+ return;
+ }
+ if ((ensure_path_mounted(kmsg_file) != 0) || (access(kmsg_file, R_OK) == -1)) {
+ free(kmsg_file);
+ } else {
+ entries[n++] = kmsg_file;
+ }
}
- if ((ensure_path_mounted(kmsg_file) != 0) || (access(kmsg_file, R_OK) == -1)) {
- free(kmsg_file);
- } else {
- entries[n++] = kmsg_file;
+ } else {
+ // If cache partition is not found, view /tmp/recovery.log instead.
+ ui->Print("No /cache partition found.\n");
+ if (access(TEMPORARY_LOG_FILE, R_OK) == -1) {
+ return;
+ } else{
+ entries[n++] = strdup(TEMPORARY_LOG_FILE);
}
}
@@ -1188,7 +1180,7 @@ static int apply_from_sdcard(Device* device, bool* wipe_cache) {
static Device::BuiltinAction
prompt_and_wait(Device* device, int status) {
for (;;) {
- finish_recovery(NULL);
+ finish_recovery();
switch (status) {
case INSTALL_SUCCESS:
case INSTALL_NONE:
@@ -1461,7 +1453,7 @@ static ssize_t logrotate(
}
std::string name(filename);
- size_t dot = name.find_last_of(".");
+ size_t dot = name.find_last_of('.');
std::string sub = name.substr(0, dot);
if (!strstr(LAST_KMSG_FILE, sub.c_str()) &&
@@ -1477,7 +1469,7 @@ static ssize_t logrotate(
if (!isdigit(number.data()[0])) {
name += ".1";
} else {
- unsigned long long i = std::stoull(number);
+ auto i = std::stoull(number);
name = sub + "." + std::to_string(i + 1);
}
}
@@ -1523,7 +1515,6 @@ int main(int argc, char **argv) {
get_args(&argc, &argv);
- const char *send_intent = NULL;
const char *update_package = NULL;
bool should_wipe_data = false;
bool should_wipe_cache = false;
@@ -1541,7 +1532,6 @@ int main(int argc, char **argv) {
int option_index;
while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) {
switch (arg) {
- case 'i': send_intent = optarg; break;
case 'n': android::base::ParseInt(optarg, &retry_count, 0); break;
case 'u': update_package = optarg; break;
case 'w': should_wipe_data = true; break;
@@ -1758,7 +1748,7 @@ int main(int argc, char **argv) {
}
// Save logs and clean up before rebooting or shutting down.
- finish_recovery(send_intent);
+ finish_recovery();
switch (after) {
case Device::SHUTDOWN:
diff --git a/res-hdpi/images/erasing_text.png b/res-hdpi/images/erasing_text.png
index e500d0268..2186c1950 100644
--- a/res-hdpi/images/erasing_text.png
+++ b/res-hdpi/images/erasing_text.png
Binary files differ
diff --git a/res-hdpi/images/error_text.png b/res-hdpi/images/error_text.png
index 9a3597b82..9700f459f 100644
--- a/res-hdpi/images/error_text.png
+++ b/res-hdpi/images/error_text.png
Binary files differ
diff --git a/res-hdpi/images/installing_security_text.png b/res-hdpi/images/installing_security_text.png
index 76e747410..0f605952c 100644
--- a/res-hdpi/images/installing_security_text.png
+++ b/res-hdpi/images/installing_security_text.png
Binary files differ
diff --git a/res-hdpi/images/installing_text.png b/res-hdpi/images/installing_text.png
index 5d2a5fa0c..ec8b875a5 100644
--- a/res-hdpi/images/installing_text.png
+++ b/res-hdpi/images/installing_text.png
Binary files differ
diff --git a/res-hdpi/images/no_command_text.png b/res-hdpi/images/no_command_text.png
index a567ad141..3eddcbbed 100644
--- a/res-hdpi/images/no_command_text.png
+++ b/res-hdpi/images/no_command_text.png
Binary files differ
diff --git a/res-mdpi/images/erasing_text.png b/res-mdpi/images/erasing_text.png
index ad68a1941..b0dd3c6d3 100644
--- a/res-mdpi/images/erasing_text.png
+++ b/res-mdpi/images/erasing_text.png
Binary files differ
diff --git a/res-mdpi/images/error_text.png b/res-mdpi/images/error_text.png
index 8ea5acb20..6a47a5956 100644
--- a/res-mdpi/images/error_text.png
+++ b/res-mdpi/images/error_text.png
Binary files differ
diff --git a/res-mdpi/images/installing_security_text.png b/res-mdpi/images/installing_security_text.png
index 615b9b73f..149939862 100644
--- a/res-mdpi/images/installing_security_text.png
+++ b/res-mdpi/images/installing_security_text.png
Binary files differ
diff --git a/res-mdpi/images/installing_text.png b/res-mdpi/images/installing_text.png
index 6cf8716b5..01e9bfefb 100644
--- a/res-mdpi/images/installing_text.png
+++ b/res-mdpi/images/installing_text.png
Binary files differ
diff --git a/res-mdpi/images/no_command_text.png b/res-mdpi/images/no_command_text.png
index 5cc6b3715..d340df518 100644
--- a/res-mdpi/images/no_command_text.png
+++ b/res-mdpi/images/no_command_text.png
Binary files differ
diff --git a/res-xhdpi/images/erasing_text.png b/res-xhdpi/images/erasing_text.png
index 01176e8cc..2f8b46918 100644
--- a/res-xhdpi/images/erasing_text.png
+++ b/res-xhdpi/images/erasing_text.png
Binary files differ
diff --git a/res-xhdpi/images/error_text.png b/res-xhdpi/images/error_text.png
index 4f890fa59..ad18851c5 100644
--- a/res-xhdpi/images/error_text.png
+++ b/res-xhdpi/images/error_text.png
Binary files differ
diff --git a/res-xhdpi/images/installing_security_text.png b/res-xhdpi/images/installing_security_text.png
index 6192832e8..acc6a7c2b 100644
--- a/res-xhdpi/images/installing_security_text.png
+++ b/res-xhdpi/images/installing_security_text.png
Binary files differ
diff --git a/res-xhdpi/images/installing_text.png b/res-xhdpi/images/installing_text.png
index 441352949..32897d0f0 100644
--- a/res-xhdpi/images/installing_text.png
+++ b/res-xhdpi/images/installing_text.png
Binary files differ
diff --git a/res-xhdpi/images/no_command_text.png b/res-xhdpi/images/no_command_text.png
index 9f7403753..eb43c59c5 100644
--- a/res-xhdpi/images/no_command_text.png
+++ b/res-xhdpi/images/no_command_text.png
Binary files differ
diff --git a/res-xxhdpi/images/erasing_text.png b/res-xxhdpi/images/erasing_text.png
index b8653eb95..8ff2b2fcf 100644
--- a/res-xxhdpi/images/erasing_text.png
+++ b/res-xxhdpi/images/erasing_text.png
Binary files differ
diff --git a/res-xxhdpi/images/error_text.png b/res-xxhdpi/images/error_text.png
index d77ee5085..658d4ea56 100644
--- a/res-xxhdpi/images/error_text.png
+++ b/res-xxhdpi/images/error_text.png
Binary files differ
diff --git a/res-xxhdpi/images/installing_security_text.png b/res-xxhdpi/images/installing_security_text.png
index ca0c191d4..23fcaa441 100644
--- a/res-xxhdpi/images/installing_security_text.png
+++ b/res-xxhdpi/images/installing_security_text.png
Binary files differ
diff --git a/res-xxhdpi/images/installing_text.png b/res-xxhdpi/images/installing_text.png
index a76a174f0..fd8e58464 100644
--- a/res-xxhdpi/images/installing_text.png
+++ b/res-xxhdpi/images/installing_text.png
Binary files differ
diff --git a/res-xxhdpi/images/no_command_text.png b/res-xxhdpi/images/no_command_text.png
index 5e363e3a5..23932d6b7 100644
--- a/res-xxhdpi/images/no_command_text.png
+++ b/res-xxhdpi/images/no_command_text.png
Binary files differ
diff --git a/res-xxxhdpi/images/erasing_text.png b/res-xxxhdpi/images/erasing_text.png
index f4a466118..031529371 100644
--- a/res-xxxhdpi/images/erasing_text.png
+++ b/res-xxxhdpi/images/erasing_text.png
Binary files differ
diff --git a/res-xxxhdpi/images/error_text.png b/res-xxxhdpi/images/error_text.png
index 317a7716f..dba127f02 100644
--- a/res-xxxhdpi/images/error_text.png
+++ b/res-xxxhdpi/images/error_text.png
Binary files differ
diff --git a/res-xxxhdpi/images/installing_security_text.png b/res-xxxhdpi/images/installing_security_text.png
index c99c9072a..6cdbef48e 100644
--- a/res-xxxhdpi/images/installing_security_text.png
+++ b/res-xxxhdpi/images/installing_security_text.png
Binary files differ
diff --git a/res-xxxhdpi/images/installing_text.png b/res-xxxhdpi/images/installing_text.png
index 91d833017..32511a9c5 100644
--- a/res-xxxhdpi/images/installing_text.png
+++ b/res-xxxhdpi/images/installing_text.png
Binary files differ
diff --git a/res-xxxhdpi/images/no_command_text.png b/res-xxxhdpi/images/no_command_text.png
index b6eb964ba..b6cdd7718 100644
--- a/res-xxxhdpi/images/no_command_text.png
+++ b/res-xxxhdpi/images/no_command_text.png
Binary files differ
diff --git a/roots.cpp b/roots.cpp
index f361cb8ca..49369475b 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "roots.h"
+
#include <errno.h>
#include <stdlib.h>
#include <sys/mount.h>
@@ -25,11 +27,9 @@
#include <fcntl.h>
#include <fs_mgr.h>
-#include "mtdutils/mtdutils.h"
-#include "mtdutils/mounts.h"
-#include "roots.h"
#include "common.h"
#include "make_ext4fs.h"
+#include "mounts.h"
#include "wipe.h"
#include "cryptfs.h"
@@ -82,9 +82,7 @@ int ensure_path_mounted_at(const char* path, const char* mount_point) {
return 0;
}
- int result;
- result = scan_mounted_volumes();
- if (result < 0) {
+ if (!scan_mounted_volumes()) {
LOGE("failed to scan mounted volumes\n");
return -1;
}
@@ -93,8 +91,7 @@ int ensure_path_mounted_at(const char* path, const char* mount_point) {
mount_point = v->mount_point;
}
- const MountedVolume* mv =
- find_mounted_volume_by_mount_point(mount_point);
+ MountedVolume* mv = find_mounted_volume_by_mount_point(mount_point);
if (mv) {
// volume is already mounted
return 0;
@@ -102,26 +99,27 @@ int ensure_path_mounted_at(const char* path, const char* mount_point) {
mkdir(mount_point, 0755); // in case it doesn't already exist
- if (strcmp(v->fs_type, "yaffs2") == 0) {
- // mount an MTD partition as a YAFFS2 filesystem.
- mtd_scan_partitions();
- const MtdPartition* partition;
- partition = mtd_find_partition_by_name(v->blk_device);
- if (partition == NULL) {
- LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
- v->blk_device, mount_point);
- return -1;
- }
- return mtd_mount_partition(partition, mount_point, v->fs_type, 0);
- } else if (strcmp(v->fs_type, "ext4") == 0 ||
+ if (strcmp(v->fs_type, "ext4") == 0 ||
strcmp(v->fs_type, "squashfs") == 0 ||
strcmp(v->fs_type, "vfat") == 0) {
- result = mount(v->blk_device, mount_point, v->fs_type,
- v->flags, v->fs_options);
- if (result == 0) return 0;
+ int result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options);
+ if (result == -1 && fs_mgr_is_formattable(v)) {
+ LOGE("failed to mount %s (%s), formatting ...\n",
+ mount_point, strerror(errno));
+ bool crypt_footer = fs_mgr_is_encryptable(v) && !strcmp(v->key_loc, "footer");
+ if (fs_mgr_do_format(v, crypt_footer) == 0) {
+ result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options);
+ } else {
+ LOGE("failed to format %s (%s)\n", mount_point, strerror(errno));
+ return -1;
+ }
+ }
- LOGE("failed to mount %s (%s)\n", mount_point, strerror(errno));
- return -1;
+ if (result == -1) {
+ LOGE("failed to mount %s (%s)\n", mount_point, strerror(errno));
+ return -1;
+ }
+ return 0;
}
LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, mount_point);
@@ -144,15 +142,12 @@ int ensure_path_unmounted(const char* path) {
return -1;
}
- int result;
- result = scan_mounted_volumes();
- if (result < 0) {
+ if (!scan_mounted_volumes()) {
LOGE("failed to scan mounted volumes\n");
return -1;
}
- const MountedVolume* mv =
- find_mounted_volume_by_mount_point(v->mount_point);
+ MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point);
if (mv == NULL) {
// volume is already unmounted
return 0;
@@ -196,29 +191,6 @@ int format_volume(const char* volume, const char* directory) {
return -1;
}
- if (strcmp(v->fs_type, "yaffs2") == 0 || strcmp(v->fs_type, "mtd") == 0) {
- mtd_scan_partitions();
- const MtdPartition* partition = mtd_find_partition_by_name(v->blk_device);
- if (partition == NULL) {
- LOGE("format_volume: no MTD partition \"%s\"\n", v->blk_device);
- return -1;
- }
-
- MtdWriteContext *write = mtd_write_partition(partition);
- if (write == NULL) {
- LOGW("format_volume: can't open MTD \"%s\"\n", v->blk_device);
- return -1;
- } else if (mtd_erase_blocks(write, -1) == (off_t) -1) {
- LOGW("format_volume: can't erase MTD \"%s\"\n", v->blk_device);
- mtd_write_close(write);
- return -1;
- } else if (mtd_write_close(write)) {
- LOGW("format_volume: can't close MTD \"%s\"\n", v->blk_device);
- return -1;
- }
- return 0;
- }
-
if (strcmp(v->fs_type, "ext4") == 0 || strcmp(v->fs_type, "f2fs") == 0) {
// if there's a key_loc that looks like a path, it should be a
// block device for storing encryption metadata. wipe it too.
diff --git a/screen_ui.cpp b/screen_ui.cpp
index c2b532657..4866873a1 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -410,7 +410,7 @@ void ScreenRecoveryUI::ProgressThreadLoop() {
// minimum of 20ms delay between frames
double delay = interval - (end-start);
if (delay < 0.02) delay = 0.02;
- usleep((long)(delay * 1000000));
+ usleep(static_cast<useconds_t>(delay * 1000000));
}
}
@@ -665,8 +665,8 @@ void ScreenRecoveryUI::ClearText() {
}
void ScreenRecoveryUI::ShowFile(FILE* fp) {
- std::vector<long> offsets;
- offsets.push_back(ftell(fp));
+ std::vector<off_t> offsets;
+ offsets.push_back(ftello(fp));
ClearText();
struct stat sb;
@@ -676,7 +676,7 @@ void ScreenRecoveryUI::ShowFile(FILE* fp) {
while (true) {
if (show_prompt) {
PrintOnScreenOnly("--(%d%% of %d bytes)--",
- static_cast<int>(100 * (double(ftell(fp)) / double(sb.st_size))),
+ static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))),
static_cast<int>(sb.st_size));
Redraw();
while (show_prompt) {
@@ -695,7 +695,7 @@ void ScreenRecoveryUI::ShowFile(FILE* fp) {
if (feof(fp)) {
return;
}
- offsets.push_back(ftell(fp));
+ offsets.push_back(ftello(fp));
}
}
ClearText();
diff --git a/tests/Android.mk b/tests/Android.mk
index a66991b21..971e5d0f0 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -46,10 +46,10 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_STATIC_LIBRARIES := \
libapplypatch \
libotafault \
- libmtdutils \
libbase \
libverifier \
- libcrypto_static \
+ libcrypto_utils \
+ libcrypto \
libminui \
libminzip \
libcutils \
diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp
index 780ff2816..6a3eebf29 100644
--- a/tests/component/verifier_test.cpp
+++ b/tests/component/verifier_test.cpp
@@ -45,14 +45,14 @@ class MockUI : public RecoveryUI {
void Init() { }
void SetStage(int, int) { }
void SetLocale(const char*) { }
- void SetBackground(Icon icon) { }
- void SetSystemUpdateText(bool security_update) { }
+ void SetBackground(Icon /*icon*/) { }
+ void SetSystemUpdateText(bool /*security_update*/) { }
- void SetProgressType(ProgressType determinate) { }
- void ShowProgress(float portion, float seconds) { }
- void SetProgress(float fraction) { }
+ void SetProgressType(ProgressType /*determinate*/) { }
+ void ShowProgress(float /*portion*/, float /*seconds*/) { }
+ void SetProgress(float /*fraction*/) { }
- void ShowText(bool visible) { }
+ void ShowText(bool /*visible*/) { }
bool IsTextVisible() { return false; }
bool WasTextEverVisible() { return false; }
void Print(const char* fmt, ...) {
@@ -69,9 +69,10 @@ class MockUI : public RecoveryUI {
}
void ShowFile(const char*) { }
- void StartMenu(const char* const * headers, const char* const * items,
- int initial_selection) { }
- int SelectMenu(int sel) { return 0; }
+ void StartMenu(const char* const* /*headers*/,
+ const char* const* /*items*/,
+ int /*initial_selection*/) { }
+ int SelectMenu(int /*sel*/) { return 0; }
void EndMenu() { }
};
@@ -94,30 +95,14 @@ class VerifierTest : public testing::TestWithParam<std::vector<std::string>> {
android::base::StringPrintf("%s%s%s%s", DATA_PATH, NATIVE_TEST_PATH,
TESTDATA_PATH, args[0].c_str());
if (sysMapFile(package.c_str(), &memmap) != 0) {
- FAIL() << "Failed to mmap " << package << ": " << strerror(errno)
- << "\n";
+ FAIL() << "Failed to mmap " << package << ": " << strerror(errno) << "\n";
}
for (auto it = ++(args.cbegin()); it != args.cend(); ++it) {
- if (it->substr(it->length() - 3, it->length()) == "256") {
- if (certs.empty()) {
- FAIL() << "May only specify -sha256 after key type\n";
- }
- certs.back().hash_len = SHA256_DIGEST_LENGTH;
- } else {
- std::string public_key_file = android::base::StringPrintf(
- "%s%s%stest_key_%s.txt", DATA_PATH, NATIVE_TEST_PATH,
- TESTDATA_PATH, it->c_str());
- ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
- certs.back().hash_len = SHA_DIGEST_LENGTH;
- }
- }
- if (certs.empty()) {
std::string public_key_file = android::base::StringPrintf(
- "%s%s%stest_key_e3.txt", DATA_PATH, NATIVE_TEST_PATH,
- TESTDATA_PATH);
+ "%s%s%stestkey_%s.txt", DATA_PATH, NATIVE_TEST_PATH,
+ TESTDATA_PATH, it->c_str());
ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
- certs.back().hash_len = SHA_DIGEST_LENGTH;
}
}
@@ -142,37 +127,38 @@ TEST_P(VerifierFailureTest, VerifyFailure) {
INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest,
::testing::Values(
- std::vector<std::string>({"otasigned.zip", "e3"}),
- std::vector<std::string>({"otasigned_f4.zip", "f4"}),
- std::vector<std::string>({"otasigned_sha256.zip", "e3", "sha256"}),
- std::vector<std::string>({"otasigned_f4_sha256.zip", "f4", "sha256"}),
- std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "ec", "sha256"})));
+ std::vector<std::string>({"otasigned_v1.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v2"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v3"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v4"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v5"})));
INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest,
::testing::Values(
- std::vector<std::string>({"otasigned.zip", "f4", "e3"}),
- std::vector<std::string>({"otasigned_f4.zip", "ec", "f4"}),
- std::vector<std::string>({"otasigned_sha256.zip", "ec", "e3", "e3", "sha256"}),
- std::vector<std::string>({"otasigned_f4_sha256.zip", "ec", "sha256", "e3", "f4", "sha256"}),
- std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "f4", "sha256", "e3", "ec", "sha256"})));
+ std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"})));
INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest,
::testing::Values(
- std::vector<std::string>({"otasigned.zip", "f4"}),
- std::vector<std::string>({"otasigned_f4.zip", "e3"}),
- std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "e3", "sha256"})));
+ std::vector<std::string>({"otasigned_v1.zip", "v2"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v5"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v5"}),
+ std::vector<std::string>({"otasigned_v5.zip", "v3"})));
INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest,
::testing::Values(
- std::vector<std::string>({"otasigned.zip", "e3", "sha256"}),
- std::vector<std::string>({"otasigned_f4.zip", "f4", "sha256"}),
- std::vector<std::string>({"otasigned_sha256.zip"}),
- std::vector<std::string>({"otasigned_f4_sha256.zip", "f4"}),
- std::vector<std::string>({"otasigned_ecdsa_sha256.zip"})));
+ std::vector<std::string>({"otasigned_v1.zip", "v3"}),
+ std::vector<std::string>({"otasigned_v2.zip", "v4"}),
+ std::vector<std::string>({"otasigned_v3.zip", "v1"}),
+ std::vector<std::string>({"otasigned_v4.zip", "v2"})));
INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest,
::testing::Values(
- std::vector<std::string>({"random.zip"}),
- std::vector<std::string>({"fake-eocd.zip"}),
- std::vector<std::string>({"alter-metadata.zip"}),
- std::vector<std::string>({"alter-footer.zip"})));
+ std::vector<std::string>({"random.zip", "v1"}),
+ std::vector<std::string>({"fake-eocd.zip", "v1"}),
+ std::vector<std::string>({"alter-metadata.zip", "v1"}),
+ std::vector<std::string>({"alter-footer.zip", "v1"})));
diff --git a/tests/testdata/otasigned.zip b/tests/testdata/otasigned_v1.zip
index a6bc53e41..a6bc53e41 100644
--- a/tests/testdata/otasigned.zip
+++ b/tests/testdata/otasigned_v1.zip
Binary files differ
diff --git a/tests/testdata/otasigned_f4.zip b/tests/testdata/otasigned_v2.zip
index dd1e4dd40..dd1e4dd40 100644
--- a/tests/testdata/otasigned_f4.zip
+++ b/tests/testdata/otasigned_v2.zip
Binary files differ
diff --git a/tests/testdata/otasigned_sha256.zip b/tests/testdata/otasigned_v3.zip
index 0ed4409b3..0ed4409b3 100644
--- a/tests/testdata/otasigned_sha256.zip
+++ b/tests/testdata/otasigned_v3.zip
Binary files differ
diff --git a/tests/testdata/otasigned_f4_sha256.zip b/tests/testdata/otasigned_v4.zip
index 3af408c40..3af408c40 100644
--- a/tests/testdata/otasigned_f4_sha256.zip
+++ b/tests/testdata/otasigned_v4.zip
Binary files differ
diff --git a/tests/testdata/otasigned_ecdsa_sha256.zip b/tests/testdata/otasigned_v5.zip
index 999fcdd0f..999fcdd0f 100644
--- a/tests/testdata/otasigned_ecdsa_sha256.zip
+++ b/tests/testdata/otasigned_v5.zip
Binary files differ
diff --git a/tests/testdata/testkey.pk8 b/tests/testdata/testkey_v1.pk8
index 586c1bd5c..586c1bd5c 100644
--- a/tests/testdata/testkey.pk8
+++ b/tests/testdata/testkey_v1.pk8
Binary files differ
diff --git a/tests/testdata/test_key_e3.txt b/tests/testdata/testkey_v1.txt
index 53f5297bd..53f5297bd 100644
--- a/tests/testdata/test_key_e3.txt
+++ b/tests/testdata/testkey_v1.txt
diff --git a/tests/testdata/testkey.x509.pem b/tests/testdata/testkey_v1.x509.pem
index e242d83e2..e242d83e2 100644
--- a/tests/testdata/testkey.x509.pem
+++ b/tests/testdata/testkey_v1.x509.pem
diff --git a/tests/testdata/test_f4.pk8 b/tests/testdata/testkey_v2.pk8
index 3052613c5..3052613c5 100644
--- a/tests/testdata/test_f4.pk8
+++ b/tests/testdata/testkey_v2.pk8
Binary files differ
diff --git a/tests/testdata/test_key_f4.txt b/tests/testdata/testkey_v2.txt
index 54ddbbad1..54ddbbad1 100644
--- a/tests/testdata/test_key_f4.txt
+++ b/tests/testdata/testkey_v2.txt
diff --git a/tests/testdata/test_f4.x509.pem b/tests/testdata/testkey_v2.x509.pem
index 814abcf99..814abcf99 100644
--- a/tests/testdata/test_f4.x509.pem
+++ b/tests/testdata/testkey_v2.x509.pem
diff --git a/tests/testdata/testkey_v3.pk8 b/tests/testdata/testkey_v3.pk8
new file mode 120000
index 000000000..18ecf9815
--- /dev/null
+++ b/tests/testdata/testkey_v3.pk8
@@ -0,0 +1 @@
+testkey_v1.pk8 \ No newline at end of file
diff --git a/tests/testdata/testkey_v3.txt b/tests/testdata/testkey_v3.txt
new file mode 100644
index 000000000..3208571a5
--- /dev/null
+++ b/tests/testdata/testkey_v3.txt
@@ -0,0 +1 @@
+v3 {64,0xc926ad21,{1795090719,2141396315,950055447,2581568430,4268923165,1920809988,546586521,3498997798,1776797858,3740060814,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,2563319927,323993566,28517732,609753416,1826472888,215237850,4261642700,4049082591,3228462402,774857746,154822455,2497198897,2758199418,3019015328,2794777644,87251430,2534927978,120774784,571297800,3695899472,2479925187,3811625450,3401832990,2394869647,3267246207,950095497,555058928,414729973,1136544882,3044590084,465547824,4058146728,2731796054,1689838846,3890756939,1048029507,895090649,247140249,178744550,3547885223,3165179243,109881576,3944604415,1044303212,3772373029,2985150306,3737520932,3599964420},{3437017481,3784475129,2800224972,3086222688,251333580,2131931323,512774938,325948880,2657486437,2102694287,3820568226,792812816,1026422502,2053275343,2800889200,3113586810,165549746,4273519969,4065247892,1902789247,772932719,3941848426,3652744109,216871947,3164400649,1942378755,3996765851,1055777370,964047799,629391717,2232744317,3910558992,191868569,2758883837,3682816752,2997714732,2702529250,3570700455,3776873832,3924067546,3555689545,2758825434,1323144535,61311905,1997411085,376844204,213777604,4077323584,9135381,1625809335,2804742137,2952293945,1117190829,4237312782,1825108855,3013147971,1111251351,2568837572,1684324211,2520978805,367251975,810756730,2353784344,1175080310}}
diff --git a/tests/testdata/testkey_sha256.x509.pem b/tests/testdata/testkey_v3.x509.pem
index 002ce8968..002ce8968 100644
--- a/tests/testdata/testkey_sha256.x509.pem
+++ b/tests/testdata/testkey_v3.x509.pem
diff --git a/tests/testdata/testkey_v4.pk8 b/tests/testdata/testkey_v4.pk8
new file mode 120000
index 000000000..683b9a3f1
--- /dev/null
+++ b/tests/testdata/testkey_v4.pk8
@@ -0,0 +1 @@
+testkey_v2.pk8 \ No newline at end of file
diff --git a/tests/testdata/testkey_v4.txt b/tests/testdata/testkey_v4.txt
new file mode 100644
index 000000000..532cbd51a
--- /dev/null
+++ b/tests/testdata/testkey_v4.txt
@@ -0,0 +1 @@
+v4 {64,0xc9bd1f21,{293133087,3210546773,865313125,250921607,3158780490,943703457,1242806226,2986289859,2942743769,2457906415,2719374299,1783459420,149579627,3081531591,3440738617,2788543742,2758457512,1146764939,3699497403,2446203424,1744968926,1159130537,2370028300,3978231572,3392699980,1487782451,1180150567,2841334302,3753960204,961373345,3333628321,748825784,2978557276,1566596926,1613056060,2600292737,1847226629,50398611,1890374404,2878700735,2286201787,1401186359,619285059,731930817,2340993166,1156490245,2992241729,151498140,318782170,3480838990,2100383433,4223552555,3628927011,4247846280,1759029513,4215632601,2719154626,3490334597,1751299340,3487864726,3668753795,4217506054,3748782284,3150295088},{1772626313,445326068,3477676155,1758201194,2986784722,491035581,3922936562,702212696,2979856666,3324974564,2488428922,3056318590,1626954946,664714029,398585816,3964097931,3356701905,2298377729,2040082097,3025491477,539143308,3348777868,2995302452,3602465520,212480763,2691021393,1307177300,704008044,2031136606,1054106474,3838318865,2441343869,1477566916,700949900,2534790355,3353533667,336163563,4106790558,2701448228,1571536379,1103842411,3623110423,1635278839,1577828979,910322800,715583630,138128831,1017877531,2289162787,447994798,1897243165,4121561445,4150719842,2131821093,2262395396,3305771534,980753571,3256525190,3128121808,1072869975,3507939515,4229109952,118381341,2209831334}}
diff --git a/tests/testdata/test_f4_sha256.x509.pem b/tests/testdata/testkey_v4.x509.pem
index 9d5376b45..9d5376b45 100644
--- a/tests/testdata/test_f4_sha256.x509.pem
+++ b/tests/testdata/testkey_v4.x509.pem
diff --git a/tests/testdata/testkey_ecdsa.pk8 b/tests/testdata/testkey_v5.pk8
index 9a521c8cf..9a521c8cf 100644
--- a/tests/testdata/testkey_ecdsa.pk8
+++ b/tests/testdata/testkey_v5.pk8
Binary files differ
diff --git a/tests/testdata/test_key_ec.txt b/tests/testdata/testkey_v5.txt
index 72b4395d9..72b4395d9 100644
--- a/tests/testdata/test_key_ec.txt
+++ b/tests/testdata/testkey_v5.txt
diff --git a/tests/testdata/testkey_ecdsa.x509.pem b/tests/testdata/testkey_v5.x509.pem
index b12283645..b12283645 100644
--- a/tests/testdata/testkey_ecdsa.x509.pem
+++ b/tests/testdata/testkey_v5.x509.pem
diff --git a/tools/ota/Android.mk b/tools/dumpkey/Android.mk
index 142c3b257..31549146d 100644
--- a/tools/ota/Android.mk
+++ b/tools/dumpkey/Android.mk
@@ -15,19 +15,8 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := add-property-tag
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-LOCAL_SRC_FILES := add-property-tag.c
-LOCAL_STATIC_LIBRARIES := libc
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := check-lost+found
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-LOCAL_SRC_FILES := check-lost+found.c
-LOCAL_STATIC_LIBRARIES := libcutils libc
-include $(BUILD_EXECUTABLE)
+LOCAL_MODULE := dumpkey
+LOCAL_SRC_FILES := DumpPublicKey.java
+LOCAL_JAR_MANIFEST := DumpPublicKey.mf
+LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/dumpkey/DumpPublicKey.java b/tools/dumpkey/DumpPublicKey.java
new file mode 100644
index 000000000..3eb139842
--- /dev/null
+++ b/tools/dumpkey/DumpPublicKey.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dumpkey;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.io.FileInputStream;
+import java.math.BigInteger;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.Key;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPoint;
+
+/**
+ * Command line tool to extract RSA public keys from X.509 certificates
+ * and output source code with data initializers for the keys.
+ * @hide
+ */
+class DumpPublicKey {
+ /**
+ * @param key to perform sanity checks on
+ * @return version number of key. Supported versions are:
+ * 1: 2048-bit RSA key with e=3 and SHA-1 hash
+ * 2: 2048-bit RSA key with e=65537 and SHA-1 hash
+ * 3: 2048-bit RSA key with e=3 and SHA-256 hash
+ * 4: 2048-bit RSA key with e=65537 and SHA-256 hash
+ * @throws Exception if the key has the wrong size or public exponent
+ */
+ static int checkRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
+ BigInteger pubexp = key.getPublicExponent();
+ BigInteger modulus = key.getModulus();
+ int version;
+
+ if (pubexp.equals(BigInteger.valueOf(3))) {
+ version = useSHA256 ? 3 : 1;
+ } else if (pubexp.equals(BigInteger.valueOf(65537))) {
+ version = useSHA256 ? 4 : 2;
+ } else {
+ throw new Exception("Public exponent should be 3 or 65537 but is " +
+ pubexp.toString(10) + ".");
+ }
+
+ if (modulus.bitLength() != 2048) {
+ throw new Exception("Modulus should be 2048 bits long but is " +
+ modulus.bitLength() + " bits.");
+ }
+
+ return version;
+ }
+
+ /**
+ * @param key to perform sanity checks on
+ * @return version number of key. Supported versions are:
+ * 5: 256-bit EC key with curve NIST P-256
+ * @throws Exception if the key has the wrong size or public exponent
+ */
+ static int checkEC(ECPublicKey key) throws Exception {
+ if (key.getParams().getCurve().getField().getFieldSize() != 256) {
+ throw new Exception("Curve must be NIST P-256");
+ }
+
+ return 5;
+ }
+
+ /**
+ * Perform sanity check on public key.
+ */
+ static int check(PublicKey key, boolean useSHA256) throws Exception {
+ if (key instanceof RSAPublicKey) {
+ return checkRSA((RSAPublicKey) key, useSHA256);
+ } else if (key instanceof ECPublicKey) {
+ if (!useSHA256) {
+ throw new Exception("Must use SHA-256 with EC keys!");
+ }
+ return checkEC((ECPublicKey) key);
+ } else {
+ throw new Exception("Unsupported key class: " + key.getClass().getName());
+ }
+ }
+
+ /**
+ * @param key to output
+ * @return a String representing this public key. If the key is a
+ * version 1 key, the string will be a C initializer; this is
+ * not true for newer key versions.
+ */
+ static String printRSA(RSAPublicKey key, boolean useSHA256) throws Exception {
+ int version = check(key, useSHA256);
+
+ BigInteger N = key.getModulus();
+
+ StringBuilder result = new StringBuilder();
+
+ int nwords = N.bitLength() / 32; // # of 32 bit integers in modulus
+
+ if (version > 1) {
+ result.append("v");
+ result.append(Integer.toString(version));
+ result.append(" ");
+ }
+
+ result.append("{");
+ result.append(nwords);
+
+ BigInteger B = BigInteger.valueOf(0x100000000L); // 2^32
+ BigInteger N0inv = B.subtract(N.modInverse(B)); // -1 / N[0] mod 2^32
+
+ result.append(",0x");
+ result.append(N0inv.toString(16));
+
+ BigInteger R = BigInteger.valueOf(2).pow(N.bitLength());
+ BigInteger RR = R.multiply(R).mod(N); // 2^4096 mod N
+
+ // Write out modulus as little endian array of integers.
+ result.append(",{");
+ for (int i = 0; i < nwords; ++i) {
+ long n = N.mod(B).longValue();
+ result.append(n);
+
+ if (i != nwords - 1) {
+ result.append(",");
+ }
+
+ N = N.divide(B);
+ }
+ result.append("}");
+
+ // Write R^2 as little endian array of integers.
+ result.append(",{");
+ for (int i = 0; i < nwords; ++i) {
+ long rr = RR.mod(B).longValue();
+ result.append(rr);
+
+ if (i != nwords - 1) {
+ result.append(",");
+ }
+
+ RR = RR.divide(B);
+ }
+ result.append("}");
+
+ result.append("}");
+ return result.toString();
+ }
+
+ /**
+ * @param key to output
+ * @return a String representing this public key. If the key is a
+ * version 1 key, the string will be a C initializer; this is
+ * not true for newer key versions.
+ */
+ static String printEC(ECPublicKey key) throws Exception {
+ int version = checkEC(key);
+
+ StringBuilder result = new StringBuilder();
+
+ result.append("v");
+ result.append(Integer.toString(version));
+ result.append(" ");
+
+ BigInteger X = key.getW().getAffineX();
+ BigInteger Y = key.getW().getAffineY();
+ int nbytes = key.getParams().getCurve().getField().getFieldSize() / 8; // # of 32 bit integers in X coordinate
+
+ result.append("{");
+ result.append(nbytes);
+
+ BigInteger B = BigInteger.valueOf(0x100L); // 2^8
+
+ // Write out Y coordinate as array of characters.
+ result.append(",{");
+ for (int i = 0; i < nbytes; ++i) {
+ long n = X.mod(B).longValue();
+ result.append(n);
+
+ if (i != nbytes - 1) {
+ result.append(",");
+ }
+
+ X = X.divide(B);
+ }
+ result.append("}");
+
+ // Write out Y coordinate as array of characters.
+ result.append(",{");
+ for (int i = 0; i < nbytes; ++i) {
+ long n = Y.mod(B).longValue();
+ result.append(n);
+
+ if (i != nbytes - 1) {
+ result.append(",");
+ }
+
+ Y = Y.divide(B);
+ }
+ result.append("}");
+
+ result.append("}");
+ return result.toString();
+ }
+
+ static String print(PublicKey key, boolean useSHA256) throws Exception {
+ if (key instanceof RSAPublicKey) {
+ return printRSA((RSAPublicKey) key, useSHA256);
+ } else if (key instanceof ECPublicKey) {
+ return printEC((ECPublicKey) key);
+ } else {
+ throw new Exception("Unsupported key class: " + key.getClass().getName());
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 1) {
+ System.err.println("Usage: DumpPublicKey certfile ... > source.c");
+ System.exit(1);
+ }
+ Security.addProvider(new BouncyCastleProvider());
+ try {
+ for (int i = 0; i < args.length; i++) {
+ FileInputStream input = new FileInputStream(args[i]);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(input);
+
+ boolean useSHA256 = false;
+ String sigAlg = cert.getSigAlgName();
+ if ("SHA1withRSA".equals(sigAlg) || "MD5withRSA".equals(sigAlg)) {
+ // SignApk has historically accepted "MD5withRSA"
+ // certificates, but treated them as "SHA1withRSA"
+ // anyway. Continue to do so for backwards
+ // compatibility.
+ useSHA256 = false;
+ } else if ("SHA256withRSA".equals(sigAlg) || "SHA256withECDSA".equals(sigAlg)) {
+ useSHA256 = true;
+ } else {
+ System.err.println(args[i] + ": unsupported signature algorithm \"" +
+ sigAlg + "\"");
+ System.exit(1);
+ }
+
+ PublicKey key = cert.getPublicKey();
+ check(key, useSHA256);
+ System.out.print(print(key, useSHA256));
+ System.out.println(i < args.length - 1 ? "," : "");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.exit(0);
+ }
+}
diff --git a/tools/dumpkey/DumpPublicKey.mf b/tools/dumpkey/DumpPublicKey.mf
new file mode 100644
index 000000000..7bb3bc88d
--- /dev/null
+++ b/tools/dumpkey/DumpPublicKey.mf
@@ -0,0 +1 @@
+Main-Class: com.android.dumpkey.DumpPublicKey
diff --git a/tools/ota/add-property-tag.c b/tools/ota/add-property-tag.c
deleted file mode 100644
index aab30b2d0..000000000
--- a/tools/ota/add-property-tag.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2008 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 <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Append a tag to a property value in a .prop file if it isn't already there.
- * Normally used to modify build properties to record incremental updates.
- */
-
-// Return nonzero if the tag should be added to this line.
-int should_tag(const char *line, const char *propname) {
- const char *prop = strstr(line, propname);
- if (prop == NULL) return 0;
-
- // Make sure this is actually the property name (not an accidental hit)
- const char *ptr;
- for (ptr = line; ptr < prop && isspace(*ptr); ++ptr) ;
- if (ptr != prop) return 0; // Must be at the beginning of the line
-
- for (ptr += strlen(propname); *ptr != '\0' && isspace(*ptr); ++ptr) ;
- return (*ptr == '='); // Must be followed by a '='
-}
-
-// Remove existing tags from the line, return the following number (if any)
-int remove_tag(char *line, const char *tag) {
- char *pos = strstr(line, tag);
- if (pos == NULL) return 0;
-
- char *end;
- int num = strtoul(pos + strlen(tag), &end, 10);
- strcpy(pos, end);
- return num;
-}
-
-// Write line to output with the tag added, adding a number (if >0)
-void write_tagged(FILE *out, const char *line, const char *tag, int number) {
- const char *end = line + strlen(line);
- while (end > line && isspace(end[-1])) --end;
- if (number > 0) {
- fprintf(out, "%.*s%s%d%s", (int)(end - line), line, tag, number, end);
- } else {
- fprintf(out, "%.*s%s%s", (int)(end - line), line, tag, end);
- }
-}
-
-int main(int argc, char **argv) {
- const char *filename = "/system/build.prop";
- const char *propname = "ro.build.fingerprint";
- const char *tag = NULL;
- int do_remove = 0, do_number = 0;
-
- int opt;
- while ((opt = getopt(argc, argv, "f:p:rn")) != -1) {
- switch (opt) {
- case 'f': filename = optarg; break;
- case 'p': propname = optarg; break;
- case 'r': do_remove = 1; break;
- case 'n': do_number = 1; break;
- case '?': return 2;
- }
- }
-
- if (argc != optind + 1) {
- fprintf(stderr,
- "usage: add-property-tag [flags] tag-to-add\n"
- "flags: -f /dir/file.prop (default /system/build.prop)\n"
- " -p prop.name (default ro.build.fingerprint)\n"
- " -r (if set, remove the tag rather than adding it)\n"
- " -n (if set, add and increment a number after the tag)\n");
- return 2;
- }
-
- tag = argv[optind];
- FILE *input = fopen(filename, "r");
- if (input == NULL) {
- fprintf(stderr, "can't read %s: %s\n", filename, strerror(errno));
- return 1;
- }
-
- char tmpname[PATH_MAX];
- snprintf(tmpname, sizeof(tmpname), "%s.tmp", filename);
- FILE *output = fopen(tmpname, "w");
- if (output == NULL) {
- fprintf(stderr, "can't write %s: %s\n", tmpname, strerror(errno));
- return 1;
- }
-
- int found = 0;
- char line[4096];
- while (fgets(line, sizeof(line), input)) {
- if (!should_tag(line, propname)) {
- fputs(line, output); // Pass through unmodified
- } else {
- found = 1;
- int number = remove_tag(line, tag);
- if (do_remove) {
- fputs(line, output); // Remove the tag but don't re-add it
- } else {
- write_tagged(output, line, tag, number + do_number);
- }
- }
- }
-
- fclose(input);
- fclose(output);
-
- if (!found) {
- fprintf(stderr, "property %s not found in %s\n", propname, filename);
- remove(tmpname);
- return 1;
- }
-
- if (rename(tmpname, filename)) {
- fprintf(stderr, "can't rename %s to %s: %s\n",
- tmpname, filename, strerror(errno));
- remove(tmpname);
- return 1;
- }
-
- return 0;
-}
diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c
deleted file mode 100644
index 8ce12d39f..000000000
--- a/tools/ota/check-lost+found.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2008 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 <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/klog.h>
-#include <sys/reboot.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "private/android_filesystem_config.h"
-
-// Sentinel file used to track whether we've forced a reboot
-static const char *kMarkerFile = "/data/misc/check-lost+found-rebooted-2";
-
-// Output file in tombstones directory (first 8K will be uploaded)
-static const char *kOutputDir = "/data/tombstones";
-static const char *kOutputFile = "/data/tombstones/check-lost+found-log";
-
-// Partitions to check
-static const char *kPartitions[] = { "/system", "/data", "/cache", NULL };
-
-/*
- * 1. If /data/misc/forced-reboot is missing, touch it & force "unclean" boot.
- * 2. Write a log entry with the number of files in lost+found directories.
- */
-
-int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) {
- mkdir(kOutputDir, 0755);
- chown(kOutputDir, AID_SYSTEM, AID_SYSTEM);
- FILE *out = fopen(kOutputFile, "a");
- if (out == NULL) {
- fprintf(stderr, "Can't write %s: %s\n", kOutputFile, strerror(errno));
- return 1;
- }
-
- // Note: only the first 8K of log will be uploaded, so be terse.
- time_t start = time(NULL);
- fprintf(out, "*** check-lost+found ***\nStarted: %s", ctime(&start));
-
- struct stat st;
- if (stat(kMarkerFile, &st)) {
- // No reboot marker -- need to force an unclean reboot.
- // But first, try to create the marker file. If that fails,
- // skip the reboot, so we don't get caught in an infinite loop.
-
- int fd = open(kMarkerFile, O_WRONLY|O_CREAT, 0444);
- if (fd >= 0 && close(fd) == 0) {
- fprintf(out, "Wrote %s, rebooting\n", kMarkerFile);
- fflush(out);
- sync(); // Make sure the marker file is committed to disk
-
- // If possible, dirty each of these partitions before rebooting,
- // to make sure the filesystem has to do a scan on mount.
- int i;
- for (i = 0; kPartitions[i] != NULL; ++i) {
- char fn[PATH_MAX];
- snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "dirty");
- fd = open(fn, O_WRONLY|O_CREAT, 0444);
- if (fd >= 0) { // Don't sweat it if we can't write the file.
- TEMP_FAILURE_RETRY(write(fd, fn, sizeof(fn))); // write, you know, some data
- close(fd);
- unlink(fn);
- }
- }
-
- reboot(RB_AUTOBOOT); // reboot immediately, with dirty filesystems
- fprintf(out, "Reboot failed?!\n");
- exit(1);
- } else {
- fprintf(out, "Can't write %s: %s\n", kMarkerFile, strerror(errno));
- }
- } else {
- fprintf(out, "Found %s\n", kMarkerFile);
- }
-
- int i;
- for (i = 0; kPartitions[i] != NULL; ++i) {
- char fn[PATH_MAX];
- snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "lost+found");
- DIR *dir = opendir(fn);
- if (dir == NULL) {
- fprintf(out, "Can't open %s: %s\n", fn, strerror(errno));
- } else {
- int count = 0;
- struct dirent *ent;
- while ((ent = readdir(dir))) {
- if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
- ++count;
- }
- closedir(dir);
- if (count > 0) {
- fprintf(out, "OMGZ FOUND %d FILES IN %s\n", count, fn);
- } else {
- fprintf(out, "%s is clean\n", fn);
- }
- }
- }
-
- char dmesg[131073];
- int len = klogctl(KLOG_READ_ALL, dmesg, sizeof(dmesg) - 1);
- if (len < 0) {
- fprintf(out, "Can't read kernel log: %s\n", strerror(errno));
- } else { // To conserve space, only write lines with certain keywords
- fprintf(out, "--- Kernel log ---\n");
- dmesg[len] = '\0';
- char *saveptr, *line;
- int in_yaffs = 0;
- for (line = strtok_r(dmesg, "\n", &saveptr); line != NULL;
- line = strtok_r(NULL, "\n", &saveptr)) {
- if (strstr(line, "yaffs: dev is")) in_yaffs = 1;
-
- if (in_yaffs ||
- strstr(line, "yaffs") ||
- strstr(line, "mtd") ||
- strstr(line, "msm_nand")) {
- fprintf(out, "%s\n", line);
- }
-
- if (strstr(line, "yaffs_read_super: isCheckpointed")) in_yaffs = 0;
- }
- }
-
- return 0;
-}
diff --git a/tools/ota/convert-to-bmp.py b/tools/ota/convert-to-bmp.py
deleted file mode 100644
index 446c09da8..000000000
--- a/tools/ota/convert-to-bmp.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/python2.4
-
-"""A simple script to convert asset images to BMP files, that supports
-RGBA image."""
-
-import struct
-import Image
-import sys
-
-infile = sys.argv[1]
-outfile = sys.argv[2]
-
-if not outfile.endswith(".bmp"):
- print >> sys.stderr, "Warning: I'm expecting to write BMP files."
-
-im = Image.open(infile)
-if im.mode == 'RGB':
- im.save(outfile)
-elif im.mode == 'RGBA':
- # Python Imaging Library doesn't write RGBA BMP files, so we roll
- # our own.
-
- BMP_HEADER_FMT = ("<" # little-endian
- "H" # signature
- "L" # file size
- "HH" # reserved (set to 0)
- "L" # offset to start of bitmap data)
- )
-
- BITMAPINFO_HEADER_FMT= ("<" # little-endian
- "L" # size of this struct
- "L" # width
- "L" # height
- "H" # planes (set to 1)
- "H" # bit count
- "L" # compression (set to 0 for minui)
- "L" # size of image data (0 if uncompressed)
- "L" # x pixels per meter (1)
- "L" # y pixels per meter (1)
- "L" # colors used (0)
- "L" # important colors (0)
- )
-
- fileheadersize = struct.calcsize(BMP_HEADER_FMT)
- infoheadersize = struct.calcsize(BITMAPINFO_HEADER_FMT)
-
- header = struct.pack(BMP_HEADER_FMT,
- 0x4d42, # "BM" in little-endian
- (fileheadersize + infoheadersize +
- im.size[0] * im.size[1] * 4),
- 0, 0,
- fileheadersize + infoheadersize)
-
- info = struct.pack(BITMAPINFO_HEADER_FMT,
- infoheadersize,
- im.size[0],
- im.size[1],
- 1,
- 32,
- 0,
- 0,
- 1,
- 1,
- 0,
- 0)
-
- f = open(outfile, "wb")
- f.write(header)
- f.write(info)
- data = im.tostring()
- for j in range(im.size[1]-1, -1, -1): # rows bottom-to-top
- for i in range(j*im.size[0]*4, (j+1)*im.size[0]*4, 4):
- f.write(data[i+2]) # B
- f.write(data[i+1]) # G
- f.write(data[i+0]) # R
- f.write(data[i+3]) # A
- f.close()
-else:
- print >> sys.stderr, "Don't know how to handle image mode '%s'." % (im.mode,)
diff --git a/tools/recovery_l10n/README.md b/tools/recovery_l10n/README.md
new file mode 100644
index 000000000..1554f6618
--- /dev/null
+++ b/tools/recovery_l10n/README.md
@@ -0,0 +1,33 @@
+# Steps to regenerate background text images under res-*dpi/images/
+
+1. Build the recovery_l10n app:
+
+ cd bootable/recovery && mma -j32
+
+2. Install the app on the device (or emulator) with the intended dpi.
+
+ * For example, we can use Nexus 5 to generate the text images under
+ res-xxhdpi.
+ * When using the emulator, make sure the NDK version matches the current
+ repository. Otherwise, the app may not work properly.
+
+ adb install $PATH_TO_APP
+
+3. Run the app, select the string to translate and press the 'go' button.
+
+4. After the app goes through the strings for all locales, pull the output png
+ file from the device.
+
+ adb root && adb pull /data/data/com.android.recovery_l10n/files/text-out.png
+
+5. Compress the output file put it under the corresponding directory.
+
+ * "pngcrush -c 0 ..." converts "text-out.png" into a 1-channel image,
+ which is accepted by Recovery. This also compresses the image file by
+ ~60%.
+ * zopflipng could further compress the png files by ~10%, more details
+ in https://github.com/google/zopfli/blob/master/README.zopflipng
+ * If you're using other png compression tools, make sure the final text
+ image works by running graphic tests under the recovery mode.
+
+ pngcrush -c 0 text-out.png $OUTPUT_PNG
diff --git a/tools/recovery_l10n/res/values-af/strings.xml b/tools/recovery_l10n/res/values-af/strings.xml
index b1974da20..d5264184a 100644
--- a/tools/recovery_l10n/res/values-af/strings.xml
+++ b/tools/recovery_l10n/res/values-af/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installeer tans stelselopdatering"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Vee tans uit"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Geen opdrag nie"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Fout!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installeer tans sekuriteitopdatering"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installeer tans stelselopdatering..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Vee tans uit..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Geen bevel."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Fout!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-am/strings.xml b/tools/recovery_l10n/res/values-am/strings.xml
index 75c17fbad..cddb099bc 100644
--- a/tools/recovery_l10n/res/values-am/strings.xml
+++ b/tools/recovery_l10n/res/values-am/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"የስርዓት ዝማኔ በመጫን ላይ…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"በመደምሰስ ላይ…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ምንም ትዕዛዝ የለም።"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ስህተት!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ar/strings.xml b/tools/recovery_l10n/res/values-ar/strings.xml
index 601b5832b..d06b96644 100644
--- a/tools/recovery_l10n/res/values-ar/strings.xml
+++ b/tools/recovery_l10n/res/values-ar/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"جارٍ تثبيت تحديث النظام…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"جارٍ المسح…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ليس هناك أي أمر."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"خطأ!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-az-rAZ/strings.xml b/tools/recovery_l10n/res/values-az-rAZ/strings.xml
index c6765a9ea..3435573dc 100644
--- a/tools/recovery_l10n/res/values-az-rAZ/strings.xml
+++ b/tools/recovery_l10n/res/values-az-rAZ/strings.xml
@@ -1,9 +1,8 @@
<?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">"Sistem güncəlləməsi quraşdırılır..."</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Silinir"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Əmr yoxdur"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Xəta!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Təhlükəsizlik güncəlləməsi yüklənir"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Sistem güncəlləməsi quraşdırılır..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Silinir..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Əmr yoxdur."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Xəta!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml b/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index c2d8f2239..000000000
--- a/tools/recovery_l10n/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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">"Ažuriranje sistema se instalira"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Briše se"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nema komande"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Greška!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalira se bezbednosno ažuriranje"</string>
-</resources>
diff --git a/tools/recovery_l10n/res/values-be-rBY/strings.xml b/tools/recovery_l10n/res/values-be-rBY/strings.xml
deleted file mode 100644
index 7c0954d31..000000000
--- a/tools/recovery_l10n/res/values-be-rBY/strings.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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-bg/strings.xml b/tools/recovery_l10n/res/values-bg/strings.xml
index 9e628a2af..004f3b93e 100644
--- a/tools/recovery_l10n/res/values-bg/strings.xml
+++ b/tools/recovery_l10n/res/values-bg/strings.xml
@@ -1,9 +1,8 @@
<?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">"Актуализацията на сигурносттa се инсталира"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Системната актуализация се инсталира…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Изтрива се…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Без команда."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Грешка!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-bn-rBD/strings.xml b/tools/recovery_l10n/res/values-bn-rBD/strings.xml
index 0a481faf1..4d2e590f4 100644
--- a/tools/recovery_l10n/res/values-bn-rBD/strings.xml
+++ b/tools/recovery_l10n/res/values-bn-rBD/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"সিস্টেম আপডেট ইনস্টল করা হচ্ছে…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"মোছা হচ্ছে…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"কোনো নির্দেশ নেই।"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ত্রুটি!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-bs-rBA/strings.xml b/tools/recovery_l10n/res/values-bs-rBA/strings.xml
deleted file mode 100644
index 412cf0276..000000000
--- a/tools/recovery_l10n/res/values-bs-rBA/strings.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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">"Ažuriranje sistema…"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Brisanje u toku"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nema komande"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Greška!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instaliranje sigurnosnog ažuriranja…"</string>
-</resources>
diff --git a/tools/recovery_l10n/res/values-ca/strings.xml b/tools/recovery_l10n/res/values-ca/strings.xml
index 3f266d2df..5d7b652c5 100644
--- a/tools/recovery_l10n/res/values-ca/strings.xml
+++ b/tools/recovery_l10n/res/values-ca/strings.xml
@@ -1,9 +1,8 @@
<?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">"S\'està instal·lant una actualització del sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"S\'està esborrant"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"No hi ha cap ordre"</string>
- <string name="recovery_error" msgid="5748178989622716736">"S\'ha produït un error"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"S\'està instal·lant una actualització de seguretat"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"S\'està instal·lant l\'actualització del sistema..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"S\'està esborrant..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Cap ordre."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-cs/strings.xml b/tools/recovery_l10n/res/values-cs/strings.xml
index eb436a810..771235d04 100644
--- a/tools/recovery_l10n/res/values-cs/strings.xml
+++ b/tools/recovery_l10n/res/values-cs/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalace aktualizace systému"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Mazání"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Žádný příkaz"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Chyba!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalace aktualizace zabezpečení"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalace aktualizace systému..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Mazání…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Žádný příkaz."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Chyba!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-da/strings.xml b/tools/recovery_l10n/res/values-da/strings.xml
index c6e64a245..c28a76fbd 100644
--- a/tools/recovery_l10n/res/values-da/strings.xml
+++ b/tools/recovery_l10n/res/values-da/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installerer systemopdateringen"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Sletter"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ingen kommando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Fejl!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installerer sikkerhedsopdateringen"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Systemopdateringen installeres…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Sletter…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ingen kommando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Fejl!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-de/strings.xml b/tools/recovery_l10n/res/values-de/strings.xml
index 6b6726a23..02d259059 100644
--- a/tools/recovery_l10n/res/values-de/strings.xml
+++ b/tools/recovery_l10n/res/values-de/strings.xml
@@ -1,9 +1,8 @@
<?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">"Systemupdate wird installiert"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Wird gelöscht"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Kein Befehl"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Fehler"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Sicherheitsupdate wird installiert"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Systemupdate wird installiert…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Wird gelöscht…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Kein Befehl"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Fehler"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-el/strings.xml b/tools/recovery_l10n/res/values-el/strings.xml
index 4cb2da5f9..aa2626b4b 100644
--- a/tools/recovery_l10n/res/values-el/strings.xml
+++ b/tools/recovery_l10n/res/values-el/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Εγκατάσταση ενημέρωσης συστήματος…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Διαγραφή…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Καμία εντολή."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Σφάλμα!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-en-rAU/strings.xml b/tools/recovery_l10n/res/values-en-rAU/strings.xml
index dc75c2374..b70d678c1 100644
--- a/tools/recovery_l10n/res/values-en-rAU/strings.xml
+++ b/tools/recovery_l10n/res/values-en-rAU/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installing system update…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Erasing…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"No command."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-en-rGB/strings.xml b/tools/recovery_l10n/res/values-en-rGB/strings.xml
index dc75c2374..b70d678c1 100644
--- a/tools/recovery_l10n/res/values-en-rGB/strings.xml
+++ b/tools/recovery_l10n/res/values-en-rGB/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installing system update…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Erasing…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"No command."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-en-rIN/strings.xml b/tools/recovery_l10n/res/values-en-rIN/strings.xml
index dc75c2374..b70d678c1 100644
--- a/tools/recovery_l10n/res/values-en-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-en-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installing system update…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Erasing…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"No command."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-es-rUS/strings.xml b/tools/recovery_l10n/res/values-es-rUS/strings.xml
index 06b86069b..256272ac7 100644
--- a/tools/recovery_l10n/res/values-es-rUS/strings.xml
+++ b/tools/recovery_l10n/res/values-es-rUS/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalando actualización del sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Borrando"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ningún comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Error"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando actualización de seguridad"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalando actualización del sistema…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Borrando…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ningún comando"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-es/strings.xml b/tools/recovery_l10n/res/values-es/strings.xml
index d8618f2f4..323f05505 100644
--- a/tools/recovery_l10n/res/values-es/strings.xml
+++ b/tools/recovery_l10n/res/values-es/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalando actualización del sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Borrando"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Sin comandos"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Error"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando actualización de seguridad"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalando actualización del sistema…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Borrando…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Sin comandos"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-et-rEE/strings.xml b/tools/recovery_l10n/res/values-et-rEE/strings.xml
index 072a9ef80..407a53d67 100644
--- a/tools/recovery_l10n/res/values-et-rEE/strings.xml
+++ b/tools/recovery_l10n/res/values-et-rEE/strings.xml
@@ -1,9 +1,8 @@
<?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">"Süsteemivärskenduse installimine"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Kustutamine"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Käsk puudub"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Viga!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Turvavärskenduse installimine"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Süsteemivärskenduste installimine ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Kustutamine ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Käsk puudub."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Viga!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-eu-rES/strings.xml b/tools/recovery_l10n/res/values-eu-rES/strings.xml
index 5540469d0..08d9c0672 100644
--- a/tools/recovery_l10n/res/values-eu-rES/strings.xml
+++ b/tools/recovery_l10n/res/values-eu-rES/strings.xml
@@ -1,9 +1,8 @@
<?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">"Sistemaren eguneratzea instalatzen"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Eduki guztia ezabatzen"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ez dago agindurik"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Errorea"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Segurtasun-eguneratzea instalatzen"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Sistemaren eguneratzea instalatzen…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Ezabatzen…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ez dago agindurik."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Errorea!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-fa/strings.xml b/tools/recovery_l10n/res/values-fa/strings.xml
index cc390ae84..dd002face 100644
--- a/tools/recovery_l10n/res/values-fa/strings.xml
+++ b/tools/recovery_l10n/res/values-fa/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"در حال نصب به‌روزرسانی سیستم ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"پاک کردن..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"فرمانی موجود نیست."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"خطا!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-fi/strings.xml b/tools/recovery_l10n/res/values-fi/strings.xml
index 5141642c8..b77417a98 100644
--- a/tools/recovery_l10n/res/values-fi/strings.xml
+++ b/tools/recovery_l10n/res/values-fi/strings.xml
@@ -1,9 +1,8 @@
<?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">"Asennetaan järjestelmäpäivitystä"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Tyhjennetään"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ei komentoa"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Virhe!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Asennetaan tietoturvapäivitystä"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Asennetaan järjestelmäpäivitystä..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Tyhjennetään..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ei komentoa."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Virhe!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-fr-rCA/strings.xml b/tools/recovery_l10n/res/values-fr-rCA/strings.xml
index b2415290b..f2a85d86a 100644
--- a/tools/recovery_l10n/res/values-fr-rCA/strings.xml
+++ b/tools/recovery_l10n/res/values-fr-rCA/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installation de la mise à jour du système en cours…"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Suppression en cours..."</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Aucune commande"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erreur!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installation de la mise à jour de sécurité en cours..."</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installation de la mise à jour du système en cours…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Effacement en cours…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Aucune commande."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erreur!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-fr/strings.xml b/tools/recovery_l10n/res/values-fr/strings.xml
index f0472b5ac..cdb4a2668 100644
--- a/tools/recovery_l10n/res/values-fr/strings.xml
+++ b/tools/recovery_l10n/res/values-fr/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installation de la mise à jour du système…"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Suppression…"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Aucune commande"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erreur !"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installation de la mise à jour de sécurité…"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installation de la mise à jour du système en cours…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Effacement en cours…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Aucune commande."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erreur !"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-gl-rES/strings.xml b/tools/recovery_l10n/res/values-gl-rES/strings.xml
index 42b2016c2..7546fbda4 100644
--- a/tools/recovery_l10n/res/values-gl-rES/strings.xml
+++ b/tools/recovery_l10n/res/values-gl-rES/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalando actualización do sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Borrando"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Non hai ningún comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erro"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando actualización de seguranza"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalando actualización do sistema..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Borrando..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ningún comando"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erro"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-gu-rIN/strings.xml b/tools/recovery_l10n/res/values-gu-rIN/strings.xml
index 2355a0f4f..a364b523c 100644
--- a/tools/recovery_l10n/res/values-gu-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-gu-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"સિસ્ટમ અપડેટ ઇન્સ્ટોલ કરી રહ્યાં છે…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"કાઢી નાખી રહ્યાં છે…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"કોઈ આદેશ નથી."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ભૂલ!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-hi/strings.xml b/tools/recovery_l10n/res/values-hi/strings.xml
index de8757848..a470d12b6 100644
--- a/tools/recovery_l10n/res/values-hi/strings.xml
+++ b/tools/recovery_l10n/res/values-hi/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"सिस्टम के बारे में नई जानकारी मिल रही है…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"मिटा रहा है…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"कोई आदेश नहीं."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"त्रुटि!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-hr/strings.xml b/tools/recovery_l10n/res/values-hr/strings.xml
index 3b75ff115..56225c015 100644
--- a/tools/recovery_l10n/res/values-hr/strings.xml
+++ b/tools/recovery_l10n/res/values-hr/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instaliranje ažuriranja sustava"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Brisanje"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nema naredbe"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Pogreška!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instaliranje sigurnosnog ažuriranja"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instaliranje ažuriranja sustava…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Brisanje…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nema naredbe."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Pogreška!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-hu/strings.xml b/tools/recovery_l10n/res/values-hu/strings.xml
index 12d4d9fe7..a64f50176 100644
--- a/tools/recovery_l10n/res/values-hu/strings.xml
+++ b/tools/recovery_l10n/res/values-hu/strings.xml
@@ -1,9 +1,8 @@
<?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">"Rendszerfrissítés telepítése"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Törlés"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nincs parancs"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Hiba!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Biztonsági frissítés telepítése"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Rendszerfrissítés telepítése..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Törlés..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nincs parancs."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Hiba!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-hy-rAM/strings.xml b/tools/recovery_l10n/res/values-hy-rAM/strings.xml
index 9d62bb763..7babe80c8 100644
--- a/tools/recovery_l10n/res/values-hy-rAM/strings.xml
+++ b/tools/recovery_l10n/res/values-hy-rAM/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Համակարգի թարմացման տեղադրում…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Ջնջում…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Հրամանը տրված չէ:"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Սխալ"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-in/strings.xml b/tools/recovery_l10n/res/values-in/strings.xml
index 0e56e0dd9..93f9c2876 100644
--- a/tools/recovery_l10n/res/values-in/strings.xml
+++ b/tools/recovery_l10n/res/values-in/strings.xml
@@ -1,9 +1,8 @@
<?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">"Memasang pembaruan sistem"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Menghapus"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Tidak ada perintah"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Error!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Memasang pembaruan keamanan"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Memasang pembaruan sistem…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Menghapus..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Tidak ada perintah."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Kesalahan!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-is-rIS/strings.xml b/tools/recovery_l10n/res/values-is-rIS/strings.xml
index 5065b6522..926e85132 100644
--- a/tools/recovery_l10n/res/values-is-rIS/strings.xml
+++ b/tools/recovery_l10n/res/values-is-rIS/strings.xml
@@ -1,9 +1,8 @@
<?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">"Setur upp kerfisuppfærslu"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Eyðir"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Engin skipun"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Villa!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Setur upp öryggisuppfærslu"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Setur upp kerfisuppfærslu…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Þurrkar út…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Engin skipun."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Villa!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-it/strings.xml b/tools/recovery_l10n/res/values-it/strings.xml
index 2c0364e60..9defe36bd 100644
--- a/tools/recovery_l10n/res/values-it/strings.xml
+++ b/tools/recovery_l10n/res/values-it/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installazione aggiornamento di sistema…"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Cancellazione…"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nessun comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Errore!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installazione aggiornamento sicurezza…"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installazione aggiornamento di sistema…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Cancellazione…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nessun comando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Errore!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-iw/strings.xml b/tools/recovery_l10n/res/values-iw/strings.xml
index ea5e6f2c9..e43bb20a9 100644
--- a/tools/recovery_l10n/res/values-iw/strings.xml
+++ b/tools/recovery_l10n/res/values-iw/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"מתקין עדכון מערכת…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"מוחק…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"אין פקודה."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"שגיאה!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ja/strings.xml b/tools/recovery_l10n/res/values-ja/strings.xml
index 36e029b0f..da0fa623a 100644
--- a/tools/recovery_l10n/res/values-ja/strings.xml
+++ b/tools/recovery_l10n/res/values-ja/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"システムアップデートをインストールしています…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"消去しています…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"コマンドが指定されていません。"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"エラーです"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ka-rGE/strings.xml b/tools/recovery_l10n/res/values-ka-rGE/strings.xml
index 6a46b3677..2d27c1799 100644
--- a/tools/recovery_l10n/res/values-ka-rGE/strings.xml
+++ b/tools/recovery_l10n/res/values-ka-rGE/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"სისტემის განახლების დაყენება…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"მიმდინარეობს წაშლა…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ბრძანება არ არის."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"შეცდომა!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-kk-rKZ/strings.xml b/tools/recovery_l10n/res/values-kk-rKZ/strings.xml
index a4bd86e66..3ca05b9eb 100644
--- a/tools/recovery_l10n/res/values-kk-rKZ/strings.xml
+++ b/tools/recovery_l10n/res/values-kk-rKZ/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Жүйе жаңартуларын орнатуда…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Өшіруде..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Пәрмен берілген жоқ."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Қате!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-km-rKH/strings.xml b/tools/recovery_l10n/res/values-km-rKH/strings.xml
index 313c0f457..0c1c272e0 100644
--- a/tools/recovery_l10n/res/values-km-rKH/strings.xml
+++ b/tools/recovery_l10n/res/values-km-rKH/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"កំពុង​ដំឡើង​បច្ចុប្បន្នភាព​ប្រព័ន្ធ…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"កំពុង​លុប…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"គ្មាន​ពាក្យ​បញ្ជា។"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"កំហុស!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-kn-rIN/strings.xml b/tools/recovery_l10n/res/values-kn-rIN/strings.xml
index 5bf6260ee..be25d7a9d 100644
--- a/tools/recovery_l10n/res/values-kn-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-kn-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"ಸಿಸ್ಟಂ ನವೀಕರಣವನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"ಅಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ಯಾವುದೇ ಆದೇಶವಿಲ್ಲ."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ದೋಷ!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ko/strings.xml b/tools/recovery_l10n/res/values-ko/strings.xml
index aca13bbe7..e46a87606 100644
--- a/tools/recovery_l10n/res/values-ko/strings.xml
+++ b/tools/recovery_l10n/res/values-ko/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"시스템 업데이트 설치 중…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"지우는 중…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"명령어가 없습니다."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"오류!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ky-rKG/strings.xml b/tools/recovery_l10n/res/values-ky-rKG/strings.xml
index 0a6bd783a..e2ced27a4 100644
--- a/tools/recovery_l10n/res/values-ky-rKG/strings.xml
+++ b/tools/recovery_l10n/res/values-ky-rKG/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Системдик жаңыртууларды орнотуу…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Өчүрүлүүдө…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Буйрук берилген жок."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Ката!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-lo-rLA/strings.xml b/tools/recovery_l10n/res/values-lo-rLA/strings.xml
index d3dbb3970..5880cca75 100644
--- a/tools/recovery_l10n/res/values-lo-rLA/strings.xml
+++ b/tools/recovery_l10n/res/values-lo-rLA/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"ກຳລັງຕິດຕັ້ງການອັບເດດລະບົບ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"ກຳລັງລຶບ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ບໍ່ມີຄຳສັ່ງ."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ຜິດພາດ!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-lt/strings.xml b/tools/recovery_l10n/res/values-lt/strings.xml
index d5d5e88fd..957ac7557 100644
--- a/tools/recovery_l10n/res/values-lt/strings.xml
+++ b/tools/recovery_l10n/res/values-lt/strings.xml
@@ -1,9 +1,8 @@
<?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">"Diegiamas sistemos naujinys"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Ištrinama"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nėra jokių komandų"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Klaida!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Diegiamas saugos naujinys"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Diegiamas sistemos naujinys…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Ištrinama…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nėra komandos."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Klaida!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-lv/strings.xml b/tools/recovery_l10n/res/values-lv/strings.xml
index d877f6a61..c5d5b93a6 100644
--- a/tools/recovery_l10n/res/values-lv/strings.xml
+++ b/tools/recovery_l10n/res/values-lv/strings.xml
@@ -1,9 +1,8 @@
<?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">"Notiek sistēmas atjauninājuma instalēšana"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Notiek dzēšana"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nav nevienas komandas"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Kļūda!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Notiek drošības atjauninājuma instalēšana"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Notiek sistēmas atjauninājuma instalēšana..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Notiek dzēšana..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nav nevienas komandas."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Kļūda!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-mk-rMK/strings.xml b/tools/recovery_l10n/res/values-mk-rMK/strings.xml
index 351459730..d91a67cac 100644
--- a/tools/recovery_l10n/res/values-mk-rMK/strings.xml
+++ b/tools/recovery_l10n/res/values-mk-rMK/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Се инсталира ажурирање на системот..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Се брише..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Нема наредба."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Грешка!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ml-rIN/strings.xml b/tools/recovery_l10n/res/values-ml-rIN/strings.xml
index b506e2530..38ebcd120 100644
--- a/tools/recovery_l10n/res/values-ml-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-ml-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"സിസ്റ്റം അപ്‌ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യുന്നു…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"മായ്‌ക്കുന്നു…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"കമാൻഡ് ഒന്നുമില്ല."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"പിശക്!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-mn-rMN/strings.xml b/tools/recovery_l10n/res/values-mn-rMN/strings.xml
index e3dd2e90e..463cafeaf 100644
--- a/tools/recovery_l10n/res/values-mn-rMN/strings.xml
+++ b/tools/recovery_l10n/res/values-mn-rMN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Системийн шинэчлэлтийг суулгаж байна…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Арилгаж байна…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Команд байхгүй."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Алдаа!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-mr-rIN/strings.xml b/tools/recovery_l10n/res/values-mr-rIN/strings.xml
index 8cf86f773..25c5d0c57 100644
--- a/tools/recovery_l10n/res/values-mr-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-mr-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"सिस्टम अद्यतन स्थापित करीत आहे..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"मिटवित आहे…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"कोणताही आदेश नाही."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"त्रुटी!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ms-rMY/strings.xml b/tools/recovery_l10n/res/values-ms-rMY/strings.xml
index 0e24ac4e1..f5635910e 100644
--- a/tools/recovery_l10n/res/values-ms-rMY/strings.xml
+++ b/tools/recovery_l10n/res/values-ms-rMY/strings.xml
@@ -1,9 +1,8 @@
<?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">"Memasang kemas kini sistem"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Memadam"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Tiada perintah"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Ralat!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Memasang kemas kini keselamatan"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Memasang kemas kini sistem..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Memadam..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Tiada arahan."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Ralat!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-my-rMM/strings.xml b/tools/recovery_l10n/res/values-my-rMM/strings.xml
index f13752461..4091b1923 100644
--- a/tools/recovery_l10n/res/values-my-rMM/strings.xml
+++ b/tools/recovery_l10n/res/values-my-rMM/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"စနစ်အား အဆင့်မြှင့်ခြင်း လုပ်ဆောင်နေသည်…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"ဖျက်နေသည် ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ညွှန်ကြားချက်မပေးထားပါ"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"မှားနေပါသည်!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-nb/strings.xml b/tools/recovery_l10n/res/values-nb/strings.xml
index ad6f20e46..4e89ad7c8 100644
--- a/tools/recovery_l10n/res/values-nb/strings.xml
+++ b/tools/recovery_l10n/res/values-nb/strings.xml
@@ -1,9 +1,8 @@
<?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">"Installerer systemoppdateringen"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Tømmer"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ingen kommandoer"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Feil!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Installerer sikkerhetsoppdateringen"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installerer systemoppdateringen ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Sletter ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ingen kommando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Feil!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ne-rNP/strings.xml b/tools/recovery_l10n/res/values-ne-rNP/strings.xml
index 1880e807b..835f275b4 100644
--- a/tools/recovery_l10n/res/values-ne-rNP/strings.xml
+++ b/tools/recovery_l10n/res/values-ne-rNP/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"प्रणाली अद्यावधिक स्थापना गर्दै..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"मेटाइदै..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"कुनै आदेश छैन।"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"त्रुटि!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-nl/strings.xml b/tools/recovery_l10n/res/values-nl/strings.xml
index 0d6c15abb..be80a6b5c 100644
--- a/tools/recovery_l10n/res/values-nl/strings.xml
+++ b/tools/recovery_l10n/res/values-nl/strings.xml
@@ -1,9 +1,8 @@
<?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">"Systeemupdate installeren"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Wissen"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Geen opdracht"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Fout!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Beveiligingsupdate installeren"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Systeemupdate installeren…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Wissen…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Geen opdracht."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Fout!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-pa-rIN/strings.xml b/tools/recovery_l10n/res/values-pa-rIN/strings.xml
index 8564c9c36..39ef32f55 100644
--- a/tools/recovery_l10n/res/values-pa-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-pa-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"ਸਿਸਟਮ ਅਪਡੇਟ ਇੰਸਟੌਲ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"ਹਟਾ ਰਿਹਾ ਹੈ…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ਕੋਈ ਕਮਾਂਡ ਨਹੀਂ।"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ਅਸ਼ੁੱਧੀ!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-pl/strings.xml b/tools/recovery_l10n/res/values-pl/strings.xml
index 8d6db388d..b1e5b7b66 100644
--- a/tools/recovery_l10n/res/values-pl/strings.xml
+++ b/tools/recovery_l10n/res/values-pl/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instaluję aktualizację systemu"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Kasuję"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Brak polecenia"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Błąd"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instaluję aktualizację zabezpieczeń"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instaluję aktualizację systemu…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Usuwam…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Brak polecenia."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Błąd"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-pt-rBR/strings.xml b/tools/recovery_l10n/res/values-pt-rBR/strings.xml
index b72704385..3cc57234e 100644
--- a/tools/recovery_l10n/res/values-pt-rBR/strings.xml
+++ b/tools/recovery_l10n/res/values-pt-rBR/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalando atualização do sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Apagando"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nenhum comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erro!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando atualização de segurança"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalando atualização do sistema..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Apagando..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nenhum comando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erro!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-pt-rPT/strings.xml b/tools/recovery_l10n/res/values-pt-rPT/strings.xml
index 981463739..7d6bc18a9 100644
--- a/tools/recovery_l10n/res/values-pt-rPT/strings.xml
+++ b/tools/recovery_l10n/res/values-pt-rPT/strings.xml
@@ -1,9 +1,8 @@
<?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">"A instalar atualização do sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"A apagar"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nenhum comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erro!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"A instalar atualização de segurança"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"A instalar a atualização do sistema..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"A apagar…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nenhum comando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erro!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-pt/strings.xml b/tools/recovery_l10n/res/values-pt/strings.xml
index b72704385..3cc57234e 100644
--- a/tools/recovery_l10n/res/values-pt/strings.xml
+++ b/tools/recovery_l10n/res/values-pt/strings.xml
@@ -1,9 +1,8 @@
<?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">"Instalando atualização do sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Apagando"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nenhum comando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Erro!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Instalando atualização de segurança"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Instalando atualização do sistema..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Apagando..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nenhum comando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Erro!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ro/strings.xml b/tools/recovery_l10n/res/values-ro/strings.xml
index 8032865b8..ad924da08 100644
--- a/tools/recovery_l10n/res/values-ro/strings.xml
+++ b/tools/recovery_l10n/res/values-ro/strings.xml
@@ -1,9 +1,8 @@
<?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">"Se instalează actualizarea de sistem"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Se șterge"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nicio comandă"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Eroare!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Se instalează actualizarea de securitate"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Se instalează actualizarea de sistem…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Se efectuează ștergerea…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nicio comandă."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Eroare!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ru/strings.xml b/tools/recovery_l10n/res/values-ru/strings.xml
index feebecf31..de0da4004 100644
--- a/tools/recovery_l10n/res/values-ru/strings.xml
+++ b/tools/recovery_l10n/res/values-ru/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Установка обновления системы…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Удаление…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Команды нет"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Ошибка"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-si-rLK/strings.xml b/tools/recovery_l10n/res/values-si-rLK/strings.xml
index 456cdc567..e717a9762 100644
--- a/tools/recovery_l10n/res/values-si-rLK/strings.xml
+++ b/tools/recovery_l10n/res/values-si-rLK/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"පද්ධති යාවත්කාල ස්ථාපනය කරමින්…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"මකමින්...."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"විධානයක් නොමැත."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"දෝෂය!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sk/strings.xml b/tools/recovery_l10n/res/values-sk/strings.xml
index b15f3802b..cae6bce7c 100644
--- a/tools/recovery_l10n/res/values-sk/strings.xml
+++ b/tools/recovery_l10n/res/values-sk/strings.xml
@@ -1,9 +1,8 @@
<?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">"Inštaluje sa aktualizácia systému"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Prebieha vymazávanie"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Žiadny príkaz"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Chyba!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Inštaluje sa bezpečnostná aktualizácia"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Inštalácia aktualizácie systému..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Prebieha mazanie..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Žiadny príkaz."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Chyba!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sl/strings.xml b/tools/recovery_l10n/res/values-sl/strings.xml
index d608b7506..3f8d46fe6 100644
--- a/tools/recovery_l10n/res/values-sl/strings.xml
+++ b/tools/recovery_l10n/res/values-sl/strings.xml
@@ -1,9 +1,8 @@
<?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">"Nameščanje posodobitve sistema"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Brisanje"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Ni ukaza"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Napaka"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Nameščanje varnostne posodobitve"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Namestitev posodobitve sistema ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Brisanje ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Ni ukaza"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Napaka"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sq-rAL/strings.xml b/tools/recovery_l10n/res/values-sq-rAL/strings.xml
index 1156931fb..29f8ef592 100644
--- a/tools/recovery_l10n/res/values-sq-rAL/strings.xml
+++ b/tools/recovery_l10n/res/values-sq-rAL/strings.xml
@@ -1,9 +1,8 @@
<?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">"Po instalon përditësimin e sistemit"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Po spastron"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Nuk ka komanda"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Gabim!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Po instalon përditësimin e sigurisë"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Po instalon përditësimin e sistemit..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Po spastron..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Nuk ka komanda."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Gabim!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sr/strings.xml b/tools/recovery_l10n/res/values-sr/strings.xml
index a593d8faa..955326053 100644
--- a/tools/recovery_l10n/res/values-sr/strings.xml
+++ b/tools/recovery_l10n/res/values-sr/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Инсталирање ажурирања система..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Брисање..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Нема команде."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Грешка!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sv/strings.xml b/tools/recovery_l10n/res/values-sv/strings.xml
index b33ce253f..f875d3008 100644
--- a/tools/recovery_l10n/res/values-sv/strings.xml
+++ b/tools/recovery_l10n/res/values-sv/strings.xml
@@ -1,9 +1,8 @@
<?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">"Systemuppdatering installeras"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Rensar"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Inget kommando"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Fel!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Säkerhetsuppdatering installeras"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Installerar systemuppdatering ..."</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Tar bort ..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Inget kommando."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Fel!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-sw/strings.xml b/tools/recovery_l10n/res/values-sw/strings.xml
index 156765881..1a5304649 100644
--- a/tools/recovery_l10n/res/values-sw/strings.xml
+++ b/tools/recovery_l10n/res/values-sw/strings.xml
@@ -1,9 +1,8 @@
<?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">"Inasakinisha sasisho la mfumo"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Inafuta"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Hakuna amri"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Hitilafu fulani imetokea!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Inasakinisha sasisho la usalama"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Inasakinisha sasisho la mfumo…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Inafuta…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Hakuna amri."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Hitilafu!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ta-rIN/strings.xml b/tools/recovery_l10n/res/values-ta-rIN/strings.xml
index d49186d8d..f6f3e0e6a 100644
--- a/tools/recovery_l10n/res/values-ta-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-ta-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"முறைமை புதுப்பிப்பை நிறுவுகிறது…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"அழிக்கிறது…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"கட்டளை இல்லை."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"பிழை!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-te-rIN/strings.xml b/tools/recovery_l10n/res/values-te-rIN/strings.xml
index cfb02c915..6d0d17af5 100644
--- a/tools/recovery_l10n/res/values-te-rIN/strings.xml
+++ b/tools/recovery_l10n/res/values-te-rIN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"సిస్టమ్ నవీకరణను ఇన్‍స్టాల్ చేస్తోంది…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"ఎరేజ్ చేస్తోంది…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ఆదేశం లేదు."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"లోపం!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-th/strings.xml b/tools/recovery_l10n/res/values-th/strings.xml
index 155affea0..bcdfa2b25 100644
--- a/tools/recovery_l10n/res/values-th/strings.xml
+++ b/tools/recovery_l10n/res/values-th/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"กำลังติดตั้งการอัปเดตระบบ…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"กำลังลบ…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"ไม่มีคำสั่ง"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"ข้อผิดพลาด!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-tl/strings.xml b/tools/recovery_l10n/res/values-tl/strings.xml
index 555b42b8d..be2ba264c 100644
--- a/tools/recovery_l10n/res/values-tl/strings.xml
+++ b/tools/recovery_l10n/res/values-tl/strings.xml
@@ -1,9 +1,8 @@
<?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">"Nag-i-install ng pag-update ng system"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Binubura"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Walang command"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Error!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Nag-i-install ng update sa seguridad"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Ini-install ang update sa system…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Binubura…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Walang command."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-tr/strings.xml b/tools/recovery_l10n/res/values-tr/strings.xml
index 5387cb2ae..8629029ca 100644
--- a/tools/recovery_l10n/res/values-tr/strings.xml
+++ b/tools/recovery_l10n/res/values-tr/strings.xml
@@ -1,9 +1,8 @@
<?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">"Sistem güncellemesi yükleniyor"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Siliniyor"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Komut yok"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Hata!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Güvenlik güncellemesi yükleniyor"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Sistem güncellemesi yükleniyor…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Siliniyor…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Komut yok."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Hata!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-uk/strings.xml b/tools/recovery_l10n/res/values-uk/strings.xml
index 0c2fa164a..762c06ff3 100644
--- a/tools/recovery_l10n/res/values-uk/strings.xml
+++ b/tools/recovery_l10n/res/values-uk/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"Встановлення оновлення системи…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Стирання…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Немає команди."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Помилка!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-ur-rPK/strings.xml b/tools/recovery_l10n/res/values-ur-rPK/strings.xml
index 12e32fbc1..dc6eb6aa1 100644
--- a/tools/recovery_l10n/res/values-ur-rPK/strings.xml
+++ b/tools/recovery_l10n/res/values-ur-rPK/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"سسٹم اپ ڈیٹ انسٹال ہو رہا ہے…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"صاف کر رہا ہے…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"کوئی کمانڈ نہیں ہے۔"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"خرابی!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-uz-rUZ/strings.xml b/tools/recovery_l10n/res/values-uz-rUZ/strings.xml
index 2c309d646..287448418 100644
--- a/tools/recovery_l10n/res/values-uz-rUZ/strings.xml
+++ b/tools/recovery_l10n/res/values-uz-rUZ/strings.xml
@@ -1,9 +1,8 @@
<?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">"Tizim yangilanishi o‘rnatilmoqda"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Tozalanmoqda…"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Buyruq yo‘q"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Xato!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Xavfsizlik yangilanishi o‘rnatilmoqda"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Tizim yangilanishi o‘rnatilmoqda…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Tozalanmoqda…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Buyruq yo‘q."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Xato!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-vi/strings.xml b/tools/recovery_l10n/res/values-vi/strings.xml
index c77d0c8c2..ab4005b7f 100644
--- a/tools/recovery_l10n/res/values-vi/strings.xml
+++ b/tools/recovery_l10n/res/values-vi/strings.xml
@@ -1,9 +1,8 @@
<?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">"Đang cài đặt bản cập nhật hệ thống"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Đang xóa"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Không có lệnh nào"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Lỗi!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Đang cài đặt bản cập nhật bảo mật"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Đang cài đặt bản cập nhật hệ thống…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Đang xóa…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Không có lệnh nào."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Lỗi!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-zh-rCN/strings.xml b/tools/recovery_l10n/res/values-zh-rCN/strings.xml
index e06149791..2e1a6f57f 100644
--- a/tools/recovery_l10n/res/values-zh-rCN/strings.xml
+++ b/tools/recovery_l10n/res/values-zh-rCN/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"正在安装系统更新…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"正在清除…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"无命令。"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"出错了!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-zh-rHK/strings.xml b/tools/recovery_l10n/res/values-zh-rHK/strings.xml
index ec3315d32..f615c7a29 100644
--- a/tools/recovery_l10n/res/values-zh-rHK/strings.xml
+++ b/tools/recovery_l10n/res/values-zh-rHK/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"正在安裝系統更新…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"正在清除…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"沒有指令。"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"錯誤!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-zh-rTW/strings.xml b/tools/recovery_l10n/res/values-zh-rTW/strings.xml
index 78eae2429..f3f6a2c21 100644
--- a/tools/recovery_l10n/res/values-zh-rTW/strings.xml
+++ b/tools/recovery_l10n/res/values-zh-rTW/strings.xml
@@ -1,9 +1,8 @@
<?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>
+ <string name="recovery_installing" msgid="7864047928003865598">"正在安裝系統更新…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"清除中..."</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"沒有指令。"</string>
+ <string name="recovery_error" msgid="4550265746256727080">"錯誤!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values-zu/strings.xml b/tools/recovery_l10n/res/values-zu/strings.xml
index 6b815e1ab..1f904a203 100644
--- a/tools/recovery_l10n/res/values-zu/strings.xml
+++ b/tools/recovery_l10n/res/values-zu/strings.xml
@@ -1,9 +1,8 @@
<?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">"Ifaka isibuyekezo sesistimu"</string>
- <string name="recovery_erasing" msgid="7334826894904037088">"Iyasula"</string>
- <string name="recovery_no_command" msgid="4465476568623024327">"Awukho umyalo"</string>
- <string name="recovery_error" msgid="5748178989622716736">"Iphutha!"</string>
- <string name="recovery_installing_security" msgid="9184031299717114342">"Ifaka isibuyekezo sokuphepha"</string>
+ <string name="recovery_installing" msgid="7864047928003865598">"Ifaka isibuyekezo sesistimu…"</string>
+ <string name="recovery_erasing" msgid="4612809744968710197">"Iyasula…"</string>
+ <string name="recovery_no_command" msgid="1915703879031023455">"Awukho umyalo."</string>
+ <string name="recovery_error" msgid="4550265746256727080">"Iphutha!"</string>
</resources>
diff --git a/tools/recovery_l10n/res/values/strings.xml b/tools/recovery_l10n/res/values/strings.xml
index 971e038d3..d56d0733c 100644
--- a/tools/recovery_l10n/res/values/strings.xml
+++ b/tools/recovery_l10n/res/values/strings.xml
@@ -9,6 +9,7 @@
<item>erasing</item>
<item>no_command</item>
<item>error</item>
+ <item>installing_security</item>
</string-array>
<!-- Displayed on the screen beneath the animated android while the
diff --git a/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java b/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
index 817a3ad7d..ac94bde1c 100644
--- a/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
+++ b/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
@@ -139,6 +139,7 @@ public class Main extends Activity {
case 1: mStringId = R.string.recovery_erasing; break;
case 2: mStringId = R.string.recovery_no_command; break;
case 3: mStringId = R.string.recovery_error; break;
+ case 4: mStringId = R.string.recovery_installing_security; break;
}
}
@Override public void onNothingSelected(AdapterView parent) { }
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index 5e804bcca..c19943fa7 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -109,6 +109,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.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/properties.h>
@@ -118,8 +119,6 @@
#define LOG_TAG "uncrypt"
#include <log/log.h>
-#include "unique_fd.h"
-
#define WINDOW_SIZE 5
// uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT.
@@ -237,8 +236,9 @@ static int produce_block_map(const char* path, const char* map_file, const char*
return -1;
}
std::string tmp_map_file = std::string(map_file) + ".tmp";
- unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
- if (!mapfd) {
+ android::base::unique_fd mapfd(open(tmp_map_file.c_str(),
+ O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
+ if (mapfd == -1) {
ALOGE("failed to open %s: %s\n", tmp_map_file.c_str(), strerror(errno));
return -1;
}
@@ -262,9 +262,10 @@ static int produce_block_map(const char* path, const char* map_file, const char*
std::vector<int> ranges;
- std::string s = android::base::StringPrintf("%s\n%" PRId64 " %ld\n",
- blk_dev, sb.st_size, static_cast<long>(sb.st_blksize));
- if (!android::base::WriteStringToFd(s, mapfd.get())) {
+ std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n",
+ blk_dev, static_cast<int64_t>(sb.st_size),
+ static_cast<int64_t>(sb.st_blksize));
+ if (!android::base::WriteStringToFd(s, mapfd)) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
}
@@ -276,16 +277,16 @@ static int produce_block_map(const char* path, const char* map_file, const char*
int head_block = 0;
int head = 0, tail = 0;
- unique_fd fd(open(path, O_RDONLY));
- if (!fd) {
+ android::base::unique_fd fd(open(path, O_RDONLY));
+ if (fd == -1) {
ALOGE("failed to open %s for reading: %s", path, strerror(errno));
return -1;
}
- unique_fd wfd(-1);
+ android::base::unique_fd wfd;
if (encrypted) {
- wfd = open(blk_dev, O_WRONLY);
- if (!wfd) {
+ wfd.reset(open(blk_dev, O_WRONLY));
+ if (wfd == -1) {
ALOGE("failed to open fd for writing: %s", strerror(errno));
return -1;
}
@@ -304,14 +305,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
if ((tail+1) % WINDOW_SIZE == head) {
// write out head buffer
int block = head_block;
- if (ioctl(fd.get(), FIBMAP, &block) != 0) {
+ if (ioctl(fd, FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
return -1;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
- if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
- static_cast<off64_t>(sb.st_blksize) * block) != 0) {
+ if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
+ static_cast<off64_t>(sb.st_blksize) * block) != 0) {
return -1;
}
}
@@ -323,7 +324,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
if (encrypted) {
size_t to_read = static_cast<size_t>(
std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
- if (!android::base::ReadFully(fd.get(), buffers[tail].data(), to_read)) {
+ if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) {
ALOGE("failed to read: %s", strerror(errno));
return -1;
}
@@ -340,14 +341,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
while (head != tail) {
// write out head buffer
int block = head_block;
- if (ioctl(fd.get(), FIBMAP, &block) != 0) {
+ if (ioctl(fd, FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
return -1;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
- if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
- static_cast<off64_t>(sb.st_blksize) * block) != 0) {
+ if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
+ static_cast<off64_t>(sb.st_blksize) * block) != 0) {
return -1;
}
}
@@ -356,38 +357,36 @@ static int produce_block_map(const char* path, const char* map_file, const char*
}
if (!android::base::WriteStringToFd(
- android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd.get())) {
+ android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
}
for (size_t i = 0; i < ranges.size(); i += 2) {
if (!android::base::WriteStringToFd(
- android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd.get())) {
+ android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
}
}
- if (fsync(mapfd.get()) == -1) {
+ if (fsync(mapfd) == -1) {
ALOGE("failed to fsync \"%s\": %s", tmp_map_file.c_str(), strerror(errno));
return -1;
}
- if (close(mapfd.get()) == -1) {
+ if (close(mapfd.release()) == -1) {
ALOGE("failed to close %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
}
- mapfd = -1;
if (encrypted) {
- if (fsync(wfd.get()) == -1) {
+ if (fsync(wfd) == -1) {
ALOGE("failed to fsync \"%s\": %s", blk_dev, strerror(errno));
return -1;
}
- if (close(wfd.get()) == -1) {
+ if (close(wfd.release()) == -1) {
ALOGE("failed to close %s: %s", blk_dev, strerror(errno));
return -1;
}
- wfd = -1;
}
if (rename(tmp_map_file.c_str(), map_file) == -1) {
@@ -397,20 +396,19 @@ static int produce_block_map(const char* path, const char* map_file, const char*
// Sync dir to make rename() result written to disk.
std::string file_name = map_file;
std::string dir_name = dirname(&file_name[0]);
- unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
- if (!dfd) {
+ android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
+ if (dfd == -1) {
ALOGE("failed to open dir %s: %s", dir_name.c_str(), strerror(errno));
return -1;
}
- if (fsync(dfd.get()) == -1) {
+ if (fsync(dfd) == -1) {
ALOGE("failed to fsync %s: %s", dir_name.c_str(), strerror(errno));
return -1;
}
- if (close(dfd.get()) == -1) {
+ if (close(dfd.release()) == -1) {
ALOGE("failed to close %s: %s", dir_name.c_str(), strerror(errno));
return -1;
}
- dfd = -1;
return 0;
}
@@ -566,20 +564,20 @@ int main(int argc, char** argv) {
// c3. The socket is created by init when starting the service. uncrypt
// will use the socket to communicate with its caller.
- unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
- if (!service_socket) {
+ android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
+ if (service_socket == -1) {
ALOGE("failed to open socket \"%s\": %s", UNCRYPT_SOCKET.c_str(), strerror(errno));
return 1;
}
- fcntl(service_socket.get(), F_SETFD, FD_CLOEXEC);
+ fcntl(service_socket, F_SETFD, FD_CLOEXEC);
- if (listen(service_socket.get(), 1) == -1) {
+ if (listen(service_socket, 1) == -1) {
ALOGE("failed to listen on socket %d: %s", service_socket.get(), strerror(errno));
return 1;
}
- unique_fd socket_fd(accept4(service_socket.get(), nullptr, nullptr, SOCK_CLOEXEC));
- if (!socket_fd) {
+ android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC));
+ if (socket_fd == -1) {
ALOGE("failed to accept on socket %d: %s", service_socket.get(), strerror(errno));
return 1;
}
@@ -587,13 +585,13 @@ int main(int argc, char** argv) {
bool success = false;
switch (action) {
case UNCRYPT:
- success = uncrypt_wrapper(input_path, map_file, socket_fd.get());
+ success = uncrypt_wrapper(input_path, map_file, socket_fd);
break;
case SETUP_BCB:
- success = setup_bcb(socket_fd.get());
+ success = setup_bcb(socket_fd);
break;
case CLEAR_BCB:
- success = clear_bcb(socket_fd.get());
+ success = clear_bcb(socket_fd);
break;
default: // Should never happen.
ALOGE("Invalid uncrypt action code: %d", action);
@@ -604,7 +602,7 @@ int main(int argc, char** argv) {
// ensure the client to receive the last status code before the socket gets
// destroyed.
int code;
- if (android::base::ReadFully(socket_fd.get(), &code, 4)) {
+ if (android::base::ReadFully(socket_fd, &code, 4)) {
ALOGI(" received %d, exiting now", code);
} else {
ALOGE("failed to read the code: %s", strerror(errno));
diff --git a/unique_fd.h b/unique_fd.h
deleted file mode 100644
index cc85383f8..000000000
--- a/unique_fd.h
+++ /dev/null
@@ -1,62 +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.
- */
-
-#ifndef UNIQUE_FD_H
-#define UNIQUE_FD_H
-
-#include <stdio.h>
-
-#include <memory>
-
-class unique_fd {
- public:
- unique_fd(int fd) : fd_(fd) { }
-
- unique_fd(unique_fd&& uf) {
- fd_ = uf.fd_;
- uf.fd_ = -1;
- }
-
- ~unique_fd() {
- if (fd_ != -1) {
- close(fd_);
- }
- }
-
- int get() {
- return fd_;
- }
-
- // Movable.
- unique_fd& operator=(unique_fd&& uf) {
- fd_ = uf.fd_;
- uf.fd_ = -1;
- return *this;
- }
-
- explicit operator bool() const {
- return fd_ != -1;
- }
-
- private:
- int fd_;
-
- // Non-copyable.
- unique_fd(const unique_fd&) = delete;
- unique_fd& operator=(const unique_fd&) = delete;
-};
-
-#endif // UNIQUE_FD_H
diff --git a/updater/Android.mk b/updater/Android.mk
index d7aa613e9..b4d427c5d 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,49 +14,57 @@
LOCAL_PATH := $(call my-dir)
-updater_src_files := \
- install.cpp \
- blockimg.cpp \
- updater.cpp
-
-#
-# Build a statically-linked binary to include in OTA packages
-#
+# updater (static executable)
+# ===============================
+# Build a statically-linked binary to include in OTA packages.
include $(CLEAR_VARS)
-# Build only in eng, so we don't end up with a copy of this in /system
-# on user builds. (TODO: find a better way to build device binaries
-# needed only for OTA packages.)
-LOCAL_MODULE_TAGS := eng
+updater_src_files := \
+ install.cpp \
+ blockimg.cpp \
+ updater.cpp
LOCAL_CLANG := true
-
LOCAL_SRC_FILES := $(updater_src_files)
-LOCAL_STATIC_LIBRARIES += libfec libfec_rs libext4_utils_static libsquashfs_utils libcrypto_static
+LOCAL_STATIC_LIBRARIES += \
+ $(TARGET_RECOVERY_UPDATER_LIBS) \
+ $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+ libfec \
+ libfec_rs \
+ libext4_utils_static \
+ libsquashfs_utils \
+ libcrypto_utils \
+ libcrypto \
+ libapplypatch \
+ libbase \
+ libotafault \
+ libedify \
+ libminzip \
+ libmounts \
+ libz \
+ libbz \
+ libcutils \
+ liblog \
+ libselinux
+
+tune2fs_static_libraries := \
+ libext2_com_err \
+ libext2_blkid \
+ libext2_quota \
+ libext2_uuid_static \
+ libext2_e2p \
+ libext2fs
+
+LOCAL_STATIC_LIBRARIES += \
+ libtune2fs \
+ $(tune2fs_static_libraries)
-ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
-LOCAL_CFLAGS += -DUSE_EXT4
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_STATIC_LIBRARIES += \
libsparse_static \
libz
-endif
-
-LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz
-LOCAL_STATIC_LIBRARIES += libbz
-LOCAL_STATIC_LIBRARIES += libcutils liblog libc
-LOCAL_STATIC_LIBRARIES += libselinux
-tune2fs_static_libraries := \
- libext2_com_err \
- libext2_blkid \
- libext2_quota \
- libext2_uuid_static \
- libext2_e2p \
- libext2fs
-LOCAL_STATIC_LIBRARIES += libtune2fs $(tune2fs_static_libraries)
LOCAL_C_INCLUDES += external/e2fsprogs/misc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index a80180a9a..f00bc4bff 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -40,6 +40,7 @@
#include <android-base/parseint.h>
#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include "applypatch/applypatch.h"
#include "edify/expr.h"
@@ -49,7 +50,6 @@
#include "minzip/Hash.h"
#include "ota_io.h"
#include "print_sha1.h"
-#include "unique_fd.h"
#include "updater.h"
#define BLOCKSIZE 4096
@@ -213,7 +213,7 @@ static void allocate(size_t size, std::vector<uint8_t>& buffer) {
}
struct RangeSinkState {
- RangeSinkState(RangeSet& rs) : tgt(rs) { };
+ explicit RangeSinkState(RangeSet& rs) : tgt(rs) { };
int fd;
const RangeSet& tgt;
@@ -398,7 +398,7 @@ struct CommandParameters {
std::string stashbase;
bool canwrite;
int createdstash;
- int fd;
+ android::base::unique_fd fd;
bool foundwrites;
bool isunresumable;
int version;
@@ -608,9 +608,7 @@ static int LoadStash(CommandParameters& params, const std::string& base, const s
return -1;
}
- int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY));
- unique_fd fd_holder(fd);
-
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY)));
if (fd == -1) {
fprintf(stderr, "open \"%s\" failed: %s\n", fn.c_str(), strerror(errno));
return -1;
@@ -665,9 +663,9 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str());
- int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
- unique_fd fd_holder(fd);
-
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC,
+ STASH_FILE_MODE)));
if (fd == -1) {
fprintf(stderr, "failed to create \"%s\": %s\n", fn.c_str(), strerror(errno));
return -1;
@@ -690,9 +688,8 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
}
std::string dname = GetStashFileName(base, "", "");
- int dfd = TEMP_FAILURE_RETRY(open(dname.c_str(), O_RDONLY | O_DIRECTORY));
- unique_fd dfd_holder(dfd);
-
+ android::base::unique_fd dfd(TEMP_FAILURE_RETRY(ota_open(dname.c_str(),
+ O_RDONLY | O_DIRECTORY)));
if (dfd == -1) {
failure_type = kFileOpenFailure;
fprintf(stderr, "failed to open \"%s\" failed: %s\n", dname.c_str(), strerror(errno));
@@ -980,8 +977,8 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t&
tgthash = params.tokens[params.cpos++];
}
- if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, params.stashbase,
- &overlap) == -1) {
+ if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd,
+ params.stashbase, &overlap) == -1) {
return -1;
}
@@ -1382,8 +1379,7 @@ static unsigned int HashString(const char *s) {
static Value* PerformBlockImageUpdate(const char* name, State* state, int /* argc */, Expr* argv[],
const Command* commands, size_t cmdcount, bool dryrun) {
- CommandParameters params;
- memset(&params, 0, sizeof(params));
+ CommandParameters params = {};
params.canwrite = !dryrun;
fprintf(stderr, "performing %s\n", dryrun ? "verification" : "update");
@@ -1452,9 +1448,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
return StringValue(strdup(""));
}
- params.fd = TEMP_FAILURE_RETRY(open(blockdev_filename->data, O_RDWR));
- unique_fd fd_holder(params.fd);
-
+ params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR)));
if (params.fd == -1) {
fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data, strerror(errno));
return StringValue(strdup(""));
@@ -1613,7 +1607,7 @@ pbiudone:
failure_type = kFsyncFailure;
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
}
- // params.fd will be automatically closed because of the fd_holder above.
+ // params.fd will be automatically closed because it's a unique_fd.
// Only delete the stash if the update cannot be resumed, or it's
// a verification run and we created the stash.
@@ -1739,9 +1733,8 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[])
return StringValue(strdup(""));
}
- int fd = open(blockdev_filename->data, O_RDWR);
- unique_fd fd_holder(fd);
- if (fd < 0) {
+ android::base::unique_fd fd(ota_open(blockdev_filename->data, O_RDWR));
+ if (fd == -1) {
ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", blockdev_filename->data,
strerror(errno));
return StringValue(strdup(""));
@@ -1795,8 +1788,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[])
return StringValue(strdup(""));
}
- int fd = open(arg_filename->data, O_RDONLY);
- unique_fd fd_holder(fd);
+ android::base::unique_fd fd(ota_open(arg_filename->data, O_RDONLY));
if (fd == -1) {
ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", arg_filename->data,
strerror(errno));
diff --git a/updater/install.cpp b/updater/install.cpp
index 005f9f97d..4c4886d51 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -27,7 +27,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
-#include <selinux/selinux.h>
#include <ftw.h>
#include <sys/capability.h>
#include <sys/xattr.h>
@@ -40,6 +39,8 @@
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
#include "bootloader.h"
#include "applypatch/applypatch.h"
@@ -49,18 +50,15 @@
#include "edify/expr.h"
#include "error_code.h"
#include "minzip/DirUtil.h"
-#include "mtdutils/mounts.h"
-#include "mtdutils/mtdutils.h"
+#include "mounts.h"
#include "openssl/sha.h"
#include "ota_io.h"
#include "updater.h"
#include "install.h"
#include "tune2fs.h"
-#ifdef USE_EXT4
#include "make_ext4fs.h"
#include "wipe.h"
-#endif
// Send over the buffer to recovery though the command pipe.
static void uiPrint(State* state, const std::string& buffer) {
@@ -82,8 +80,7 @@ static void uiPrint(State* state, const std::string& buffer) {
fprintf(stderr, "%s", buffer.c_str());
}
-__attribute__((__format__(printf, 2, 3))) __nonnull((2))
-void uiPrintf(State* state, const char* format, ...) {
+void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) {
std::string error_msg;
va_list ap;
@@ -109,7 +106,6 @@ char* PrintSha1(const uint8_t* digest) {
// mount(fs_type, partition_type, location, mount_point)
//
-// fs_type="yaffs2" partition_type="MTD" location=partition
// fs_type="ext4" partition_type="EMMC" location=device
Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
@@ -171,33 +167,14 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
}
}
- if (strcmp(partition_type, "MTD") == 0) {
- mtd_scan_partitions();
- const MtdPartition* mtd;
- mtd = mtd_find_partition_by_name(location);
- if (mtd == NULL) {
- uiPrintf(state, "%s: no mtd partition named \"%s\"\n",
- name, location);
- result = strdup("");
- goto done;
- }
- if (mtd_mount_partition(mtd, mount_point, fs_type, 0 /* rw */) != 0) {
- uiPrintf(state, "mtd mount of %s failed: %s\n",
- location, strerror(errno));
- result = strdup("");
- goto done;
- }
- result = mount_point;
+ if (mount(location, mount_point, fs_type,
+ MS_NOATIME | MS_NODEV | MS_NODIRATIME,
+ has_mount_options ? mount_options : "") < 0) {
+ uiPrintf(state, "%s: failed to mount %s at %s: %s\n",
+ name, location, mount_point, strerror(errno));
+ result = strdup("");
} else {
- if (mount(location, mount_point, fs_type,
- MS_NOATIME | MS_NODEV | MS_NODIRATIME,
- has_mount_options ? mount_options : "") < 0) {
- uiPrintf(state, "%s: failed to mount %s at %s: %s\n",
- name, location, mount_point, strerror(errno));
- result = strdup("");
- } else {
- result = mount_point;
- }
+ result = mount_point;
}
done:
@@ -227,7 +204,7 @@ Value* IsMountedFn(const char* name, State* state, int argc, Expr* argv[]) {
scan_mounted_volumes();
{
- const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
+ MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
if (vol == NULL) {
result = strdup("");
} else {
@@ -257,7 +234,7 @@ Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) {
scan_mounted_volumes();
{
- const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
+ MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
if (vol == NULL) {
uiPrintf(state, "unmount of %s failed; no such volume\n", mount_point);
result = strdup("");
@@ -293,7 +270,6 @@ static int exec_cmd(const char* path, char* const argv[]) {
// format(fs_type, partition_type, location, fs_size, mount_point)
//
-// fs_type="yaffs2" partition_type="MTD" location=partition fs_size=<bytes> mount_point=<location>
// fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location>
// fs_type="f2fs" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location>
// if fs_size == 0, then make fs uses the entire partition.
@@ -334,35 +310,7 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
goto done;
}
- if (strcmp(partition_type, "MTD") == 0) {
- mtd_scan_partitions();
- const MtdPartition* mtd = mtd_find_partition_by_name(location);
- if (mtd == NULL) {
- printf("%s: no mtd partition named \"%s\"",
- name, location);
- result = strdup("");
- goto done;
- }
- MtdWriteContext* ctx = mtd_write_partition(mtd);
- if (ctx == NULL) {
- printf("%s: can't write \"%s\"", name, location);
- result = strdup("");
- goto done;
- }
- if (mtd_erase_blocks(ctx, -1) == -1) {
- mtd_write_close(ctx);
- printf("%s: failed to erase \"%s\"", name, location);
- result = strdup("");
- goto done;
- }
- if (mtd_write_close(ctx) != 0) {
- printf("%s: failed to close \"%s\"", name, location);
- result = strdup("");
- goto done;
- }
- result = location;
-#ifdef USE_EXT4
- } else if (strcmp(fs_type, "ext4") == 0) {
+ if (strcmp(fs_type, "ext4") == 0) {
int status = make_ext4fs(location, atoll(fs_size), mount_point, sehandle);
if (status != 0) {
printf("%s: make_ext4fs failed (%d) on %s",
@@ -389,7 +337,6 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
goto done;
}
result = location;
-#endif
} else {
printf("%s: unsupported fs_type \"%s\" partition_type \"%s\"",
name, fs_type, partition_type);
@@ -561,7 +508,7 @@ Value* PackageExtractFileFn(const char* name, State* state,
}
{
- int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC,
+ int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR));
if (fd == -1) {
printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno));
@@ -604,8 +551,8 @@ Value* PackageExtractFileFn(const char* name, State* state,
v->size = mzGetZipEntryUncompLen(entry);
v->data = reinterpret_cast<char*>(malloc(v->size));
if (v->data == NULL) {
- printf("%s: failed to allocate %ld bytes for %s\n",
- name, (long)v->size, zip_path);
+ printf("%s: failed to allocate %zd bytes for %s\n",
+ name, v->size, zip_path);
goto done1;
}
@@ -998,13 +945,13 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
buffer = reinterpret_cast<char*>(malloc(st.st_size+1));
if (buffer == NULL) {
- ErrorAbort(state, kFileGetPropFailure, "%s: failed to alloc %lld bytes", name,
- (long long)st.st_size+1);
+ ErrorAbort(state, kFileGetPropFailure, "%s: failed to alloc %zu bytes", name,
+ static_cast<size_t>(st.st_size+1));
goto done;
}
FILE* f;
- f = fopen(filename, "rb");
+ f = ota_fopen(filename, "rb");
if (f == NULL) {
ErrorAbort(state, kFileOpenFailure, "%s: failed to open %s: %s", name, filename,
strerror(errno));
@@ -1012,14 +959,14 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
}
if (ota_fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) {
- ErrorAbort(state, kFreadFailure, "%s: failed to read %lld bytes from %s",
- name, (long long)st.st_size+1, filename);
- fclose(f);
+ ErrorAbort(state, kFreadFailure, "%s: failed to read %zu bytes from %s",
+ name, static_cast<size_t>(st.st_size), filename);
+ ota_fclose(f);
goto done;
}
buffer[st.st_size] = '\0';
- fclose(f);
+ ota_fclose(f);
char* line;
line = strtok(buffer, "\n");
@@ -1066,98 +1013,6 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
return StringValue(result);
}
-// write_raw_image(filename_or_blob, partition)
-Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
- char* result = NULL;
-
- Value* partition_value;
- Value* contents;
- if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) {
- return NULL;
- }
-
- char* partition = NULL;
- if (partition_value->type != VAL_STRING) {
- ErrorAbort(state, kArgsParsingFailure, "partition argument to %s must be string", name);
- goto done;
- }
- partition = partition_value->data;
- if (strlen(partition) == 0) {
- ErrorAbort(state, kArgsParsingFailure, "partition argument to %s can't be empty", name);
- goto done;
- }
- if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) {
- ErrorAbort(state, kArgsParsingFailure, "file argument to %s can't be empty", name);
- goto done;
- }
-
- mtd_scan_partitions();
- const MtdPartition* mtd;
- mtd = mtd_find_partition_by_name(partition);
- if (mtd == NULL) {
- printf("%s: no mtd partition named \"%s\"\n", name, partition);
- result = strdup("");
- goto done;
- }
-
- MtdWriteContext* ctx;
- ctx = mtd_write_partition(mtd);
- if (ctx == NULL) {
- printf("%s: can't write mtd partition \"%s\"\n",
- name, partition);
- result = strdup("");
- goto done;
- }
-
- bool success;
-
- if (contents->type == VAL_STRING) {
- // we're given a filename as the contents
- char* filename = contents->data;
- FILE* f = ota_fopen(filename, "rb");
- if (f == NULL) {
- printf("%s: can't open %s: %s\n", name, filename, strerror(errno));
- result = strdup("");
- goto done;
- }
-
- success = true;
- char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ));
- int read;
- while (success && (read = ota_fread(buffer, 1, BUFSIZ, f)) > 0) {
- int wrote = mtd_write_data(ctx, buffer, read);
- success = success && (wrote == read);
- }
- free(buffer);
- ota_fclose(f);
- } else {
- // we're given a blob as the contents
- ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size);
- success = (wrote == contents->size);
- }
- if (!success) {
- printf("mtd_write_data to %s failed: %s\n",
- partition, strerror(errno));
- }
-
- if (mtd_erase_blocks(ctx, -1) == -1) {
- printf("%s: error erasing blocks of %s\n", name, partition);
- }
- if (mtd_write_close(ctx) != 0) {
- printf("%s: error closing write of %s\n", name, partition);
- }
-
- printf("%s %s partition\n",
- success ? "wrote" : "failed to write", partition);
-
- result = success ? partition : strdup("");
-
-done:
- if (result != partition) FreeValue(partition_value);
- FreeValue(contents);
- return StringValue(result);
-}
-
// apply_patch_space(bytes)
Value* ApplyPatchSpaceFn(const char* name, State* state,
int argc, Expr* argv[]) {
@@ -1450,10 +1305,10 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) {
// zero out the 'command' field of the bootloader message.
memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command));
- FILE* f = fopen(filename, "r+b");
+ FILE* f = ota_fopen(filename, "r+b");
fseek(f, offsetof(struct bootloader_message, command), SEEK_SET);
ota_fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f);
- fclose(f);
+ ota_fclose(f);
free(filename);
strcpy(buffer, "reboot,");
@@ -1492,7 +1347,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
// bootloader message that the main recovery uses to save its
// arguments in case of the device restarting midway through
// package installation.
- FILE* f = fopen(filename, "r+b");
+ FILE* f = ota_fopen(filename, "r+b");
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
int to_write = strlen(stagestr)+1;
int max_size = sizeof(((struct bootloader_message*)0)->stage);
@@ -1501,7 +1356,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
stagestr[max_size-1] = 0;
}
ota_fwrite(stagestr, to_write, 1, f);
- fclose(f);
+ ota_fclose(f);
free(stagestr);
return StringValue(filename);
@@ -1518,10 +1373,10 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
if (ReadArgs(state, argv, 1, &filename) < 0) return NULL;
char buffer[sizeof(((struct bootloader_message*)0)->stage)];
- FILE* f = fopen(filename, "rb");
+ FILE* f = ota_fopen(filename, "rb");
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
ota_fread(buffer, sizeof(buffer), 1, f);
- fclose(f);
+ ota_fclose(f);
buffer[sizeof(buffer)-1] = '\0';
return StringValue(strdup(buffer));
@@ -1616,7 +1471,6 @@ void RegisterInstallFunctions() {
RegisterFunction("getprop", GetPropFn);
RegisterFunction("file_getprop", FileGetPropFn);
- RegisterFunction("write_raw_image", WriteRawImageFn);
RegisterFunction("apply_patch", ApplyPatchFn);
RegisterFunction("apply_patch_check", ApplyPatchCheckFn);
diff --git a/updater/install.h b/updater/install.h
index 70e343404..b3b8a4dd5 100644
--- a/updater/install.h
+++ b/updater/install.h
@@ -20,8 +20,8 @@
void RegisterInstallFunctions();
// uiPrintf function prints msg to screen as well as logs
-void uiPrintf(State* state, const char* format, ...);
+void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) __attribute__((__format__(printf, 2, 3)));
-static int make_parents(char* name);
+static int make_parents(char* _Nonnull name);
#endif
diff --git a/updater/updater.cpp b/updater/updater.cpp
index e956dd557..c222cee0d 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -27,6 +27,9 @@
#include "minzip/SysUtil.h"
#include "config.h"
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+
// Generated by the makefile, this function defines the
// RegisterDeviceExtensions() function, which calls all the
// registration functions for device-specific extensions.
diff --git a/updater/updater.h b/updater/updater.h
index d1dfdd05e..d3a09b93d 100644
--- a/updater/updater.h
+++ b/updater/updater.h
@@ -20,9 +20,6 @@
#include <stdio.h>
#include "minzip/Zip.h"
-#include <selinux/selinux.h>
-#include <selinux/label.h>
-
typedef struct {
FILE* cmd_pipe;
ZipArchive* package_zip;
@@ -32,6 +29,7 @@ typedef struct {
size_t package_zip_len;
} UpdaterInfo;
+struct selabel_handle;
extern struct selabel_handle *sehandle;
#endif
diff --git a/verifier.cpp b/verifier.cpp
index 16cc7cf03..996a1fdf9 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -22,6 +22,7 @@
#include <algorithm>
#include <memory>
+#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
diff --git a/wear_ui.cpp b/wear_ui.cpp
index f9727af01..7ca879bcb 100644
--- a/wear_ui.cpp
+++ b/wear_ui.cpp
@@ -277,7 +277,7 @@ void WearRecoveryUI::progress_loop() {
// minimum of 20ms delay between frames
double delay = interval - (end-start);
if (delay < 0.02) delay = 0.02;
- usleep((long)(delay * 1000000));
+ usleep(static_cast<useconds_t>(delay * 1000000));
}
}
@@ -500,8 +500,8 @@ void WearRecoveryUI::Redraw()
}
void WearRecoveryUI::ShowFile(FILE* fp) {
- std::vector<long> offsets;
- offsets.push_back(ftell(fp));
+ std::vector<off_t> offsets;
+ offsets.push_back(ftello(fp));
ClearText();
struct stat sb;
@@ -511,7 +511,7 @@ void WearRecoveryUI::ShowFile(FILE* fp) {
while (true) {
if (show_prompt) {
Print("--(%d%% of %d bytes)--",
- static_cast<int>(100 * (double(ftell(fp)) / double(sb.st_size))),
+ static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))),
static_cast<int>(sb.st_size));
Redraw();
while (show_prompt) {
@@ -530,7 +530,7 @@ void WearRecoveryUI::ShowFile(FILE* fp) {
if (feof(fp)) {
return;
}
- offsets.push_back(ftell(fp));
+ offsets.push_back(ftello(fp));
}
}
ClearText();