Merge "Reboot and retry on I/O errors"
diff --git a/Android.mk b/Android.mk
index 4477fef..fc981e1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,18 +14,20 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# libfusesideload (static library)
+# ===============================
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := fuse_sideload.cpp
 LOCAL_CLANG := true
 LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
 LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-
 LOCAL_MODULE := libfusesideload
-
 LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt
 include $(BUILD_STATIC_LIBRARY)
 
+# recovery (static executable)
+# ===============================
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
@@ -102,7 +104,8 @@
 
 include $(BUILD_EXECUTABLE)
 
-# All the APIs for testing
+# libverifier (static library)
+# ===============================
 include $(CLEAR_VARS)
 LOCAL_CLANG := true
 LOCAL_MODULE := libverifier
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 90a86dc..9e64718 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -14,59 +14,83 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# libapplypatch (static library)
+# ===============================
 include $(CLEAR_VARS)
-
 LOCAL_CLANG := true
-LOCAL_SRC_FILES := applypatch.cpp bspatch.cpp freecache.cpp imgpatch.cpp utils.cpp
+LOCAL_SRC_FILES := \
+    applypatch.cpp \
+    bspatch.cpp \
+    freecache.cpp \
+    imgpatch.cpp \
+    utils.cpp
 LOCAL_MODULE := libapplypatch
 LOCAL_MODULE_TAGS := eng
-LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libbase libotafault libmtdutils libcrypto_static libbz libz
-
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/include \
+    bootable/recovery
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES += \
+    libotafault \
+    libmtdutils \
+    libbase \
+    libcrypto_static \
+    libbz \
+    libz
 include $(BUILD_STATIC_LIBRARY)
 
+# libimgpatch (static library)
+# ===============================
 include $(CLEAR_VARS)
-
 LOCAL_CLANG := true
 LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
 LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/include \
+    bootable/recovery
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
 include $(BUILD_STATIC_LIBRARY)
 
-ifeq ($(HOST_OS),linux)
+# libimgpatch (host static library)
+# ===============================
 include $(CLEAR_VARS)
-
 LOCAL_CLANG := true
 LOCAL_SRC_FILES := bspatch.cpp imgpatch.cpp utils.cpp
 LOCAL_MODULE := libimgpatch
-LOCAL_C_INCLUDES += bootable/recovery
+LOCAL_MODULE_HOST_OS := linux
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/include \
+    bootable/recovery
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES += libcrypto_static libbz libz
-
 include $(BUILD_HOST_STATIC_LIBRARY)
-endif  # HOST_OS == linux
 
+# applypatch (executable)
+# ===============================
 include $(CLEAR_VARS)
-
 LOCAL_CLANG := true
 LOCAL_SRC_FILES := main.cpp
 LOCAL_MODULE := applypatch
 LOCAL_C_INCLUDES += bootable/recovery
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libmtdutils libcrypto_static libbz libedify
+LOCAL_STATIC_LIBRARIES += \
+    libapplypatch \
+    libbase \
+    libedify \
+    libotafault \
+    libminzip \
+    libmtdutils \
+    libcrypto_static \
+    libbz
 LOCAL_SHARED_LIBRARIES += libz libcutils libc
-
 include $(BUILD_EXECUTABLE)
 
+# imgdiff (host static executable)
+# ===============================
 include $(CLEAR_VARS)
-
 LOCAL_CLANG := true
 LOCAL_SRC_FILES := imgdiff.cpp utils.cpp bsdiff.cpp
 LOCAL_MODULE := imgdiff
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_C_INCLUDES += external/zlib external/bzip2
 LOCAL_STATIC_LIBRARIES += libz libbz
-
+LOCAL_FORCE_STATIC_EXECUTABLE := true
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 6445159..c8594c2 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -31,7 +31,7 @@
 #include <android-base/strings.h>
 
 #include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
 #include "mtdutils/mtdutils.h"
 #include "edify/expr.h"
 #include "ota_io.h"
diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp
index 1fc1455..a4945da 100644
--- a/applypatch/bspatch.cpp
+++ b/applypatch/bspatch.cpp
@@ -30,7 +30,7 @@
 #include <bzlib.h>
 
 #include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
 
 void ShowBSDiffLicense() {
     puts("The bsdiff library used herein is:\n"
diff --git a/applypatch/freecache.cpp b/applypatch/freecache.cpp
index c84f427..331cae2 100644
--- a/applypatch/freecache.cpp
+++ b/applypatch/freecache.cpp
@@ -32,7 +32,7 @@
 #include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
 
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
 
 static int EliminateOpenFiles(std::set<std::string>* files) {
   std::unique_ptr<DIR, decltype(&closedir)> d(opendir("/proc"), closedir);
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp
index 0ab995b..4251c01 100644
--- a/applypatch/imgpatch.cpp
+++ b/applypatch/imgpatch.cpp
@@ -28,7 +28,7 @@
 
 #include "zlib.h"
 #include "openssl/sha.h"
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
 #include "imgdiff.h"
 #include "utils.h"
 
diff --git a/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h
similarity index 100%
rename from applypatch/applypatch.h
rename to applypatch/include/applypatch/applypatch.h
diff --git a/applypatch/main.cpp b/applypatch/main.cpp
index 9013760..0ff8cbf 100644
--- a/applypatch/main.cpp
+++ b/applypatch/main.cpp
@@ -22,7 +22,7 @@
 #include <memory>
 #include <vector>
 
-#include "applypatch.h"
+#include "applypatch/applypatch.h"
 #include "edify/expr.h"
 #include "openssl/sha.h"
 
diff --git a/etc/init.rc b/etc/init.rc
index dc18659..5915b8d 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -1,6 +1,9 @@
 import /init.recovery.${ro.hardware}.rc
 
 on early-init
+    # Set the security context of /postinstall if present.
+    restorecon /postinstall
+
     start ueventd
     start healthd
 
diff --git a/otafault/Android.mk b/otafault/Android.mk
index 7468de6..52d7067 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -14,29 +14,34 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# otafault (static library)
+# ===============================
 include $(CLEAR_VARS)
 
 otafault_static_libs := \
     libminzip \
-    libz \
     libselinux \
+    libz
 
 LOCAL_SRC_FILES := config.cpp ota_io.cpp
-LOCAL_MODULE_TAGS := eng
 LOCAL_MODULE := libotafault
 LOCAL_CLANG := true
 LOCAL_C_INCLUDES := bootable/recovery
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs)
+LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
 
 include $(BUILD_STATIC_LIBRARY)
 
+# otafault_test (static executable)
+# ===============================
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
 LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE := otafault_test
-LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
+LOCAL_STATIC_LIBRARIES := \
+    libotafault \
+    $(otafault_static_libs)
 LOCAL_C_INCLUDES := bootable/recovery
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 
diff --git a/recovery.cpp b/recovery.cpp
index 90742d8..6781fa4 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -101,6 +101,7 @@
 char* stage = NULL;
 char* reason = NULL;
 bool modified_flash = false;
+static bool has_cache = false;
 
 /*
  * The recovery tool communicates with the main system through /cache files.
@@ -313,8 +314,8 @@
         }
     }
 
-    // --- if that doesn't work, try the command file
-    if (*argc <= 1) {
+    // --- if that doesn't work, try the command file (if we have /cache).
+    if (*argc <= 1 && has_cache) {
         FILE *fp = fopen_path(COMMAND_FILE, "r");
         if (fp != NULL) {
             char *token;
@@ -436,6 +437,11 @@
 }
 
 static void copy_logs() {
+    // We can do nothing for now if there's no /cache partition.
+    if (!has_cache) {
+        return;
+    }
+
     // We only rotate and record the log of the current session if there are
     // actual attempts to modify the flash, such as wipes, installs from BCB
     // or menu selections. This is to avoid unnecessary rotation (and
@@ -467,7 +473,7 @@
 static void
 finish_recovery(const char *send_intent) {
     // By this point, we're ready to return to the main system...
-    if (send_intent != NULL) {
+    if (send_intent != NULL && has_cache) {
         FILE *fp = fopen_path(INTENT_FILE, "w");
         if (fp == NULL) {
             LOGE("Can't open %s\n", INTENT_FILE);
@@ -480,7 +486,7 @@
     // Save the locale to cache, so if recovery is next started up
     // without a --locale argument (eg, directly from the bootloader)
     // it will use the last-known locale.
-    if (locale != NULL) {
+    if (locale != NULL && has_cache) {
         LOGI("Saving locale \"%s\"\n", locale);
         FILE* fp = fopen_path(LOCALE_FILE, "w");
         fwrite(locale, 1, strlen(locale), fp);
@@ -497,12 +503,13 @@
     set_bootloader_message(&boot);
 
     // Remove the command file, so recovery won't repeat indefinitely.
-    if (ensure_path_mounted(COMMAND_FILE) != 0 ||
-        (unlink(COMMAND_FILE) && errno != ENOENT)) {
-        LOGW("Can't unlink %s\n", COMMAND_FILE);
+    if (has_cache) {
+        if (ensure_path_mounted(COMMAND_FILE) != 0 || (unlink(COMMAND_FILE) && errno != ENOENT)) {
+            LOGW("Can't unlink %s\n", COMMAND_FILE);
+        }
+        ensure_path_unmounted(CACHE_ROOT);
     }
 
-    ensure_path_unmounted(CACHE_ROOT);
     sync();  // For good measure.
 }
 
@@ -771,7 +778,7 @@
     bool success =
         device->PreWipeData() &&
         erase_volume("/data") &&
-        erase_volume("/cache") &&
+        (has_cache ? erase_volume("/cache") : true) &&
         device->PostWipeData();
     ui->Print("Data wipe %s.\n", success ? "complete" : "failed");
     return success;
@@ -779,6 +786,11 @@
 
 // Return true on success.
 static bool wipe_cache(bool should_confirm, Device* device) {
+    if (!has_cache) {
+        ui->Print("No /cache partition found.\n");
+        return false;
+    }
+
     if (should_confirm && !yes_no(device, "Wipe cache?", "  THIS CAN NOT BE UNDONE!")) {
         return false;
     }
@@ -792,6 +804,11 @@
 }
 
 static void choose_recovery_file(Device* device) {
+    if (!has_cache) {
+        ui->Print("No /cache partition found.\n");
+        return;
+    }
+
     // "Back" + KEEP_LOG_COUNT * 2 + terminating nullptr entry
     char* entries[1 + KEEP_LOG_COUNT * 2 + 1];
     memset(entries, 0, sizeof(entries));
@@ -1168,6 +1185,8 @@
     printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));
 
     load_volume_table();
+    has_cache = volume_for_path(CACHE_ROOT) != nullptr;
+
     get_args(&argc, &argv);
 
     const char *send_intent = NULL;
@@ -1210,7 +1229,7 @@
         }
     }
 
-    if (locale == NULL) {
+    if (locale == nullptr && has_cache) {
         load_locale_from_cache();
     }
     printf("locale is [%s]\n", locale);
diff --git a/updater/Android.mk b/updater/Android.mk
index d7aa613..47c56cc 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -14,26 +14,50 @@
 
 LOCAL_PATH := $(call my-dir)
 
-updater_src_files := \
-	install.cpp \
-	blockimg.cpp \
-	updater.cpp
-
-#
-# Build a statically-linked binary to include in OTA packages
-#
+# updater (static executable)
+# ===============================
+# Build a statically-linked binary to include in OTA packages.
 include $(CLEAR_VARS)
 
-# Build only in eng, so we don't end up with a copy of this in /system
-# on user builds.  (TODO: find a better way to build device binaries
-# needed only for OTA packages.)
-LOCAL_MODULE_TAGS := eng
+updater_src_files := \
+    install.cpp \
+    blockimg.cpp \
+    updater.cpp
 
 LOCAL_CLANG := true
-
 LOCAL_SRC_FILES := $(updater_src_files)
 
-LOCAL_STATIC_LIBRARIES += libfec libfec_rs libext4_utils_static libsquashfs_utils libcrypto_static
+LOCAL_STATIC_LIBRARIES += \
+    $(TARGET_RECOVERY_UPDATER_LIBS) \
+    $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
+    libfec \
+    libfec_rs \
+    libext4_utils_static \
+    libsquashfs_utils \
+    libcrypto_static \
+    libapplypatch \
+    libbase \
+    libotafault \
+    libedify \
+    libmtdutils \
+    libminzip \
+    libz \
+    libbz \
+    libcutils \
+    liblog \
+    libselinux
+
+tune2fs_static_libraries := \
+    libext2_com_err \
+    libext2_blkid \
+    libext2_quota \
+    libext2_uuid_static \
+    libext2_e2p \
+    libext2fs
+
+LOCAL_STATIC_LIBRARIES += \
+    libtune2fs \
+    $(tune2fs_static_libraries)
 
 ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
 LOCAL_CFLAGS += -DUSE_EXT4
@@ -44,20 +68,6 @@
     libz
 endif
 
-LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
-LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz
-LOCAL_STATIC_LIBRARIES += libbz
-LOCAL_STATIC_LIBRARIES += libcutils liblog libc
-LOCAL_STATIC_LIBRARIES += libselinux
-tune2fs_static_libraries := \
- libext2_com_err \
- libext2_blkid \
- libext2_quota \
- libext2_uuid_static \
- libext2_e2p \
- libext2fs
-LOCAL_STATIC_LIBRARIES += libtune2fs $(tune2fs_static_libraries)
-
 LOCAL_C_INCLUDES += external/e2fsprogs/misc
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/..