summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp2
-rw-r--r--Android.mk9
-rw-r--r--OWNERS2
-rw-r--r--applypatch/Android.bp196
-rw-r--r--applypatch/Android.mk196
-rw-r--r--applypatch/Makefile33
-rw-r--r--applypatch/applypatch.cpp2
-rw-r--r--applypatch/bspatch.cpp2
-rw-r--r--applypatch/imgdiff.cpp4
-rw-r--r--applypatch/include/applypatch/imgdiff_image.h2
-rw-r--r--applypatch/libimgpatch.pc6
-rw-r--r--boot_control/Android.mk3
-rw-r--r--edify/Android.bp45
-rw-r--r--edify/Android.mk52
-rw-r--r--edify/expr.cpp4
-rw-r--r--edify/include/edify/expr.h (renamed from edify/expr.h)2
-rw-r--r--edify/lexer.ll2
-rw-r--r--edify/parser.yy2
-rw-r--r--install.cpp2
-rw-r--r--minadbd/Android.mk17
-rw-r--r--minadbd/minadbd_services.cpp30
-rw-r--r--minui/Android.mk5
-rw-r--r--minui/events.cpp1
-rw-r--r--otafault/ota_io.cpp1
-rw-r--r--otautil/Android.bp4
-rw-r--r--otautil/SysUtil.cpp7
-rw-r--r--otautil/include/otautil/error_code.h (renamed from error_code.h)2
-rw-r--r--otautil/include/otautil/print_sha1.h (renamed from print_sha1.h)20
-rw-r--r--otautil/include/otautil/rangeset.h142
-rw-r--r--otautil/rangeset.cpp200
-rw-r--r--rangeset.h278
-rw-r--r--recovery.cpp23
-rw-r--r--rotate_logs.cpp120
-rw-r--r--rotate_logs.h22
-rw-r--r--stub_ui.h22
-rw-r--r--tests/Android.mk1
-rw-r--r--tests/component/applypatch_test.cpp2
-rw-r--r--tests/component/imgdiff_test.cpp1
-rw-r--r--tests/component/updater_test.cpp224
-rw-r--r--tests/unit/rangeset_test.cpp4
-rw-r--r--uncrypt/Android.mk2
-rw-r--r--uncrypt/uncrypt.cpp2
-rw-r--r--updater/Android.mk2
-rw-r--r--updater/blockimg.cpp63
-rw-r--r--updater/install.cpp6
-rw-r--r--updater/updater.cpp2
-rw-r--r--verifier.cpp2
-rw-r--r--vr_ui.cpp2
-rw-r--r--wear_ui.cpp3
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 \
diff --git a/OWNERS b/OWNERS
index 09754c650..b3f11dcd6 100644
--- a/OWNERS
+++ b/OWNERS
@@ -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.
diff --git a/stub_ui.h b/stub_ui.h
index 85dbcfd89..1f6b29acb 100644
--- a/stub_ui.h
+++ b/stub_ui.h
@@ -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(&params.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(&params.nti.cv);
+ pthread_mutex_unlock(&params.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(&params.nti.mu);
+ pthread_cond_destroy(&params.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;
diff --git a/vr_ui.cpp b/vr_ui.cpp
index 07cc9da59..a58c99efd 100644
--- a/vr_ui.cpp
+++ b/vr_ui.cpp
@@ -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) {