Snap for 10716635 from 92651d78547c49e206d0601b6e7ad5d1efedc30b to mainline-neuralnetworks-release

Change-Id: I7a1d5106a4b75bdf2b16df9d10576ca346a51eb8
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 4242912..8da6982 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -57,12 +57,12 @@
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <private/android_filesystem_config.h>
 #include <property_info_parser/property_info_parser.h>
 #include <property_info_serializer/property_info_serializer.h>
 #include <selinux/android.h>
 #include <selinux/label.h>
 #include <selinux/selinux.h>
+
 #include "debug_ramdisk.h"
 #include "epoll.h"
 #include "init.h"
@@ -111,12 +111,12 @@
 
 static bool persistent_properties_loaded = false;
 
+static int property_set_fd = -1;
 static int from_init_socket = -1;
 static int init_socket = -1;
 static bool accept_messages = false;
 static std::mutex accept_messages_lock;
 static std::thread property_service_thread;
-static std::thread property_service_for_system_thread;
 
 static std::unique_ptr<PersistWriteThread> persist_write_thread;
 
@@ -394,37 +394,31 @@
         return {PROP_ERROR_INVALID_VALUE};
     }
 
-    if (name == "sys.powerctl") {
-        // No action here - NotifyPropertyChange will trigger the appropriate action, and since this
-        // can come to the second thread, we mustn't call out to the __system_property_* functions
-        // which support multiple readers but only one mutator.
+    prop_info* pi = (prop_info*)__system_property_find(name.c_str());
+    if (pi != nullptr) {
+        // ro.* properties are actually "write-once".
+        if (StartsWith(name, "ro.")) {
+            *error = "Read-only property was already set";
+            return {PROP_ERROR_READ_ONLY_PROPERTY};
+        }
+
+        __system_property_update(pi, value.c_str(), valuelen);
     } else {
-        prop_info* pi = (prop_info*)__system_property_find(name.c_str());
-        if (pi != nullptr) {
-            // ro.* properties are actually "write-once".
-            if (StartsWith(name, "ro.")) {
-                *error = "Read-only property was already set";
-                return {PROP_ERROR_READ_ONLY_PROPERTY};
-            }
-
-            __system_property_update(pi, value.c_str(), valuelen);
-        } else {
-            int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
-            if (rc < 0) {
-                *error = "__system_property_add failed";
-                return {PROP_ERROR_SET_FAILED};
-            }
+        int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
+        if (rc < 0) {
+            *error = "__system_property_add failed";
+            return {PROP_ERROR_SET_FAILED};
         }
+    }
 
-        // Don't write properties to disk until after we have read all default
-        // properties to prevent them from being overwritten by default values.
-        if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
-            if (persist_write_thread) {
-                persist_write_thread->Write(name, value, std::move(*socket));
-                return {};
-            }
-            WritePersistentProperty(name, value);
+    // Don't write properties to disk until after we have read all default
+    // properties to prevent them from being overwritten by default values.
+    if (socket && persistent_properties_loaded && StartsWith(name, "persist.")) {
+        if (persist_write_thread) {
+            persist_write_thread->Write(name, value, std::move(*socket));
+            return {};
         }
+        WritePersistentProperty(name, value);
     }
 
     NotifyPropertyChange(name, value);
@@ -585,10 +579,10 @@
     return *ret;
 }
 
-static void handle_property_set_fd(int fd) {
+static void handle_property_set_fd() {
     static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */
 
-    int s = accept4(fd, nullptr, nullptr, SOCK_CLOEXEC);
+    int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);
     if (s == -1) {
         return;
     }
@@ -1425,21 +1419,19 @@
     }
 }
 
-static void PropertyServiceThread(int fd, bool listen_init) {
+static void PropertyServiceThread() {
     Epoll epoll;
     if (auto result = epoll.Open(); !result.ok()) {
         LOG(FATAL) << result.error();
     }
 
-    if (auto result = epoll.RegisterHandler(fd, std::bind(handle_property_set_fd, fd));
+    if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);
         !result.ok()) {
         LOG(FATAL) << result.error();
     }
 
-    if (listen_init) {
-        if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
-            LOG(FATAL) << result.error();
-        }
+    if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
+        LOG(FATAL) << result.error();
     }
 
     while (true) {
@@ -1490,23 +1482,6 @@
     cv_.notify_all();
 }
 
-void StartThread(const char* name, int mode, int gid, std::thread& t, bool listen_init) {
-    int fd = -1;
-    if (auto result = CreateSocket(name, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
-                                   /*passcred=*/false, /*should_listen=*/false, mode, /*uid=*/0,
-                                   /*gid=*/gid, /*socketcon=*/{});
-        result.ok()) {
-        fd = *result;
-    } else {
-        LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
-    }
-
-    listen(fd, 8);
-
-    auto new_thread = std::thread(PropertyServiceThread, fd, listen_init);
-    t.swap(new_thread);
-}
-
 void StartPropertyService(int* epoll_socket) {
     InitPropertySet("ro.property_service.version", "2");
 
@@ -1518,9 +1493,19 @@
     init_socket = sockets[1];
     StartSendingMessages();
 
-    StartThread(PROP_SERVICE_FOR_SYSTEM_NAME, 0660, AID_SYSTEM, property_service_for_system_thread,
-                true);
-    StartThread(PROP_SERVICE_NAME, 0666, 0, property_service_thread, false);
+    if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+                                   /*passcred=*/false, /*should_listen=*/false, 0666, /*uid=*/0,
+                                   /*gid=*/0, /*socketcon=*/{});
+        result.ok()) {
+        property_set_fd = *result;
+    } else {
+        LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
+    }
+
+    listen(property_set_fd, 8);
+
+    auto new_thread = std::thread{PropertyServiceThread};
+    property_service_thread.swap(new_thread);
 
     auto async_persist_writes =
             android::base::GetBoolProperty("ro.property_service.async_persist_writes", false);
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 44dba2a..f51b076 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -114,9 +114,26 @@
 
 IProfileAttribute::~IProfileAttribute() = default;
 
-void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name) {
+const std::string& ProfileAttribute::file_name() const {
+    if (controller()->version() == 2 && !file_v2_name_.empty()) return file_v2_name_;
+    return file_name_;
+}
+
+void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name,
+                             const std::string& file_v2_name) {
     controller_ = controller;
     file_name_ = file_name;
+    file_v2_name_ = file_v2_name;
+}
+
+bool ProfileAttribute::GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const {
+    if (controller()->version() == 2) {
+        // all cgroup v2 attributes use the same process group hierarchy
+        *path = StringPrintf("%s/uid_%u/pid_%d/%s", controller()->path(), uid, pid,
+                             file_name().c_str());
+        return true;
+    }
+    return GetPathForTask(pid, path);
 }
 
 bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
@@ -129,12 +146,11 @@
         return true;
     }
 
-    const std::string& file_name =
-            controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
     if (subgroup.empty()) {
-        *path = StringPrintf("%s/%s", controller()->path(), file_name.c_str());
+        *path = StringPrintf("%s/%s", controller()->path(), file_name().c_str());
     } else {
-        *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), file_name.c_str());
+        *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(),
+                             file_name().c_str());
     }
     return true;
 }
@@ -144,9 +160,7 @@
         return true;
     }
 
-    const std::string& file_name =
-            controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
-    *path = StringPrintf("%s/uid_%d/%s", controller()->path(), uid, file_name.c_str());
+    *path = StringPrintf("%s/uid_%u/%s", controller()->path(), uid, file_name().c_str());
     return true;
 }
 
@@ -205,18 +219,7 @@
 
 #endif
 
-bool SetAttributeAction::ExecuteForProcess(uid_t, pid_t pid) const {
-    return ExecuteForTask(pid);
-}
-
-bool SetAttributeAction::ExecuteForTask(int tid) const {
-    std::string path;
-
-    if (!attribute_->GetPathForTask(tid, &path)) {
-        LOG(ERROR) << "Failed to find cgroup for tid " << tid;
-        return false;
-    }
-
+bool SetAttributeAction::WriteValueToFile(const std::string& path) const {
     if (!WriteStringToFile(value_, path)) {
         if (access(path.c_str(), F_OK) < 0) {
             if (optional_) {
@@ -236,6 +239,28 @@
     return true;
 }
 
+bool SetAttributeAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
+    std::string path;
+
+    if (!attribute_->GetPathForProcess(uid, pid, &path)) {
+        LOG(ERROR) << "Failed to find cgroup for uid " << uid << " pid " << pid;
+        return false;
+    }
+
+    return WriteValueToFile(path);
+}
+
+bool SetAttributeAction::ExecuteForTask(int tid) const {
+    std::string path;
+
+    if (!attribute_->GetPathForTask(tid, &path)) {
+        LOG(ERROR) << "Failed to find cgroup for tid " << tid;
+        return false;
+    }
+
+    return WriteValueToFile(path);
+}
+
 bool SetAttributeAction::ExecuteForUID(uid_t uid) const {
     std::string path;
 
@@ -816,7 +841,7 @@
                 attributes_[name] =
                         std::make_unique<ProfileAttribute>(controller, file_attr, file_v2_attr);
             } else {
-                iter->second->Reset(controller, file_attr);
+                iter->second->Reset(controller, file_attr, file_v2_attr);
             }
         } else {
             LOG(WARNING) << "Controller " << controller_name << " is not found";
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index a62c5b0..4663f64 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -32,9 +32,11 @@
 class IProfileAttribute {
   public:
     virtual ~IProfileAttribute() = 0;
-    virtual void Reset(const CgroupController& controller, const std::string& file_name) = 0;
+    virtual void Reset(const CgroupController& controller, const std::string& file_name,
+                       const std::string& file_v2_name) = 0;
     virtual const CgroupController* controller() const = 0;
     virtual const std::string& file_name() const = 0;
+    virtual bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const = 0;
     virtual bool GetPathForTask(int tid, std::string* path) const = 0;
     virtual bool GetPathForUID(uid_t uid, std::string* path) const = 0;
 };
@@ -50,9 +52,11 @@
     ~ProfileAttribute() = default;
 
     const CgroupController* controller() const override { return &controller_; }
-    const std::string& file_name() const override { return file_name_; }
-    void Reset(const CgroupController& controller, const std::string& file_name) override;
+    const std::string& file_name() const override;
+    void Reset(const CgroupController& controller, const std::string& file_name,
+               const std::string& file_v2_name) override;
 
+    bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override;
     bool GetPathForTask(int tid, std::string* path) const override;
     bool GetPathForUID(uid_t uid, std::string* path) const override;
 
@@ -131,6 +135,8 @@
     const IProfileAttribute* attribute_;
     std::string value_;
     bool optional_;
+
+    bool WriteValueToFile(const std::string& path) const;
 };
 
 // Set cgroup profile element
diff --git a/libprocessgroup/task_profiles_test.cpp b/libprocessgroup/task_profiles_test.cpp
index eadbe76..99d819a 100644
--- a/libprocessgroup/task_profiles_test.cpp
+++ b/libprocessgroup/task_profiles_test.cpp
@@ -102,7 +102,8 @@
   public:
     ProfileAttributeMock(const std::string& file_name) : file_name_(file_name) {}
     ~ProfileAttributeMock() override = default;
-    void Reset(const CgroupController& controller, const std::string& file_name) override {
+    void Reset(const CgroupController& controller, const std::string& file_name,
+               const std::string& file_v2_name) override {
         CHECK(false);
     }
     const CgroupController* controller() const override {
@@ -110,6 +111,9 @@
         return {};
     }
     const std::string& file_name() const override { return file_name_; }
+    bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override {
+        return GetPathForTask(pid, path);
+    }
     bool GetPathForTask(int tid, std::string* path) const override {
 #ifdef __ANDROID__
         CHECK(CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, path));
@@ -125,9 +129,7 @@
         return true;
     };
 
-    bool GetPathForUID(uid_t, std::string*) const override {
-        return false;
-    }
+    bool GetPathForUID(uid_t, std::string*) const override { return false; }
 
   private:
     const std::string file_name_;