Merge "Only restorecon CE storage after unlocked." into nyc-mr1-dev
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 78b49f8..af2c81f 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -370,19 +370,7 @@
     *buf = '\0';
 }
 
-static void copy_to_file(int inFd, int outFd) {
-    const size_t BUFSIZE = 32 * 1024;
-    char* buf = (char*) malloc(BUFSIZE);
-    if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
-    int len;
-    long total = 0;
-#ifdef _WIN32
-    int old_stdin_mode = -1;
-    int old_stdout_mode = -1;
-#endif
-
-    D("copy_to_file(%d -> %d)", inFd, outFd);
-
+static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) {
     if (inFd == STDIN_FILENO) {
         stdin_raw_init();
 #ifdef _WIN32
@@ -401,6 +389,39 @@
         }
     }
 #endif
+}
+
+static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) {
+    if (inFd == STDIN_FILENO) {
+        stdin_raw_restore();
+#ifdef _WIN32
+        if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
+            fatal_errno("could not restore stdin mode");
+        }
+#endif
+    }
+
+#ifdef _WIN32
+    if (outFd == STDOUT_FILENO) {
+        if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
+            fatal_errno("could not restore stdout mode");
+        }
+    }
+#endif
+}
+
+static void copy_to_file(int inFd, int outFd) {
+    const size_t BUFSIZE = 32 * 1024;
+    char* buf = (char*) malloc(BUFSIZE);
+    if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
+    int len;
+    long total = 0;
+    int old_stdin_mode = -1;
+    int old_stdout_mode = -1;
+
+    D("copy_to_file(%d -> %d)", inFd, outFd);
+
+    stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode);
 
     while (true) {
         if (inFd == STDIN_FILENO) {
@@ -425,22 +446,7 @@
         total += len;
     }
 
-    if (inFd == STDIN_FILENO) {
-        stdin_raw_restore();
-#ifdef _WIN32
-        if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
-            fatal_errno("could not restore stdin mode");
-        }
-#endif
-    }
-
-#ifdef _WIN32
-    if (outFd == STDOUT_FILENO) {
-        if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
-            fatal_errno("could not restore stdout mode");
-        }
-    }
-#endif
+    stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
 
     D("copy_to_file() finished after %lu bytes", total);
     free(buf);
@@ -1234,6 +1240,29 @@
     return send_shell_command(transport, serial, cmd, true);
 }
 
+static void write_zeros(int bytes, int fd) {
+    int old_stdin_mode = -1;
+    int old_stdout_mode = -1;
+    char* buf = (char*) calloc(1, bytes);
+    if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros");
+
+    D("write_zeros(%d) -> %d", bytes, fd);
+
+    stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
+
+    if (fd == STDOUT_FILENO) {
+        fwrite(buf, 1, bytes, stdout);
+        fflush(stdout);
+    } else {
+        adb_write(fd, buf, bytes);
+    }
+
+    stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
+
+    D("write_zeros() finished");
+    free(buf);
+}
+
 static int backup(int argc, const char** argv) {
     const char* filename = "backup.ab";
 
@@ -1314,6 +1343,9 @@
     printf("Now unlock your device and confirm the restore operation.\n");
     copy_to_file(tarFd, fd);
 
+    // Provide an in-band EOD marker in case the archive file is malformed
+    write_zeros(512*2, fd);
+
     // Wait until the other side finishes, or it'll get sent SIGHUP.
     copy_to_file(fd, STDOUT_FILENO);
 
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3b2999b..c1c3174 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -327,9 +327,6 @@
             "                                           been flashed to is set as active.\n"
             "                                           Secondary images may be flashed to\n"
             "                                           an inactive slot.\n"
-            "  flash-primary                            Same as flashall, but do not flash\n"
-            "                                           secondary images.\n"
-            "  flash-secondary                          Only flashes the secondary images.\n"
             "  flash <partition> [ <filename> ]         Write a file to a flash partition.\n"
             "  flashing lock                            Locks the device. Prevents flashing.\n"
             "  flashing unlock                          Unlocks the device. Allows flashing\n"
@@ -404,6 +401,9 @@
             "                                           supported, this sets the current slot\n"
             "                                           to be active. This will run after all\n"
             "                                           non-reboot commands.\n"
+            "  --skip-secondary                         Will not flash secondary slots when\n"
+            "                                           performing a flashall or update. This\n"
+            "                                           will preserve data on other slots.\n"
 #if !defined(_WIN32)
             "  --wipe-and-use-fbe                       On devices which support it,\n"
             "                                           erase userdata and cache, and\n"
@@ -1064,7 +1064,7 @@
     }
 }
 
-static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first) {
+static void do_update(Transport* transport, const char* filename, const std::string& slot_override, bool erase_first, bool skip_secondary) {
     queue_info_dump();
 
     fb_queue_query_save("product", cur_product, sizeof(cur_product));
@@ -1086,8 +1086,7 @@
     setup_requirements(reinterpret_cast<char*>(data), sz);
 
     std::string secondary;
-    bool update_secondary = slot_override != "all";
-    if (update_secondary) {
+    if (!skip_secondary) {
         if (slot_override != "") {
             secondary = get_other_slot(transport, slot_override);
         } else {
@@ -1097,13 +1096,13 @@
             if (supports_AB(transport)) {
                 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
             }
-            update_secondary = false;
+            skip_secondary = true;
         }
     }
     for (size_t i = 0; i < ARRAY_SIZE(images); ++i) {
         const char* slot = slot_override.c_str();
         if (images[i].is_secondary) {
-            if (update_secondary) {
+            if (!skip_secondary) {
                 slot = secondary.c_str();
             } else {
                 continue;
@@ -1137,7 +1136,11 @@
     }
 
     CloseArchive(zip);
-    set_active(transport, slot_override);
+    if (slot_override == "all") {
+        set_active(transport, "a");
+    } else {
+        set_active(transport, slot_override);
+    }
 }
 
 static void do_send_signature(const std::string& fn) {
@@ -1153,24 +1156,23 @@
     fb_queue_command("signature", "installing signature");
 }
 
-static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool flash_primary, bool flash_secondary) {
+static void do_flashall(Transport* transport, const std::string& slot_override, int erase_first, bool skip_secondary) {
     std::string fname;
-    if (flash_primary) {
-        queue_info_dump();
+    queue_info_dump();
 
-        fb_queue_query_save("product", cur_product, sizeof(cur_product));
+    fb_queue_query_save("product", cur_product, sizeof(cur_product));
 
-        fname = find_item("info", product);
-        if (fname == "") die("cannot find android-info.txt");
+    fname = find_item("info", product);
+    if (fname == "") die("cannot find android-info.txt");
 
-        int64_t sz;
-        void* data = load_file(fname.c_str(), &sz);
-        if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno));
+    int64_t sz;
+    void* data = load_file(fname.c_str(), &sz);
+    if (data == nullptr) die("could not load android-info.txt: %s", strerror(errno));
 
-        setup_requirements(reinterpret_cast<char*>(data), sz);
-    }
+    setup_requirements(reinterpret_cast<char*>(data), sz);
+
     std::string secondary;
-    if (flash_secondary) {
+    if (!skip_secondary) {
         if (slot_override != "") {
             secondary = get_other_slot(transport, slot_override);
         } else {
@@ -1180,16 +1182,16 @@
             if (supports_AB(transport)) {
                 fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
             }
-            flash_secondary = false;
+            skip_secondary = true;
         }
     }
 
     for (size_t i = 0; i < ARRAY_SIZE(images); i++) {
         const char* slot = NULL;
         if (images[i].is_secondary) {
-            if (flash_secondary) slot = secondary.c_str();
+            if (!skip_secondary) slot = secondary.c_str();
         } else {
-            if (flash_primary) slot = slot_override.c_str();
+            slot = slot_override.c_str();
         }
         if (!slot) continue;
         fname = find_item_given_name(images[i].img_name, product);
@@ -1209,7 +1211,11 @@
         do_for_partitions(transport, images[i].part_name, slot, flashall, false);
     }
 
-    if (flash_primary) set_active(transport, slot_override);
+    if (slot_override == "all") {
+        set_active(transport, "a");
+    } else {
+        set_active(transport, slot_override);
+    }
 }
 
 #define skip(n) do { argc -= (n); argv += (n); } while (0)
@@ -1388,6 +1394,7 @@
     bool wants_reboot = false;
     bool wants_reboot_bootloader = false;
     bool wants_set_active = false;
+    bool skip_secondary = false;
     bool erase_first = true;
     bool set_fbe_marker = false;
     void *data;
@@ -1412,6 +1419,7 @@
         {"slot", required_argument, 0, 0},
         {"set_active", optional_argument, 0, 'a'},
         {"set-active", optional_argument, 0, 'a'},
+        {"skip-secondary", no_argument, 0, 0},
 #if !defined(_WIN32)
         {"wipe-and-use-fbe", no_argument, 0, 0},
 #endif
@@ -1496,6 +1504,8 @@
                 return 0;
             } else if (strcmp("slot", longopts[longindex].name) == 0) {
                 slot_override = std::string(optarg);
+            } else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
+                skip_secondary = true;
 #if !defined(_WIN32)
             } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
                 wants_wipe = true;
@@ -1702,26 +1712,22 @@
         } else if(!strcmp(*argv, "flashall")) {
             skip(1);
             if (slot_override == "all") {
-                 fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.");
-                 do_flashall(transport, slot_override, erase_first, true, false);
+                fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
+                do_flashall(transport, slot_override, erase_first, true);
             } else {
-                do_flashall(transport, slot_override, erase_first, true, true);
+                do_flashall(transport, slot_override, erase_first, skip_secondary);
             }
             wants_reboot = true;
-        } else if(!strcmp(*argv, "flash-primary")) {
-            skip(1);
-            do_flashall(transport, slot_override, erase_first, true, false);
-            wants_reboot = true;
-        } else if(!strcmp(*argv, "flash-secondary")) {
-            skip(1);
-            do_flashall(transport, slot_override, erase_first, false, true);
-            wants_reboot = true;
         } else if(!strcmp(*argv, "update")) {
+            bool slot_all = (slot_override == "all");
+            if (slot_all) {
+                fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n");
+            }
             if (argc > 1) {
-                do_update(transport, argv[1], slot_override, erase_first);
+                do_update(transport, argv[1], slot_override, erase_first, skip_secondary || slot_all);
                 skip(2);
             } else {
-                do_update(transport, "update.zip", slot_override, erase_first);
+                do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
                 skip(1);
             }
             wants_reboot = 1;
diff --git a/liblog/logger.h b/liblog/logger.h
index c727f29..0964756 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -146,11 +146,13 @@
 /* OS specific dribs and drabs */
 
 #if defined(_WIN32)
+#include <private/android_filesystem_config.h>
 typedef uint32_t uid_t;
+static inline uid_t __android_log_uid() { return AID_SYSTEM; }
+#else
+static inline uid_t __android_log_uid() { return getuid(); }
 #endif
 
-LIBLOG_HIDDEN uid_t __android_log_uid();
-LIBLOG_HIDDEN pid_t __android_log_pid();
 LIBLOG_HIDDEN void __android_log_lock();
 LIBLOG_HIDDEN int __android_log_trylock();
 LIBLOG_HIDDEN void __android_log_unlock();
diff --git a/liblog/logger_lock.c b/liblog/logger_lock.c
index ee979bd..14feee0 100644
--- a/liblog/logger_lock.c
+++ b/liblog/logger_lock.c
@@ -22,34 +22,8 @@
 #include <pthread.h>
 #endif
 
-#include <private/android_filesystem_config.h>
-
 #include "logger.h"
 
-LIBLOG_HIDDEN uid_t __android_log_uid()
-{
-#if defined(_WIN32)
-    return AID_SYSTEM;
-#else
-    static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
-
-    if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
-        last_uid = getuid();
-    }
-    return last_uid;
-#endif
-}
-
-LIBLOG_HIDDEN pid_t __android_log_pid()
-{
-    static pid_t last_pid = (pid_t) -1;
-
-    if (last_pid == (pid_t) -1) {
-        last_pid = getpid();
-    }
-    return last_pid;
-}
-
 #if !defined(_WIN32)
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c
index 2ba31fa..944feba 100644
--- a/liblog/pmsg_writer.c
+++ b/liblog/pmsg_writer.c
@@ -142,7 +142,7 @@
     pmsgHeader.magic = LOGGER_MAGIC;
     pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);
     pmsgHeader.uid = __android_log_uid();
-    pmsgHeader.pid = __android_log_pid();
+    pmsgHeader.pid = getpid();
 
     header.id = logId;
     header.tid = gettid();
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d086f4e..56379db 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -234,6 +234,8 @@
     # expecting it to point to /proc/self/fd
     symlink /proc/self/fd /dev/fd
 
+    export DOWNLOAD_CACHE /data/cache
+
 # Healthd can trigger a full boot from charger mode by signaling this
 # property when the power button is held.
 on property:sys.boot_from_charger_mode=1
@@ -454,6 +456,11 @@
     mkdir /data/media 0770 media_rw media_rw
     mkdir /data/media/obb 0770 media_rw media_rw
 
+    mkdir /data/cache 0770 system cache
+    mkdir /data/cache/recovery 0770 system cache
+    mkdir /data/cache/backup_stage 0700 system system
+    mkdir /data/cache/backup 0700 system system
+
     init_user0
 
     # Reload policy from /data/security if present.
@@ -565,7 +572,7 @@
 
 on nonencrypted
     # A/B update verifier that marks a successful boot.
-    exec - root -- /system/bin/update_verifier nonencrypted
+    exec - root cache -- /system/bin/update_verifier nonencrypted
     class_start main
     class_start late_start
 
@@ -588,12 +595,12 @@
 
 on property:vold.decrypt=trigger_restart_min_framework
     # A/B update verifier that marks a successful boot.
-    exec - root -- /system/bin/update_verifier trigger_restart_min_framework
+    exec - root cache -- /system/bin/update_verifier trigger_restart_min_framework
     class_start main
 
 on property:vold.decrypt=trigger_restart_framework
     # A/B update verifier that marks a successful boot.
-    exec - root -- /system/bin/update_verifier trigger_restart_framework
+    exec - root cache -- /system/bin/update_verifier trigger_restart_framework
     class_start main
     class_start late_start