Merge "fs_config supports shell wildcard patterns"
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index d587589..4c5d8cb 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -356,6 +356,9 @@
     DWORD desiredAccess = 0;
     DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
 
+    // CreateFileW is inherently O_CLOEXEC by default.
+    options &= ~O_CLOEXEC;
+
     switch (options) {
         case O_RDONLY:
             desiredAccess = GENERIC_READ;
diff --git a/adb/test_adb.py b/adb/test_adb.py
index 430fc3d..14e5071 100755
--- a/adb/test_adb.py
+++ b/adb/test_adb.py
@@ -422,6 +422,9 @@
         with fake_adbd() as (port, _):
             serial = "localhost:{}".format(port)
             with adb_connect(self, serial):
+                # Wait a bit to give adb some time to connect.
+                time.sleep(0.25)
+
                 output = subprocess.check_output(["adb", "-s", serial,
                                                   "get-state"])
                 self.assertEqual(output.strip(), b"device")
diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc
index 1300a27..85caf25 100644
--- a/bootstat/bootstat.rc
+++ b/bootstat/bootstat.rc
@@ -1,7 +1,9 @@
 # This file is the LOCAL_INIT_RC file for the bootstat command.
 
-# mirror bootloader boot reason to system boot reason
-on property:ro.boot.bootreason=*
+# Mirror bootloader boot reason to system boot reason
+# ro.boot.bootreason should be set by init already
+# before post-fs trigger
+on post-fs && property:ro.boot.bootreason=*
     setprop sys.boot.reason ${ro.boot.bootreason}
 
 on post-fs-data
@@ -66,11 +68,16 @@
 on property:init.svc.zygote=stopping
     setprop sys.logbootcomplete 0
 
+# Set boot reason
+on zygote-start
+    # Converts bootloader boot reason and persist.sys.boot.reason to system boot reason
+    # Need go after persist peroperties are loaded which is right before zygote-start trigger
+    exec_background - system log -- /system/bin/bootstat --set_system_boot_reason
+
 # Record boot complete metrics.
 on property:sys.boot_completed=1 && property:sys.logbootcomplete=1
-    # Converts bootloader boot reason to system boot reason
     # Record boot_complete and related stats (decryption, etc).
     # Record the boot reason.
     # Record time since factory reset.
     # Log all boot events.
-    exec_background - system log -- /system/bin/bootstat --set_system_boot_reason --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l
+    exec_background - system log -- /system/bin/bootstat --record_boot_complete --record_boot_reason --record_time_since_factory_reset -l
diff --git a/libmeminfo/libdmabufinfo/dmabufinfo.cpp b/libmeminfo/libdmabufinfo/dmabufinfo.cpp
index b4ad667..0212cd2 100644
--- a/libmeminfo/libdmabufinfo/dmabufinfo.cpp
+++ b/libmeminfo/libdmabufinfo/dmabufinfo.cpp
@@ -130,7 +130,7 @@
             if (buf->count() == 0)
                 buf->SetCount(count);
             buf->AddFdRef(pid);
-            return true;
+            continue;
         }
 
         DmaBuffer& db =
diff --git a/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
index e3be320..a16c3fd 100644
--- a/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
+++ b/libmeminfo/libdmabufinfo/include/dmabufinfo/dmabufinfo.h
@@ -30,17 +30,21 @@
   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) {}
+        : inode_(inode), size_(size), count_(count), exporter_(exporter), name_(name) {
+        total_refs_ = 0;
+    }
     ~DmaBuffer() = default;
 
     // Adds one file descriptor reference for the given pid
     void AddFdRef(pid_t pid) {
         AddRefToPidMap(pid, &fdrefs_);
+        total_refs_++;
     }
 
     // Adds one map reference for the given pid
     void AddMapRef(pid_t pid) {
         AddRefToPidMap(pid, &maprefs_);
+        total_refs_++;
     }
 
     // Getters for each property
@@ -48,7 +52,7 @@
     const std::unordered_map<pid_t, int>& fdrefs() const { return fdrefs_; }
     const std::unordered_map<pid_t, int>& maprefs() const { return maprefs_; }
     ino_t inode() const { return inode_; }
-    uint64_t total_refs() const { return fdrefs_.size() + maprefs_.size(); }
+    uint64_t total_refs() const { return total_refs_; }
     uint64_t count() const { return count_; };
     const std::string& name() const { return name_; }
     const std::string& exporter() const { return exporter_; }
@@ -65,6 +69,7 @@
     ino_t inode_;
     uint64_t size_;
     uint64_t count_;
+    uint64_t total_refs_;
     std::string exporter_;
     std::string name_;
     std::unordered_map<pid_t, int> fdrefs_;
@@ -81,7 +86,6 @@
 // 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");
@@ -89,13 +93,13 @@
 
 // Read and return dmabuf objects for a given process without the help
 // of DEBUGFS
-//
 // Returns false if something went wrong with the function, true otherwise.
 bool ReadDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs);
 
-// Append dmabuf objects for a given process without the help
-// of DEBUGFS to an existing vector
-//
+// Append new dmabuf objects from a given process to an existing vector.
+// When the vector contains an existing element with a matching inode,
+// the reference counts will be updated.
+// Does not depend on DEBUGFS.
 // Returns false if something went wrong with the function, true otherwise.
 bool AppendDmaBufInfo(pid_t pid, std::vector<DmaBuffer>* dmabufs);
 
diff --git a/libmeminfo/libdmabufinfo/tools/Android.bp b/libmeminfo/libdmabufinfo/tools/Android.bp
new file mode 100644
index 0000000..339583e
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/tools/Android.bp
@@ -0,0 +1,31 @@
+// 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_binary {
+    name: "dmabuf_dump",
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    srcs: ["dmabuf_dump.cpp"],
+    shared_libs: [
+        "libbase",
+        "libmeminfo",
+    ],
+    static_libs: [
+        "libdmabufinfo",
+        "libc++fs",
+    ],
+}
\ No newline at end of file
diff --git a/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp b/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp
new file mode 100644
index 0000000..5ee9c3d
--- /dev/null
+++ b/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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 <dirent.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+#include <android-base/stringprintf.h>
+#include <dmabufinfo/dmabufinfo.h>
+
+using DmaBuffer = ::android::dmabufinfo::DmaBuffer;
+
+[[noreturn]] static void usage(int exit_status) {
+    fprintf(stderr,
+            "Usage: %s [PID] \n"
+            "\t If PID is supplied, the dmabuf information for this process is shown.\n"
+            "\t Otherwise, shows the information for all processes.\n",
+            getprogname());
+
+    exit(exit_status);
+}
+
+static std::string GetProcessBaseName(pid_t pid) {
+    std::string pid_path = android::base::StringPrintf("/proc/%d/comm", pid);
+    std::ifstream in{pid_path};
+    if (!in) return std::string("N/A");
+    std::string line;
+    std::getline(in, line);
+    if (!in) return std::string("N/A");
+    return line;
+}
+
+static void AddPidsToSet(const std::unordered_map<pid_t, int>& map, std::set<pid_t>* set)
+{
+    for (auto it = map.begin(); it != map.end(); ++it)
+        set->insert(it->first);
+}
+
+static void PrintDmaBufInfo(const std::vector<DmaBuffer>& bufs) {
+    std::set<pid_t> pid_set;
+    std::map<pid_t, int> pid_column;
+
+    if (bufs.empty()) {
+        std::cout << "dmabuf info not found ¯\\_(ツ)_/¯" << std::endl;
+        return;
+    }
+
+    // Find all unique pids in the input vector, create a set
+    for (int i = 0; i < bufs.size(); i++) {
+        AddPidsToSet(bufs[i].fdrefs(), &pid_set);
+        AddPidsToSet(bufs[i].maprefs(), &pid_set);
+    }
+
+    int pid_count = 0;
+
+    std::cout << "\t\t\t\t\t\t";
+
+    // Create a map to convert each unique pid into a column number
+    for (auto it = pid_set.begin(); it != pid_set.end(); ++it, ++pid_count) {
+        pid_column.insert(std::make_pair(*it, pid_count));
+        std::cout << ::android::base::StringPrintf("[pid: % 4d]\t", *it);
+    }
+
+    std::cout << std::endl << "\t\t\t\t\t\t";
+
+    for (auto it = pid_set.begin(); it != pid_set.end(); ++it) {
+        std::cout << ::android::base::StringPrintf("%16s",
+            GetProcessBaseName(*it).c_str());
+    }
+
+    std::cout << std::endl << "\tinode\t\tsize\t\tcount\t";
+    for (int i = 0; i < pid_count; i++) {
+        std::cout << "fd\tmap\t";
+    }
+    std::cout << std::endl;
+
+    auto fds = std::make_unique<int[]>(pid_count);
+    auto maps = std::make_unique<int[]>(pid_count);
+    auto pss = std::make_unique<long[]>(pid_count);
+
+    memset(pss.get(), 0, sizeof(long) * pid_count);
+
+    for (auto buf = bufs.begin(); buf != bufs.end(); ++buf) {
+
+        std::cout << ::android::base::StringPrintf("%16lu\t%10" PRIu64 "\t%" PRIu64 "\t",
+            buf->inode(),buf->size(), buf->count());
+
+        memset(fds.get(), 0, sizeof(int) * pid_count);
+        memset(maps.get(), 0, sizeof(int) * pid_count);
+
+        for (auto it = buf->fdrefs().begin(); it != buf->fdrefs().end(); ++it) {
+            fds[pid_column[it->first]] = it->second;
+            pss[pid_column[it->first]] += buf->size() * it->second / buf->count();
+        }
+
+        for (auto it = buf->maprefs().begin(); it != buf->maprefs().end(); ++it) {
+            maps[pid_column[it->first]] = it->second;
+            pss[pid_column[it->first]] += buf->size() * it->second / buf->count();
+        }
+
+        for (int i = 0; i < pid_count; i++) {
+            std::cout << ::android::base::StringPrintf("%d\t%d\t", fds[i], maps[i]);
+        }
+        std::cout << std::endl;
+    }
+    std::cout << "-----------------------------------------" << std::endl;
+    std::cout << "PSS                                      ";
+    for (int i = 0; i < pid_count; i++) {
+        std::cout << ::android::base::StringPrintf("%15ldK", pss[i] / 1024);
+    }
+    std::cout << std::endl;
+}
+
+int main(int argc, char* argv[]) {
+    pid_t pid = -1;
+    std::vector<DmaBuffer> bufs;
+    bool show_all = true;
+
+    if (argc > 1) {
+        if (sscanf(argv[1], "%d", &pid) == 1) {
+            show_all = false;
+        }
+        else {
+            usage(EXIT_FAILURE);
+        }
+    }
+
+    if (show_all) {
+        if (!ReadDmaBufInfo(&bufs)) {
+            std::cerr << "Unable to read DEBUGFS dmabuf info" << std::endl;
+            exit(EXIT_FAILURE);
+        }
+        std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir("/proc"), closedir);
+        if (!dir) {
+            std::cerr << "Failed to open /proc directory" << std::endl;
+            exit(EXIT_FAILURE);
+        }
+        struct dirent* dent;
+        while ((dent = readdir(dir.get()))) {
+            if (dent->d_type != DT_DIR) continue;
+
+            int matched = sscanf(dent->d_name, "%d", &pid);
+            if (matched != 1) {
+                continue;
+            }
+
+            if (!AppendDmaBufInfo(pid, &bufs)) {
+                std::cerr << "Unable to read dmabuf info for pid " << pid << std::endl;
+                exit(EXIT_FAILURE);
+            }
+        }
+    } else {
+        if (!ReadDmaBufInfo(pid, &bufs)) {
+            std::cerr << "Unable to read dmabuf info" << std::endl;
+            exit(EXIT_FAILURE);
+        }
+    }
+    PrintDmaBufInfo(bufs);
+    return 0;
+}
+
+
diff --git a/libmeminfo/vts/Android.bp b/libmeminfo/vts/Android.bp
new file mode 100644
index 0000000..5a3a23b
--- /dev/null
+++ b/libmeminfo/vts/Android.bp
@@ -0,0 +1,20 @@
+// 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_test {
+    name: "vts_meminfo_test",
+    defaults: ["libmeminfo_defaults"],
+    srcs: ["vts_meminfo_test.cpp"],
+    static_libs: ["libmeminfo"],
+}
diff --git a/libmeminfo/vts/Android.mk b/libmeminfo/vts/Android.mk
new file mode 100644
index 0000000..62d68d9
--- /dev/null
+++ b/libmeminfo/vts/Android.mk
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsKernelMemInfoTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/libmeminfo/vts/AndroidTest.xml b/libmeminfo/vts/AndroidTest.xml
new file mode 100644
index 0000000..530d16e
--- /dev/null
+++ b/libmeminfo/vts/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for VTS VtsKernelMemInfoTest.">
+    <option name="config-descriptor:metadata" key="plan" value="vts-kernel" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HostDrivenTest.push"/>
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsKernelMemInfoTest"/>
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_meminfo_test/vts_meminfo_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_meminfo_test/vts_meminfo_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="10m"/>
+    </test>
+</configuration>
diff --git a/libmeminfo/vts/vts_meminfo_test.cpp b/libmeminfo/vts/vts_meminfo_test.cpp
new file mode 100644
index 0000000..3193c31
--- /dev/null
+++ b/libmeminfo/vts/vts_meminfo_test.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 <meminfo/procmeminfo.h>
+
+namespace android {
+namespace meminfo {
+
+// /proc/<pid>/smaps_rollup support is required.
+TEST(SmapsRollup, IsSupported) {
+    // Use init's pid for this test since it's the only known pid.
+    ASSERT_TRUE(IsSmapsRollupSupported(1));
+}
+
+}  // namespace meminfo
+}  // namespace android
diff --git a/libsystem/OWNERS b/libsystem/OWNERS
index aeb160c..fdea804 100644
--- a/libsystem/OWNERS
+++ b/libsystem/OWNERS
@@ -1,2 +1,9 @@
-jessehall@google.com
-olv@google.com
+# graphics/composer
+adyabr@google.com
+lpy@google.com
+marissaw@google.com
+stoza@google.com
+vhau@google.com
+
+# camera
+etalvala@google.com