Merge "adb: turn off fastdeploy."
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index 3c9dd04..b26c691 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -75,16 +75,20 @@
 
 // Returns the device used to mount a directory in the fstab.
 static std::string find_fstab_mount(const char* dir) {
-    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
-                                                               fs_mgr_free_fstab);
-    struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab.get(), dir);
-    if (!rec) {
+    Fstab fstab;
+    if (!ReadDefaultFstab(&fstab)) {
         return "";
     }
-    if (fs_mgr_is_logical(rec)) {
-        fs_mgr_update_logical_partition(rec);
+
+    auto entry = std::find_if(fstab.begin(), fstab.end(),
+                              [&dir](const auto& entry) { return entry.mount_point == dir; });
+    if (entry == fstab.end()) {
+        return "";
     }
-    return rec->blk_device;
+    if (entry->fs_mgr_flags.logical) {
+        fs_mgr_update_logical_partition(&(*entry));
+    }
+    return entry->blk_device;
 }
 
 // The proc entry for / is full of lies, so check fstab instead.
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
index 3676de5..f5c28c6 100644
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ b/adb/daemon/set_verity_enable_state_service.cpp
@@ -41,8 +41,6 @@
 
 #include "fec/io.h"
 
-struct fstab *fstab;
-
 #ifdef ALLOW_ADBD_DISABLE_VERITY
 static const bool kAllowDisableVerity = true;
 #else
@@ -213,18 +211,18 @@
         // Not using AVB - assume VB1.0.
 
         // read all fstab entries at once from all sources
-        if (!fstab) fstab = fs_mgr_read_fstab_default();
-        if (!fstab) {
+        Fstab fstab;
+        if (!ReadDefaultFstab(&fstab)) {
             WriteFdExactly(fd.get(), "Failed to read fstab\n");
             suggest_run_adb_root(fd.get());
             return;
         }
 
         // Loop through entries looking for ones that verity manages.
-        for (int i = 0; i < fstab->num_entries; i++) {
-            if (fs_mgr_is_verified(&fstab->recs[i])) {
-                if (set_verity_enabled_state(fd.get(), fstab->recs[i].blk_device,
-                                             fstab->recs[i].mount_point, enable)) {
+        for (const auto& entry : fstab) {
+            if (entry.fs_mgr_flags.verify) {
+                if (set_verity_enabled_state(fd.get(), entry.blk_device.c_str(),
+                                             entry.mount_point.c_str(), enable)) {
                     any_changed = true;
                 }
             }
diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp
index f737405..99854c9 100644
--- a/fastboot/device/flashing.cpp
+++ b/fastboot/device/flashing.cpp
@@ -52,15 +52,17 @@
     // Following appears to have a first time 2% impact on flashing speeds.
 
     // Convert partition_name to a validated mount point and wipe.
-    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
-                                                               fs_mgr_free_fstab);
-    for (auto i = 0; i < fstab->num_entries; i++) {
-        const auto mount_point = fstab->recs[i].mount_point;
-        if (!mount_point) continue;
-        auto partition = android::base::Basename(mount_point);
-        if ("/"s == mount_point) partition = "system";
+    Fstab fstab;
+    ReadDefaultFstab(&fstab);
+
+    for (const auto& entry : fstab) {
+        auto partition = android::base::Basename(entry.mount_point);
+        if ("/" == entry.mount_point) {
+            partition = "system";
+        }
+
         if ((partition + device->GetCurrentSlot()) == partition_name) {
-            fs_mgr_overlayfs_teardown(mount_point);
+            fs_mgr_overlayfs_teardown(entry.mount_point.c_str());
         }
     }
 }
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index ded3678..26ce3b2 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -889,19 +889,6 @@
     return true;
 }
 
-bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
-    auto entry = FstabRecToFstabEntry(rec);
-
-    if (!fs_mgr_update_logical_partition(&entry)) {
-        return false;
-    }
-
-    free(rec->blk_device);
-    rec->blk_device = strdup(entry.blk_device.c_str());
-
-    return true;
-}
-
 class CheckpointManager {
   public:
     CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index e87332f..1685e50 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -79,7 +79,6 @@
         std::function<void(const std::string& mount_point, int mode)> callback);
 bool fs_mgr_swapon_all(const Fstab& fstab);
 bool fs_mgr_update_logical_partition(FstabEntry* entry);
-bool fs_mgr_update_logical_partition(struct fstab_rec* rec);
 
 int fs_mgr_do_format(const FstabEntry& entry, bool reserve_footer);
 int fs_mgr_do_format(fstab_rec* rec, bool reserve_footer);
diff --git a/fs_mgr/libfs_avb/Android.bp b/fs_mgr/libfs_avb/Android.bp
index 191e803..3e93265 100644
--- a/fs_mgr/libfs_avb/Android.bp
+++ b/fs_mgr/libfs_avb/Android.bp
@@ -88,6 +88,7 @@
 cc_test_host {
     name: "libfs_avb_test",
     defaults: ["libfs_avb_host_test_defaults"],
+    test_suites: ["general-tests"],
     static_libs: [
         "libfs_avb_test_util",
     ],
@@ -103,6 +104,7 @@
 cc_test_host {
     name: "libfs_avb_internal_test",
     defaults: ["libfs_avb_host_test_defaults"],
+    test_suites: ["general-tests"],
     static_libs: [
         "libfs_avb_test_util",
     ],
diff --git a/fs_mgr/libfs_avb/TEST_MAPPING b/fs_mgr/libfs_avb/TEST_MAPPING
new file mode 100644
index 0000000..dc23827
--- /dev/null
+++ b/fs_mgr/libfs_avb/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "libfs_avb_test",
+      "host": true
+    },
+    {
+      "name": "libfs_avb_internal_test",
+      "host": true
+    }
+  ]
+}
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index 8f08169..69724f8 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -442,10 +442,6 @@
 }
 
 TEST_F(BuilderTest, block_device_info) {
-    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
-                                                               fs_mgr_free_fstab);
-    ASSERT_NE(fstab, nullptr);
-
     PartitionOpener opener;
 
     BlockDeviceInfo device_info;
diff --git a/healthd/OWNERS b/healthd/OWNERS
index 00df08a..d3f8758 100644
--- a/healthd/OWNERS
+++ b/healthd/OWNERS
@@ -1,2 +1,2 @@
 elsk@google.com
-toddpoynor@google.com
+hridya@google.com
diff --git a/healthd/animation.h b/healthd/animation.h
index f59fb38..9476c91 100644
--- a/healthd/animation.h
+++ b/healthd/animation.h
@@ -48,6 +48,25 @@
         GRFont* font;
     };
 
+    // When libminui loads PNG images:
+    // - When treating paths as relative paths, it adds ".png" suffix.
+    // - When treating paths as absolute paths, it doesn't add the suffix. Hence, the suffix
+    //   is added here.
+    void set_resource_root(const std::string& root) {
+        if (!animation_file.empty()) {
+            animation_file = root + animation_file + ".png";
+        }
+        if (!fail_file.empty()) {
+            fail_file = root + fail_file + ".png";
+        }
+        if (!text_clock.font_file.empty()) {
+            text_clock.font_file = root + text_clock.font_file + ".png";
+        }
+        if (!text_percent.font_file.empty()) {
+            text_percent.font_file = root + text_percent.font_file + ".png";
+        }
+    }
+
     std::string animation_file;
     std::string fail_file;
 
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 2eb5497..8f2f727 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -80,8 +80,13 @@
 #define LOGW(x...) KLOG_WARNING("charger", x);
 #define LOGV(x...) KLOG_DEBUG("charger", x);
 
-static constexpr const char* animation_desc_path =
-    "/res/values/charger/animation.txt";
+// Resources in /product/etc/res overrides resources in /res.
+// If the device is using the Generic System Image (GSI), resources may exist in
+// both paths.
+static constexpr const char* product_animation_desc_path =
+        "/product/etc/res/values/charger/animation.txt";
+static constexpr const char* product_animation_root = "/product/etc/res/images/";
+static constexpr const char* animation_desc_path = "/res/values/charger/animation.txt";
 
 struct key_state {
     bool pending;
@@ -600,7 +605,10 @@
     bool parse_success;
 
     std::string content;
-    if (base::ReadFileToString(animation_desc_path, &content)) {
+    if (base::ReadFileToString(product_animation_desc_path, &content)) {
+        parse_success = parse_animation_desc(content, &battery_animation);
+        battery_animation.set_resource_root(product_animation_root);
+    } else if (base::ReadFileToString(animation_desc_path, &content)) {
         parse_success = parse_animation_desc(content, &battery_animation);
     } else {
         LOGW("Could not open animation description at %s\n", animation_desc_path);
diff --git a/liblog/tests/AndroidTest.xml b/liblog/tests/AndroidTest.xml
index 7b64433..bee0497 100644
--- a/liblog/tests/AndroidTest.xml
+++ b/liblog/tests/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Config for CTS Logging Library test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="systems" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
         <option name="push" value="CtsLiblogTestCases->/data/local/tmp/CtsLiblogTestCases" />
diff --git a/libmeminfo/libdmabufinfo/Android.bp b/libmeminfo/libdmabufinfo/Android.bp
new file mode 100644
index 0000000..3d5f2e7
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/Android.bp
@@ -0,0 +1,55 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_defaults {
+    name: "dmabufinfo_defaults",
+    static_libs: [
+        "libbase",
+        "liblog",
+        "libprocinfo",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+cc_library_static {
+    name: "libdmabufinfo",
+    defaults: ["dmabufinfo_defaults"],
+    export_include_dirs: ["include"],
+    static_libs: ["libc++fs"],
+
+    srcs: [
+         "dmabufinfo.cpp",
+    ],
+}
+
+cc_test {
+    name: "dmabufinfo_test",
+    defaults: ["dmabufinfo_defaults"],
+    srcs: [
+         "dmabufinfo_test.cpp"
+    ],
+
+    static_libs: [
+        "libc++fs",
+        "libdmabufinfo",
+        "libion",
+        "libmeminfo",
+    ],
+}
diff --git a/libmeminfo/libdmabufinfo/dmabufinfo.cpp b/libmeminfo/libdmabufinfo/dmabufinfo.cpp
new file mode 100644
index 0000000..41ecc51
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/dmabufinfo.cpp
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2019 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 <dmabufinfo/dmabufinfo.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <procinfo/process_map.h>
+
+namespace android {
+namespace dmabufinfo {
+
+static bool FileIsDmaBuf(const std::string& path) {
+    return ::android::base::StartsWith(path, "/dmabuf");
+}
+
+static bool ReadDmaBufFdInfo(pid_t pid, int fd, std::string* name, std::string* exporter,
+                             uint64_t* count) {
+    std::string fdinfo = ::android::base::StringPrintf("/proc/%d/fdinfo/%d", pid, fd);
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(fdinfo.c_str(), "re"), fclose};
+    if (fp == nullptr) {
+        LOG(ERROR) << "Failed to open dmabuf info from debugfs";
+        return false;
+    }
+
+    char* line = nullptr;
+    size_t len = 0;
+    while (getline(&line, &len, fp.get()) > 0) {
+        switch (line[0]) {
+            case 'c':
+                if (strncmp(line, "count:", 6) == 0) {
+                    char* c = line + 6;
+                    *count = strtoull(c, nullptr, 10);
+                }
+                break;
+            case 'e':
+                if (strncmp(line, "exp_name:", 9) == 0) {
+                    char* c = line + 9;
+                    *exporter = ::android::base::Trim(c);
+                }
+                break;
+            case 'n':
+                if (strncmp(line, "name:", 5) == 0) {
+                    char* c = line + 5;
+                    *name = ::android::base::Trim(std::string(c));
+                }
+                break;
+        }
+    }
+
+    free(line);
+    return true;
+}
+
+static bool ReadDmaBufFdRefs(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
+    std::string fdpath = ::android::base::StringPrintf("/proc/%d/fd", pid);
+    for (auto& de : std::filesystem::directory_iterator(fdpath)) {
+        if (!std::filesystem::is_symlink(de.path())) {
+            continue;
+        }
+
+        std::string target;
+        if (!::android::base::Readlink(de.path().string(), &target)) {
+            LOG(ERROR) << "Failed to find target for symlink: " << de.path().string();
+            return false;
+        }
+
+        if (!FileIsDmaBuf(target)) {
+            continue;
+        }
+
+        int fd;
+        if (!::android::base::ParseInt(de.path().filename().string(), &fd)) {
+            LOG(ERROR) << "Dmabuf fd: " << de.path().string() << " is invalid";
+            return false;
+        }
+
+        // Set defaults in case the kernel doesn't give us the information
+        // we need in fdinfo
+        std::string name = "<unknown>";
+        std::string exporter = "<unknown>";
+        uint64_t count = 0;
+        if (!ReadDmaBufFdInfo(pid, fd, &name, &exporter, &count)) {
+            LOG(ERROR) << "Failed to read fdinfo for: " << de.path().string();
+            return false;
+        }
+
+        struct stat sb;
+        if (stat(de.path().c_str(), &sb) < 0) {
+            PLOG(ERROR) << "Failed to stat: " << de.path().string();
+            return false;
+        }
+
+        DmaBuffer& buf =
+                dmabufs->emplace_back(sb.st_ino, sb.st_blocks * 512, count, exporter, name);
+        buf.AddFdRef(pid);
+    }
+
+    return true;
+}
+
+static bool ReadDmaBufMapRefs(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
+    std::string mapspath = ::android::base::StringPrintf("/proc/%d/maps", pid);
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(mapspath.c_str(), "re"), fclose};
+    if (fp == nullptr) {
+        LOG(ERROR) << "Failed to open maps for pid: " << pid;
+        return false;
+    }
+
+    char* line = nullptr;
+    size_t len = 0;
+
+    // Process the map if it is dmabuf. Add map reference to existing object in 'dmabufs'
+    // if it was already found. If it wasn't create a new one and append it to 'dmabufs'
+    auto account_dmabuf = [&](uint64_t start, uint64_t end, uint16_t /* flags */,
+                              uint64_t /* pgoff */, const char* name) {
+        // no need to look into this mapping if it is not dmabuf
+        if (!FileIsDmaBuf(std::string(name))) {
+            return;
+        }
+
+        // TODO (b/123532375) : Add inode number to the callback of ReadMapFileContent.
+        //
+        // Workaround: we know 'name' points to the name at the end of 'line'.
+        // We use that to backtrack and pick up the inode number from the line as well.
+        // start    end      flag pgoff    mj:mn inode   name
+        // 00400000-00409000 r-xp 00000000 00:00 426998  /dmabuf (deleted)
+        const char* p = name;
+        p--;
+        // skip spaces
+        while (p != line && *p == ' ') {
+            p--;
+        }
+        // walk backwards to the beginning of inode number
+        while (p != line && isdigit(*p)) {
+            p--;
+        }
+        uint64_t inode = strtoull(p, nullptr, 10);
+        auto buf = std::find_if(dmabufs->begin(), dmabufs->end(),
+                                [&inode](const DmaBuffer& dbuf) { return dbuf.inode() == inode; });
+        if (buf != dmabufs->end()) {
+            buf->AddMapRef(pid);
+            return;
+        }
+
+        // We have a new buffer, but unknown count and name
+        DmaBuffer& dbuf = dmabufs->emplace_back(inode, end - start, 0, "<unknown>", "<unknown>");
+        dbuf.AddMapRef(pid);
+    };
+
+    while (getline(&line, &len, fp.get()) > 0) {
+        if (!::android::procinfo::ReadMapFileContent(line, account_dmabuf)) {
+            LOG(ERROR) << "Failed t parse maps for pid: " << pid;
+            return false;
+        }
+    }
+
+    free(line);
+    return true;
+}
+
+// Public methods
+bool ReadDmaBufInfo(std::vector<DmaBuffer>* dmabufs, const std::string& path) {
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+    if (fp == nullptr) {
+        LOG(ERROR) << "Failed to open dmabuf info from debugfs";
+        return false;
+    }
+
+    char* line = nullptr;
+    size_t len = 0;
+    dmabufs->clear();
+    while (getline(&line, &len, fp.get()) > 0) {
+        // The new dmabuf bufinfo format adds inode number and a name at the end
+        // We are looking for lines as follows:
+        // size     flags       mode        count  exp_name ino         name
+        // 01048576 00000002    00000007    00000001    ion 00018758    CAMERA
+        // 01048576 00000002    00000007    00000001    ion 00018758
+        uint64_t size, count;
+        char* exporter_name = nullptr;
+        ino_t inode;
+        char* name = nullptr;
+        int matched = sscanf(line, "%" SCNu64 "%*x %*x %" SCNu64 " %ms %lu %ms", &size, &count,
+                             &exporter_name, &inode, &name);
+        if (matched < 4) {
+            continue;
+        }
+        dmabufs->emplace_back(inode, size, count, exporter_name, matched > 4 ? name : "");
+        free(exporter_name);
+        free(name);
+    }
+
+    free(line);
+
+    return true;
+}
+
+bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs) {
+    dmabufs->clear();
+    if (!ReadDmaBufFdRefs(pid, dmabufs)) {
+        LOG(ERROR) << "Failed to read dmabuf fd references";
+        return false;
+    }
+
+    if (!ReadDmaBufMapRefs(pid, dmabufs)) {
+        LOG(ERROR) << "Failed to read dmabuf map references";
+        return false;
+    }
+    return true;
+}
+
+}  // namespace dmabufinfo
+}  // namespace android
diff --git a/libmeminfo/libdmabufinfo/dmabufinfo_test.cpp b/libmeminfo/libdmabufinfo/dmabufinfo_test.cpp
new file mode 100644
index 0000000..aa5f16c
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/dmabufinfo_test.cpp
@@ -0,0 +1,252 @@
+/* Copyright (C) 2019 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 <gtest/gtest.h>
+#include <linux/dma-buf.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <ion/ion.h>
+
+#include <dmabufinfo/dmabufinfo.h>
+
+using namespace ::android::dmabufinfo;
+using namespace ::android::base;
+
+#define MAX_HEAP_NAME 32
+#define ION_HEAP_ANY_MASK (0x7fffffff)
+
+struct ion_heap_data {
+    char name[MAX_HEAP_NAME];
+    __u32 type;
+    __u32 heap_id;
+    __u32 reserved0;
+    __u32 reserved1;
+    __u32 reserved2;
+};
+
+#ifndef DMA_BUF_SET_NAME
+#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 5, const char*)
+#endif
+
+#define EXPECT_ONE_BUF_EQ(_bufptr, _name, _fdrefs, _maprefs, _expname, _count, _size) \
+    do {                                                                              \
+        EXPECT_EQ(_bufptr->name(), _name);                                            \
+        EXPECT_EQ(_bufptr->fdrefs().size(), _fdrefs);                                 \
+        EXPECT_EQ(_bufptr->maprefs().size(), _maprefs);                               \
+        EXPECT_EQ(_bufptr->exporter(), _expname);                                     \
+        EXPECT_EQ(_bufptr->count(), _count);                                          \
+        EXPECT_EQ(_bufptr->size(), _size);                                            \
+    } while (0)
+
+#define EXPECT_PID_IN_FDREFS(_bufptr, _pid, _expect)                         \
+    do {                                                                     \
+        const std::vector<pid_t>& _fdrefs = _bufptr->fdrefs();               \
+        auto _ref = std::find_if(_fdrefs.begin(), _fdrefs.end(),             \
+                                 [&](const pid_t& p) { return p == _pid; }); \
+        EXPECT_EQ((_ref == _fdrefs.end()), _expect);                         \
+    } while (0)
+
+#define EXPECT_PID_IN_MAPREFS(_bufptr, _pid, _expect)                        \
+    do {                                                                     \
+        const std::vector<pid_t>& _maprefs = _bufptr->maprefs();             \
+        auto _ref = std::find_if(_maprefs.begin(), _maprefs.end(),           \
+                                 [&](const pid_t& p) { return p == _pid; }); \
+        EXPECT_EQ((_ref == _maprefs.end()), _expect);                        \
+    } while (0)
+
+TEST(DmaBufInfoParser, TestReadDmaBufInfo) {
+    std::string bufinfo = R"bufinfo(00045056    00000002    00000007    00000002    ion 00022069    
+	Attached Devices:
+Total 0 devices attached
+01048576    00000002    00000007    00000001    ion 00019834    CAMERA
+	Attached Devices:
+	soc:qcom,cam_smmu:msm_cam_smmu_icp
+Total 1 devices attached)bufinfo";
+
+    TemporaryFile tf;
+    ASSERT_TRUE(tf.fd != -1);
+    ASSERT_TRUE(::android::base::WriteStringToFd(bufinfo, tf.fd));
+    std::string path = std::string(tf.path);
+
+    std::vector<DmaBuffer> dmabufs;
+    EXPECT_TRUE(ReadDmaBufInfo(&dmabufs, path));
+
+    EXPECT_EQ(dmabufs.size(), 2UL);
+
+    EXPECT_EQ(dmabufs[0].size(), 45056UL);
+    EXPECT_EQ(dmabufs[0].inode(), 22069UL);
+    EXPECT_EQ(dmabufs[0].count(), 2UL);
+    EXPECT_EQ(dmabufs[0].exporter(), "ion");
+    EXPECT_TRUE(dmabufs[0].name().empty());
+    EXPECT_EQ(dmabufs[0].total_refs(), 0ULL);
+    EXPECT_TRUE(dmabufs[0].fdrefs().empty());
+    EXPECT_TRUE(dmabufs[0].maprefs().empty());
+
+    EXPECT_EQ(dmabufs[1].size(), 1048576UL);
+    EXPECT_EQ(dmabufs[1].inode(), 19834UL);
+    EXPECT_EQ(dmabufs[1].count(), 1UL);
+    EXPECT_EQ(dmabufs[1].exporter(), "ion");
+    EXPECT_FALSE(dmabufs[1].name().empty());
+    EXPECT_EQ(dmabufs[1].name(), "CAMERA");
+    EXPECT_EQ(dmabufs[1].total_refs(), 0ULL);
+    EXPECT_TRUE(dmabufs[1].fdrefs().empty());
+    EXPECT_TRUE(dmabufs[1].maprefs().empty());
+}
+
+class DmaBufTester : public ::testing::Test {
+  public:
+    DmaBufTester() : ion_fd(ion_open()), ion_heap_mask(get_ion_heap_mask()) {}
+
+    ~DmaBufTester() {
+        if (is_valid()) {
+            ion_close(ion_fd);
+        }
+    }
+
+    bool is_valid() { return (ion_fd >= 0 && ion_heap_mask > 0); }
+
+    unique_fd allocate(uint64_t size, const std::string& name) {
+        int fd;
+        int err = ion_alloc_fd(ion_fd, size, 0, ion_heap_mask, 0, &fd);
+        if (err < 0) {
+            return unique_fd{err};
+        }
+
+        if (!name.empty()) {
+            err = ioctl(fd, DMA_BUF_SET_NAME, name.c_str());
+            if (err < 0) return unique_fd{-errno};
+        }
+
+        return unique_fd{fd};
+    }
+
+  private:
+    int get_ion_heap_mask() {
+        if (ion_fd < 0) {
+            return 0;
+        }
+
+        if (ion_is_legacy(ion_fd)) {
+            // Since ION is still in staging, we've seen that the heap mask ids are also
+            // changed across kernels for some reason. So, here we basically ask for a buffer
+            // from _any_ heap.
+            return ION_HEAP_ANY_MASK;
+        }
+
+        int cnt;
+        int err = ion_query_heap_cnt(ion_fd, &cnt);
+        if (err < 0) {
+            return err;
+        }
+
+        std::vector<ion_heap_data> heaps;
+        heaps.resize(cnt);
+        err = ion_query_get_heaps(ion_fd, cnt, &heaps[0]);
+        if (err < 0) {
+            return err;
+        }
+
+        unsigned int ret = 0;
+        for (auto& it : heaps) {
+            if (!strcmp(it.name, "ion_system_heap")) {
+                ret |= (1 << it.heap_id);
+            }
+        }
+
+        return ret;
+    }
+
+    unique_fd ion_fd;
+    const int ion_heap_mask;
+};
+
+TEST_F(DmaBufTester, TestFdRef) {
+    // Test if a dma buffer is found while the corresponding file descriptor
+    // is open
+    ASSERT_TRUE(is_valid());
+    pid_t pid = getpid();
+    std::vector<DmaBuffer> dmabufs;
+    {
+        // Allocate one buffer and make sure the library can see it
+        unique_fd buf = allocate(4096, "dmabuftester-4k");
+        ASSERT_GT(buf, 0) << "Allocated buffer is invalid";
+        ASSERT_TRUE(ReadDmaBufInfo(pid, &dmabufs));
+
+        EXPECT_EQ(dmabufs.size(), 1UL);
+        EXPECT_ONE_BUF_EQ(dmabufs.begin(), "dmabuftester-4k", 1UL, 0UL, "ion", 1UL, 4096ULL);
+
+        // Make sure the buffer has the right pid too.
+        EXPECT_PID_IN_FDREFS(dmabufs.begin(), pid, false);
+    }
+
+    // Now make sure the buffer has disappeared
+    ASSERT_TRUE(ReadDmaBufInfo(pid, &dmabufs));
+    EXPECT_TRUE(dmabufs.empty());
+}
+
+TEST_F(DmaBufTester, TestMapRef) {
+    // Test to make sure we can find a buffer if the fd is closed but the buffer
+    // is mapped
+    ASSERT_TRUE(is_valid());
+    pid_t pid = getpid();
+    std::vector<DmaBuffer> dmabufs;
+    {
+        // Allocate one buffer and make sure the library can see it
+        unique_fd buf = allocate(4096, "dmabuftester-4k");
+        ASSERT_GT(buf, 0) << "Allocated buffer is invalid";
+        auto ptr = mmap(0, 4096, PROT_READ, MAP_SHARED, buf, 0);
+        ASSERT_NE(ptr, MAP_FAILED);
+        ASSERT_TRUE(ReadDmaBufInfo(pid, &dmabufs));
+
+        EXPECT_EQ(dmabufs.size(), 1UL);
+        EXPECT_ONE_BUF_EQ(dmabufs.begin(), "dmabuftester-4k", 1UL, 1UL, "ion", 2UL, 4096ULL);
+
+        // Make sure the buffer has the right pid too.
+        EXPECT_PID_IN_FDREFS(dmabufs.begin(), pid, false);
+        EXPECT_PID_IN_MAPREFS(dmabufs.begin(), pid, false);
+
+        // close the file descriptor and re-read the stats
+        buf.reset(-1);
+        ASSERT_TRUE(ReadDmaBufInfo(pid, &dmabufs));
+
+        EXPECT_EQ(dmabufs.size(), 1UL);
+        EXPECT_ONE_BUF_EQ(dmabufs.begin(), "<unknown>", 0UL, 1UL, "<unknown>", 0UL, 4096ULL);
+
+        EXPECT_PID_IN_FDREFS(dmabufs.begin(), pid, true);
+        EXPECT_PID_IN_MAPREFS(dmabufs.begin(), pid, false);
+
+        // unmap the bufer and lose all references
+        munmap(ptr, 4096);
+    }
+
+    // Now make sure the buffer has disappeared
+    ASSERT_TRUE(ReadDmaBufInfo(pid, &dmabufs));
+    EXPECT_TRUE(dmabufs.empty());
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ::android::base::InitLogging(argv, android::base::StderrLogger);
+    return RUN_ALL_TESTS();
+}
diff --git a/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
new file mode 100644
index 0000000..29ce4d0
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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 <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+namespace android {
+namespace dmabufinfo {
+
+struct DmaBuffer {
+  public:
+    DmaBuffer(ino_t inode, uint64_t size, uint64_t count, const std::string& exporter,
+              const std::string& name)
+        : inode_(inode), size_(size), count_(count), exporter_(exporter), name_(name) {}
+    ~DmaBuffer() = default;
+
+    // Adds one file descriptor reference for the given pid
+    void AddFdRef(pid_t pid) { fdrefs_.emplace_back(pid); }
+
+    // Adds one map reference for the given pid
+    void AddMapRef(pid_t pid) { maprefs_.emplace_back(pid); }
+
+    // Getters for each property
+    uint64_t size() { return size_; }
+    const std::vector<pid_t>& fdrefs() const { return fdrefs_; }
+    const std::vector<pid_t>& maprefs() const { return maprefs_; }
+    ino_t inode() const { return inode_; }
+    uint64_t total_refs() const { return fdrefs_.size() + maprefs_.size(); }
+    uint64_t count() const { return count_; };
+    const std::string& name() const { return name_; }
+    const std::string& exporter() const { return exporter_; }
+
+  private:
+    ino_t inode_;
+    uint64_t size_;
+    uint64_t count_;
+    std::string exporter_;
+    std::string name_;
+    std::vector<pid_t> fdrefs_;
+    std::vector<pid_t> maprefs_;
+};
+
+// Read and return current dma buf objects from
+// DEBUGFS/dma_buf/bufinfo. The references to each dma buffer are not
+// populated here and will return an empty vector.
+// Returns false if something went wrong with the function, true otherwise.
+bool ReadDmaBufInfo(std::vector<DmaBuffer>* dmabufs,
+                    const std::string& path = "/sys/kernel/debug/dma_buf/bufinfo");
+
+// Read and return dmabuf objects for a given process without the help
+// of DEBUGFS
+bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs);
+
+}  // namespace dmabufinfo
+}  // namespace android
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index f4788d7..ddda7fd 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -81,6 +81,12 @@
 
   const std::vector<FrameData>& frames() { return frames_; }
 
+  std::vector<FrameData> ConsumeFrames() {
+    std::vector<FrameData> frames = std::move(frames_);
+    frames_.clear();
+    return frames;
+  }
+
   std::string FormatFrame(size_t frame_num);
   static std::string FormatFrame(const FrameData& frame, bool is32bit);
 
diff --git a/libunwindstack/tools/unwind_info.cpp b/libunwindstack/tools/unwind_info.cpp
index 3f5b88b..19982d8 100644
--- a/libunwindstack/tools/unwind_info.cpp
+++ b/libunwindstack/tools/unwind_info.cpp
@@ -44,10 +44,10 @@
   }
 
   printf("ARM Unwind Information:\n");
+  uint64_t load_bias = elf->GetLoadBias();
   for (const auto& entry : interface->pt_loads()) {
-    uint64_t load_bias = entry.second.table_offset;
     printf(" PC Range 0x%" PRIx64 " - 0x%" PRIx64 "\n", entry.second.offset + load_bias,
-           entry.second.table_size + load_bias);
+           entry.second.offset + entry.second.table_size + load_bias);
     for (auto pc : *interface) {
       std::string name;
       printf("  PC 0x%" PRIx64, pc + load_bias);
diff --git a/logd/tests/AndroidTest.xml b/logd/tests/AndroidTest.xml
index 84f0764..1e71a73 100644
--- a/logd/tests/AndroidTest.xml
+++ b/logd/tests/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Config for CTS Logging Daemon test cases">
     <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="systems" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
         <option name="push" value="CtsLogdTestCases->/data/local/tmp/CtsLogdTestCases" />
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index d2c0f2e..c97baeb 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -63,6 +63,7 @@
 namespace.default.visible = true
 namespace.default.link.runtime.shared_libs  = libart.so:libartd.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs += libnativebridge.so
 namespace.default.link.runtime.shared_libs += libnativehelper.so
 namespace.default.link.runtime.shared_libs += libnativeloader.so