Merge "healthd: Remove libhealthd dependency from charger"
diff --git a/base/Android.bp b/base/Android.bp
index f5000c1..25ae535 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -61,7 +61,6 @@
         "parsenetaddress.cpp",
         "process.cpp",
         "properties.cpp",
-        "quick_exit.cpp",
         "stringprintf.cpp",
         "strings.cpp",
         "threads.cpp",
@@ -154,7 +153,6 @@
         "parsenetaddress_test.cpp",
         "process_test.cpp",
         "properties_test.cpp",
-        "quick_exit_test.cpp",
         "result_test.cpp",
         "scopeguard_test.cpp",
         "stringprintf_test.cpp",
diff --git a/base/include/android-base/quick_exit.h b/base/include/android-base/quick_exit.h
deleted file mode 100644
index a03b14f..0000000
--- a/base/include/android-base/quick_exit.h
+++ /dev/null
@@ -1,34 +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.
- */
-
-#pragma once
-
-#include <stdlib.h>
-
-// Provide emulation for at_quick_exit/quick_exit on platforms that don't have it.
-namespace android {
-namespace base {
-
-// Bionic and glibc have quick_exit, Darwin and Windows don't.
-#if !defined(__linux__)
-  void quick_exit(int exit_code) __attribute__((noreturn));
-  int at_quick_exit(void (*func)());
-#else
-  using ::at_quick_exit;
-  using ::quick_exit;
-#endif
-}
-}
diff --git a/base/quick_exit.cpp b/base/quick_exit.cpp
deleted file mode 100644
index e4dd62b..0000000
--- a/base/quick_exit.cpp
+++ /dev/null
@@ -1,46 +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.
- */
-
-#include "android-base/quick_exit.h"
-
-#if !defined(__linux__)
-
-#include <mutex>
-#include <vector>
-
-namespace android {
-namespace base {
-
-static auto& quick_exit_mutex = *new std::mutex();
-static auto& quick_exit_handlers = *new std::vector<void (*)()>();
-
-void quick_exit(int exit_code) {
-  std::lock_guard<std::mutex> lock(quick_exit_mutex);
-  for (auto it = quick_exit_handlers.rbegin(); it != quick_exit_handlers.rend(); ++it) {
-    (*it)();
-  }
-  _Exit(exit_code);
-}
-
-int at_quick_exit(void (*func)()) {
-  std::lock_guard<std::mutex> lock(quick_exit_mutex);
-  quick_exit_handlers.push_back(func);
-  return 0;
-}
-
-}  // namespace base
-}  // namespace android
-#endif
diff --git a/base/quick_exit_test.cpp b/base/quick_exit_test.cpp
deleted file mode 100644
index 7ca8156..0000000
--- a/base/quick_exit_test.cpp
+++ /dev/null
@@ -1,54 +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.
- */
-
-#include "android-base/quick_exit.h"
-
-#include <gtest/gtest.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <string>
-
-#include "android-base/test_utils.h"
-
-// These tests are a bit sketchy, since each test run adds global state that affects subsequent
-// tests (including ones not in this file!). Exit with 0 in Exiter and stick the at_quick_exit test
-// at the end to hack around this.
-struct Exiter {
-  ~Exiter() {
-    _Exit(0);
-  }
-};
-
-TEST(quick_exit, smoke) {
-  ASSERT_EXIT(android::base::quick_exit(123), testing::ExitedWithCode(123), "");
-}
-
-TEST(quick_exit, skip_static_destructors) {
-  static Exiter exiter;
-  ASSERT_EXIT(android::base::quick_exit(123), testing::ExitedWithCode(123), "");
-}
-
-TEST(quick_exit, at_quick_exit) {
-  static int counter = 4;
-  // "Functions passed to at_quick_exit are called in reverse order of their registration."
-  ASSERT_EQ(0, android::base::at_quick_exit([]() { _exit(counter); }));
-  ASSERT_EQ(0, android::base::at_quick_exit([]() { counter += 2; }));
-  ASSERT_EQ(0, android::base::at_quick_exit([]() { counter *= 10; }));
-  ASSERT_EXIT(android::base::quick_exit(123), testing::ExitedWithCode(42), "");
-}
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index f452a64..02a887e 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -122,6 +122,7 @@
 
     shared_libs: [
         "android.hardware.boot@1.0",
+        "android.hardware.boot@1.1",
         "android.hardware.fastboot@1.0",
         "android.hardware.health@2.0",
         "libadbd",
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 8a72627..7fba67c 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -34,6 +34,7 @@
 #define FB_CMD_UPDATE_SUPER "update-super"
 #define FB_CMD_OEM "oem"
 #define FB_CMD_GSI "gsi"
+#define FB_CMD_SNAPSHOT_UPDATE "snapshot-update"
 
 #define RESPONSE_OKAY "OKAY"
 #define RESPONSE_FAIL "FAIL"
@@ -66,3 +67,4 @@
 #define FB_VAR_BATTERY_VOLTAGE "battery-voltage"
 #define FB_VAR_BATTERY_SOC_OK "battery-soc-ok"
 #define FB_VAR_SUPER_PARTITION_NAME "super-partition-name"
+#define FB_VAR_SNAPSHOT_UPDATE_STATUS "snapshot-update-status"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 4c77c75..dfd5690 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -25,6 +25,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
 #include <cutils/android_reboot.h>
 #include <ext4_utils/wipe.h>
 #include <fs_mgr.h>
@@ -44,8 +45,10 @@
 using ::android::hardware::boot::V1_0::BoolResult;
 using ::android::hardware::boot::V1_0::CommandResult;
 using ::android::hardware::boot::V1_0::Slot;
+using ::android::hardware::boot::V1_1::MergeStatus;
 using ::android::hardware::fastboot::V1_0::Result;
 using ::android::hardware::fastboot::V1_0::Status;
+using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
 
 struct VariableHandlers {
     // Callback to retrieve the value of a single variable.
@@ -101,7 +104,8 @@
             {FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
             {FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
             {FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
-            {FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}}};
+            {FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}},
+            {FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}}};
 
     if (args.size() < 2) {
         return device->WriteFail("Missing argument");
@@ -547,3 +551,40 @@
     }
     return device->WriteStatus(FastbootResult::OKAY, "Success");
 }
+
+bool SnapshotUpdateHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+    // Note that we use the HAL rather than mounting /metadata, since we want
+    // our results to match the bootloader.
+    auto hal = device->boot_control_hal();
+    if (!hal) return device->WriteFail("Not supported");
+
+    android::sp<IBootControl1_1> hal11 = IBootControl1_1::castFrom(hal);
+    if (!hal11) return device->WriteFail("Not supported");
+
+    // If no arguments, return the same thing as a getvar. Note that we get the
+    // HAL first so we can return "not supported" before we return the less
+    // specific error message below.
+    if (args.size() < 2 || args[1].empty()) {
+        std::string message;
+        if (!GetSnapshotUpdateStatus(device, {}, &message)) {
+            return device->WriteFail("Could not determine update status");
+        }
+        device->WriteInfo(message);
+        return device->WriteOkay("");
+    }
+
+    if (args.size() != 2 || args[1] != "cancel") {
+        return device->WriteFail("Invalid arguments");
+    }
+
+    MergeStatus status = hal11->getSnapshotMergeStatus();
+    switch (status) {
+        case MergeStatus::SNAPSHOTTED:
+        case MergeStatus::MERGING:
+            hal11->setSnapshotMergeStatus(MergeStatus::CANCELLED);
+            break;
+        default:
+            break;
+    }
+    return device->WriteStatus(FastbootResult::OKAY, "Success");
+}
diff --git a/fastboot/device/commands.h b/fastboot/device/commands.h
index 9b6e7b6..c1324bc 100644
--- a/fastboot/device/commands.h
+++ b/fastboot/device/commands.h
@@ -49,3 +49,4 @@
 bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>& args);
 bool OemCmdHandler(FastbootDevice* device, const std::vector<std::string>& args);
 bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args);
+bool SnapshotUpdateHandler(FastbootDevice* device, const std::vector<std::string>& args);
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 56fafab..d3c2bda 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -54,6 +54,7 @@
               {FB_CMD_UPDATE_SUPER, UpdateSuperHandler},
               {FB_CMD_OEM, OemCmdHandler},
               {FB_CMD_GSI, GsiHandler},
+              {FB_CMD_SNAPSHOT_UPDATE, SnapshotUpdateHandler},
       }),
       transport_(std::make_unique<ClientUsbTransport>()),
       boot_control_hal_(IBootControl::getService()),
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index 130a3cf..6e613d6 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -23,6 +23,7 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
 #include <ext4_utils/ext4_utils.h>
 #include <fs_mgr.h>
 #include <healthhalutils/HealthHalUtils.h>
@@ -34,9 +35,11 @@
 
 using ::android::hardware::boot::V1_0::BoolResult;
 using ::android::hardware::boot::V1_0::Slot;
+using ::android::hardware::boot::V1_1::MergeStatus;
 using ::android::hardware::fastboot::V1_0::FileSystemType;
 using ::android::hardware::fastboot::V1_0::Result;
 using ::android::hardware::fastboot::V1_0::Status;
+using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
 using namespace android::fs_mgr;
 
 constexpr char kFastbootProtocolVersion[] = "0.4";
@@ -424,3 +427,34 @@
     *message = fs_mgr_get_super_partition_name(slot_number);
     return true;
 }
+
+bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
+                             std::string* message) {
+    // Note that we use the HAL rather than mounting /metadata, since we want
+    // our results to match the bootloader.
+    auto hal = device->boot_control_hal();
+    if (!hal) {
+        *message = "not supported";
+        return false;
+    }
+
+    android::sp<IBootControl1_1> hal11 = IBootControl1_1::castFrom(hal);
+    if (!hal11) {
+        *message = "not supported";
+        return false;
+    }
+
+    MergeStatus status = hal11->getSnapshotMergeStatus();
+    switch (status) {
+        case MergeStatus::SNAPSHOTTED:
+            *message = "snapshotted";
+            break;
+        case MergeStatus::MERGING:
+            *message = "merging";
+            break;
+        default:
+            *message = "none";
+            break;
+    }
+    return true;
+}
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
index 015a4c5..4dec10f 100644
--- a/fastboot/device/variables.h
+++ b/fastboot/device/variables.h
@@ -61,6 +61,8 @@
                      std::string* message);
 bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& args,
                            std::string* message);
+bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& args,
+                             std::string* message);
 
 // Helpers for getvar all.
 std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 2fe3b1a..7ce7c7c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -396,6 +396,9 @@
             " gsi wipe|disable           Wipe or disable a GSI installation (fastbootd only).\n"
             " wipe-super [SUPER_EMPTY]   Wipe the super partition. This will reset it to\n"
             "                            contain an empty set of default dynamic partitions.\n"
+            " snapshot-update cancel     On devices that support snapshot-based updates, cancel\n"
+            "                            an in-progress update. This may make the device\n"
+            "                            unbootable until it is reflashed.\n"
             "\n"
             "boot image:\n"
             " boot KERNEL [RAMDISK [SECOND]]\n"
@@ -1216,6 +1219,14 @@
     target_sparse_limit = -1;
 }
 
+static void CancelSnapshotIfNeeded() {
+    std::string merge_status = "none";
+    if (fb->GetVar(FB_VAR_SNAPSHOT_UPDATE_STATUS, &merge_status) == fastboot::SUCCESS &&
+        merge_status != "none") {
+        fb->SnapshotUpdateCommand("Cancel");
+    }
+}
+
 class ImageSource {
   public:
     virtual bool ReadFile(const std::string& name, std::vector<char>* out) const = 0;
@@ -1268,6 +1279,8 @@
     DetermineSecondarySlot();
     CollectImages();
 
+    CancelSnapshotIfNeeded();
+
     // First flash boot partitions. We allow this to happen either in userspace
     // or in bootloader fastboot.
     FlashImages(boot_images_);
@@ -2071,12 +2084,24 @@
                 image = next_arg(&args);
             }
             do_wipe_super(image, slot_override);
+        } else if (command == "snapshot-update") {
+            std::string arg;
+            if (!args.empty()) {
+                arg = next_arg(&args);
+            }
+            if (!arg.empty() && arg != "cancel") {
+                syntax_error("expected: snapshot-update [cancel]");
+            }
+            fb->SnapshotUpdateCommand(arg);
         } else {
             syntax_error("unknown command %s", command.c_str());
         }
     }
 
     if (wants_wipe) {
+        if (force_flash) {
+            CancelSnapshotIfNeeded();
+        }
         std::vector<std::string> partitions = { "userdata", "cache", "metadata" };
         for (const auto& partition : partitions) {
             std::string partition_type;
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index b897182..6a5ad20 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -122,6 +122,12 @@
                       response, info);
 }
 
+RetCode FastBootDriver::SnapshotUpdateCommand(const std::string& command, std::string* response,
+                                              std::vector<std::string>* info) {
+    std::string raw = FB_CMD_SNAPSHOT_UPDATE ":" + command;
+    return RawCommand(raw, response, info);
+}
+
 RetCode FastBootDriver::FlashPartition(const std::string& partition,
                                        const std::vector<char>& data) {
     RetCode ret;
diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h
index af02637..7265632 100644
--- a/fastboot/fastboot_driver.h
+++ b/fastboot/fastboot_driver.h
@@ -104,6 +104,8 @@
                       std::vector<std::string>* info = nullptr);
     RetCode Upload(const std::string& outfile, std::string* response = nullptr,
                    std::vector<std::string>* info = nullptr);
+    RetCode SnapshotUpdateCommand(const std::string& command, std::string* response = nullptr,
+                                  std::vector<std::string>* info = nullptr);
 
     /* HIGHER LEVEL COMMANDS -- Composed of the commands above */
     RetCode FlashPartition(const std::string& partition, const std::vector<char>& data);
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 65f0eff..eb737bb 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -74,6 +74,7 @@
         "liblogwrap",
         "libdm",
         "libext2_uuid",
+        "libfscrypt",
         "libfstab",
     ],
     cppflags: [
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 6faead0..a8059b7 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -58,6 +58,7 @@
 #include <fs_avb/fs_avb.h>
 #include <fs_mgr/file_wait.h>
 #include <fs_mgr_overlayfs.h>
+#include <fscrypt/fscrypt.h>
 #include <libdm/dm.h>
 #include <liblp/metadata_format.h>
 #include <linux/fs.h>
@@ -84,6 +85,9 @@
 
 #define SYSFS_EXT4_VERITY "/sys/fs/ext4/features/verity"
 
+// FIXME: this should be in system/extras
+#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800
+
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
 
 using android::base::Basename;
@@ -412,25 +416,43 @@
 // Enable file-based encryption if needed.
 static void tune_encrypt(const std::string& blk_device, const FstabEntry& entry,
                          const struct ext4_super_block* sb, int* fs_stat) {
-    bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0;
-    bool want_encrypt = entry.fs_mgr_flags.file_encryption;
-
-    if (has_encrypt || !want_encrypt) {
+    if (!entry.fs_mgr_flags.file_encryption) {
+        return;  // Nothing needs done.
+    }
+    std::vector<std::string> features_needed;
+    if ((sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) == 0) {
+        features_needed.emplace_back("encrypt");
+    }
+    android::fscrypt::EncryptionOptions options;
+    if (!android::fscrypt::ParseOptions(entry.encryption_options, &options)) {
+        LERROR << "Unable to parse encryption options on " << blk_device << ": "
+               << entry.encryption_options;
         return;
     }
-
+    if ((options.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) != 0) {
+        // We can only use this policy on ext4 if the "stable_inodes" feature
+        // is set on the filesystem, otherwise shrinking will break encrypted files.
+        if ((sb->s_feature_compat & cpu_to_le32(EXT4_FEATURE_COMPAT_STABLE_INODES)) == 0) {
+            features_needed.emplace_back("stable_inodes");
+        }
+    }
+    if (features_needed.size() == 0) {
+        return;
+    }
     if (!tune2fs_available()) {
         LERROR << "Unable to enable ext4 encryption on " << blk_device
                << " because " TUNE2FS_BIN " is missing";
         return;
     }
 
-    const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device.c_str()};
+    auto flags = android::base::Join(features_needed, ',');
+    auto flag_arg = "-O"s + flags;
+    const char* argv[] = {TUNE2FS_BIN, flag_arg.c_str(), blk_device.c_str()};
 
-    LINFO << "Enabling ext4 encryption on " << blk_device;
+    LINFO << "Enabling ext4 flags " << flags << " on " << blk_device;
     if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
         LERROR << "Failed to run " TUNE2FS_BIN " to enable "
-               << "ext4 encryption on " << blk_device;
+               << "ext4 flags " << flags << " on " << blk_device;
         *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
     }
 }
diff --git a/fs_mgr/libsnapshot/utility.cpp b/fs_mgr/libsnapshot/utility.cpp
index 615cbca..1b2f528 100644
--- a/fs_mgr/libsnapshot/utility.cpp
+++ b/fs_mgr/libsnapshot/utility.cpp
@@ -19,6 +19,7 @@
 #include <android-base/strings.h>
 #include <fs_mgr/roots.h>
 
+using android::dm::kSectorSize;
 using android::fs_mgr::EnsurePathMounted;
 using android::fs_mgr::EnsurePathUnmounted;
 using android::fs_mgr::Fstab;
@@ -94,13 +95,11 @@
     // so it can be used to resume the last state of a snapshot device;
     // - an _INVALID_ snapshot otherwise.
     // To avoid zero-filling the whole CoW file when a new dm-snapshot is
-    // created, here we zero-fill only the first 32 bits. This is a temporary
-    // workaround that will be discussed again when the kernel API gets
-    // consolidated.
-    // TODO(b/139202197): Remove this hack once the kernel API is consolidated.
-    constexpr ssize_t kDmSnapZeroFillSize = 4;  // 32-bit
+    // created, here we zero-fill only the first chunk to be compliant with
+    // lvm.
+    constexpr ssize_t kDmSnapZeroFillSize = kSectorSize * kSnapshotChunkSize;
 
-    char zeros[kDmSnapZeroFillSize] = {0};
+    std::vector<uint8_t> zeros(kDmSnapZeroFillSize, 0);
     android::base::unique_fd fd(open(device.c_str(), O_WRONLY | O_BINARY));
     if (fd < 0) {
         PLOG(ERROR) << "Can't open COW device: " << device;
@@ -108,7 +107,7 @@
     }
 
     LOG(INFO) << "Zero-filling COW device: " << device;
-    if (!android::base::WriteFully(fd, zeros, kDmSnapZeroFillSize)) {
+    if (!android::base::WriteFully(fd, zeros.data(), kDmSnapZeroFillSize)) {
         PLOG(ERROR) << "Can't zero-fill COW device for " << device;
         return false;
     }
diff --git a/init/Android.bp b/init/Android.bp
index bd2d38c..776a3a6 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -79,7 +79,6 @@
         "libdl",
         "libext4_utils",
         "libfs_mgr",
-        "libfscrypt",
         "libgsi",
         "libhidl-gen-utils",
         "libkeyutils",
diff --git a/init/Android.mk b/init/Android.mk
index 4e4c002..997b2bc 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -91,7 +91,6 @@
     libsquashfs_utils \
     liblogwrap \
     libext4_utils \
-    libfscrypt \
     libcrypto_utils \
     libsparse \
     libavb \
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index fd2d766..ac44796 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -239,11 +239,16 @@
     }
 
     Modprobe m({"/lib/modules"});
-    if (!m.LoadListedModules()) {
-        LOG(FATAL) << "Failed to load kernel modules";
+    auto want_console = ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline);
+    if (!m.LoadListedModules(!want_console)) {
+        if (want_console) {
+            LOG(ERROR) << "Failed to load kernel modules, starting console";
+        } else {
+            LOG(FATAL) << "Failed to load kernel modules";
+        }
     }
 
-    if (ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline)) {
+    if (want_console) {
         StartConsole();
     }
 
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index 5dd5cf1..9b33a1c 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -26,6 +26,7 @@
 
 // android/api-level.h
 #define __ANDROID_API_P__ 28
+#define __ANDROID_API_Q__ 29
 #define __ANDROID_API_R__ 30
 
 // sys/system_properties.h
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index e7808a9..e6a341d 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -560,6 +560,11 @@
             str_args[0] = "/system/bin/watchdogd";
         }
     }
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+        if (str_args[0] == "/charger") {
+            str_args[0] = "/system/bin/charger";
+        }
+    }
 
     service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
     return {};
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 8947256..a8fcc87 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -61,8 +61,8 @@
 
 TEST(util, ReadFileSymbolicLink) {
     errno = 0;
-    // lrwxrwxrwx 1 root root 13 1970-01-01 00:00 charger -> /sbin/healthd
-    auto file_contents = ReadFile("/charger");
+    // lrw------- 1 root root 23 2008-12-31 19:00 default.prop -> system/etc/prop.default
+    auto file_contents = ReadFile("/default.prop");
     EXPECT_EQ(ELOOP, errno);
     ASSERT_FALSE(file_contents);
     EXPECT_EQ("open() failed: Too many symbolic links encountered",
diff --git a/libmodprobe/include/modprobe/modprobe.h b/libmodprobe/include/modprobe/modprobe.h
index 421d826..333fc55 100644
--- a/libmodprobe/include/modprobe/modprobe.h
+++ b/libmodprobe/include/modprobe/modprobe.h
@@ -26,7 +26,7 @@
   public:
     Modprobe(const std::vector<std::string>&);
 
-    bool LoadListedModules();
+    bool LoadListedModules(bool strict = true);
     bool LoadWithAliases(const std::string& module_name, bool strict,
                          const std::string& parameters = "");
     bool Remove(const std::string& module_name);
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index 3c78ec9..6b9107f 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -360,13 +360,15 @@
     return true;
 }
 
-bool Modprobe::LoadListedModules() {
+bool Modprobe::LoadListedModules(bool strict) {
+    auto ret = true;
     for (const auto& module : module_load_) {
         if (!LoadWithAliases(module, true)) {
-            return false;
+            ret = false;
+            if (strict) break;
         }
     }
-    return true;
+    return ret;
 }
 
 bool Modprobe::Remove(const std::string& module_name) {
diff --git a/libstats/OWNERS b/libstats/OWNERS
index ed06fbc..7855774 100644
--- a/libstats/OWNERS
+++ b/libstats/OWNERS
@@ -1,4 +1,7 @@
-bookatz@google.com
 joeo@google.com
+muhammadq@google.com
+ruchirr@google.com
+singhtejinder@google.com
+tsaichristine@google.com
 yaochen@google.com
-yanglu@google.com
+yro@google.com
diff --git a/logcat/Android.bp b/logcat/Android.bp
index e472d08..61fba59 100644
--- a/logcat/Android.bp
+++ b/logcat/Android.bp
@@ -36,19 +36,13 @@
 
     defaults: ["logcat_defaults"],
     srcs: [
-        "logcat_main.cpp",
         "logcat.cpp",
     ],
 }
 
-cc_binary {
+sh_binary {
     name: "logcatd",
-
-    defaults: ["logcat_defaults"],
-    srcs: [
-        "logcatd_main.cpp",
-        "logcat.cpp",
-    ],
+    src: "logcatd",
 }
 
 sh_binary {
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index dc84fd2..70ccb80 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include "logcat.h"
-
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
@@ -1177,7 +1175,7 @@
     return EXIT_SUCCESS;
 }
 
-int RunLogcat(int argc, char** argv) {
+int main(int argc, char** argv) {
     Logcat logcat;
     return logcat.Run(argc, argv);
 }
diff --git a/logcat/logcat.h b/logcat/logcat.h
deleted file mode 100644
index 4cc112b..0000000
--- a/logcat/logcat.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2005-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
-
-int RunLogcat(int argc, char** argv);
\ No newline at end of file
diff --git a/logcat/logcat_main.cpp b/logcat/logcat_main.cpp
deleted file mode 100644
index 59ab716..0000000
--- a/logcat/logcat_main.cpp
+++ /dev/null
@@ -1,25 +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.
- */
-
-#include <signal.h>
-#include <stdlib.h>
-
-#include "logcat.h"
-
-int main(int argc, char** argv) {
-    signal(SIGPIPE, exit);
-    return RunLogcat(argc, argv);
-}
diff --git a/logcat/logcatd b/logcat/logcatd
new file mode 100755
index 0000000..622e567
--- /dev/null
+++ b/logcat/logcatd
@@ -0,0 +1,25 @@
+#! /system/bin/sh
+
+# This is primarily meant to be used by logpersist.  This script is run as an init service, which
+# first reads the 'last' logcat to persistent storage with `-L` then run logcat again without
+# `-L` to read the current logcat buffers to persistent storage.
+
+has_last="false"
+for arg in "$@"; do
+  if [ "$arg" == "-L" -o "$arg" == "--last" ]; then
+    has_last="true"
+  fi
+done
+
+if [ "$has_last" == "true" ]; then
+  logcat "$@"
+fi
+
+args_without_last=()
+for arg in "$@"; do
+  if [ "$arg" != "-L" -a "$arg" != "--last" ]; then
+    ARGS+=("$arg")
+  fi
+done
+
+exec logcat "${ARGS[@]}"
diff --git a/logcat/logcatd_main.cpp b/logcat/logcatd_main.cpp
deleted file mode 100644
index 4da933f..0000000
--- a/logcat/logcatd_main.cpp
+++ /dev/null
@@ -1,64 +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.
- */
-
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-
-#include "logcat.h"
-
-int main(int argc, char** argv) {
-    signal(SIGPIPE, exit);
-
-    // Save and detect presence of -L or --last flag
-    std::vector<std::string> args;
-    bool last = false;
-    for (int i = 0; i < argc; ++i) {
-        if (!argv[i]) continue;
-        args.push_back(std::string(argv[i]));
-        if (!strcmp(argv[i], "-L") || !strcmp(argv[i], "--last")) last = true;
-    }
-
-    // Generate argv from saved content
-    std::vector<const char*> argv_hold;
-    for (auto& str : args) argv_hold.push_back(str.c_str());
-    argv_hold.push_back(nullptr);
-
-    int ret = 0;
-    if (last) {
-        // Run logcat command with -L flag
-        ret = RunLogcat(argv_hold.size() - 1, (char**)&argv_hold[0]);
-        // Remove -L and --last flags from argument list
-        for (std::vector<const char*>::iterator it = argv_hold.begin();
-             it != argv_hold.end();) {
-            if (!*it || (strcmp(*it, "-L") && strcmp(*it, "--last"))) {
-                ++it;
-            } else {
-                it = argv_hold.erase(it);
-            }
-        }
-        // fall through to re-run the command regardless of the arguments
-        // passed in.  For instance, we expect -h to report help stutter.
-    }
-
-    // Run logcat command without -L flag
-    int retval = RunLogcat(argv_hold.size() - 1, (char**)&argv_hold[0]);
-    if (!ret) ret = retval;
-    return ret;
-}
diff --git a/logcat/logpersist b/logcat/logpersist
index c09b6b2..05b46f0 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -148,9 +148,9 @@
     echo "WARNING: Can not use --size or --buffer with ${progname%.*}.stop" >&2
   fi
   if [ "true" = "${clear}" ]; then
-    setprop ${property} "clear"
+    setprop ${property#persist.} "clear"
   else
-    setprop ${property} "stop"
+    setprop ${property#persist.} "stop"
   fi
   if [ -n "`getprop ${property#persist.}.buffer`" ]; then
     setprop ${property}.buffer ""
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 5241730..eac3f06 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -293,78 +293,26 @@
 LOCAL_MODULE_STEM := ld.config.txt
 include $(BUILD_PREBUILT)
 
-# Returns the unique installed basenames of a module, or module.so if there are
-# none.  The guess is to handle cases like libc, where the module itself is
-# marked uninstallable but a symlink is installed with the name libc.so.
-# $(1): list of libraries
-# $(2): suffix to to add to each library (not used for guess)
-define module-installed-files-or-guess
-$(foreach lib,$(1),$(or $(strip $(sort $(notdir $(call module-installed-files,$(lib)$(2))))),$(lib).so))
-endef
-
 #######################################
-# llndk.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := llndk.libraries.txt
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(call module-installed-files-or-guess,$(LLNDK_LIBRARIES),)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \
-		echo $(lib) >> $@;)
+# {llndk,vndkcore,vndksp,vndkprivate,vndkcorevariant}.libraries.txt
+vndk_libraries_files := \
+  llndk.libraries.txt:$(SOONG_LLNDK_LIBRARIES_FILE)\
+  vndkcore.libraries.txt:$(SOONG_VNDKCORE_LIBRARIES_FILE)\
+  vndksp.libraries.txt:$(SOONG_VNDKSP_LIBRARIES_FILE)\
+  vndkprivate.libraries.txt:$(SOONG_VNDKPRIVATE_LIBRARIES_FILE)\
+  vndkcorevariant.libraries.txt:$(SOONG_VNDKCOREVARIANT_LIBRARIES_FILE)
 
-#######################################
-# vndksp.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := vndksp.libraries.txt
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_SAMEPROCESS_LIBRARIES),.com.android.vndk.current)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \
-		echo $(lib) >> $@;)
-
-#######################################
-# vndkcore.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := vndkcore.libraries.txt
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_CORE_LIBRARIES),.com.android.vndk.current)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_VNDK_CORE_LIBRARIES), \
-		echo $(lib) >> $@;)
-
-#######################################
-# vndkprivate.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := vndkprivate.libraries.txt
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_PRIVATE_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_PRIVATE_LIBRARIES),.com.android.vndk.current)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_VNDK_PRIVATE_LIBRARIES), \
-		echo $(lib) >> $@;)
+$(foreach pair,$(vndk_libraries_files),\
+  $(eval _filename := $(call word-colon,1,$(pair)))\
+  $(eval _prebuilt := $(call word-colon,2,$(pair)))\
+  $(eval include $(CLEAR_VARS))\
+  $(eval LOCAL_MODULE := $(_filename))\
+  $(eval LOCAL_MODULE_CLASS := ETC)\
+  $(eval LOCAL_PREBUILT_MODULE_FILE := $(_prebuilt))\
+  $(eval LOCAL_MODULE_PATH := $(TARGET_OUT_ETC))\
+  $(eval LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE)))\
+  $(eval include $(BUILD_PREBUILT)))
+vndk_libraries_files :=
 
 #######################################
 # sanitizer.libraries.txt
@@ -391,22 +339,6 @@
 		echo $(lib) >> $@;)
 
 #######################################
-# vndkcorevariant.libraries.txt
-include $(CLEAR_VARS)
-LOCAL_MODULE := vndkcorevariant.libraries.txt
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-LOCAL_MODULE_STEM := $(call append_vndk_version,$(LOCAL_MODULE))
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_VARIANT_LIBRARIES := $(call module-installed-files-or-guess,$(VNDK_USING_CORE_VARIANT_LIBRARIES),.vendor)
-$(LOCAL_BUILT_MODULE):
-	@echo "Generate: $@"
-	@mkdir -p $(dir $@)
-	$(hide) echo -n > $@
-	$(hide) $(foreach lib,$(PRIVATE_VNDK_CORE_VARIANT_LIBRARIES), \
-		echo $(lib) >> $@;)
-
-#######################################
 # adb_debug.prop in debug ramdisk
 include $(CLEAR_VARS)
 LOCAL_MODULE := adb_debug.prop
diff --git a/trusty/OWNERS b/trusty/OWNERS
index e807d71..1fb473e 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -2,6 +2,8 @@
 dkrahn@google.com
 drewry@google.com
 gmar@google.com
+mmaurer@google.com
 ncbray@google.com
-rpere@google.com
 swillden@google.com
+trong@google.com
+wenhaowang@google.com
diff --git a/trusty/utils/trusty-ut-ctrl/Android.bp b/trusty/utils/trusty-ut-ctrl/Android.bp
index 77d1f70..9c8af7b 100644
--- a/trusty/utils/trusty-ut-ctrl/Android.bp
+++ b/trusty/utils/trusty-ut-ctrl/Android.bp
@@ -20,6 +20,8 @@
     shared_libs: [
         "libc",
         "liblog",
+    ],
+    static_libs: [
         "libtrusty",
     ],
     gtest: false,