diff options
49 files changed, 938 insertions, 838 deletions
diff --git a/Android.bp b/Android.bp index 99ca3a45c..22407e0e2 100644 --- a/Android.bp +++ b/Android.bp @@ -1,5 +1,7 @@ subdirs = [ + "applypatch", "bootloader_message", + "edify", "otafault", "otautil", ] diff --git a/Android.mk b/Android.mk index ac72bac01..7e34c10f9 100644 --- a/Android.mk +++ b/Android.mk @@ -94,7 +94,7 @@ endif endif LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION) -LOCAL_CFLAGS += -Wall -Wno-unused-parameter -Werror +LOCAL_CFLAGS += -Wall -Werror ifneq ($(TARGET_RECOVERY_UI_MARGIN_HEIGHT),) LOCAL_CFLAGS += -DRECOVERY_UI_MARGIN_HEIGHT=$(TARGET_RECOVERY_UI_MARGIN_HEIGHT) @@ -173,9 +173,7 @@ LOCAL_STATIC_LIBRARIES := \ libcutils \ libutils \ liblog \ - libselinux \ - libm \ - libc + libselinux LOCAL_HAL_STATIC_LIBRARIES := libhealthd @@ -229,6 +227,7 @@ LOCAL_SRC_FILES := \ asn1_decoder.cpp \ verifier.cpp LOCAL_STATIC_LIBRARIES := \ + libotautil \ libcrypto_utils \ libcrypto \ libbase @@ -259,9 +258,7 @@ LOCAL_MODULE := librecovery_ui_vr include $(BUILD_STATIC_LIBRARY) include \ - $(LOCAL_PATH)/applypatch/Android.mk \ $(LOCAL_PATH)/boot_control/Android.mk \ - $(LOCAL_PATH)/edify/Android.mk \ $(LOCAL_PATH)/minadbd/Android.mk \ $(LOCAL_PATH)/minui/Android.mk \ $(LOCAL_PATH)/tests/Android.mk \ @@ -1,3 +1,3 @@ -enh+aosp-gerrit@google.com +enh@google.com tbao@google.com xunchang@google.com diff --git a/applypatch/Android.bp b/applypatch/Android.bp new file mode 100644 index 000000000..922f67abf --- /dev/null +++ b/applypatch/Android.bp @@ -0,0 +1,196 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_defaults { + name: "applypatch_defaults", + + cflags: [ + "-D_FILE_OFFSET_BITS=64", + "-DZLIB_CONST", + "-Wall", + "-Werror", + ], + + local_include_dirs: [ + "include", + ], +} + +cc_library_static { + name: "libapplypatch", + + defaults: [ + "applypatch_defaults", + ], + + srcs: [ + "applypatch.cpp", + "bspatch.cpp", + "freecache.cpp", + "imgpatch.cpp", + ], + + export_include_dirs: [ + "include", + ], + + static_libs: [ + "libbase", + "libbspatch", + "libbz", + "libcrypto", + "libedify", + "libotafault", + "libotautil", + "libz", + ], +} + +cc_library_static { + name: "libapplypatch_modes", + + defaults: [ + "applypatch_defaults", + ], + + srcs: [ + "applypatch_modes.cpp", + ], + + static_libs: [ + "libapplypatch", + "libbase", + "libcrypto", + "libedify", + "libotautil", + ], +} + +cc_binary { + name: "applypatch", + + defaults: [ + "applypatch_defaults", + ], + + srcs: [ + "applypatch_main.cpp", + ], + + static_libs: [ + "libapplypatch_modes", + "libapplypatch", + "libedify", + "libotafault", + "libotautil", + "libbspatch", + ], + + shared_libs: [ + "libbase", + "libbz", + "libcrypto", + "liblog", + "libz", + "libziparchive", + ], +} + +cc_library_static { + name: "libimgdiff", + + host_supported: true, + + defaults: [ + "applypatch_defaults", + ], + + srcs: [ + "imgdiff.cpp", + ], + + export_include_dirs: [ + "include", + ], + + static_libs: [ + "libbase", + "libbsdiff", + "libdivsufsort", + "libdivsufsort64", + "liblog", + "libotautil", + "libutils", + "libz", + "libziparchive", + ], +} + +cc_binary_host { + name: "imgdiff", + + srcs: [ + "imgdiff_main.cpp", + ], + + defaults: [ + "applypatch_defaults", + ], + + static_libs: [ + "libimgdiff", + "libotautil", + "libbsdiff", + "libdivsufsort", + "libdivsufsort64", + "libziparchive", + "libbase", + "libutils", + "liblog", + "libbz", + "libz", + ], +} + +cc_library_static { + name: "libimgpatch", + + // The host module is for recovery_host_test (Linux only). + host_supported: true, + + defaults: [ + "applypatch_defaults", + ], + + srcs: [ + "bspatch.cpp", + "imgpatch.cpp", + ], + + static_libs: [ + "libbase", + "libbspatch", + "libbz", + "libcrypto", + "libedify", + "libotautil", + "libz", + ], + + target: { + darwin: { + enabled: false, + }, + }, +} diff --git a/applypatch/Android.mk b/applypatch/Android.mk deleted file mode 100644 index db72e8eee..000000000 --- a/applypatch/Android.mk +++ /dev/null @@ -1,196 +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. - -LOCAL_PATH := $(call my-dir) - -# libapplypatch (static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - applypatch.cpp \ - bspatch.cpp \ - freecache.cpp \ - imgpatch.cpp -LOCAL_MODULE := libapplypatch -LOCAL_MODULE_TAGS := eng -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -LOCAL_STATIC_LIBRARIES := \ - libotafault \ - libbase \ - libcrypto \ - libbspatch \ - libbz \ - libz -LOCAL_CFLAGS := \ - -DZLIB_CONST \ - -Wall \ - -Werror -include $(BUILD_STATIC_LIBRARY) - -# libimgpatch (static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - bspatch.cpp \ - imgpatch.cpp -LOCAL_MODULE := libimgpatch -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -LOCAL_STATIC_LIBRARIES := \ - libedify \ - libcrypto \ - libbspatch \ - libbase \ - libbz \ - libz -LOCAL_CFLAGS := \ - -DZLIB_CONST \ - -Wall \ - -Werror -include $(BUILD_STATIC_LIBRARY) - -# libimgpatch (host static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - bspatch.cpp \ - imgpatch.cpp -LOCAL_MODULE := libimgpatch -LOCAL_MODULE_HOST_OS := linux -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -LOCAL_STATIC_LIBRARIES := \ - libedify \ - libcrypto \ - libbspatch \ - libbase \ - libbz \ - libz -LOCAL_CFLAGS := \ - -DZLIB_CONST \ - -Wall \ - -Werror -include $(BUILD_HOST_STATIC_LIBRARY) - -# libapplypatch_modes (static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - applypatch_modes.cpp -LOCAL_MODULE := libapplypatch_modes -LOCAL_C_INCLUDES := bootable/recovery -LOCAL_STATIC_LIBRARIES := \ - libapplypatch \ - libbase \ - libedify \ - libcrypto -LOCAL_CFLAGS := -Wall -Werror -include $(BUILD_STATIC_LIBRARY) - -# applypatch (target executable) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := applypatch_main.cpp -LOCAL_MODULE := applypatch -LOCAL_C_INCLUDES := bootable/recovery -LOCAL_STATIC_LIBRARIES := \ - libapplypatch_modes \ - libapplypatch \ - libedify \ - libotafault \ - libbspatch \ - libbase \ - libziparchive \ - liblog \ - libcrypto \ - libbz -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libz \ - libcutils -LOCAL_CFLAGS := -Wall -Werror -include $(BUILD_EXECUTABLE) - -libimgdiff_src_files := imgdiff.cpp - -# libbsdiff is compiled with -D_FILE_OFFSET_BITS=64. -libimgdiff_cflags := \ - -Wall \ - -Werror \ - -D_FILE_OFFSET_BITS=64 \ - -DZLIB_CONST - -libimgdiff_static_libraries := \ - libbsdiff \ - libdivsufsort \ - libdivsufsort64 \ - libziparchive \ - libutils \ - liblog \ - libbase \ - libz - -# libimgdiff (static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - $(libimgdiff_src_files) -LOCAL_MODULE := libimgdiff -LOCAL_CFLAGS := \ - $(libimgdiff_cflags) -LOCAL_STATIC_LIBRARIES := \ - $(libimgdiff_static_libraries) -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -include $(BUILD_STATIC_LIBRARY) - -# libimgdiff (host static library) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := \ - $(libimgdiff_src_files) -LOCAL_MODULE := libimgdiff -LOCAL_CFLAGS := \ - $(libimgdiff_cflags) -LOCAL_STATIC_LIBRARIES := \ - $(libimgdiff_static_libraries) -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include -include $(BUILD_HOST_STATIC_LIBRARY) - -# imgdiff (host static executable) -# =============================== -include $(CLEAR_VARS) -LOCAL_SRC_FILES := imgdiff_main.cpp -LOCAL_MODULE := imgdiff -LOCAL_CFLAGS := -Wall -Werror -LOCAL_STATIC_LIBRARIES := \ - libimgdiff \ - $(libimgdiff_static_libraries) \ - libbz -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/include \ - bootable/recovery -include $(BUILD_HOST_EXECUTABLE) diff --git a/applypatch/Makefile b/applypatch/Makefile deleted file mode 100644 index fb4984303..000000000 --- a/applypatch/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# 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 729d2a910..c8b75df79 100644 --- a/applypatch/applypatch.cpp +++ b/applypatch/applypatch.cpp @@ -40,7 +40,7 @@ #include "edify/expr.h" #include "otafault/ota_io.h" -#include "print_sha1.h" +#include "otautil/print_sha1.h" static int LoadPartitionContents(const std::string& filename, FileContents* file); static size_t FileSink(const unsigned char* data, size_t len, int fd); diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp index b2f29fbd6..c291464a8 100644 --- a/applypatch/bspatch.cpp +++ b/applypatch/bspatch.cpp @@ -31,7 +31,7 @@ #include "applypatch/applypatch.h" #include "edify/expr.h" -#include "print_sha1.h" +#include "otautil/print_sha1.h" void ShowBSDiffLicense() { puts("The bsdiff library used herein is:\n" diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp index ccd68dc3e..f57e7942c 100644 --- a/applypatch/imgdiff.cpp +++ b/applypatch/imgdiff.cpp @@ -160,13 +160,15 @@ #include <android-base/logging.h> #include <android-base/memory.h> #include <android-base/parseint.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> #include <android-base/unique_fd.h> #include <bsdiff/bsdiff.h> #include <ziparchive/zip_archive.h> #include <zlib.h> #include "applypatch/imgdiff_image.h" -#include "rangeset.h" +#include "otautil/rangeset.h" using android::base::get_unaligned; diff --git a/applypatch/include/applypatch/imgdiff_image.h b/applypatch/include/applypatch/imgdiff_image.h index 4e915e5e7..00a84f3a9 100644 --- a/applypatch/include/applypatch/imgdiff_image.h +++ b/applypatch/include/applypatch/imgdiff_image.h @@ -29,7 +29,7 @@ #include <zlib.h> #include "imgdiff.h" -#include "rangeset.h" +#include "otautil/rangeset.h" class ImageChunk { public: diff --git a/applypatch/libimgpatch.pc b/applypatch/libimgpatch.pc deleted file mode 100644 index e5002934f..000000000 --- a/applypatch/libimgpatch.pc +++ /dev/null @@ -1,6 +0,0 @@ -# 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/boot_control/Android.mk b/boot_control/Android.mk index 27e3d9765..9814d7122 100644 --- a/boot_control/Android.mk +++ b/boot_control/Android.mk @@ -24,8 +24,7 @@ LOCAL_CFLAGS := \ -D_FILE_OFFSET_BITS=64 \ -Werror \ -Wall \ - -Wextra \ - -Wno-unused-parameter + -Wextra LOCAL_SHARED_LIBRARIES := liblog LOCAL_STATIC_LIBRARIES := libbootloader_message libfs_mgr libbase LOCAL_POST_INSTALL_CMD := \ diff --git a/edify/Android.bp b/edify/Android.bp new file mode 100644 index 000000000..42947eb4e --- /dev/null +++ b/edify/Android.bp @@ -0,0 +1,45 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_library_static { + name: "libedify", + + host_supported: true, + + srcs: [ + "expr.cpp", + "lexer.ll", + "parser.yy", + ], + + cflags: [ + "-Wall", + "-Werror", + "-Wno-deprecated-register", + "-Wno-unused-parameter", + ], + + export_include_dirs: [ + "include", + ], + + local_include_dirs: [ + "include", + ], + + static_libs: [ + "libbase", + "libotautil", + ], +} diff --git a/edify/Android.mk b/edify/Android.mk deleted file mode 100644 index fbf2b1b06..000000000 --- a/edify/Android.mk +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 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. - -LOCAL_PATH := $(call my-dir) - -edify_src_files := \ - lexer.ll \ - parser.yy \ - expr.cpp - -# -# Build the device-side library (static library) -# -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(edify_src_files) - -LOCAL_CFLAGS := -Wall -Werror -LOCAL_CPPFLAGS := -Wno-unused-parameter -LOCAL_CPPFLAGS += -Wno-deprecated-register -LOCAL_MODULE := libedify -LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. -LOCAL_STATIC_LIBRARIES += libbase - -include $(BUILD_STATIC_LIBRARY) - -# -# Build the host-side library (static library) -# -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(edify_src_files) - -LOCAL_CFLAGS := -Wall -Werror -LOCAL_CPPFLAGS := -Wno-unused-parameter -LOCAL_CPPFLAGS += -Wno-deprecated-register -LOCAL_MODULE := libedify -LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. -LOCAL_STATIC_LIBRARIES += libbase - -include $(BUILD_HOST_STATIC_LIBRARY) diff --git a/edify/expr.cpp b/edify/expr.cpp index 403162d6d..1b8623f03 100644 --- a/edify/expr.cpp +++ b/edify/expr.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "expr.h" +#include "edify/expr.h" #include <stdarg.h> #include <stdio.h> @@ -31,7 +31,7 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> -#include "error_code.h" +#include "otautil/error_code.h" // Functions should: // diff --git a/edify/expr.h b/edify/include/edify/expr.h index 32828028a..770d1cf0d 100644 --- a/edify/expr.h +++ b/edify/include/edify/expr.h @@ -23,7 +23,7 @@ #include <string> #include <vector> -// Forward declaration to avoid including "error_code.h". +// Forward declaration to avoid including "otautil/error_code.h". enum ErrorCode : int; enum CauseCode : int; diff --git a/edify/lexer.ll b/edify/lexer.ll index cb4594371..4e04003b1 100644 --- a/edify/lexer.ll +++ b/edify/lexer.ll @@ -18,7 +18,7 @@ #include <string.h> #include <string> -#include "expr.h" +#include "edify/expr.h" #include "yydefs.h" #include "parser.h" diff --git a/edify/parser.yy b/edify/parser.yy index b1685eb1f..bd2e0105f 100644 --- a/edify/parser.yy +++ b/edify/parser.yy @@ -25,7 +25,7 @@ #include <android-base/macros.h> -#include "expr.h" +#include "edify/expr.h" #include "yydefs.h" #include "parser.h" diff --git a/install.cpp b/install.cpp index 74d1a68b3..d05893171 100644 --- a/install.cpp +++ b/install.cpp @@ -49,9 +49,9 @@ #include <ziparchive/zip_archive.h> #include "common.h" -#include "error_code.h" #include "otautil/SysUtil.h" #include "otautil/ThermalUtil.h" +#include "otautil/error_code.h" #include "private/install.h" #include "roots.h" #include "ui.h" diff --git a/minadbd/Android.mk b/minadbd/Android.mk index 8d86fd653..803171d99 100644 --- a/minadbd/Android.mk +++ b/minadbd/Android.mk @@ -1,13 +1,26 @@ # Copyright 2005 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. LOCAL_PATH:= $(call my-dir) minadbd_cflags := \ -Wall -Werror \ - -Wno-unused-parameter \ -Wno-missing-field-initializers \ -DADB_HOST=0 \ +# libadbd (static library) +# =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ @@ -24,6 +37,8 @@ LOCAL_STATIC_LIBRARIES := libcrypto libbase include $(BUILD_STATIC_LIBRARY) +# minadbd_test (native test) +# =============================== include $(CLEAR_VARS) LOCAL_MODULE := minadbd_test diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp index 61c06cc0a..9f0f1f87d 100644 --- a/minadbd/minadbd_services.cpp +++ b/minadbd/minadbd_services.cpp @@ -58,20 +58,20 @@ static int create_service_thread(void (*func)(int, const std::string&), const st return s[0]; } -int service_to_fd(const char* name, const atransport* transport) { - int ret = -1; +int service_to_fd(const char* name, const atransport* /* transport */) { + int ret = -1; - if (!strncmp(name, "sideload:", 9)) { - // this exit status causes recovery to print a special error - // message saying to use a newer adb (that supports - // sideload-host). - exit(3); - } else if (!strncmp(name, "sideload-host:", 14)) { - std::string arg(name + 14); - ret = create_service_thread(sideload_host_service, arg); - } - if (ret >= 0) { - close_on_exec(ret); - } - return ret; + if (!strncmp(name, "sideload:", 9)) { + // this exit status causes recovery to print a special error + // message saying to use a newer adb (that supports + // sideload-host). + exit(3); + } else if (!strncmp(name, "sideload-host:", 14)) { + std::string arg(name + 14); + ret = create_service_thread(sideload_host_service, arg); + } + if (ret >= 0) { + close_on_exec(ret); + } + return ret; } diff --git a/minui/Android.mk b/minui/Android.mk index 9a217a48f..ae1552b1b 100644 --- a/minui/Android.mk +++ b/minui/Android.mk @@ -13,6 +13,9 @@ # limitations under the License. LOCAL_PATH := $(call my-dir) + +# libminui (static library) +# =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := \ @@ -66,6 +69,8 @@ endif include $(BUILD_STATIC_LIBRARY) +# libminui (shared library) +# =============================== # Used by OEMs for factory test images. include $(CLEAR_VARS) LOCAL_MODULE := libminui diff --git a/minui/events.cpp b/minui/events.cpp index 24c2a8277..2894c3b6b 100644 --- a/minui/events.cpp +++ b/minui/events.cpp @@ -15,6 +15,7 @@ */ #include <dirent.h> +#include <errno.h> #include <fcntl.h> #include <linux/input.h> #include <stdio.h> diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 1308973a5..63ef18e26 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -26,6 +26,7 @@ #include <map> #include <mutex> +#include <string> #include <android-base/thread_annotations.h> diff --git a/otautil/Android.bp b/otautil/Android.bp index 9cde7baa7..5efb12d60 100644 --- a/otautil/Android.bp +++ b/otautil/Android.bp @@ -15,10 +15,13 @@ cc_library_static { name: "libotautil", + host_supported: true, + srcs: [ "SysUtil.cpp", "DirUtil.cpp", "ThermalUtil.cpp", + "rangeset.cpp", ], static_libs: [ @@ -27,6 +30,7 @@ cc_library_static { ], cflags: [ + "-D_FILE_OFFSET_BITS=64", "-Werror", "-Wall", ], diff --git a/otautil/SysUtil.cpp b/otautil/SysUtil.cpp index d54a824d2..48336ad07 100644 --- a/otautil/SysUtil.cpp +++ b/otautil/SysUtil.cpp @@ -16,6 +16,7 @@ #include "otautil/SysUtil.h" +#include <errno.h> // TEMP_FAILURE_RETRY #include <fcntl.h> #include <stdint.h> // SIZE_MAX #include <sys/mman.h> @@ -100,7 +101,7 @@ bool MemMapping::MapBlockFile(const std::string& filename) { } // Reserve enough contiguous address space for the whole file. - void* reserve = mmap64(nullptr, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + void* reserve = mmap(nullptr, blocks * blksize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); if (reserve == MAP_FAILED) { PLOG(ERROR) << "failed to reserve address space"; return false; @@ -135,8 +136,8 @@ bool MemMapping::MapBlockFile(const std::string& filename) { break; } - void* range_start = mmap64(next, range_size, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, - static_cast<off64_t>(start) * blksize); + void* range_start = mmap(next, range_size, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, + static_cast<off_t>(start) * blksize); if (range_start == MAP_FAILED) { PLOG(ERROR) << "failed to map range " << i << ": " << line; success = false; diff --git a/error_code.h b/otautil/include/otautil/error_code.h index 26b9bb40d..b0ff42d8d 100644 --- a/error_code.h +++ b/otautil/include/otautil/error_code.h @@ -75,4 +75,4 @@ enum UncryptErrorCode : int { kUncryptBlockDeviceFindError, }; -#endif // _ERROR_CODE_H_ +#endif // _ERROR_CODE_H_ diff --git a/print_sha1.h b/otautil/include/otautil/print_sha1.h index d0c18b355..03a8d292a 100644 --- a/print_sha1.h +++ b/otautil/include/otautil/print_sha1.h @@ -23,25 +23,25 @@ #include <openssl/sha.h> static std::string print_sha1(const uint8_t* sha1, size_t len) { - const char* hex = "0123456789abcdef"; - std::string result = ""; - for (size_t i = 0; i < len; ++i) { - result.push_back(hex[(sha1[i]>>4) & 0xf]); - result.push_back(hex[sha1[i] & 0xf]); - } - return result; + const char* hex = "0123456789abcdef"; + std::string result = ""; + for (size_t i = 0; i < len; ++i) { + result.push_back(hex[(sha1[i] >> 4) & 0xf]); + result.push_back(hex[sha1[i] & 0xf]); + } + return result; } [[maybe_unused]] static std::string print_sha1(const uint8_t sha1[SHA_DIGEST_LENGTH]) { - return print_sha1(sha1, SHA_DIGEST_LENGTH); + return print_sha1(sha1, SHA_DIGEST_LENGTH); } [[maybe_unused]] static std::string short_sha1(const uint8_t sha1[SHA_DIGEST_LENGTH]) { - return print_sha1(sha1, 4); + return print_sha1(sha1, 4); } [[maybe_unused]] static std::string print_hex(const uint8_t* bytes, size_t len) { - return print_sha1(bytes, len); + return print_sha1(bytes, len); } #endif // RECOVERY_PRINT_SHA1_H diff --git a/otautil/include/otautil/rangeset.h b/otautil/include/otautil/rangeset.h new file mode 100644 index 000000000..c4234d181 --- /dev/null +++ b/otautil/include/otautil/rangeset.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <stddef.h> + +#include <string> +#include <utility> +#include <vector> + +using Range = std::pair<size_t, size_t>; + +class RangeSet { + public: + RangeSet() : blocks_(0) {} + + explicit RangeSet(std::vector<Range>&& pairs); + + static RangeSet Parse(const std::string& range_text); + + std::string ToString() const; + + // Get the block number for the i-th (starting from 0) block in the RangeSet. + size_t GetBlockNumber(size_t idx) const; + + // RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" + // and "5,7" are not overlapped. + bool Overlaps(const RangeSet& other) const; + + // size() gives the number of Range's in this RangeSet. + size_t size() const { + return ranges_.size(); + } + + // blocks() gives the number of all blocks in this RangeSet. + size_t blocks() const { + return blocks_; + } + + // We provide const iterators only. + std::vector<Range>::const_iterator cbegin() const { + return ranges_.cbegin(); + } + + std::vector<Range>::const_iterator cend() const { + return ranges_.cend(); + } + + // Need to provide begin()/end() since range-based loop expects begin()/end(). + std::vector<Range>::const_iterator begin() const { + return ranges_.cbegin(); + } + + std::vector<Range>::const_iterator end() const { + return ranges_.cend(); + } + + // Reverse const iterators for MoveRange(). + std::vector<Range>::const_reverse_iterator crbegin() const { + return ranges_.crbegin(); + } + + std::vector<Range>::const_reverse_iterator crend() const { + return ranges_.crend(); + } + + const Range& operator[](size_t i) const { + return ranges_[i]; + } + + bool operator==(const RangeSet& other) const { + // The orders of Range's matter. "4,1,5,8,10" != "4,8,10,1,5". + return (ranges_ == other.ranges_); + } + + bool operator!=(const RangeSet& other) const { + return ranges_ != other.ranges_; + } + + protected: + // Actual limit for each value and the total number are both INT_MAX. + std::vector<Range> ranges_; + size_t blocks_; +}; + +// The class is a sorted version of a RangeSet; and it's useful in imgdiff to split the input +// files when we're handling large zip files. Specifically, we can treat the input file as a +// continuous RangeSet (i.e. RangeSet("0-99") for a 100 blocks file); and break it down into +// several smaller chunks based on the zip entries. + +// For example, [source: 0-99] can be split into +// [split_src1: 10-29]; [split_src2: 40-49, 60-69]; [split_src3: 70-89] +// Here "10-29" simply means block 10th to block 29th with respect to the original input file. +// Also, note that the split sources should be mutual exclusive, but they don't need to cover +// every block in the original source. +class SortedRangeSet : public RangeSet { + public: + SortedRangeSet() {} + + // Ranges in the the set should be mutually exclusive; and they're sorted by the start block. + explicit SortedRangeSet(std::vector<Range>&& pairs); + + void Insert(const Range& to_insert); + + // Insert the input SortedRangeSet; keep the ranges sorted and merge the overlap ranges. + void Insert(const SortedRangeSet& rs); + + // Compute the block range the file occupies, and insert that range. + void Insert(size_t start, size_t len); + + void Clear(); + + using RangeSet::Overlaps; + + bool Overlaps(size_t start, size_t len) const; + + // Given an offset of the file, checks if the corresponding block (by considering the file as + // 0-based continuous block ranges) is covered by the SortedRangeSet. If so, returns the offset + // within this SortedRangeSet. + // + // For example, the 4106-th byte of a file is from block 1, assuming a block size of 4096-byte. + // The mapped offset within a SortedRangeSet("1-9 15-19") is 10. + // + // An offset of 65546 falls into the 16-th block in a file. Block 16 is contained as the 10-th + // item in SortedRangeSet("1-9 15-19"). So its data can be found at offset 40970 (i.e. 4096 * 10 + // + 10) in a range represented by this SortedRangeSet. + size_t GetOffsetInRangeSet(size_t old_offset) const; +}; diff --git a/otautil/rangeset.cpp b/otautil/rangeset.cpp new file mode 100644 index 000000000..a121a4efc --- /dev/null +++ b/otautil/rangeset.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otautil/rangeset.h" + +#include <stddef.h> + +#include <string> +#include <utility> +#include <vector> + +#include <android-base/logging.h> +#include <android-base/parseint.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> + +RangeSet::RangeSet(std::vector<Range>&& pairs) { + CHECK_NE(pairs.size(), static_cast<size_t>(0)) << "Invalid number of tokens"; + + // Sanity check the input. + size_t result = 0; + for (const auto& range : pairs) { + CHECK_LT(range.first, range.second) << "Empty or negative range: " << range.first << ", " + << range.second; + size_t sz = range.second - range.first; + CHECK_LE(result, SIZE_MAX - sz) << "RangeSet size overflow"; + result += sz; + } + + ranges_ = pairs; + blocks_ = result; +} + +RangeSet RangeSet::Parse(const std::string& range_text) { + std::vector<std::string> pieces = android::base::Split(range_text, ","); + CHECK_GE(pieces.size(), static_cast<size_t>(3)) << "Invalid range text: " << range_text; + + size_t num; + CHECK(android::base::ParseUint(pieces[0], &num, static_cast<size_t>(INT_MAX))) + << "Failed to parse the number of tokens: " << range_text; + + CHECK_NE(num, static_cast<size_t>(0)) << "Invalid number of tokens: " << range_text; + CHECK_EQ(num % 2, static_cast<size_t>(0)) << "Number of tokens must be even: " << range_text; + CHECK_EQ(num, pieces.size() - 1) << "Mismatching number of tokens: " << range_text; + + std::vector<Range> pairs; + for (size_t i = 0; i < num; i += 2) { + size_t first; + CHECK(android::base::ParseUint(pieces[i + 1], &first, static_cast<size_t>(INT_MAX))); + size_t second; + CHECK(android::base::ParseUint(pieces[i + 2], &second, static_cast<size_t>(INT_MAX))); + + pairs.emplace_back(first, second); + } + + return RangeSet(std::move(pairs)); +} + +std::string RangeSet::ToString() const { + if (ranges_.empty()) { + return ""; + } + std::string result = std::to_string(ranges_.size() * 2); + for (const auto& r : ranges_) { + result += android::base::StringPrintf(",%zu,%zu", r.first, r.second); + } + + return result; +} + +// Get the block number for the i-th (starting from 0) block in the RangeSet. +size_t RangeSet::GetBlockNumber(size_t idx) const { + CHECK_LT(idx, blocks_) << "Out of bound index " << idx << " (total blocks: " << blocks_ << ")"; + + for (const auto& range : ranges_) { + if (idx < range.second - range.first) { + return range.first + idx; + } + idx -= (range.second - range.first); + } + + CHECK(false) << "Failed to find block number for index " << idx; + return 0; // Unreachable, but to make compiler happy. +} + +// RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" +// and "5,7" are not overlapped. +bool RangeSet::Overlaps(const RangeSet& other) const { + for (const auto& range : ranges_) { + size_t start = range.first; + size_t end = range.second; + for (const auto& other_range : other.ranges_) { + size_t other_start = other_range.first; + size_t other_end = other_range.second; + // [start, end) vs [other_start, other_end) + if (!(other_start >= end || start >= other_end)) { + return true; + } + } + } + return false; +} + +static constexpr size_t kBlockSize = 4096; + +// Ranges in the the set should be mutually exclusive; and they're sorted by the start block. +SortedRangeSet::SortedRangeSet(std::vector<Range>&& pairs) : RangeSet(std::move(pairs)) { + std::sort(ranges_.begin(), ranges_.end()); +} + +void SortedRangeSet::Insert(const Range& to_insert) { + SortedRangeSet rs({ to_insert }); + Insert(rs); +} + +// Insert the input SortedRangeSet; keep the ranges sorted and merge the overlap ranges. +void SortedRangeSet::Insert(const SortedRangeSet& rs) { + if (rs.size() == 0) { + return; + } + // Merge and sort the two RangeSets. + std::vector<Range> temp = std::move(ranges_); + std::copy(rs.begin(), rs.end(), std::back_inserter(temp)); + std::sort(temp.begin(), temp.end()); + + Clear(); + // Trim overlaps and insert the result back to ranges_. + Range to_insert = temp.front(); + for (auto it = temp.cbegin() + 1; it != temp.cend(); it++) { + if (it->first <= to_insert.second) { + to_insert.second = std::max(to_insert.second, it->second); + } else { + ranges_.push_back(to_insert); + blocks_ += (to_insert.second - to_insert.first); + to_insert = *it; + } + } + ranges_.push_back(to_insert); + blocks_ += (to_insert.second - to_insert.first); +} + +// Compute the block range the file occupies, and insert that range. +void SortedRangeSet::Insert(size_t start, size_t len) { + Range to_insert{ start / kBlockSize, (start + len - 1) / kBlockSize + 1 }; + Insert(to_insert); +} + +void SortedRangeSet::Clear() { + blocks_ = 0; + ranges_.clear(); +} + +bool SortedRangeSet::Overlaps(size_t start, size_t len) const { + RangeSet rs({ { start / kBlockSize, (start + len - 1) / kBlockSize + 1 } }); + return Overlaps(rs); +} + +// Given an offset of the file, checks if the corresponding block (by considering the file as +// 0-based continuous block ranges) is covered by the SortedRangeSet. If so, returns the offset +// within this SortedRangeSet. +// +// For example, the 4106-th byte of a file is from block 1, assuming a block size of 4096-byte. +// The mapped offset within a SortedRangeSet("1-9 15-19") is 10. +// +// An offset of 65546 falls into the 16-th block in a file. Block 16 is contained as the 10-th +// item in SortedRangeSet("1-9 15-19"). So its data can be found at offset 40970 (i.e. 4096 * 10 +// + 10) in a range represented by this SortedRangeSet. +size_t SortedRangeSet::GetOffsetInRangeSet(size_t old_offset) const { + size_t old_block_start = old_offset / kBlockSize; + size_t new_block_start = 0; + for (const auto& range : ranges_) { + // Find the index of old_block_start. + if (old_block_start >= range.second) { + new_block_start += (range.second - range.first); + } else if (old_block_start >= range.first) { + new_block_start += (old_block_start - range.first); + return (new_block_start * kBlockSize + old_offset % kBlockSize); + } else { + CHECK(false) << "block_start " << old_block_start + << " is missing between two ranges: " << this->ToString(); + return 0; + } + } + CHECK(false) << "block_start " << old_block_start + << " exceeds the limit of current RangeSet: " << this->ToString(); + return 0; +} diff --git a/rangeset.h b/rangeset.h deleted file mode 100644 index f224a08be..000000000 --- a/rangeset.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stddef.h> - -#include <string> -#include <utility> -#include <vector> - -#include <android-base/logging.h> -#include <android-base/parseint.h> -#include <android-base/stringprintf.h> -#include <android-base/strings.h> - -using Range = std::pair<size_t, size_t>; - -class RangeSet { - public: - RangeSet() : blocks_(0) {} - - explicit RangeSet(std::vector<Range>&& pairs) { - CHECK_NE(pairs.size(), static_cast<size_t>(0)) << "Invalid number of tokens"; - - // Sanity check the input. - size_t result = 0; - for (const auto& range : pairs) { - CHECK_LT(range.first, range.second) - << "Empty or negative range: " << range.first << ", " << range.second; - size_t sz = range.second - range.first; - CHECK_LE(result, SIZE_MAX - sz) << "RangeSet size overflow"; - result += sz; - } - - ranges_ = pairs; - blocks_ = result; - } - - static RangeSet Parse(const std::string& range_text) { - std::vector<std::string> pieces = android::base::Split(range_text, ","); - CHECK_GE(pieces.size(), static_cast<size_t>(3)) << "Invalid range text: " << range_text; - - size_t num; - CHECK(android::base::ParseUint(pieces[0], &num, static_cast<size_t>(INT_MAX))) - << "Failed to parse the number of tokens: " << range_text; - - CHECK_NE(num, static_cast<size_t>(0)) << "Invalid number of tokens: " << range_text; - CHECK_EQ(num % 2, static_cast<size_t>(0)) << "Number of tokens must be even: " << range_text; - CHECK_EQ(num, pieces.size() - 1) << "Mismatching number of tokens: " << range_text; - - std::vector<Range> pairs; - for (size_t i = 0; i < num; i += 2) { - size_t first; - CHECK(android::base::ParseUint(pieces[i + 1], &first, static_cast<size_t>(INT_MAX))); - size_t second; - CHECK(android::base::ParseUint(pieces[i + 2], &second, static_cast<size_t>(INT_MAX))); - - pairs.emplace_back(first, second); - } - - return RangeSet(std::move(pairs)); - } - - std::string ToString() const { - if (ranges_.empty()) { - return ""; - } - std::string result = std::to_string(ranges_.size() * 2); - for (const auto& r : ranges_) { - result += android::base::StringPrintf(",%zu,%zu", r.first, r.second); - } - - return result; - } - - // Get the block number for the i-th (starting from 0) block in the RangeSet. - size_t GetBlockNumber(size_t idx) const { - CHECK_LT(idx, blocks_) << "Out of bound index " << idx << " (total blocks: " << blocks_ << ")"; - - for (const auto& range : ranges_) { - if (idx < range.second - range.first) { - return range.first + idx; - } - idx -= (range.second - range.first); - } - - CHECK(false) << "Failed to find block number for index " << idx; - return 0; // Unreachable, but to make compiler happy. - } - - // RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" - // and "5,7" are not overlapped. - bool Overlaps(const RangeSet& other) const { - for (const auto& range : ranges_) { - size_t start = range.first; - size_t end = range.second; - for (const auto& other_range : other.ranges_) { - size_t other_start = other_range.first; - size_t other_end = other_range.second; - // [start, end) vs [other_start, other_end) - if (!(other_start >= end || start >= other_end)) { - return true; - } - } - } - return false; - } - - // size() gives the number of Range's in this RangeSet. - size_t size() const { - return ranges_.size(); - } - - // blocks() gives the number of all blocks in this RangeSet. - size_t blocks() const { - return blocks_; - } - - // We provide const iterators only. - std::vector<Range>::const_iterator cbegin() const { - return ranges_.cbegin(); - } - - std::vector<Range>::const_iterator cend() const { - return ranges_.cend(); - } - - // Need to provide begin()/end() since range-based loop expects begin()/end(). - std::vector<Range>::const_iterator begin() const { - return ranges_.cbegin(); - } - - std::vector<Range>::const_iterator end() const { - return ranges_.cend(); - } - - // Reverse const iterators for MoveRange(). - std::vector<Range>::const_reverse_iterator crbegin() const { - return ranges_.crbegin(); - } - - std::vector<Range>::const_reverse_iterator crend() const { - return ranges_.crend(); - } - - const Range& operator[](size_t i) const { - return ranges_[i]; - } - - bool operator==(const RangeSet& other) const { - // The orders of Range's matter. "4,1,5,8,10" != "4,8,10,1,5". - return (ranges_ == other.ranges_); - } - - bool operator!=(const RangeSet& other) const { - return ranges_ != other.ranges_; - } - - protected: - // Actual limit for each value and the total number are both INT_MAX. - std::vector<Range> ranges_; - size_t blocks_; -}; - -static constexpr size_t kBlockSize = 4096; - -// The class is a sorted version of a RangeSet; and it's useful in imgdiff to split the input -// files when we're handling large zip files. Specifically, we can treat the input file as a -// continuous RangeSet (i.e. RangeSet("0-99") for a 100 blocks file); and break it down into -// several smaller chunks based on the zip entries. - -// For example, [source: 0-99] can be split into -// [split_src1: 10-29]; [split_src2: 40-49, 60-69]; [split_src3: 70-89] -// Here "10-29" simply means block 10th to block 29th with respect to the original input file. -// Also, note that the split sources should be mutual exclusive, but they don't need to cover -// every block in the original source. -class SortedRangeSet : public RangeSet { - public: - SortedRangeSet() {} - - // Ranges in the the set should be mutually exclusive; and they're sorted by the start block. - explicit SortedRangeSet(std::vector<Range>&& pairs) : RangeSet(std::move(pairs)) { - std::sort(ranges_.begin(), ranges_.end()); - } - - void Insert(const Range& to_insert) { - SortedRangeSet rs({ to_insert }); - Insert(rs); - } - - // Insert the input SortedRangeSet; keep the ranges sorted and merge the overlap ranges. - void Insert(const SortedRangeSet& rs) { - if (rs.size() == 0) { - return; - } - // Merge and sort the two RangeSets. - std::vector<Range> temp = std::move(ranges_); - std::copy(rs.begin(), rs.end(), std::back_inserter(temp)); - std::sort(temp.begin(), temp.end()); - - Clear(); - // Trim overlaps and insert the result back to ranges_. - Range to_insert = temp.front(); - for (auto it = temp.cbegin() + 1; it != temp.cend(); it++) { - if (it->first <= to_insert.second) { - to_insert.second = std::max(to_insert.second, it->second); - } else { - ranges_.push_back(to_insert); - blocks_ += (to_insert.second - to_insert.first); - to_insert = *it; - } - } - ranges_.push_back(to_insert); - blocks_ += (to_insert.second - to_insert.first); - } - - void Clear() { - blocks_ = 0; - ranges_.clear(); - } - - using RangeSet::Overlaps; - bool Overlaps(size_t start, size_t len) const { - RangeSet rs({ { start / kBlockSize, (start + len - 1) / kBlockSize + 1 } }); - return Overlaps(rs); - } - - // Compute the block range the file occupies, and insert that range. - void Insert(size_t start, size_t len) { - Range to_insert{ start / kBlockSize, (start + len - 1) / kBlockSize + 1 }; - Insert(to_insert); - } - - // Given an offset of the file, checks if the corresponding block (by considering the file as - // 0-based continuous block ranges) is covered by the SortedRangeSet. If so, returns the offset - // within this SortedRangeSet. - // - // For example, the 4106-th byte of a file is from block 1, assuming a block size of 4096-byte. - // The mapped offset within a SortedRangeSet("1-9 15-19") is 10. - // - // An offset of 65546 falls into the 16-th block in a file. Block 16 is contained as the 10-th - // item in SortedRangeSet("1-9 15-19"). So its data can be found at offset 40970 (i.e. 4096 * 10 - // + 10) in a range represented by this SortedRangeSet. - size_t GetOffsetInRangeSet(size_t old_offset) const { - size_t old_block_start = old_offset / kBlockSize; - size_t new_block_start = 0; - for (const auto& range : ranges_) { - // Find the index of old_block_start. - if (old_block_start >= range.second) { - new_block_start += (range.second - range.first); - } else if (old_block_start >= range.first) { - new_block_start += (old_block_start - range.first); - return (new_block_start * kBlockSize + old_offset % kBlockSize); - } else { - CHECK(false) << "block_start " << old_block_start - << " is missing between two ranges: " << this->ToString(); - return 0; - } - } - CHECK(false) << "block_start " << old_block_start - << " exceeds the limit of current RangeSet: " << this->ToString(); - return 0; - } -};
\ No newline at end of file diff --git a/recovery.cpp b/recovery.cpp index 4dc5b540e..a89916337 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -61,13 +61,13 @@ #include "adb_install.h" #include "common.h" #include "device.h" -#include "error_code.h" #include "fuse_sdcard_provider.h" #include "fuse_sideload.h" #include "install.h" #include "minadbd/minadbd.h" #include "minui/minui.h" #include "otautil/DirUtil.h" +#include "otautil/error_code.h" #include "roots.h" #include "rotate_logs.h" #include "screen_ui.h" @@ -1214,9 +1214,8 @@ static Device::BuiltinAction prompt_and_wait(Device* device, int status) { } } -static void -print_property(const char *key, const char *name, void *cookie) { - printf("%s=%s\n", key, name); +static void print_property(const char* key, const char* name, void* /* cookie */) { + printf("%s=%s\n", key, name); } static std::string load_locale_from_cache() { @@ -1250,14 +1249,14 @@ void ui_print(const char* format, ...) { static constexpr char log_characters[] = "VDIWEF"; -void UiLogger(android::base::LogId id, android::base::LogSeverity severity, - const char* tag, const char* file, unsigned int line, - const char* message) { - if (severity >= android::base::ERROR && ui != nullptr) { - ui->Print("E:%s\n", message); - } else { - fprintf(stdout, "%c:%s\n", log_characters[severity], message); - } +void UiLogger(android::base::LogId /* id */, android::base::LogSeverity severity, + const char* /* tag */, const char* /* file */, unsigned int /* line */, + const char* message) { + if (severity >= android::base::ERROR && ui != nullptr) { + ui->Print("E:%s\n", message); + } else { + fprintf(stdout, "%c:%s\n", log_characters[severity], message); + } } static bool is_battery_ok() { diff --git a/rotate_logs.cpp b/rotate_logs.cpp index fc220215e..da008792c 100644 --- a/rotate_logs.cpp +++ b/rotate_logs.cpp @@ -31,85 +31,77 @@ static const std::string LAST_KMSG_FILTER = "recovery/last_kmsg"; static const std::string LAST_LOG_FILTER = "recovery/last_log"; -ssize_t logbasename( - log_id_t /* logId */, - char /* prio */, - const char *filename, - const char * /* buf */, size_t len, - void *arg) { - bool* doRotate = static_cast<bool*>(arg); - if (LAST_KMSG_FILTER.find(filename) != std::string::npos || - LAST_LOG_FILTER.find(filename) != std::string::npos) { - *doRotate = true; - } - return len; +ssize_t logbasename(log_id_t /* id */, char /* prio */, const char* filename, const char* /* buf */, + size_t len, void* arg) { + bool* do_rotate = static_cast<bool*>(arg); + if (LAST_KMSG_FILTER.find(filename) != std::string::npos || + LAST_LOG_FILTER.find(filename) != std::string::npos) { + *do_rotate = true; + } + return len; } -ssize_t logrotate( - log_id_t logId, - char prio, - const char *filename, - const char *buf, size_t len, - void *arg) { - bool* doRotate = static_cast<bool*>(arg); - if (!*doRotate) { - return __android_log_pmsg_file_write(logId, prio, filename, buf, len); - } +ssize_t logrotate(log_id_t id, char prio, const char* filename, const char* buf, size_t len, + void* arg) { + bool* do_rotate = static_cast<bool*>(arg); + if (!*do_rotate) { + return __android_log_pmsg_file_write(id, prio, filename, buf, len); + } - std::string name(filename); - size_t dot = name.find_last_of('.'); - std::string sub = name.substr(0, dot); + std::string name(filename); + size_t dot = name.find_last_of('.'); + std::string sub = name.substr(0, dot); - if (LAST_KMSG_FILTER.find(sub) == std::string::npos && - LAST_LOG_FILTER.find(sub) == std::string::npos) { - return __android_log_pmsg_file_write(logId, prio, filename, buf, len); - } + if (LAST_KMSG_FILTER.find(sub) == std::string::npos && + LAST_LOG_FILTER.find(sub) == std::string::npos) { + return __android_log_pmsg_file_write(id, prio, filename, buf, len); + } - // filename rotation - if (dot == std::string::npos) { - name += ".1"; + // filename rotation + if (dot == std::string::npos) { + name += ".1"; + } else { + std::string number = name.substr(dot + 1); + if (!isdigit(number[0])) { + name += ".1"; } else { - std::string number = name.substr(dot + 1); - if (!isdigit(number[0])) { - name += ".1"; - } else { - size_t i; - if (!android::base::ParseUint(number, &i)) { - LOG(ERROR) << "failed to parse uint in " << number; - return -1; - } - name = sub + "." + std::to_string(i + 1); - } + size_t i; + if (!android::base::ParseUint(number, &i)) { + LOG(ERROR) << "failed to parse uint in " << number; + return -1; + } + name = sub + "." + std::to_string(i + 1); } + } - return __android_log_pmsg_file_write(logId, prio, name.c_str(), buf, len); + return __android_log_pmsg_file_write(id, prio, name.c_str(), buf, len); } // Rename last_log -> last_log.1 -> last_log.2 -> ... -> last_log.$max. // Similarly rename last_kmsg -> last_kmsg.1 -> ... -> last_kmsg.$max. // Overwrite any existing last_log.$max and last_kmsg.$max. void rotate_logs(const char* last_log_file, const char* last_kmsg_file) { - // Logs should only be rotated once. - static bool rotated = false; - if (rotated) { - return; - } - rotated = true; + // Logs should only be rotated once. + static bool rotated = false; + if (rotated) { + return; + } + rotated = true; - for (int i = KEEP_LOG_COUNT - 1; i >= 0; --i) { - std::string old_log = android::base::StringPrintf("%s", last_log_file); - if (i > 0) { - old_log += "." + std::to_string(i); - } - std::string new_log = android::base::StringPrintf("%s.%d", last_log_file, i+1); - // Ignore errors if old_log doesn't exist. - rename(old_log.c_str(), new_log.c_str()); + for (int i = KEEP_LOG_COUNT - 1; i >= 0; --i) { + std::string old_log = android::base::StringPrintf("%s", last_log_file); + if (i > 0) { + old_log += "." + std::to_string(i); + } + std::string new_log = android::base::StringPrintf("%s.%d", last_log_file, i + 1); + // Ignore errors if old_log doesn't exist. + rename(old_log.c_str(), new_log.c_str()); - std::string old_kmsg = android::base::StringPrintf("%s", last_kmsg_file); - if (i > 0) { - old_kmsg += "." + std::to_string(i); - } - std::string new_kmsg = android::base::StringPrintf("%s.%d", last_kmsg_file, i+1); - rename(old_kmsg.c_str(), new_kmsg.c_str()); + std::string old_kmsg = android::base::StringPrintf("%s", last_kmsg_file); + if (i > 0) { + old_kmsg += "." + std::to_string(i); } + std::string new_kmsg = android::base::StringPrintf("%s.%d", last_kmsg_file, i + 1); + rename(old_kmsg.c_str(), new_kmsg.c_str()); + } } diff --git a/rotate_logs.h b/rotate_logs.h index 809c213b6..007c33d44 100644 --- a/rotate_logs.h +++ b/rotate_logs.h @@ -17,24 +17,18 @@ #ifndef _ROTATE_LOGS_H #define _ROTATE_LOGS_H -#include <string> +#include <stddef.h> +#include <sys/types.h> -#include <private/android_logger.h> /* private pmsg functions */ +#include <log/log_id.h> -constexpr int KEEP_LOG_COUNT = 10; +static constexpr int KEEP_LOG_COUNT = 10; -ssize_t logbasename(log_id_t /* logId */, - char /* prio */, - const char *filename, - const char * /* buf */, size_t len, - void *arg); +ssize_t logbasename(log_id_t id, char prio, const char* filename, const char* buf, size_t len, + void* arg); -ssize_t logrotate( - log_id_t logId, - char prio, - const char *filename, - const char *buf, size_t len, - void *arg); +ssize_t logrotate(log_id_t id, char prio, const char* filename, const char* buf, size_t len, + void* arg); // Rename last_log -> last_log.1 -> last_log.2 -> ... -> last_log.$max. // Similarly rename last_kmsg -> last_kmsg.1 -> ... -> last_kmsg.$max. @@ -24,18 +24,18 @@ class StubRecoveryUI : public RecoveryUI { public: StubRecoveryUI() = default; - void SetBackground(Icon icon) override {} - void SetSystemUpdateText(bool security_update) override {} + void SetBackground(Icon /* icon */) override {} + void SetSystemUpdateText(bool /* security_update */) override {} // progress indicator - void SetProgressType(ProgressType type) override {} - void ShowProgress(float portion, float seconds) override {} - void SetProgress(float fraction) override {} + void SetProgressType(ProgressType /* type */) override {} + void ShowProgress(float /* portion */, float /* seconds */) override {} + void SetProgress(float /* fraction */) override {} - void SetStage(int current, int max) override {} + void SetStage(int /* current */, int /* max */) override {} // text log - void ShowText(bool visible) override {} + void ShowText(bool /* visible */) override {} bool IsTextVisible() override { return false; } @@ -50,12 +50,12 @@ class StubRecoveryUI : public RecoveryUI { vprintf(fmt, ap); va_end(ap); } - void PrintOnScreenOnly(const char* fmt, ...) override {} - void ShowFile(const char* filename) override {} + void PrintOnScreenOnly(const char* /* fmt */, ...) override {} + void ShowFile(const char* /* filename */) override {} // menu display - void StartMenu(const char* const* headers, const char* const* items, - int initial_selection) override {} + void StartMenu(const char* const* /* headers */, const char* const* /* items */, + int /* initial_selection */) override {} int SelectMenu(int sel) override { return sel; } diff --git a/tests/Android.mk b/tests/Android.mk index 31c7de177..b0f71a832 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -201,6 +201,7 @@ LOCAL_SRC_FILES := \ LOCAL_STATIC_LIBRARIES := \ libimgdiff \ libimgpatch \ + libotautil \ libbsdiff \ libbspatch \ libziparchive \ diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp index 42542898b..15ec08fe7 100644 --- a/tests/component/applypatch_test.cpp +++ b/tests/component/applypatch_test.cpp @@ -35,7 +35,7 @@ #include "applypatch/applypatch.h" #include "applypatch/applypatch_modes.h" #include "common/test_constants.h" -#include "print_sha1.h" +#include "otautil/print_sha1.h" static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize = nullptr) { ASSERT_NE(nullptr, sha1); diff --git a/tests/component/imgdiff_test.cpp b/tests/component/imgdiff_test.cpp index 161d58d45..bf591dae4 100644 --- a/tests/component/imgdiff_test.cpp +++ b/tests/component/imgdiff_test.cpp @@ -24,6 +24,7 @@ #include <android-base/file.h> #include <android-base/memory.h> #include <android-base/stringprintf.h> +#include <android-base/strings.h> #include <android-base/test_utils.h> #include <applypatch/imgdiff.h> #include <applypatch/imgdiff_image.h> diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp index 19653ec50..d9d01d427 100644 --- a/tests/component/updater_test.cpp +++ b/tests/component/updater_test.cpp @@ -23,6 +23,7 @@ #include <algorithm> #include <memory> #include <string> +#include <unordered_map> #include <vector> #include <android-base/file.h> @@ -39,9 +40,9 @@ #include "common/test_constants.h" #include "edify/expr.h" -#include "error_code.h" #include "otautil/SysUtil.h" -#include "print_sha1.h" +#include "otautil/error_code.h" +#include "otautil/print_sha1.h" #include "updater/blockimg.h" #include "updater/install.h" #include "updater/updater.h" @@ -74,6 +75,23 @@ static void expect(const char* expected, const char* expr_str, CauseCode cause_c ASSERT_EQ(cause_code, state.cause_code); } +static void BuildUpdatePackage(const std::unordered_map<std::string, std::string>& entries, + int fd) { + FILE* zip_file_ptr = fdopen(fd, "wb"); + ZipWriter zip_writer(zip_file_ptr); + + for (const auto& entry : entries) { + ASSERT_EQ(0, zip_writer.StartEntry(entry.first.c_str(), 0)); + if (!entry.second.empty()) { + ASSERT_EQ(0, zip_writer.WriteBytes(entry.second.data(), entry.second.size())); + } + ASSERT_EQ(0, zip_writer.FinishEntry()); + } + + ASSERT_EQ(0, zip_writer.Finish()); + ASSERT_EQ(0, fclose(zip_file_ptr)); +} + static std::string get_sha1(const std::string& content) { uint8_t digest[SHA_DIGEST_LENGTH]; SHA1(reinterpret_cast<const uint8_t*>(content.c_str()), content.size(), digest); @@ -420,30 +438,19 @@ TEST_F(UpdaterTest, show_progress) { ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); } -TEST_F(UpdaterTest, block_image_update) { - // Create a zip file with new_data and patch_data. - TemporaryFile zip_file; - FILE* zip_file_ptr = fdopen(zip_file.release(), "wb"); - ZipWriter zip_writer(zip_file_ptr); - - // Add a dummy new data. - ASSERT_EQ(0, zip_writer.StartEntry("new_data", 0)); - ASSERT_EQ(0, zip_writer.FinishEntry()); - - // Generate and add the patch data. +TEST_F(UpdaterTest, block_image_update_patch_data) { std::string src_content = std::string(4096, 'a') + std::string(4096, 'c'); std::string tgt_content = std::string(4096, 'b') + std::string(4096, 'd'); + + // Generate the patch data. TemporaryFile patch_file; ASSERT_EQ(0, bsdiff::bsdiff(reinterpret_cast<const uint8_t*>(src_content.data()), src_content.size(), reinterpret_cast<const uint8_t*>(tgt_content.data()), tgt_content.size(), patch_file.path, nullptr)); std::string patch_content; ASSERT_TRUE(android::base::ReadFileToString(patch_file.path, &patch_content)); - ASSERT_EQ(0, zip_writer.StartEntry("patch_data", 0)); - ASSERT_EQ(0, zip_writer.WriteBytes(patch_content.data(), patch_content.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Add two transfer lists. The first one contains a bsdiff; and we expect the update to succeed. + // Create the transfer list that contains a bsdiff. std::string src_hash = get_sha1(src_content); std::string tgt_hash = get_sha1(tgt_content); std::vector<std::string> transfer_list = { @@ -456,27 +463,16 @@ TEST_F(UpdaterTest, block_image_update) { src_hash.c_str(), tgt_hash.c_str(), src_hash.c_str()), "free " + src_hash, }; - ASSERT_EQ(0, zip_writer.StartEntry("transfer_list", 0)); - std::string commands = android::base::Join(transfer_list, '\n'); - ASSERT_EQ(0, zip_writer.WriteBytes(commands.data(), commands.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Stash and free some blocks, then fail the 2nd update intentionally. - std::vector<std::string> fail_transfer_list = { - "4", - "2", - "0", - "2", - "stash " + tgt_hash + " 2,0,2", - "free " + tgt_hash, - "fail", + std::unordered_map<std::string, std::string> entries = { + { "new_data", "" }, + { "patch_data", patch_content }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, }; - ASSERT_EQ(0, zip_writer.StartEntry("fail_transfer_list", 0)); - std::string fail_commands = android::base::Join(fail_transfer_list, '\n'); - ASSERT_EQ(0, zip_writer.WriteBytes(fail_commands.data(), fail_commands.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - ASSERT_EQ(0, zip_writer.Finish()); - ASSERT_EQ(0, fclose(zip_file_ptr)); + + // Build the update package. + TemporaryFile zip_file; + BuildUpdatePackage(entries, zip_file.release()); MemMapping map; ASSERT_TRUE(map.MapFile(zip_file.path)); @@ -491,7 +487,7 @@ TEST_F(UpdaterTest, block_image_update) { updater_info.package_zip_addr = map.addr; updater_info.package_zip_len = map.length; - // Execute the commands in the 1st transfer list. + // Execute the commands in the transfer list. TemporaryFile update_file; ASSERT_TRUE(android::base::WriteStringToFile(src_content, update_file.path)); std::string script = "block_image_update(\"" + std::string(update_file.path) + @@ -502,44 +498,98 @@ TEST_F(UpdaterTest, block_image_update) { ASSERT_TRUE(android::base::ReadFileToString(update_file.path, &updated_content)); ASSERT_EQ(tgt_hash, get_sha1(updated_content)); - // Expect the 2nd update to fail, but expect the stashed blocks to be freed. - script = "block_image_update(\"" + std::string(update_file.path) + - R"(", package_extract_file("fail_transfer_list"), "new_data", "patch_data"))"; + ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); + CloseArchive(handle); +} + +TEST_F(UpdaterTest, block_image_update_fail) { + std::string src_content(4096 * 2, 'e'); + std::string src_hash = get_sha1(src_content); + // Stash and free some blocks, then fail the update intentionally. + std::vector<std::string> transfer_list = { + "4", "2", "0", "2", "stash " + src_hash + " 2,0,2", "free " + src_hash, "fail", + }; + + // Add a new data of 10 bytes to test the deadlock. + std::unordered_map<std::string, std::string> entries = { + { "new_data", std::string(10, 0) }, + { "patch_data", "" }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, + }; + + // Build the update package. + TemporaryFile zip_file; + BuildUpdatePackage(entries, zip_file.release()); + + MemMapping map; + ASSERT_TRUE(map.MapFile(zip_file.path)); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); + + // Set up the handler, command_pipe, patch offset & length. + UpdaterInfo updater_info; + updater_info.package_zip = handle; + TemporaryFile temp_pipe; + updater_info.cmd_pipe = fdopen(temp_pipe.release(), "wbe"); + updater_info.package_zip_addr = map.addr; + updater_info.package_zip_len = map.length; + + TemporaryFile update_file; + ASSERT_TRUE(android::base::WriteStringToFile(src_content, update_file.path)); + // Expect the stashed blocks to be freed. + std::string script = "block_image_update(\"" + std::string(update_file.path) + + R"(", package_extract_file("transfer_list"), "new_data", "patch_data"))"; expect("", script.c_str(), kNoCause, &updater_info); // Updater generates the stash name based on the input file name. std::string name_digest = get_sha1(update_file.path); std::string stash_base = "/cache/recovery/" + name_digest; ASSERT_EQ(0, access(stash_base.c_str(), F_OK)); - ASSERT_EQ(-1, access((stash_base + tgt_hash).c_str(), F_OK)); + ASSERT_EQ(-1, access((stash_base + src_hash).c_str(), F_OK)); ASSERT_EQ(0, rmdir(stash_base.c_str())); ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); CloseArchive(handle); } -TEST_F(UpdaterTest, new_data_short_write) { - // Create a zip file with new_data. +TEST_F(UpdaterTest, new_data_over_write) { + std::vector<std::string> transfer_list = { + "4", "1", "0", "0", "new 2,0,1", + }; + + // Write 4096 + 100 bytes of new data. + std::unordered_map<std::string, std::string> entries = { + { "new_data", std::string(4196, 0) }, + { "patch_data", "" }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, + }; + + // Build the update package. TemporaryFile zip_file; - FILE* zip_file_ptr = fdopen(zip_file.release(), "wb"); - ZipWriter zip_writer(zip_file_ptr); + BuildUpdatePackage(entries, zip_file.release()); + + MemMapping map; + ASSERT_TRUE(map.MapFile(zip_file.path)); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_file.path, &handle)); - // Add the empty new data. - ASSERT_EQ(0, zip_writer.StartEntry("empty_new_data", 0)); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Add the short written new data. - ASSERT_EQ(0, zip_writer.StartEntry("short_new_data", 0)); - std::string new_data_short = std::string(10, 'a'); - ASSERT_EQ(0, zip_writer.WriteBytes(new_data_short.data(), new_data_short.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Add the data of exactly one block. - ASSERT_EQ(0, zip_writer.StartEntry("exact_new_data", 0)); - std::string new_data_exact = std::string(4096, 'a'); - ASSERT_EQ(0, zip_writer.WriteBytes(new_data_exact.data(), new_data_exact.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Add a dummy patch data. - ASSERT_EQ(0, zip_writer.StartEntry("patch_data", 0)); - ASSERT_EQ(0, zip_writer.FinishEntry()); + // Set up the handler, command_pipe, patch offset & length. + UpdaterInfo updater_info; + updater_info.package_zip = handle; + TemporaryFile temp_pipe; + updater_info.cmd_pipe = fdopen(temp_pipe.release(), "wbe"); + updater_info.package_zip_addr = map.addr; + updater_info.package_zip_len = map.length; + TemporaryFile update_file; + std::string script = "block_image_update(\"" + std::string(update_file.path) + + R"(", package_extract_file("transfer_list"), "new_data", "patch_data"))"; + expect("t", script.c_str(), kNoCause, &updater_info); + + ASSERT_EQ(0, fclose(updater_info.cmd_pipe)); + CloseArchive(handle); +} + +TEST_F(UpdaterTest, new_data_short_write) { std::vector<std::string> transfer_list = { "4", "1", @@ -547,12 +597,17 @@ TEST_F(UpdaterTest, new_data_short_write) { "0", "new 2,0,1", }; - ASSERT_EQ(0, zip_writer.StartEntry("transfer_list", 0)); - std::string commands = android::base::Join(transfer_list, '\n'); - ASSERT_EQ(0, zip_writer.WriteBytes(commands.data(), commands.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - ASSERT_EQ(0, zip_writer.Finish()); - ASSERT_EQ(0, fclose(zip_file_ptr)); + + std::unordered_map<std::string, std::string> entries = { + { "empty_new_data", "" }, + { "short_new_data", std::string(10, 'a') }, + { "exact_new_data", std::string(4096, 'a') }, + { "patch_data", "" }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, + }; + + TemporaryFile zip_file; + BuildUpdatePackage(entries, zip_file.release()); MemMapping map; ASSERT_TRUE(map.MapFile(zip_file.path)); @@ -587,14 +642,6 @@ TEST_F(UpdaterTest, new_data_short_write) { } TEST_F(UpdaterTest, brotli_new_data) { - // Create a zip file with new_data. - TemporaryFile zip_file; - FILE* zip_file_ptr = fdopen(zip_file.release(), "wb"); - ZipWriter zip_writer(zip_file_ptr); - - // Add a brotli compressed new data entry. - ASSERT_EQ(0, zip_writer.StartEntry("new.dat.br", 0)); - auto generator = []() { return rand() % 128; }; // Generate 100 blocks of random data. std::string brotli_new_data; @@ -602,16 +649,12 @@ TEST_F(UpdaterTest, brotli_new_data) { generate_n(back_inserter(brotli_new_data), 4096 * 100, generator); size_t encoded_size = BrotliEncoderMaxCompressedSize(brotli_new_data.size()); - std::vector<uint8_t> encoded_data(encoded_size); + std::string encoded_data(encoded_size, 0); ASSERT_TRUE(BrotliEncoderCompress( BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE, brotli_new_data.size(), - reinterpret_cast<const uint8_t*>(brotli_new_data.data()), &encoded_size, encoded_data.data())); - - ASSERT_EQ(0, zip_writer.WriteBytes(encoded_data.data(), encoded_size)); - ASSERT_EQ(0, zip_writer.FinishEntry()); - // Add a dummy patch data. - ASSERT_EQ(0, zip_writer.StartEntry("patch_data", 0)); - ASSERT_EQ(0, zip_writer.FinishEntry()); + reinterpret_cast<const uint8_t*>(brotli_new_data.data()), &encoded_size, + reinterpret_cast<uint8_t*>(const_cast<char*>(encoded_data.data())))); + encoded_data.resize(encoded_size); // Write a few small chunks of new data, then a large chunk, and finally a few small chunks. // This helps us to catch potential short writes. @@ -627,12 +670,15 @@ TEST_F(UpdaterTest, brotli_new_data) { "new 2,98,99", "new 2,99,100", }; - ASSERT_EQ(0, zip_writer.StartEntry("transfer_list", 0)); - std::string commands = android::base::Join(transfer_list, '\n'); - ASSERT_EQ(0, zip_writer.WriteBytes(commands.data(), commands.size())); - ASSERT_EQ(0, zip_writer.FinishEntry()); - ASSERT_EQ(0, zip_writer.Finish()); - ASSERT_EQ(0, fclose(zip_file_ptr)); + + std::unordered_map<std::string, std::string> entries = { + { "new.dat.br", std::move(encoded_data) }, + { "patch_data", "" }, + { "transfer_list", android::base::Join(transfer_list, '\n') }, + }; + + TemporaryFile zip_file; + BuildUpdatePackage(entries, zip_file.release()); MemMapping map; ASSERT_TRUE(map.MapFile(zip_file.path)); diff --git a/tests/unit/rangeset_test.cpp b/tests/unit/rangeset_test.cpp index 15bcec855..b3ed99215 100644 --- a/tests/unit/rangeset_test.cpp +++ b/tests/unit/rangeset_test.cpp @@ -21,7 +21,7 @@ #include <gtest/gtest.h> -#include "rangeset.h" +#include "otautil/rangeset.h" TEST(RangeSetTest, Parse_smoke) { RangeSet rs = RangeSet::Parse("2,1,10"); @@ -156,4 +156,4 @@ TEST(SortedRangeSetTest, file_range) { ASSERT_EQ(static_cast<size_t>(40970), rs.GetOffsetInRangeSet(4096 * 16 + 10)); // block#10 not in range. ASSERT_EXIT(rs.GetOffsetInRangeSet(40970), ::testing::KilledBySignal(SIGABRT), ""); -}
\ No newline at end of file +} diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk index a3b0ca98d..601f9276e 100644 --- a/uncrypt/Android.mk +++ b/uncrypt/Android.mk @@ -17,10 +17,10 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := uncrypt.cpp -LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. LOCAL_MODULE := uncrypt LOCAL_STATIC_LIBRARIES := \ libbootloader_message \ + libotautil \ libbase \ liblog \ libfs_mgr \ diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp index 7a2ccbc7c..645faadbf 100644 --- a/uncrypt/uncrypt.cpp +++ b/uncrypt/uncrypt.cpp @@ -116,7 +116,7 @@ #include <cutils/sockets.h> #include <fs_mgr.h> -#include "error_code.h" +#include "otautil/error_code.h" static constexpr int WINDOW_SIZE = 5; static constexpr int FIBMAP_RETRY_LIMIT = 3; diff --git a/updater/Android.mk b/updater/Android.mk index 12181602f..6f334ee18 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -67,7 +67,6 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := \ -Wall \ - -Wno-unused-parameter \ -Werror LOCAL_EXPORT_C_INCLUDE_DIRS := \ @@ -93,7 +92,6 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := \ -Wall \ - -Wno-unused-parameter \ -Werror LOCAL_STATIC_LIBRARIES := \ diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index 696cddf41..6c7b3efcf 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -50,10 +50,10 @@ #include <ziparchive/zip_archive.h> #include "edify/expr.h" -#include "error_code.h" #include "otafault/ota_io.h" -#include "print_sha1.h" -#include "rangeset.h" +#include "otautil/error_code.h" +#include "otautil/print_sha1.h" +#include "otautil/rangeset.h" #include "updater/install.h" #include "updater/updater.h" @@ -281,6 +281,11 @@ static bool receive_new_data(const uint8_t* data, size_t size, void* cookie) { // Wait for nti->writer to be non-null, indicating some of this data is wanted. pthread_mutex_lock(&nti->mu); while (nti->writer == nullptr) { + // End the new data receiver if we encounter an error when performing block image update. + if (!nti->receiver_available) { + pthread_mutex_unlock(&nti->mu); + return false; + } pthread_cond_wait(&nti->cv, &nti->mu); } pthread_mutex_unlock(&nti->mu); @@ -316,6 +321,11 @@ static bool receive_brotli_new_data(const uint8_t* data, size_t size, void* cook // Wait for nti->writer to be non-null, indicating some of this data is wanted. pthread_mutex_lock(&nti->mu); while (nti->writer == nullptr) { + // End the receiver if we encounter an error when performing block image update. + if (!nti->receiver_available) { + pthread_mutex_unlock(&nti->mu); + return false; + } pthread_cond_wait(&nti->cv, &nti->mu); } pthread_mutex_unlock(&nti->mu); @@ -1591,29 +1601,44 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, } } + rc = 0; + +pbiudone: if (params.canwrite) { - pthread_join(params.thread, nullptr); + pthread_mutex_lock(¶ms.nti.mu); + if (params.nti.receiver_available) { + LOG(WARNING) << "new data receiver is still available after executing all commands."; + } + params.nti.receiver_available = false; + pthread_cond_broadcast(¶ms.nti.cv); + pthread_mutex_unlock(¶ms.nti.mu); + int ret = pthread_join(params.thread, nullptr); + if (ret != 0) { + LOG(WARNING) << "pthread join returned with " << strerror(ret); + } - LOG(INFO) << "wrote " << params.written << " blocks; expected " << total_blocks; - LOG(INFO) << "stashed " << params.stashed << " blocks"; - LOG(INFO) << "max alloc needed was " << params.buffer.size(); + if (rc == 0) { + LOG(INFO) << "wrote " << params.written << " blocks; expected " << total_blocks; + LOG(INFO) << "stashed " << params.stashed << " blocks"; + LOG(INFO) << "max alloc needed was " << params.buffer.size(); - const char* partition = strrchr(blockdev_filename->data.c_str(), '/'); - if (partition != nullptr && *(partition + 1) != 0) { - fprintf(cmd_pipe, "log bytes_written_%s: %zu\n", partition + 1, params.written * BLOCKSIZE); - fprintf(cmd_pipe, "log bytes_stashed_%s: %zu\n", partition + 1, params.stashed * BLOCKSIZE); - fflush(cmd_pipe); + const char* partition = strrchr(blockdev_filename->data.c_str(), '/'); + if (partition != nullptr && *(partition + 1) != 0) { + fprintf(cmd_pipe, "log bytes_written_%s: %zu\n", partition + 1, params.written * BLOCKSIZE); + fprintf(cmd_pipe, "log bytes_stashed_%s: %zu\n", partition + 1, params.stashed * BLOCKSIZE); + fflush(cmd_pipe); + } + // Delete stash only after successfully completing the update, as it may contain blocks needed + // to complete the update later. + DeleteStash(params.stashbase); } - // Delete stash only after successfully completing the update, as it may contain blocks needed - // to complete the update later. - DeleteStash(params.stashbase); - } else { + + pthread_mutex_destroy(¶ms.nti.mu); + pthread_cond_destroy(¶ms.nti.cv); + } else if (rc == 0) { LOG(INFO) << "verified partition contents; update may be resumed"; } - rc = 0; - -pbiudone: if (ota_fsync(params.fd) == -1) { failure_type = kFsyncFailure; PLOG(ERROR) << "fsync failed"; diff --git a/updater/install.cpp b/updater/install.cpp index fc085d5aa..9425d1872 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -54,15 +54,15 @@ #include <openssl/sha.h> #include <selinux/label.h> #include <selinux/selinux.h> +#include <tune2fs.h> #include <ziparchive/zip_archive.h> #include "edify/expr.h" -#include "error_code.h" #include "mounts.h" #include "otafault/ota_io.h" #include "otautil/DirUtil.h" -#include "print_sha1.h" -#include "tune2fs.h" +#include "otautil/error_code.h" +#include "otautil/print_sha1.h" #include "updater/updater.h" // Send over the buffer to recovery though the command pipe. diff --git a/updater/updater.cpp b/updater/updater.cpp index 309c309a5..f55a0d3bd 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp @@ -31,10 +31,10 @@ #include <ziparchive/zip_archive.h> #include "edify/expr.h" -#include "error_code.h" #include "otafault/config.h" #include "otautil/DirUtil.h" #include "otautil/SysUtil.h" +#include "otautil/error_code.h" #include "updater/blockimg.h" #include "updater/install.h" diff --git a/verifier.cpp b/verifier.cpp index 18437fb7a..283e04300 100644 --- a/verifier.cpp +++ b/verifier.cpp @@ -32,7 +32,7 @@ #include <openssl/obj_mac.h> #include "asn1_decoder.h" -#include "print_sha1.h" +#include "otautil/print_sha1.h" static constexpr size_t MiB = 1024 * 1024; @@ -53,7 +53,7 @@ int VrRecoveryUI::DrawHorizontalRule(int y) const { return y + 4; } -void VrRecoveryUI::DrawHighlightBar(int x, int y, int width, int height) const { +void VrRecoveryUI::DrawHighlightBar(int /* x */, int y, int /* width */, int height) const { gr_fill(kMarginWidth + kStereoOffset, y, ScreenWidth() - kMarginWidth + kStereoOffset, y + height); gr_fill(ScreenWidth() + kMarginWidth - kStereoOffset, y, gr_fb_width() - kMarginWidth - kStereoOffset, y + height); diff --git a/wear_ui.cpp b/wear_ui.cpp index e2ee48804..ca6b1b102 100644 --- a/wear_ui.cpp +++ b/wear_ui.cpp @@ -150,8 +150,7 @@ void WearRecoveryUI::update_progress_locked() { gr_flip(); } -void WearRecoveryUI::SetStage(int current, int max) { -} +void WearRecoveryUI::SetStage(int /* current */, int /* max */) {} void WearRecoveryUI::StartMenu(const char* const* headers, const char* const* items, int initial_selection) { |