Merge "Add eaeltsin to OWNERS"
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index bf58315..d9f2837 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -99,6 +99,11 @@
         "fs_mgr_boot_config.cpp",
         "fs_mgr_slotselect.cpp",
     ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
     export_include_dirs: ["include_fstab"],
     header_libs: ["libbase_headers"],
 }
diff --git a/fs_mgr/README.overlayfs.md b/fs_mgr/README.overlayfs.md
index 960410c..8784c94 100644
--- a/fs_mgr/README.overlayfs.md
+++ b/fs_mgr/README.overlayfs.md
@@ -53,9 +53,13 @@
     $ adb disable-verity
     $ adb reboot
 
-can be replaced with:
+*or*
 
-    $ adb reboot -R
+    $ adb remount
+
+can be replaced in both places with:
+
+    $ adb remount -R
 
 which will not reboot if everything is already prepared and ready
 to go.
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index a1519da..06c8176 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -26,6 +26,8 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
+
+#include <algorithm>
 #include <memory>
 
 #include <android-base/file.h>
@@ -476,10 +478,16 @@
 
         while ((entry = readdir(dir.get()))) {
             const char* name = entry->d_name;
+            std::vector<String8>::iterator itIgnoreName;
 
             if (!strcmp(name, ".") || !strcmp(name, ".."))
                 continue;
 
+            itIgnoreName = find(hc->ignorePowerSupplyNames.begin(),
+                                hc->ignorePowerSupplyNames.end(), String8(name));
+            if (itIgnoreName != hc->ignorePowerSupplyNames.end())
+                continue;
+
             // Look for "type" file in each subdirectory
             path.clear();
             path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index c01e8d7..a900071 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -22,6 +22,8 @@
 #include <utils/Errors.h>
 #include <utils/String8.h>
 
+#include <vector>
+
 // periodic_chores_interval_fast, periodic_chores_interval_slow: intervals at
 // which healthd wakes up to poll health state and perform periodic chores,
 // in units of seconds:
@@ -71,6 +73,7 @@
     int (*energyCounter)(int64_t *);
     int boot_min_cap;
     bool (*screen_on)(android::BatteryProperties *props);
+    std::vector<android::String8> ignorePowerSupplyNames;
 };
 
 enum EventWakeup {
diff --git a/init/init.cpp b/init/init.cpp
index dc46a82..d360fdd 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -451,6 +451,8 @@
     // Also, binder can't be used by recovery.
 #ifndef RECOVERY
     android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    android::ProcessState::self()->setCallRestriction(
+            ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY);
 #endif
     return Success();
 }
diff --git a/janitors/OWNERS b/janitors/OWNERS
new file mode 100644
index 0000000..0610b41
--- /dev/null
+++ b/janitors/OWNERS
@@ -0,0 +1,4 @@
+# OWNERS file for projects that don't really have owners so much as volunteer janitors.
+enh@google.com
+hhb@google.com
+narayan@google.com
diff --git a/libmeminfo/include/meminfo/meminfo.h b/libmeminfo/include/meminfo/meminfo.h
index 5ee32d4..2fc7867 100644
--- a/libmeminfo/include/meminfo/meminfo.h
+++ b/libmeminfo/include/meminfo/meminfo.h
@@ -72,15 +72,10 @@
         : start(s), end(e), offset(off), flags(f), name(n) {}
     ~Vma() = default;
 
-    void clear() {
-        memset(&usage, 0, sizeof(usage));
-        memset(&wss, 0, sizeof(wss));
-    }
+    void clear() { memset(&usage, 0, sizeof(usage)); }
 
     // Memory usage of this mapping.
     MemUsage usage;
-    // Working set within this mapping.
-    MemUsage wss;
 };
 
 }  // namespace meminfo
diff --git a/libmeminfo/include/meminfo/procmeminfo.h b/libmeminfo/include/meminfo/procmeminfo.h
index 0bfd80f..0b66074 100644
--- a/libmeminfo/include/meminfo/procmeminfo.h
+++ b/libmeminfo/include/meminfo/procmeminfo.h
@@ -64,7 +64,12 @@
     //   private_dirty
     //   SwapPss
     // All other fields of MemUsage are zeroed.
-    bool SmapsOrRollup(bool use_rollup, MemUsage* stats) const;
+    bool SmapsOrRollup(MemUsage* stats) const;
+
+    // Used to parse either of /proc/<pid>/{smaps, smaps_rollup} and record the process's
+    // Pss.
+    // Returns 'true' on success and the value of Pss in the out parameter.
+    bool SmapsOrRollupPss(uint64_t* pss) const;
 
     const std::vector<uint16_t>& SwapOffsets();
 
@@ -82,7 +87,6 @@
     std::vector<Vma> maps_;
 
     MemUsage usage_;
-    MemUsage wss_;
     std::vector<uint16_t> swap_offsets_;
 };
 
@@ -90,10 +94,21 @@
 // same format as /proc/<pid>/smaps. Returns 'false' if the file is malformed.
 bool ForEachVmaFromFile(const std::string& path, const VmaCallback& callback);
 
+// Returns if the kernel supports /proc/<pid>/smaps_rollup. Assumes that the
+// calling process has access to the /proc/<pid>/smaps_rollup.
+// Returns 'false' if the calling process has no permission to read the file if it exists
+// of if the file doesn't exist.
+bool IsSmapsRollupSupported(pid_t pid);
+
 // Same as ProcMemInfo::SmapsOrRollup but reads the statistics directly
 // from a file. The file MUST be in the same format as /proc/<pid>/smaps
 // or /proc/<pid>/smaps_rollup
 bool SmapsOrRollupFromFile(const std::string& path, MemUsage* stats);
 
+// Same as ProcMemInfo::SmapsOrRollupPss but reads the statistics directly
+// from a file and returns total Pss in kB. The file MUST be in the same format
+// as /proc/<pid>/smaps or /proc/<pid>/smaps_rollup
+bool SmapsOrRollupPssFromFile(const std::string& path, uint64_t* pss);
+
 }  // namespace meminfo
 }  // namespace android
diff --git a/libmeminfo/libmeminfo_test.cpp b/libmeminfo/libmeminfo_test.cpp
index 20ed3bf..e689a26 100644
--- a/libmeminfo/libmeminfo_test.cpp
+++ b/libmeminfo/libmeminfo_test.cpp
@@ -284,13 +284,22 @@
     EXPECT_EQ(swap_offsets.size(), 0);
 }
 
+TEST(TestProcMemInfo, IsSmapsSupportedTest) {
+    std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
+    bool supported = IsSmapsRollupSupported(pid);
+    EXPECT_EQ(!access(path.c_str(), F_OK | R_OK), supported);
+    // Second call must return what the first one returned regardless of the pid parameter.
+    // So, deliberately pass invalid pid.
+    EXPECT_EQ(supported, IsSmapsRollupSupported(-1));
+}
+
 TEST(TestProcMemInfo, SmapsOrRollupReturn) {
     // if /proc/<pid>/smaps_rollup file exists, .SmapsRollup() must return true;
     // false otherwise
     std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
     ProcMemInfo proc_mem(pid);
     MemUsage stats;
-    EXPECT_EQ(!access(path.c_str(), F_OK), proc_mem.SmapsOrRollup(true, &stats));
+    EXPECT_EQ(!access(path.c_str(), F_OK), proc_mem.SmapsOrRollup(&stats));
 }
 
 TEST(TestProcMemInfo, SmapsOrRollupTest) {
@@ -365,6 +374,50 @@
     EXPECT_EQ(stats.swap_pss, 70);
 }
 
+TEST(TestProcMemInfo, SmapsOrRollupPssRollupTest) {
+    // This is a made up smaps for the test
+    std::string smaps =
+            R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)]
+Name:           [anon:dalvik-main space (region space)]
+Size:               8448 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                2652 kB
+Pss:                2652 kB
+Shared_Clean:        840 kB
+Shared_Dirty:         40 kB
+Private_Clean:        84 kB
+Private_Dirty:      2652 kB
+Referenced:         2652 kB
+Anonymous:          2652 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                102 kB
+SwapPss:              70 kB
+Locked:             2652 kB
+VmFlags: rd wr mr mw me ac 
+)smaps";
+
+    TemporaryFile tf;
+    ASSERT_TRUE(tf.fd != -1);
+    ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
+
+    uint64_t pss;
+    ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
+    EXPECT_EQ(pss, 2652);
+}
+
+TEST(TestProcMemInfo, SmapsOrRollupPssSmapsTest) {
+    std::string exec_dir = ::android::base::GetExecutableDirectory();
+    std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
+
+    uint64_t pss;
+    ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
+    EXPECT_EQ(pss, 19119);
+}
+
 TEST(TestProcMemInfo, ForEachVmaFromFileTest) {
     std::string exec_dir = ::android::base::GetExecutableDirectory();
     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
@@ -374,6 +427,9 @@
     auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
     ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
 
+    // We should get a total of 6 vmas
+    ASSERT_EQ(vmas.size(), 6);
+
     // Expect values to be equal to what we have in testdata1/smaps_short
     // Check for sizes first
     ASSERT_EQ(vmas[0].usage.vss, 32768);
@@ -468,6 +524,8 @@
     auto vmas = proc_mem.Smaps(path);
 
     ASSERT_FALSE(vmas.empty());
+    // We should get a total of 6 vmas
+    ASSERT_EQ(vmas.size(), 6);
 
     // Expect values to be equal to what we have in testdata1/smaps_short
     // Check for sizes first
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index 1f8db1a..347a293 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
+#include <atomic>
 #include <fstream>
 #include <iostream>
 #include <memory>
@@ -157,14 +158,14 @@
     if (!get_wss_) {
         LOG(WARNING) << "Trying to read process working set for " << pid_
                      << " using invalid object";
-        return wss_;
+        return usage_;
     }
 
     if (maps_.empty() && !ReadMaps(get_wss_)) {
         LOG(ERROR) << "Failed to get working set for Process " << pid_;
     }
 
-    return wss_;
+    return usage_;
 }
 
 bool ProcMemInfo::ForEachVma(const VmaCallback& callback) {
@@ -172,11 +173,17 @@
     return ForEachVmaFromFile(path, callback);
 }
 
-bool ProcMemInfo::SmapsOrRollup(bool use_rollup, MemUsage* stats) const {
-    std::string path = ::android::base::StringPrintf("/proc/%d/%s", pid_,
-                                                     use_rollup ? "smaps_rollup" : "smaps");
+bool ProcMemInfo::SmapsOrRollup(MemUsage* stats) const {
+    std::string path = ::android::base::StringPrintf(
+            "/proc/%d/%s", pid_, IsSmapsRollupSupported(pid_) ? "smaps_rollup" : "smaps");
     return SmapsOrRollupFromFile(path, stats);
-};
+}
+
+bool ProcMemInfo::SmapsOrRollupPss(uint64_t* pss) const {
+    std::string path = ::android::base::StringPrintf(
+            "/proc/%d/%s", pid_, IsSmapsRollupSupported(pid_) ? "smaps_rollup" : "smaps");
+    return SmapsOrRollupPssFromFile(path, pss);
+}
 
 const std::vector<uint16_t>& ProcMemInfo::SwapOffsets() {
     if (get_wss_) {
@@ -228,11 +235,7 @@
             maps_.clear();
             return false;
         }
-        if (get_wss) {
-            add_mem_usage(&wss_, vma.wss);
-        } else {
-            add_mem_usage(&usage_, vma.usage);
-        }
+        add_mem_usage(&usage_, vma.usage);
     }
 
     return true;
@@ -300,31 +303,20 @@
             // This effectively makes vss = rss for the working set is requested.
             // The libpagemap implementation returns vss > rss for
             // working set, which doesn't make sense.
-            vma.wss.vss += pagesz;
-            vma.wss.rss += pagesz;
-            vma.wss.uss += is_private ? pagesz : 0;
-            vma.wss.pss += pagesz / pg_counts[i];
-            if (is_private) {
-                vma.wss.private_dirty += is_dirty ? pagesz : 0;
-                vma.wss.private_clean += is_dirty ? 0 : pagesz;
-            } else {
-                vma.wss.shared_dirty += is_dirty ? pagesz : 0;
-                vma.wss.shared_clean += is_dirty ? 0 : pagesz;
-            }
+            vma.usage.vss += pagesz;
+        }
+
+        vma.usage.rss += pagesz;
+        vma.usage.uss += is_private ? pagesz : 0;
+        vma.usage.pss += pagesz / pg_counts[i];
+        if (is_private) {
+            vma.usage.private_dirty += is_dirty ? pagesz : 0;
+            vma.usage.private_clean += is_dirty ? 0 : pagesz;
         } else {
-            vma.usage.rss += pagesz;
-            vma.usage.uss += is_private ? pagesz : 0;
-            vma.usage.pss += pagesz / pg_counts[i];
-            if (is_private) {
-                vma.usage.private_dirty += is_dirty ? pagesz : 0;
-                vma.usage.private_clean += is_dirty ? 0 : pagesz;
-            } else {
-                vma.usage.shared_dirty += is_dirty ? pagesz : 0;
-                vma.usage.shared_clean += is_dirty ? 0 : pagesz;
-            }
+            vma.usage.shared_dirty += is_dirty ? pagesz : 0;
+            vma.usage.shared_clean += is_dirty ? 0 : pagesz;
         }
     }
-
     return true;
 }
 
@@ -338,8 +330,9 @@
     char* line = nullptr;
     bool parsing_vma = false;
     ssize_t line_len;
+    size_t line_alloc = 0;
     Vma vma;
-    while ((line_len = getline(&line, 0, fp.get())) > 0) {
+    while ((line_len = getline(&line, &line_alloc, fp.get())) > 0) {
         // Make sure the line buffer terminates like a C string for ReadMapFile
         line[line_len] = '\0';
 
@@ -382,6 +375,31 @@
     return true;
 }
 
+enum smaps_rollup_support { UNTRIED, SUPPORTED, UNSUPPORTED };
+
+static std::atomic<smaps_rollup_support> g_rollup_support = UNTRIED;
+
+bool IsSmapsRollupSupported(pid_t pid) {
+    // Similar to OpenSmapsOrRollup checks from android_os_Debug.cpp, except
+    // the method only checks if rollup is supported and returns the status
+    // right away.
+    enum smaps_rollup_support rollup_support = g_rollup_support.load(std::memory_order_relaxed);
+    if (rollup_support != UNTRIED) {
+        return rollup_support == SUPPORTED;
+    }
+    std::string rollup_file = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
+    if (access(rollup_file.c_str(), F_OK | R_OK)) {
+        // No check for errno = ENOENT necessary here. The caller MUST fallback to
+        // using /proc/<pid>/smaps instead anyway.
+        g_rollup_support.store(UNSUPPORTED, std::memory_order_relaxed);
+        return false;
+    }
+
+    g_rollup_support.store(SUPPORTED, std::memory_order_relaxed);
+    LOG(INFO) << "Using smaps_rollup for pss collection";
+    return true;
+}
+
 bool SmapsOrRollupFromFile(const std::string& path, MemUsage* stats) {
     auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
     if (fp == nullptr) {
@@ -426,5 +444,22 @@
     return true;
 }
 
+bool SmapsOrRollupPssFromFile(const std::string& path, uint64_t* pss) {
+    auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
+    if (fp == nullptr) {
+        return false;
+    }
+    *pss = 0;
+    char line[1024];
+    while (fgets(line, sizeof(line), fp.get()) != nullptr) {
+        uint64_t v;
+        if (sscanf(line, "Pss: %" SCNu64 " kB", &v) == 1) {
+            *pss += v;
+        }
+    }
+
+    return true;
+}
+
 }  // namespace meminfo
 }  // namespace android
diff --git a/libmeminfo/tools/procmem.cpp b/libmeminfo/tools/procmem.cpp
index b9b174d..47881ed 100644
--- a/libmeminfo/tools/procmem.cpp
+++ b/libmeminfo/tools/procmem.cpp
@@ -98,7 +98,7 @@
     std::stringstream ss;
     print_header(ss);
     for (auto& vma : maps) {
-        const MemUsage& vma_stats = show_wss ? vma.wss : vma.usage;
+        const MemUsage& vma_stats = vma.usage;
         if (hide_zeroes && vma_stats.rss == 0) {
             continue;
         }
@@ -116,14 +116,14 @@
 int main(int argc, char* argv[]) {
     int opt;
     auto pss_sort = [](const Vma& a, const Vma& b) {
-        uint64_t pss_a = show_wss ? a.wss.pss : a.usage.pss;
-        uint64_t pss_b = show_wss ? b.wss.pss : b.usage.pss;
+        uint64_t pss_a = a.usage.pss;
+        uint64_t pss_b = b.usage.pss;
         return pss_a > pss_b;
     };
 
     auto uss_sort = [](const Vma& a, const Vma& b) {
-        uint64_t uss_a = show_wss ? a.wss.uss : a.usage.uss;
-        uint64_t uss_b = show_wss ? b.wss.uss : b.usage.uss;
+        uint64_t uss_a = a.usage.uss;
+        uint64_t uss_b = b.usage.uss;
         return uss_a > uss_b;
     };
 
@@ -182,7 +182,7 @@
     }
 
     ProcMemInfo proc(pid, show_wss);
-    const MemUsage& proc_stats = show_wss ? proc.Wss() : proc.Usage();
+    const MemUsage& proc_stats = proc.Usage();
     std::vector<Vma> maps(proc.Maps());
     if (sort_func != nullptr) {
         std::sort(maps.begin(), maps.end(), sort_func);
diff --git a/libmeminfo/tools/procrank.cpp b/libmeminfo/tools/procrank.cpp
index a751722..21a684c 100644
--- a/libmeminfo/tools/procrank.cpp
+++ b/libmeminfo/tools/procrank.cpp
@@ -465,7 +465,7 @@
         }
 
         // Skip processes with no memory mappings
-        uint64_t vss = show_wss ? proc.Wss().vss : proc.Usage().vss;
+        uint64_t vss = proc.Usage().vss;
         if (vss == 0) return true;
 
         // collect swap_offset counts from all processes in 1st pass
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index 9997b2a..a2d8d81 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -33,6 +33,11 @@
 
 namespace android {
 
+#ifdef __APPLE__
+template <typename T>
+void UNUSED(const T&) {}
+#endif
+
 extern "C" {
 
 // Environment values required by the apps running with native bridge.
@@ -254,10 +259,6 @@
   return strncmp(instruction_set, ABI_STRING, strlen(ABI_STRING) + 1) != 0;
 }
 
-#ifdef __APPLE__
-template<typename T> void UNUSED(const T&) {}
-#endif
-
 bool PreInitializeNativeBridge(const char* app_data_dir_in, const char* instruction_set) {
   if (state != NativeBridgeState::kOpened) {
     ALOGE("Invalid state: native bridge is expected to be opened.");
diff --git a/libnativebridge/tests/Android.bp b/libnativebridge/tests/Android.bp
index 7c82927..744a4a8 100644
--- a/libnativebridge/tests/Android.bp
+++ b/libnativebridge/tests/Android.bp
@@ -88,7 +88,7 @@
 }
 
 // Build the test for the C API.
-art_cc_test {
+cc_test {
     name: "libnativebridge-api-tests",
     host_supported: true,
     test_per_src: true,