[automerger skipped] libprocessgroup: Add support for task profiles am: 82b72a5667 am: 953472f577
am: 43a0b172f4 -s ours
am skip reason: change_id If5532d6dc570add825cebd5b5148e00c7d688e32 with SHA1 192aee782d is in history

Change-Id: Ifc9b1962eeaa62dd5c3cc05a2d9cb79db3853383
diff --git a/adb/daemon/auth.cpp b/adb/daemon/auth.cpp
index 1800f84..a829bac 100644
--- a/adb/daemon/auth.cpp
+++ b/adb/daemon/auth.cpp
@@ -18,6 +18,7 @@
 
 #include "adb.h"
 #include "adb_auth.h"
+#include "adb_io.h"
 #include "fdevent.h"
 #include "sysdeps.h"
 #include "transport.h"
@@ -39,9 +40,9 @@
 static fdevent* framework_fde = nullptr;
 static int framework_fd = -1;
 
-static void usb_disconnected(void* unused, atransport* t);
-static struct adisconnect usb_disconnect = { usb_disconnected, nullptr};
-static atransport* usb_transport;
+static void adb_disconnected(void* unused, atransport* t);
+static struct adisconnect adb_disconnect = {adb_disconnected, nullptr};
+static atransport* adb_transport;
 static bool needs_retry = false;
 
 bool auth_required = true;
@@ -98,10 +99,17 @@
     return okay;
 }
 
-static void usb_disconnected(void* unused, atransport* t) {
-    LOG(INFO) << "USB disconnect";
-    usb_transport = nullptr;
+static void adb_disconnected(void* unused, atransport* t) {
+    LOG(INFO) << "ADB disconnect";
+    adb_transport = nullptr;
     needs_retry = false;
+    if (framework_fd >= 0) {
+        const char msg[] = "DC";
+        LOG(DEBUG) << "Sending '" << msg << "'";
+        if (!WriteFdExactly(framework_fd, msg, sizeof(msg))) {
+            PLOG(ERROR) << "Failed to send disconnected message";
+        }
+    }
 }
 
 static void framework_disconnected() {
@@ -119,17 +127,17 @@
         if (ret <= 0) {
             framework_disconnected();
         } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
-            if (usb_transport) {
-                adbd_auth_verified(usb_transport);
+            if (adb_transport) {
+                adbd_auth_verified(adb_transport);
             }
         }
     }
 }
 
 void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
-    if (!usb_transport) {
-        usb_transport = t;
-        t->AddDisconnect(&usb_disconnect);
+    if (!adb_transport) {
+        adb_transport = t;
+        t->AddDisconnect(&adb_disconnect);
     }
 
     if (framework_fd < 0) {
@@ -151,7 +159,7 @@
     }
     LOG(DEBUG) << "Sending '" << msg << "'";
 
-    if (unix_write(framework_fd, msg, msg_len) == -1) {
+    if (!WriteFdExactly(framework_fd, msg, msg_len)) {
         PLOG(ERROR) << "Failed to write PK";
         return;
     }
@@ -175,7 +183,7 @@
 
     if (needs_retry) {
         needs_retry = false;
-        send_auth_request(usb_transport);
+        send_auth_request(adb_transport);
     }
 }
 
diff --git a/init/service.cpp b/init/service.cpp
index a6eb7f7..84cb2d8 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -991,27 +991,33 @@
         std::for_each(descriptors_.begin(), descriptors_.end(),
                       std::bind(&DescriptorInfo::CreateAndPublish, std::placeholders::_1, scon));
 
-        // See if there were "writepid" instructions to write to files under /dev/cpuset/.
-        auto cpuset_predicate = [](const std::string& path) {
-            return StartsWith(path, "/dev/cpuset/");
-        };
-        auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
-        if (iter == writepid_files_.end()) {
-            // There were no "writepid" instructions for cpusets, check if the system default
-            // cpuset is specified to be used for the process.
-            std::string default_cpuset = GetProperty("ro.cpuset.default", "");
-            if (!default_cpuset.empty()) {
-                // Make sure the cpuset name starts and ends with '/'.
-                // A single '/' means the 'root' cpuset.
-                if (default_cpuset.front() != '/') {
-                    default_cpuset.insert(0, 1, '/');
+        // See if there were "writepid" instructions to write to files under cpuset path.
+        std::string cpuset_path;
+        if (CgroupGetControllerPath("cpuset", &cpuset_path)) {
+            auto cpuset_predicate = [&cpuset_path](const std::string& path) {
+                return StartsWith(path, cpuset_path + "/");
+            };
+            auto iter =
+                    std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
+            if (iter == writepid_files_.end()) {
+                // There were no "writepid" instructions for cpusets, check if the system default
+                // cpuset is specified to be used for the process.
+                std::string default_cpuset = GetProperty("ro.cpuset.default", "");
+                if (!default_cpuset.empty()) {
+                    // Make sure the cpuset name starts and ends with '/'.
+                    // A single '/' means the 'root' cpuset.
+                    if (default_cpuset.front() != '/') {
+                        default_cpuset.insert(0, 1, '/');
+                    }
+                    if (default_cpuset.back() != '/') {
+                        default_cpuset.push_back('/');
+                    }
+                    writepid_files_.push_back(
+                            StringPrintf("%s%stasks", cpuset_path.c_str(), default_cpuset.c_str()));
                 }
-                if (default_cpuset.back() != '/') {
-                    default_cpuset.push_back('/');
-                }
-                writepid_files_.push_back(
-                    StringPrintf("/dev/cpuset%stasks", default_cpuset.c_str()));
             }
+        } else {
+            LOG(ERROR) << "cpuset cgroup controller is not mounted!";
         }
         std::string pid_str = std::to_string(getpid());
         for (const auto& file : writepid_files_) {
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index 1b5f217..12cfb7e 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -142,6 +142,9 @@
     return true;
 }
 
+// To avoid issues in sdk_mac build
+#if defined(__ANDROID__)
+
 static bool SetupCgroup(const CgroupDescriptor& descriptor) {
     const CgroupController* controller = descriptor.controller();
 
@@ -180,6 +183,15 @@
     return true;
 }
 
+#else
+
+// Stubs for non-Android targets.
+static bool SetupCgroup(const CgroupDescriptor&) {
+    return false;
+}
+
+#endif
+
 static bool WriteRcFile(const std::map<std::string, CgroupDescriptor>& descriptors) {
     std::string cgroup_rc_path = StringPrintf("%s/%s", CGROUPS_RC_DIR, CgroupMap::CGROUPS_RC_FILE);
     unique_fd fd(TEMP_FAILURE_RETRY(open(cgroup_rc_path.c_str(),
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index 4c8aa6d..337b032 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -36,6 +36,8 @@
     return p == SP_DEFAULT ? SP_SYSTEM_DEFAULT : p;
 }
 
+#if defined(__ANDROID__)
+
 int set_cpuset_policy(int tid, SchedPolicy policy) {
     if (tid == 0) {
         tid = GetThreadId();
@@ -195,6 +197,21 @@
     return 0;
 }
 
+#else
+
+/* Stubs for non-Android targets. */
+
+int set_sched_policy(int, SchedPolicy) {
+    return 0;
+}
+
+int get_sched_policy(int, SchedPolicy* policy) {
+    *policy = SP_SYSTEM_DEFAULT;
+    return 0;
+}
+
+#endif
+
 const char* get_sched_policy_name(SchedPolicy policy) {
     policy = _policy(policy);
     static const char* const kSchedPolicyNames[] = {
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index eb50f85..ec6cbbc 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -18,7 +18,6 @@
 #define LOG_TAG "libprocessgroup"
 
 #include <fcntl.h>
-#include <sys/prctl.h>
 #include <task_profiles.h>
 #include <string>
 
@@ -32,6 +31,11 @@
 #include <json/reader.h>
 #include <json/value.h>
 
+// To avoid issues in sdk_mac build
+#if defined(__ANDROID__)
+#include <sys/prctl.h>
+#endif
+
 using android::base::GetThreadId;
 using android::base::StringPrintf;
 using android::base::unique_fd;
@@ -69,6 +73,9 @@
     return false;
 }
 
+// To avoid issues in sdk_mac build
+#if defined(__ANDROID__)
+
 bool SetTimerSlackAction::IsTimerSlackSupported(int tid) {
     auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
 
@@ -97,6 +104,8 @@
     return true;
 }
 
+#endif
+
 bool SetAttributeAction::ExecuteForProcess(uid_t, pid_t pid) const {
     return ExecuteForTask(pid);
 }
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 684762a..886ead1 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -63,6 +63,9 @@
     int clamp_;
 };
 
+// To avoid issues in sdk_mac build
+#if defined(__ANDROID__)
+
 class SetTimerSlackAction : public ProfileAction {
   public:
     SetTimerSlackAction(unsigned long slack) noexcept : slack_(slack) {}
@@ -75,6 +78,17 @@
     static bool IsTimerSlackSupported(int tid);
 };
 
+#else
+
+class SetTimerSlackAction : public ProfileAction {
+  public:
+    SetTimerSlackAction(unsigned long) noexcept {}
+
+    virtual bool ExecuteForTask(int) const { return true; }
+};
+
+#endif
+
 // Set attribute profile element
 class SetAttributeAction : public ProfileAction {
   public:
diff --git a/libsystem/include/system/graphics-base-v1.2.h b/libsystem/include/system/graphics-base-v1.2.h
new file mode 100644
index 0000000..5b857d9
--- /dev/null
+++ b/libsystem/include/system/graphics-base-v1.2.h
@@ -0,0 +1,29 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.graphics.common@1.2
+// Location: hardware/interfaces/graphics/common/1.2/
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    HAL_HDR_HDR10_PLUS = 4,
+} android_hdr_v1_2_t;
+
+typedef enum {
+    HAL_DATASPACE_DISPLAY_BT2020 = 142999552 /* ((STANDARD_BT2020 | TRANSFER_SRGB) | RANGE_FULL) */,
+    HAL_DATASPACE_DYNAMIC_DEPTH = 4098 /* 0x1002 */,
+} android_dataspace_v1_2_t;
+
+typedef enum {
+    HAL_PIXEL_FORMAT_HSV_888 = 55 /* 0x37 */,
+} android_pixel_format_v1_2_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
diff --git a/libsystem/include/system/graphics-base.h b/libsystem/include/system/graphics-base.h
index ea92007..92ee077 100644
--- a/libsystem/include/system/graphics-base.h
+++ b/libsystem/include/system/graphics-base.h
@@ -3,5 +3,6 @@
 
 #include "graphics-base-v1.0.h"
 #include "graphics-base-v1.1.h"
+#include "graphics-base-v1.2.h"
 
 #endif  // SYSTEM_CORE_GRAPHICS_BASE_H_
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 2047e2f..6cb059e 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -984,7 +984,7 @@
 }
 
 #ifdef LMKD_LOG_STATS
-static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
+static void memory_stat_parse_line(char* line, struct memory_stat* mem_st) {
     char key[LINE_MAX + 1];
     int64_t value;
 
@@ -1006,25 +1006,63 @@
         mem_st->swap_in_bytes = value;
 }
 
-static int memory_stat_parse(struct memory_stat *mem_st,  int pid, uid_t uid) {
-   FILE *fp;
-   char buf[PATH_MAX];
+static int memory_stat_from_cgroup(struct memory_stat* mem_st, int pid, uid_t uid) {
+    FILE *fp;
+    char buf[PATH_MAX];
 
-   snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
+    snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
 
-   fp = fopen(buf, "r");
+    fp = fopen(buf, "r");
 
-   if (fp == NULL) {
-       ALOGE("%s open failed: %s", buf, strerror(errno));
-       return -1;
-   }
+    if (fp == NULL) {
+        ALOGE("%s open failed: %s", buf, strerror(errno));
+        return -1;
+    }
 
-   while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
-       memory_stat_parse_line(buf, mem_st);
-   }
-   fclose(fp);
+    while (fgets(buf, PAGE_SIZE, fp) != NULL) {
+        memory_stat_parse_line(buf, mem_st);
+    }
+    fclose(fp);
 
-   return 0;
+    return 0;
+}
+
+static int memory_stat_from_procfs(struct memory_stat* mem_st, int pid) {
+    char path[PATH_MAX];
+    char buffer[PROC_STAT_BUFFER_SIZE];
+    int fd, ret;
+
+    snprintf(path, sizeof(path), PROC_STAT_FILE_PATH, pid);
+    if ((fd = open(path, O_RDONLY | O_CLOEXEC)) < 0) {
+        ALOGE("%s open failed: %s", path, strerror(errno));
+        return -1;
+    }
+
+    ret = read(fd, buffer, sizeof(buffer));
+    if (ret < 0) {
+        ALOGE("%s read failed: %s", path, strerror(errno));
+        close(fd);
+        return -1;
+    }
+    close(fd);
+
+    // field 10 is pgfault
+    // field 12 is pgmajfault
+    // field 22 is starttime
+    // field 24 is rss_in_pages
+    int64_t pgfault = 0, pgmajfault = 0, starttime = 0, rss_in_pages = 0;
+    if (sscanf(buffer,
+               "%*u %*s %*s %*d %*d %*d %*d %*d %*d %" SCNd64 " %*d "
+               "%" SCNd64 " %*d %*u %*u %*d %*d %*d %*d %*d %*d "
+               "%" SCNd64 " %*d %" SCNd64 "",
+               &pgfault, &pgmajfault, &starttime, &rss_in_pages) != 4) {
+        return -1;
+    }
+    mem_st->pgfault = pgfault;
+    mem_st->pgmajfault = pgmajfault;
+    mem_st->rss_in_bytes = (rss_in_pages * PAGE_SIZE);
+    mem_st->process_start_time_ns = starttime * (NS_PER_SEC / sysconf(_SC_CLK_TCK));
+    return 0;
 }
 #endif
 
@@ -1316,7 +1354,11 @@
 
 #ifdef LMKD_LOG_STATS
     if (enable_stats_log) {
-        memory_stat_parse_result = memory_stat_parse(&mem_st, pid, uid);
+        if (per_app_memcg) {
+            memory_stat_parse_result = memory_stat_from_cgroup(&mem_st, pid, uid);
+        } else {
+            memory_stat_parse_result = memory_stat_from_procfs(&mem_st, pid);
+        }
     }
 #endif
 
@@ -1343,7 +1385,10 @@
         if (memory_stat_parse_result == 0) {
             stats_write_lmk_kill_occurred(log_ctx, LMK_KILL_OCCURRED, uid, taskname,
                     procp->oomadj, mem_st.pgfault, mem_st.pgmajfault, mem_st.rss_in_bytes,
-                    mem_st.cache_in_bytes, mem_st.swap_in_bytes);
+                    mem_st.cache_in_bytes, mem_st.swap_in_bytes, mem_st.process_start_time_ns);
+        } else if (enable_stats_log) {
+            stats_write_lmk_kill_occurred(log_ctx, LMK_KILL_OCCURRED, uid, taskname, procp->oomadj,
+                                          -1, -1, tasksize * BYTES_IN_KILOBYTE, -1, -1, -1);
         }
 #endif
         result = tasksize;
diff --git a/lmkd/statslog.c b/lmkd/statslog.c
index 66d1164..689e8ae 100644
--- a/lmkd/statslog.c
+++ b/lmkd/statslog.c
@@ -65,7 +65,7 @@
 stats_write_lmk_kill_occurred(android_log_context ctx, int32_t code, int32_t uid,
                               char const* process_name, int32_t oom_score, int64_t pgfault,
                               int64_t pgmajfault, int64_t rss_in_bytes, int64_t cache_in_bytes,
-                              int64_t swap_in_bytes) {
+                              int64_t swap_in_bytes, int64_t process_start_time_ns) {
     assert(ctx != NULL);
     int ret = -EINVAL;
     if (!ctx) {
@@ -113,5 +113,9 @@
         return ret;
     }
 
+    if ((ret = android_log_write_int64(ctx, process_start_time_ns)) < 0) {
+        return ret;
+    }
+
     return write_to_logger(ctx, LOG_ID_STATS);
 }
diff --git a/lmkd/statslog.h b/lmkd/statslog.h
index edebb19..f3abe11 100644
--- a/lmkd/statslog.h
+++ b/lmkd/statslog.h
@@ -64,9 +64,13 @@
     int64_t rss_in_bytes;
     int64_t cache_in_bytes;
     int64_t swap_in_bytes;
+    int64_t process_start_time_ns;
 };
 
 #define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%u/memory.stat"
+#define PROC_STAT_FILE_PATH "/proc/%d/stat"
+#define PROC_STAT_BUFFER_SIZE 1024
+#define BYTES_IN_KILOBYTE 1024
 
 /**
  * Logs the change in LMKD state which is used as start/stop boundaries for logging
@@ -84,7 +88,7 @@
 stats_write_lmk_kill_occurred(android_log_context ctx, int32_t code, int32_t uid,
                               char const* process_name, int32_t oom_score, int64_t pgfault,
                               int64_t pgmajfault, int64_t rss_in_bytes, int64_t cache_in_bytes,
-                              int64_t swap_in_bytes);
+                              int64_t swap_in_bytes, int64_t process_start_time_ns);
 
 __END_DECLS
 
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index d8f6095..27e855f 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libamidi.so
 libbinder_ndk.so
 libc.so
 libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.iot.txt b/rootdir/etc/public.libraries.iot.txt
index 20905bf..b565340 100644
--- a/rootdir/etc/public.libraries.iot.txt
+++ b/rootdir/etc/public.libraries.iot.txt
@@ -2,6 +2,7 @@
 libandroid.so
 libandroidthings.so
 libaaudio.so
+libamidi.so
 libbinder_ndk.so
 libc.so
 libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 4ece5b5..7cbda08 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libamidi.so
 libbinder_ndk.so
 libc.so
 libcamera2ndk.so
diff --git a/rootdir/init.rc b/rootdir/init.rc
index c6e2116..79873c0 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -632,6 +632,12 @@
     chown root system /sys/module/lowmemorykiller/parameters/minfree
     chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
 
+    # System server manages zram writeback
+    chown root system /sys/block/zram0/idle
+    chmod 0664 /sys/block/zram0/idle
+    chown root system /sys/block/zram0/writeback
+    chmod 0664 /sys/block/zram0/writeback
+
     # Tweak background writeout
     write /proc/sys/vm/dirty_expire_centisecs 200
     write /proc/sys/vm/dirty_background_ratio  5