Merge "disable module loading after BOOT_COMPLETED broadcast" into oc-dev
diff --git a/include/system b/include/system
new file mode 120000
index 0000000..b443c36
--- /dev/null
+++ b/include/system
@@ -0,0 +1 @@
+../libsystem/include/system
\ No newline at end of file
diff --git a/init/Android.mk b/init/Android.mk
index 1ca88d7..e97f4f2 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -8,12 +8,14 @@
 init_options += \
     -DALLOW_LOCAL_PROP_OVERRIDE=1 \
     -DALLOW_PERMISSIVE_SELINUX=1 \
-    -DREBOOT_BOOTLOADER_ON_PANIC=1
+    -DREBOOT_BOOTLOADER_ON_PANIC=1 \
+    -DDUMP_ON_UMOUNT_FAILURE=1
 else
 init_options += \
     -DALLOW_LOCAL_PROP_OVERRIDE=0 \
     -DALLOW_PERMISSIVE_SELINUX=0 \
-    -DREBOOT_BOOTLOADER_ON_PANIC=0
+    -DREBOOT_BOOTLOADER_ON_PANIC=0 \
+    -DDUMP_ON_UMOUNT_FAILURE=0
 endif
 
 ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT)))
diff --git a/init/init.cpp b/init/init.cpp
index 94bf37a..e6932d9 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -736,6 +736,18 @@
     return true;
 }
 
+static bool selinux_get_vendor_mapping_version(std::string* plat_vers) {
+    if (!read_first_line("/vendor/etc/selinux/plat_sepolicy_vers.txt", plat_vers)) {
+        PLOG(ERROR) << "Failed to read /vendor/etc/selinux/plat_sepolicy_vers.txt";
+        return false;
+    }
+    if (plat_vers->empty()) {
+        LOG(ERROR) << "No version present in plat_sepolicy_vers.txt";
+        return false;
+    }
+    return true;
+}
+
 static constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
 
 static bool selinux_is_split_policy_device() { return access(plat_policy_cil_file, R_OK) != -1; }
@@ -790,6 +802,12 @@
         return false;
     }
 
+    // Determine which mapping file to include
+    std::string vend_plat_vers;
+    if (!selinux_get_vendor_mapping_version(&vend_plat_vers)) {
+        return false;
+    }
+    std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil");
     // clang-format off
     const char* compile_args[] = {
         "/system/bin/secilc",
@@ -797,7 +815,7 @@
         "-M", "true",
         // Target the highest policy language version supported by the kernel
         "-c", std::to_string(max_policy_version).c_str(),
-        "/system/etc/selinux/mapping_sepolicy.cil",
+        mapping_file.c_str(),
         "/vendor/etc/selinux/nonplat_sepolicy.cil",
         "-o", compiled_sepolicy,
         // We don't care about file_contexts output by the compiler
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 62e5c85..8e46d57 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -15,10 +15,12 @@
  */
 #include <dirent.h>
 #include <fcntl.h>
+#include <linux/fs.h>
 #include <mntent.h>
+#include <selinux/selinux.h>
 #include <sys/cdefs.h>
+#include <sys/ioctl.h>
 #include <sys/mount.h>
-#include <sys/quota.h>
 #include <sys/reboot.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
@@ -36,6 +38,7 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 #include <bootloader_message/bootloader_message.h>
 #include <cutils/android_reboot.h>
 #include <fs_mgr.h>
@@ -67,39 +70,58 @@
 // Utility for struct mntent
 class MountEntry {
   public:
-    explicit MountEntry(const mntent& entry, bool isMounted = true)
+    explicit MountEntry(const mntent& entry)
         : mnt_fsname_(entry.mnt_fsname),
           mnt_dir_(entry.mnt_dir),
           mnt_type_(entry.mnt_type),
-          is_mounted_(isMounted) {}
+          mnt_opts_(entry.mnt_opts) {}
 
-    bool IsF2Fs() const { return mnt_type_ == "f2fs"; }
+    bool Umount() {
+        int r = umount2(mnt_dir_.c_str(), 0);
+        if (r == 0) {
+            LOG(INFO) << "umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_;
+            return true;
+        } else {
+            PLOG(WARNING) << "cannot umount " << mnt_fsname_ << ":" << mnt_dir_ << " opts "
+                          << mnt_opts_;
+            return false;
+        }
+    }
 
-    bool IsExt4() const { return mnt_type_ == "ext4"; }
-
-    bool is_mounted() const { return is_mounted_; }
-
-    void set_is_mounted() { is_mounted_ = false; }
-
-    const std::string& mnt_fsname() const { return mnt_fsname_; }
-
-    const std::string& mnt_dir() const { return mnt_dir_; }
+    void DoFsck() {
+        int st;
+        if (IsF2Fs()) {
+            const char* f2fs_argv[] = {
+                "/system/bin/fsck.f2fs", "-f", mnt_fsname_.c_str(),
+            };
+            android_fork_execvp_ext(arraysize(f2fs_argv), (char**)f2fs_argv, &st, true, LOG_KLOG,
+                                    true, nullptr, nullptr, 0);
+        } else if (IsExt4()) {
+            const char* ext4_argv[] = {
+                "/system/bin/e2fsck", "-f", "-y", mnt_fsname_.c_str(),
+            };
+            android_fork_execvp_ext(arraysize(ext4_argv), (char**)ext4_argv, &st, true, LOG_KLOG,
+                                    true, nullptr, nullptr, 0);
+        }
+    }
 
     static bool IsBlockDevice(const struct mntent& mntent) {
         return android::base::StartsWith(mntent.mnt_fsname, "/dev/block");
     }
 
     static bool IsEmulatedDevice(const struct mntent& mntent) {
-        static const std::string SDCARDFS_NAME = "sdcardfs";
-        return android::base::StartsWith(mntent.mnt_fsname, "/data/") &&
-               SDCARDFS_NAME == mntent.mnt_type;
+        return android::base::StartsWith(mntent.mnt_fsname, "/data/");
     }
 
   private:
+    bool IsF2Fs() const { return mnt_type_ == "f2fs"; }
+
+    bool IsExt4() const { return mnt_type_ == "ext4"; }
+
     std::string mnt_fsname_;
     std::string mnt_dir_;
     std::string mnt_type_;
-    bool is_mounted_;
+    std::string mnt_opts_;
 };
 
 // Turn off backlight while we are performing power down cleanup activities.
@@ -125,50 +147,6 @@
     }
 }
 
-static void DoFsck(const MountEntry& entry) {
-    static constexpr int UNMOUNT_CHECK_TIMES = 10;
-
-    if (!entry.IsF2Fs() && !entry.IsExt4()) return;
-
-    int count = 0;
-    while (count++ < UNMOUNT_CHECK_TIMES) {
-        int fd = TEMP_FAILURE_RETRY(open(entry.mnt_fsname().c_str(), O_RDONLY | O_EXCL));
-        if (fd >= 0) {
-            /* |entry->mnt_dir| has sucessfully been unmounted. */
-            close(fd);
-            break;
-        } else if (errno == EBUSY) {
-            // Some processes using |entry->mnt_dir| are still alive. Wait for a
-            // while then retry.
-            std::this_thread::sleep_for(5000ms / UNMOUNT_CHECK_TIMES);
-            continue;
-        } else {
-            /* Cannot open the device. Give up. */
-            return;
-        }
-    }
-
-    // NB: With watchdog still running, there is no cap on the time it takes
-    // to complete the fsck, from the users perspective the device graphics
-    // and responses are locked-up and they may choose to hold the power
-    // button in frustration if it drags out.
-
-    int st;
-    if (entry.IsF2Fs()) {
-        const char* f2fs_argv[] = {
-            "/system/bin/fsck.f2fs", "-f", entry.mnt_fsname().c_str(),
-        };
-        android_fork_execvp_ext(arraysize(f2fs_argv), (char**)f2fs_argv, &st, true, LOG_KLOG, true,
-                                nullptr, nullptr, 0);
-    } else if (entry.IsExt4()) {
-        const char* ext4_argv[] = {
-            "/system/bin/e2fsck", "-f", "-y", entry.mnt_fsname().c_str(),
-        };
-        android_fork_execvp_ext(arraysize(ext4_argv), (char**)ext4_argv, &st, true, LOG_KLOG, true,
-                                nullptr, nullptr, 0);
-    }
-}
-
 static void ShutdownVold() {
     const char* vdc_argv[] = {"/system/bin/vdc", "volume", "shutdown"};
     int status;
@@ -202,21 +180,11 @@
     abort();
 }
 
-static void DoSync() {
-    // quota sync is not done by sync call, so should be done separately.
-    // quota sync is in VFS level, so do it before sync, which goes down to fs level.
-    int r = quotactl(QCMD(Q_SYNC, 0), nullptr, 0 /* do not care */, 0 /* do not care */);
-    if (r < 0) {
-        PLOG(ERROR) << "quotactl failed";
-    }
-    sync();
-}
-
 /* Find all read+write block devices and emulated devices in /proc/mounts
  * and add them to correpsponding list.
  */
 static bool FindPartitionsToUmount(std::vector<MountEntry>* blockDevPartitions,
-                                   std::vector<MountEntry>* emulatedPartitions) {
+                                   std::vector<MountEntry>* emulatedPartitions, bool dump) {
     std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "r"), endmntent);
     if (fp == nullptr) {
         PLOG(ERROR) << "Failed to open /proc/mounts";
@@ -224,44 +192,63 @@
     }
     mntent* mentry;
     while ((mentry = getmntent(fp.get())) != nullptr) {
-        if (MountEntry::IsBlockDevice(*mentry) && hasmntopt(mentry, "rw")) {
-            blockDevPartitions->emplace_back(*mentry);
+        if (dump) {
+            LOG(INFO) << "mount entry " << mentry->mnt_fsname << ":" << mentry->mnt_dir << " opts "
+                      << mentry->mnt_opts << " type " << mentry->mnt_type;
+        } else if (MountEntry::IsBlockDevice(*mentry) && hasmntopt(mentry, "rw")) {
+            blockDevPartitions->emplace(blockDevPartitions->begin(), *mentry);
         } else if (MountEntry::IsEmulatedDevice(*mentry)) {
-            emulatedPartitions->emplace_back(*mentry);
+            emulatedPartitions->emplace(emulatedPartitions->begin(), *mentry);
         }
     }
     return true;
 }
 
-static bool UmountPartitions(std::vector<MountEntry>* partitions, int maxRetry, int flags) {
-    static constexpr int SLEEP_AFTER_RETRY_US = 100000;
-
-    bool umountDone;
-    int retryCounter = 0;
-
-    while (true) {
-        umountDone = true;
-        for (auto& entry : *partitions) {
-            if (entry.is_mounted()) {
-                int r = umount2(entry.mnt_dir().c_str(), flags);
-                if (r == 0) {
-                    entry.set_is_mounted();
-                    LOG(INFO) << StringPrintf("umounted %s, flags:0x%x", entry.mnt_fsname().c_str(),
-                                              flags);
-                } else {
-                    umountDone = false;
-                    PLOG(WARNING) << StringPrintf("cannot umount %s, mnt_dir %s, flags:0x%x",
-                                                  entry.mnt_fsname().c_str(),
-                                                  entry.mnt_dir().c_str(), flags);
-                }
-            }
-        }
-        if (umountDone) break;
-        retryCounter++;
-        if (retryCounter >= maxRetry) break;
-        usleep(SLEEP_AFTER_RETRY_US);
+static void DumpUmountDebuggingInfo() {
+    int status;
+    if (!security_getenforce()) {
+        LOG(INFO) << "Run lsof";
+        const char* lsof_argv[] = {"/system/bin/lsof"};
+        android_fork_execvp_ext(arraysize(lsof_argv), (char**)lsof_argv, &status, true, LOG_KLOG,
+                                true, nullptr, nullptr, 0);
     }
-    return umountDone;
+    FindPartitionsToUmount(nullptr, nullptr, true);
+}
+
+static UmountStat UmountPartitions(int timeoutMs) {
+    Timer t;
+    UmountStat stat = UMOUNT_STAT_TIMEOUT;
+    int retry = 0;
+    /* data partition needs all pending writes to be completed and all emulated partitions
+     * umounted.If the current waiting is not good enough, give
+     * up and leave it to e2fsck after reboot to fix it.
+     */
+    while (true) {
+        std::vector<MountEntry> block_devices;
+        std::vector<MountEntry> emulated_devices;
+        if (!FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
+            return UMOUNT_STAT_ERROR;
+        }
+        if (block_devices.size() == 0) {
+            stat = UMOUNT_STAT_SUCCESS;
+            break;
+        }
+        if ((timeoutMs < t.duration_ms()) && retry > 0) {  // try umount at least once
+            stat = UMOUNT_STAT_TIMEOUT;
+            break;
+        }
+        if (emulated_devices.size() > 0 &&
+            std::all_of(emulated_devices.begin(), emulated_devices.end(),
+                        [](auto& entry) { return entry.Umount(); })) {
+            sync();
+        }
+        for (auto& entry : block_devices) {
+            entry.Umount();
+        }
+        retry++;
+        std::this_thread::sleep_for(100ms);
+    }
+    return stat;
 }
 
 static void KillAllProcesses() { android::base::WriteStringToFile("i", "/proc/sysrq-trigger"); }
@@ -277,56 +264,38 @@
  */
 static UmountStat TryUmountAndFsck(bool runFsck, int timeoutMs) {
     Timer t;
-    std::vector<MountEntry> emulatedPartitions;
-    std::vector<MountEntry> blockDevRwPartitions;
+    std::vector<MountEntry> block_devices;
+    std::vector<MountEntry> emulated_devices;
 
     TurnOffBacklight();  // this part can take time. save power.
 
-    if (!FindPartitionsToUmount(&blockDevRwPartitions, &emulatedPartitions)) {
+    if (runFsck && !FindPartitionsToUmount(&block_devices, &emulated_devices, false)) {
         return UMOUNT_STAT_ERROR;
     }
-    if (emulatedPartitions.size() > 0) {
-        LOG(WARNING) << "emulated partitions still exist, will umount";
-        /* Pending writes in emulated partitions can fail umount. After a few trials, detach
-         * it so that it can be umounted when all writes are done.
-         */
-        if (!UmountPartitions(&emulatedPartitions, 1, 0)) {
-            UmountPartitions(&emulatedPartitions, 1, MNT_DETACH);
-        }
-    }
-    DoSync();  // emulated partition change can lead to update
-    UmountStat stat = UMOUNT_STAT_SUCCESS;
-    /* data partition needs all pending writes to be completed and all emulated partitions
-     * umounted. If umount failed in the above step, it DETACH is requested, so umount can
-     * still happen while waiting for /data. If the current waiting is not good enough, give
-     * up and leave it to e2fsck after reboot to fix it.
-     */
-    int remainingTimeMs = timeoutMs - t.duration_ms();
-    // each retry takes 100ms, and run at least once.
-    int retry = std::max(remainingTimeMs / 100, 1);
-    if (!UmountPartitions(&blockDevRwPartitions, retry, 0)) {
-        /* Last resort, kill all and try again */
-        LOG(WARNING) << "umount still failing, trying kill all";
+
+    UmountStat stat = UmountPartitions(timeoutMs - t.duration_ms());
+    if (stat != UMOUNT_STAT_SUCCESS) {
+        LOG(INFO) << "umount timeout, last resort, kill all and try";
+        if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
         KillAllProcesses();
-        DoSync();
-        if (!UmountPartitions(&blockDevRwPartitions, 1, 0)) {
-            stat = UMOUNT_STAT_TIMEOUT;
-        }
-    }
-    // fsck part is excluded from timeout check. It only runs for user initiated shutdown
-    // and should not affect reboot time.
-    if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
-        for (auto& entry : blockDevRwPartitions) {
-            DoFsck(entry);
-        }
+        // even if it succeeds, still it is timeout and do not run fsck with all processes killed
+        UmountPartitions(0);
+        if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
     }
 
+    if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
+        // fsck part is excluded from timeout check. It only runs for user initiated shutdown
+        // and should not affect reboot time.
+        for (auto& entry : block_devices) {
+            entry.DoFsck();
+        }
+    }
     return stat;
 }
 
 static void __attribute__((noreturn)) DoThermalOff() {
     LOG(WARNING) << "Thermal system shutdown";
-    DoSync();
+    sync();
     RebootSystem(ANDROID_RB_THERMOFF, "");
     abort();
 }
@@ -426,8 +395,8 @@
 
     // minimum safety steps before restarting
     // 2. kill all services except ones that are necessary for the shutdown sequence.
-    ServiceManager::GetInstance().ForEachService([&kill_after_apps](Service* s) {
-        if (!s->IsShutdownCritical() || kill_after_apps.count(s->name())) s->Stop();
+    ServiceManager::GetInstance().ForEachService([](Service* s) {
+        if (!s->IsShutdownCritical()) s->Stop();
     });
     ServiceManager::GetInstance().ReapAnyOutstandingChildren();
 
@@ -435,12 +404,20 @@
     Service* voldService = ServiceManager::GetInstance().FindServiceByName("vold");
     if (voldService != nullptr && voldService->IsRunning()) {
         ShutdownVold();
+        voldService->Stop();
     } else {
         LOG(INFO) << "vold not running, skipping vold shutdown";
     }
+    // logcat stopped here
+    ServiceManager::GetInstance().ForEachService([&kill_after_apps](Service* s) {
+        if (kill_after_apps.count(s->name())) s->Stop();
+    });
     // 4. sync, try umount, and optionally run fsck for user shutdown
-    DoSync();
+    sync();
     UmountStat stat = TryUmountAndFsck(runFsck, shutdownTimeout * 1000 - t.duration_ms());
+    // Follow what linux shutdown is doing: one more sync with little bit delay
+    sync();
+    std::this_thread::sleep_for(100ms);
     LogShutdownTime(stat, &t);
     // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
     RebootSystem(cmd, rebootTarget);
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index fdcf22f..b19a2fd 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -35,22 +35,13 @@
 
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
+#include <private/fs_config.h>
 #include <utils/Compat.h>
 
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
 
-/* The following structure is stored little endian */
-struct fs_path_config_from_file {
-    uint16_t len;
-    uint16_t mode;
-    uint16_t uid;
-    uint16_t gid;
-    uint64_t capabilities;
-    char prefix[];
-} __attribute__((__aligned__(sizeof(uint64_t))));
-
 /* My kingdom for <endian.h> */
 static inline uint16_t get2LE(const uint8_t* src) { return src[0] | (src[1] << 8); }
 
@@ -236,21 +227,24 @@
     /* clang-format on */
 };
 
+static size_t strip(const char* path, size_t len, const char suffix[]) {
+    if (len < strlen(suffix)) return len;
+    if (strncmp(path + len - strlen(suffix), suffix, strlen(suffix))) return len;
+    return len - strlen(suffix);
+}
+
 static int fs_config_open(int dir, int which, const char* target_out_path) {
     int fd = -1;
 
     if (target_out_path && *target_out_path) {
         /* target_out_path is the path to the directory holding content of
-         * system partition but as we cannot guaranty it ends with '/system'
-         * we need this below skip_len logic */
+         * system partition but as we cannot guarantee it ends with '/system'
+         * or with or without a trailing slash, need to strip them carefully. */
         char* name = NULL;
-        int target_out_path_len = strlen(target_out_path);
-        int skip_len = strlen("/system");
-
-        if (target_out_path[target_out_path_len] == '/') {
-            skip_len++;
-        }
-        if (asprintf(&name, "%s%s", target_out_path, conf[which][dir] + skip_len) != -1) {
+        size_t len = strlen(target_out_path);
+        len = strip(target_out_path, len, "/");
+        len = strip(target_out_path, len, "/system");
+        if (asprintf(&name, "%.*s%s", (int)len, target_out_path, conf[which][dir]) != -1) {
             fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY));
             free(name);
         }
diff --git a/libcutils/include/private/fs_config.h b/libcutils/include/private/fs_config.h
new file mode 100644
index 0000000..7dad668
--- /dev/null
+++ b/libcutils/include/private/fs_config.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_CUTILS_PRIVATE_FS_CONFIG_H
+#define _LIBS_CUTILS_PRIVATE_FS_CONFIG_H
+
+#include <stdint.h>
+
+/*
+ * binary format for the runtime <partition>/etc/fs_config_(dirs|files)
+ * filesystem override files.
+ */
+
+/* The following structure is stored little endian */
+struct fs_path_config_from_file {
+    uint16_t len;
+    uint16_t mode;
+    uint16_t uid;
+    uint16_t gid;
+    uint64_t capabilities;
+    char prefix[];
+} __attribute__((__aligned__(sizeof(uint64_t))));
+
+#endif /* _LIBS_CUTILS_PRIVATE_FS_CONFIG_H */
diff --git a/libgrallocusage/GrallocUsageConversion.cpp b/libgrallocusage/GrallocUsageConversion.cpp
index 8164beb..05c8ec4 100644
--- a/libgrallocusage/GrallocUsageConversion.cpp
+++ b/libgrallocusage/GrallocUsageConversion.cpp
@@ -16,49 +16,51 @@
 
 #include <grallocusage/GrallocUsageConversion.h>
 
-#include <android/hardware/graphics/allocator/2.0/types.h>
 #include <hardware/gralloc.h>
-
-using android::hardware::graphics::allocator::V2_0::ProducerUsage;
-using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
+#include <hardware/gralloc1.h>
 
 void android_convertGralloc0To1Usage(int32_t usage, uint64_t* producerUsage,
                                      uint64_t* consumerUsage) {
-    constexpr uint64_t PRODUCER_MASK = ProducerUsage::CPU_READ |
-                                       /* ProducerUsage::CPU_READ_OFTEN | */
-                                       ProducerUsage::CPU_WRITE |
-                                       /* ProducerUsage::CPU_WRITE_OFTEN | */
-                                       ProducerUsage::GPU_RENDER_TARGET | ProducerUsage::PROTECTED |
-                                       ProducerUsage::CAMERA | ProducerUsage::VIDEO_DECODER |
-                                       ProducerUsage::SENSOR_DIRECT_DATA;
-    constexpr uint64_t CONSUMER_MASK = ConsumerUsage::CPU_READ |
-                                       /* ConsumerUsage::CPU_READ_OFTEN | */
-                                       ConsumerUsage::GPU_TEXTURE | ConsumerUsage::HWCOMPOSER |
-                                       ConsumerUsage::CLIENT_TARGET | ConsumerUsage::CURSOR |
-                                       ConsumerUsage::VIDEO_ENCODER | ConsumerUsage::CAMERA |
-                                       ConsumerUsage::RENDERSCRIPT | ConsumerUsage::GPU_DATA_BUFFER;
+    constexpr uint64_t PRODUCER_MASK =
+        GRALLOC1_PRODUCER_USAGE_CPU_READ |
+        /* GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN | */
+        GRALLOC1_PRODUCER_USAGE_CPU_WRITE |
+        /* GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN | */
+        GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET | GRALLOC1_PRODUCER_USAGE_PROTECTED |
+        GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER |
+        GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA;
+    constexpr uint64_t CONSUMER_MASK =
+        GRALLOC1_CONSUMER_USAGE_CPU_READ |
+        /* GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN | */
+        GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE | GRALLOC1_CONSUMER_USAGE_HWCOMPOSER |
+        GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET | GRALLOC1_CONSUMER_USAGE_CURSOR |
+        GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CAMERA |
+        GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT | GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
     *producerUsage = static_cast<uint64_t>(usage) & PRODUCER_MASK;
     *consumerUsage = static_cast<uint64_t>(usage) & CONSUMER_MASK;
     if ((static_cast<uint32_t>(usage) & GRALLOC_USAGE_SW_READ_OFTEN) == GRALLOC_USAGE_SW_READ_OFTEN) {
-        *producerUsage |= ProducerUsage::CPU_READ_OFTEN;
-        *consumerUsage |= ConsumerUsage::CPU_READ_OFTEN;
+        *producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+        *consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
     }
     if ((static_cast<uint32_t>(usage) & GRALLOC_USAGE_SW_WRITE_OFTEN) ==
         GRALLOC_USAGE_SW_WRITE_OFTEN) {
-        *producerUsage |= ProducerUsage::CPU_WRITE_OFTEN;
+        *producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
     }
 }
 
 int32_t android_convertGralloc1To0Usage(uint64_t producerUsage, uint64_t consumerUsage) {
-    static_assert(uint64_t(ConsumerUsage::CPU_READ_OFTEN) == uint64_t(ProducerUsage::CPU_READ_OFTEN),
+    static_assert(uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
+                      uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN),
                   "expected ConsumerUsage and ProducerUsage CPU_READ_OFTEN bits to match");
     uint64_t merged = producerUsage | consumerUsage;
-    if ((merged & (ConsumerUsage::CPU_READ_OFTEN)) != 0) {
-        merged &= ~uint64_t(ConsumerUsage::CPU_READ_OFTEN);
+    if ((merged & (GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)) ==
+        GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
+        merged &= ~uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
         merged |= GRALLOC_USAGE_SW_READ_OFTEN;
     }
-    if ((merged & (ProducerUsage::CPU_WRITE_OFTEN)) != 0) {
-        merged &= ~uint64_t(ProducerUsage::CPU_WRITE_OFTEN);
+    if ((merged & (GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) ==
+        GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
+        merged &= ~uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
         merged |= GRALLOC_USAGE_SW_WRITE_OFTEN;
     }
     return static_cast<int32_t>(merged);
diff --git a/liblog/Android.bp b/liblog/Android.bp
index bb8c3af..e74aa82 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -107,14 +107,16 @@
     license: "NOTICE",
 }
 
-cc_library_headers {
-    name: "liblog_vndk_headers",
-    export_include_dirs: ["include_vndk"],
-}
-
 ndk_library {
-    name: "liblog.ndk",
+    name: "liblog",
     symbol_file: "liblog.map.txt",
     first_version: "9",
     unversioned_until: "current",
 }
+
+llndk_library {
+    name: "liblog",
+    symbol_file: "liblog.map.txt",
+    unversioned: true,
+    export_include_dirs: ["include_vndk"],
+}
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
index 599dc90..c00f2a0 100644
--- a/liblog/liblog.map.txt
+++ b/liblog/liblog.map.txt
@@ -1,6 +1,10 @@
 LIBLOG {
   global:
+    android_name_to_log_id; # vndk
+    android_log_id_to_name; # vndk
     __android_log_assert;
+    __android_log_buf_print; # vndk
+    __android_log_buf_write; # vndk
     __android_log_print;
     __android_log_vprint;
     __android_log_write;
@@ -8,8 +12,27 @@
     *;
 };
 
+LIBLOG_L {
+  global:
+    android_logger_clear; # vndk
+    android_logger_get_id; # vndk
+    android_logger_get_log_readable_size; # vndk
+    android_logger_get_log_version; # vndk
+    android_logger_get_log_size; # vndk
+    android_logger_list_alloc; # vndk
+    android_logger_list_alloc_time; # vndk
+    android_logger_list_free; # vndk
+    android_logger_list_open; # vndk
+    android_logger_list_read; # vndk
+    android_logger_open; # vndk
+    android_logger_set_log_size; # vndk
+};
+
 LIBLOG_M {
   global:
+    android_logger_get_prune_list; # vndk
+    android_logger_set_prune_list; # vndk
+    android_logger_get_statistics; # vndk
     __android_log_is_loggable;
 };
 
diff --git a/liblog/properties.c b/liblog/properties.c
index 0b0ef52..adf1900 100644
--- a/liblog/properties.c
+++ b/liblog/properties.c
@@ -95,7 +95,7 @@
   /* calculate the size of our key temporary buffer */
   const size_t taglen = tag ? len : 0;
   /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
-  char key[sizeof(log_namespace) + taglen]; /* may be > PROP_NAME_MAX */
+  char key[sizeof(log_namespace) + taglen];
   char* kp;
   size_t i;
   char c = 0;
@@ -108,7 +108,8 @@
    * Where the missing tag matches all tags and becomes the
    * system global default. We do not support ro.log.tag* .
    */
-  static char last_tag[PROP_NAME_MAX];
+  static char* last_tag;
+  static size_t last_tag_len;
   static uint32_t global_serial;
   /* some compilers erroneously see uninitialized use. !not_locked */
   uint32_t current_global_serial = 0;
@@ -147,25 +148,29 @@
   if (taglen) {
     int local_change_detected = change_detected;
     if (!not_locked) {
-      if (!last_tag[0] || (last_tag[0] != tag[0]) ||
-          strncmp(
-              last_tag + 1, tag + 1,
-              (len < sizeof(last_tag)) ? (len - 1) : (sizeof(last_tag) - 1)) ||
-          ((len < sizeof(last_tag)) && last_tag[len])) {
+      if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) ||
+          strncmp(last_tag + 1, tag + 1, last_tag_len - 1)) {
         /* invalidate log.tag.<tag> cache */
         for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
           tag_cache[i].cache.pinfo = NULL;
           tag_cache[i].c = '\0';
         }
-        last_tag[0] = '\0';
+        if (last_tag) last_tag[0] = '\0';
         local_change_detected = 1;
       }
-      if (!last_tag[0]) {
-        if (len < sizeof(last_tag)) {
+      if (!last_tag || !last_tag[0]) {
+        if (!last_tag) {
+          last_tag = calloc(1, len + 1);
+          last_tag_len = 0;
+          if (last_tag) last_tag_len = len + 1;
+        } else if (len >= last_tag_len) {
+          last_tag = realloc(last_tag, len + 1);
+          last_tag_len = 0;
+          if (last_tag) last_tag_len = len + 1;
+        }
+        if (last_tag) {
           strncpy(last_tag, tag, len);
           last_tag[len] = '\0';
-        } else {
-          strncpy(last_tag, tag, sizeof(last_tag));
         }
       }
     }
@@ -435,7 +440,7 @@
                                                            int flag) {
   struct cache_property property = { { NULL, -1 }, { 0 } };
   if (flag & BOOL_DEFAULT_FLAG_PERSIST) {
-    char newkey[PROP_NAME_MAX];
+    char newkey[strlen("persist.") + strlen(key) + 1];
     snprintf(newkey, sizeof(newkey), "ro.%s", key);
     refresh_cache_property(&property, newkey);
     property.cache.pinfo = NULL;
@@ -600,8 +605,8 @@
     evaluate_property_get_size
     /* clang-format on */
   };
-  char key_persist[PROP_NAME_MAX];
-  char key_ro[PROP_NAME_MAX];
+  char key_persist[strlen(global_tunable) + strlen(".security") + 1];
+  char key_ro[strlen(global_default) + strlen(".security") + 1];
   struct cache2_property_size local = {
     /* clang-format off */
     PTHREAD_MUTEX_INITIALIZER, 0,
diff --git a/libsync/Android.bp b/libsync/Android.bp
index b293da4..e7dcf36 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -7,7 +7,7 @@
 }
 
 ndk_library {
-    name: "libsync.ndk",
+    name: "libsync",
     symbol_file: "libsync.map.txt",
     first_version: "26",
 }
diff --git a/libsystem/Android.bp b/libsystem/Android.bp
new file mode 100644
index 0000000..4d076d5
--- /dev/null
+++ b/libsystem/Android.bp
@@ -0,0 +1,4 @@
+cc_library_headers {
+    name: "libsystem_headers",
+    export_include_dirs: ["include"],
+}
diff --git a/include/system/camera.h b/libsystem/include/system/camera.h
similarity index 100%
rename from include/system/camera.h
rename to libsystem/include/system/camera.h
diff --git a/include/system/graphics-base.h b/libsystem/include/system/graphics-base.h
similarity index 100%
rename from include/system/graphics-base.h
rename to libsystem/include/system/graphics-base.h
diff --git a/include/system/graphics.h b/libsystem/include/system/graphics.h
similarity index 100%
rename from include/system/graphics.h
rename to libsystem/include/system/graphics.h
diff --git a/include/system/qemu_pipe.h b/libsystem/include/system/qemu_pipe.h
similarity index 100%
rename from include/system/qemu_pipe.h
rename to libsystem/include/system/qemu_pipe.h
diff --git a/include/system/radio.h b/libsystem/include/system/radio.h
similarity index 100%
rename from include/system/radio.h
rename to libsystem/include/system/radio.h
diff --git a/include/system/thread_defs.h b/libsystem/include/system/thread_defs.h
similarity index 100%
rename from include/system/thread_defs.h
rename to libsystem/include/system/thread_defs.h
diff --git a/include/system/window-deprecated.h b/libsystem/include/system/window-deprecated.h
similarity index 100%
rename from include/system/window-deprecated.h
rename to libsystem/include/system/window-deprecated.h
diff --git a/include/system/window.h b/libsystem/include/system/window.h
similarity index 100%
rename from include/system/window.h
rename to libsystem/include/system/window.h
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index c2055b7..78de40a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -386,6 +386,14 @@
   const uint8_t* const cd_end = cd_ptr + cd_length;
   const uint8_t* ptr = cd_ptr;
   for (uint16_t i = 0; i < num_entries; i++) {
+    if (ptr > cd_end - sizeof(CentralDirectoryRecord)) {
+      ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
+#if defined(__ANDROID__)
+      android_errorWriteLog(0x534e4554, "36392138");
+#endif
+      return -1;
+    }
+
     const CentralDirectoryRecord* cdr =
         reinterpret_cast<const CentralDirectoryRecord*>(ptr);
     if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
@@ -393,11 +401,6 @@
       return -1;
     }
 
-    if (ptr + sizeof(CentralDirectoryRecord) > cd_end) {
-      ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
-      return -1;
-    }
-
     const off64_t local_header_offset = cdr->local_file_header_offset;
     if (local_header_offset >= archive->directory_offset) {
       ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16,
@@ -573,6 +576,17 @@
 
   // Paranoia: Match the values specified in the local file header
   // to those specified in the central directory.
+
+  // Verify that the central directory and local file header have the same general purpose bit
+  // flags set.
+  if (lfh->gpb_flags != cdr->gpb_flags) {
+    ALOGW("Zip: gpb flag mismatch. expected {%04" PRIx16 "}, was {%04" PRIx16 "}",
+          cdr->gpb_flags, lfh->gpb_flags);
+    return kInconsistentInformation;
+  }
+
+  // If there is no trailing data descriptor, verify that the central directory and local file
+  // header agree on the crc, compressed, and uncompressed sizes of the entry.
   if ((lfh->gpb_flags & kGPBDDFlagMask) == 0) {
     data->has_data_descriptor = 0;
     if (data->compressed_length != lfh->compressed_size
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 2edf224..6d28bdb 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -479,7 +479,9 @@
   for (FileEntry& file : files_) {
     CentralDirectoryRecord cdr = {};
     cdr.record_signature = CentralDirectoryRecord::kSignature;
-    cdr.gpb_flags |= kGPBDDFlagMask;
+    if ((file.compression_method & kCompressDeflated) || !seekable_) {
+      cdr.gpb_flags |= kGPBDDFlagMask;
+    }
     cdr.compression_method = file.compression_method;
     cdr.last_mod_time = file.last_mod_time;
     cdr.last_mod_date = file.last_mod_date;