Merge "system/core: use proper nativehelper headers" am: 4f59afe9fa am: 6208cd1322 am: 106c355688
am: 57db1511bd

Change-Id: If1de13ecd84a5bf43edefd844e1b46104bddf9a0
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 80def73..0b656aa 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -40,6 +40,7 @@
 LOCAL_MODULE_TAGS := debug
 LOCAL_MODULE_HOST_OS := darwin linux windows
 LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
+LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid
 
 LOCAL_SRC_FILES_linux := usb_linux.cpp
 LOCAL_STATIC_LIBRARIES_linux := libselinux
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 99ca7dd..f3c000e 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -10,14 +10,22 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#ifndef WIN32
+#include <sys/wait.h>
+#endif
 #include <unistd.h>
+#include <vector>
 
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
 #include <ext4_utils/make_ext4fs.h>
 #include <sparse/sparse.h>
 
+using android::base::StringPrintf;
 using android::base::unique_fd;
 
+#ifdef WIN32
 static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir,
                                        unsigned eraseBlkSize, unsigned logicalBlkSize)
 {
@@ -34,6 +42,84 @@
     }
     return 0;
 }
+#else
+static int exec_e2fs_cmd(const char* path, char* const argv[]) {
+    int status;
+    pid_t child;
+    if ((child = fork()) == 0) {
+        setenv("MKE2FS_CONFIG", "", 1);
+        execvp(path, argv);
+        _exit(EXIT_FAILURE);
+    }
+    if (child < 0) {
+        fprintf(stderr, "%s failed with fork %s\n", path, strerror(errno));
+        return -1;
+    }
+    if (TEMP_FAILURE_RETRY(waitpid(child, &status, 0)) == -1) {
+        fprintf(stderr, "%s failed with waitpid %s\n", path, strerror(errno));
+        return -1;
+    }
+    int ret = -1;
+    if (WIFEXITED(status)) {
+        ret = WEXITSTATUS(status);
+        if (ret != 0) {
+            fprintf(stderr, "%s failed with status %d\n", path, ret);
+        }
+    }
+    return ret;
+}
+
+static int generate_ext4_image(const char* fileName, long long partSize,
+                               const std::string& initial_dir, unsigned eraseBlkSize,
+                               unsigned logicalBlkSize) {
+    static constexpr int block_size = 4096;
+    const std::string exec_dir = android::base::GetExecutableDirectory();
+
+    const std::string mke2fs_path = exec_dir + "/mke2fs";
+    std::vector<const char*> mke2fs_args = {mke2fs_path.c_str(), "-t", "ext4", "-b"};
+
+    std::string block_size_str = std::to_string(block_size);
+    mke2fs_args.push_back(block_size_str.c_str());
+
+    std::string ext_attr = "android_sparse";
+    if (eraseBlkSize != 0 && logicalBlkSize != 0) {
+        int raid_stride = logicalBlkSize / block_size;
+        int raid_stripe_width = eraseBlkSize / block_size;
+        // stride should be the max of 8kb and logical block size
+        if (logicalBlkSize != 0 && logicalBlkSize < 8192) raid_stride = 8192 / block_size;
+        ext_attr += StringPrintf(",stride=%d,stripe-width=%d", raid_stride, raid_stripe_width);
+    }
+    mke2fs_args.push_back("-E");
+    mke2fs_args.push_back(ext_attr.c_str());
+    mke2fs_args.push_back(fileName);
+
+    std::string size_str = std::to_string(partSize / block_size);
+    mke2fs_args.push_back(size_str.c_str());
+    mke2fs_args.push_back(nullptr);
+
+    int ret = exec_e2fs_cmd(mke2fs_args[0], const_cast<char**>(mke2fs_args.data()));
+    if (ret != 0) {
+        fprintf(stderr, "mke2fs failed: %d\n", ret);
+        return -1;
+    }
+
+    if (initial_dir.empty()) {
+        return 0;
+    }
+
+    const std::string e2fsdroid_path = exec_dir + "/e2fsdroid";
+    std::vector<const char*> e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(),
+                                               fileName, nullptr};
+
+    ret = exec_e2fs_cmd(e2fsdroid_args[0], const_cast<char**>(e2fsdroid_args.data()));
+    if (ret != 0) {
+        fprintf(stderr, "e2fsdroid failed: %d\n", ret);
+        return -1;
+    }
+
+    return 0;
+}
+#endif
 
 #ifdef USE_F2FS
 static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir,
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index f3ca724..9249343 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_MODULE:= fs_mgr
 LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := mke2fs mke2fs.conf e2fsdroid
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index a03d92c..fc88217 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -24,21 +24,16 @@
 #include <cutils/partition_utils.h>
 #include <sys/mount.h>
 
-#include <ext4_utils/ext4_utils.h>
 #include <ext4_utils/ext4.h>
-#include <ext4_utils/make_ext4fs.h>
-#include <selinux/selinux.h>
-#include <selinux/label.h>
+#include <ext4_utils/ext4_utils.h>
+#include <logwrap/logwrap.h>
 #include <selinux/android.h>
+#include <selinux/label.h>
+#include <selinux/selinux.h>
 
 #include "fs_mgr_priv.h"
 #include "cryptfs.h"
 
-extern "C" {
-extern struct fs_info info;     /* magic global from ext4_utils */
-extern void reset_ext4fs_info();
-}
-
 static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
 {
     uint64_t dev_sz;
@@ -55,30 +50,36 @@
         return -1;
     }
 
-    struct selabel_handle *sehandle = selinux_android_file_context_handle();
-    if (!sehandle) {
-        /* libselinux logs specific error */
-        LERROR << "Cannot initialize android file_contexts";
-        close(fd);
-        return -1;
-    }
-
-    /* Format the partition using the calculated length */
-    reset_ext4fs_info();
-    info.len = (off64_t)dev_sz;
-    if (crypt_footer) {
-        info.len -= CRYPT_FOOTER_OFFSET;
-    }
-
-    /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
-    rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL, NULL, NULL);
-    if (rc) {
-        LERROR << "make_ext4fs returned " << rc;
-    }
     close(fd);
 
-    if (sehandle) {
-        selabel_close(sehandle);
+    /* Format the partition using the calculated length */
+    if (crypt_footer) {
+        dev_sz -= CRYPT_FOOTER_OFFSET;
+    }
+
+    std::string size_str = std::to_string(dev_sz / 4096);
+    const char* const mke2fs_args[] = {
+        "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
+
+    rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
+                                 true, LOG_KLOG, true, nullptr, nullptr, 0);
+    if (rc) {
+        LERROR << "mke2fs returned " << rc;
+        return rc;
+    }
+
+    const char* const e2fsdroid_args[] = {
+        "/system/bin/e2fsdroid",
+        "-e",
+        "-a",
+        fs_mnt_point,
+        fs_blkdev,
+        nullptr};
+
+    rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
+                                 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
+    if (rc) {
+        LERROR << "e2fsdroid returned " << rc;
     }
 
     return rc;
@@ -86,44 +87,10 @@
 
 static int format_f2fs(char *fs_blkdev)
 {
-    char * args[5];
-    int pid;
-    int rc = 0;
+    const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
 
-    args[0] = (char *)"/system/bin/make_f2fs";
-    args[1] = (char *)"-f";
-    args[2] = (char *)"-O encrypt";
-    args[3] = fs_blkdev;
-    args[4] = (char *)0;
-
-    pid = fork();
-    if (pid < 0) {
-       return pid;
-    }
-    if (!pid) {
-        /* This doesn't return */
-        execv(args[0], args);
-        exit(1);
-    }
-    for(;;) {
-        pid_t p = waitpid(pid, &rc, 0);
-        if (p != pid) {
-            LERROR << "Error waiting for child process - " << p;
-            rc = -1;
-            break;
-        }
-        if (WIFEXITED(rc)) {
-            rc = WEXITSTATUS(rc);
-            LINFO << args[0] << " done, status " << rc;
-            if (rc) {
-                rc = -1;
-            }
-            break;
-        }
-        LERROR << "Still waiting for " << args[0] << "...";
-    }
-
-    return rc;
+    return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
+                                   LOG_KLOG, true, nullptr, nullptr, 0);
 }
 
 int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer)
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 0dfd9d8..28f0b07 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -21,8 +21,7 @@
 LOCAL_SRC_FILES := \
 	SoftGateKeeperDevice.cpp \
 	IGateKeeperService.cpp \
-	gatekeeperd.cpp \
-	IUserManager.cpp
+	gatekeeperd.cpp
 
 LOCAL_MODULE := gatekeeperd
 LOCAL_SHARED_LIBRARIES := \
diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserManager.cpp
deleted file mode 100644
index 8167d19..0000000
--- a/gatekeeperd/IUserManager.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#define LOG_TAG "IUserManager"
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-
-#include "IUserManager.h"
-
-namespace android {
-
-class BpUserManager : public BpInterface<IUserManager>
-{
-public:
-    explicit BpUserManager(const sp<IBinder>& impl) :
-            BpInterface<IUserManager>(impl) {
-    }
-    virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
-        data.writeInt32(user_id);
-        status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
-        if (rc != NO_ERROR) {
-            ALOGE("%s: failed (%d)\n", __func__, rc);
-            return -1;
-        }
-
-        int32_t exception = reply.readExceptionCode();
-        if (exception != 0) {
-            ALOGE("%s: got exception (%d)\n", __func__, exception);
-            return -1;
-        }
-
-        return reply.readInt32();
-    }
-
-};
-
-IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
-
-}; // namespace android
-
diff --git a/gatekeeperd/IUserManager.h b/gatekeeperd/IUserManager.h
deleted file mode 100644
index 640e9b5..0000000
--- a/gatekeeperd/IUserManager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef IUSERMANAGER_H_
-#define IUSERMANAGER_H_
-
-#include <inttypes.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-/*
-* Communication channel to UserManager
-*/
-class IUserManager : public IInterface {
-    public:
-        // must be kept in sync with IUserManager.aidl
-        enum {
-            GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
-        };
-
-        virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
-
-        DECLARE_META_INTERFACE(UserManager);
-};
-
-}; // namespace android
-
-#endif // IUSERMANAGER_H_
-
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index c6369f9..184c6d2 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -37,7 +37,6 @@
 #include <utils/String16.h>
 
 #include "SoftGateKeeperDevice.h"
-#include "IUserManager.h"
 
 #include <hidl/HidlSupport.h>
 #include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -334,23 +333,7 @@
         return ret;
     }
 
-    virtual uint64_t getSecureUserId(uint32_t uid) {
-        uint64_t sid = read_sid(uid);
-         if (sid == 0) {
-            // might be a work profile, look up the parent
-            sp<IServiceManager> sm = defaultServiceManager();
-            sp<IBinder> binder = sm->getService(String16("user"));
-            sp<IUserManager> um = interface_cast<IUserManager>(binder);
-            int32_t parent = um->getCredentialOwnerProfile(uid);
-            if (parent < 0) {
-                return 0;
-            } else if (parent != (int32_t) uid) {
-                return read_sid(parent);
-            }
-        }
-        return sid;
-
-    }
+    virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
 
     virtual void clearSecureUserId(uint32_t uid) {
         IPCThreadState* ipc = IPCThreadState::self();
diff --git a/healthd/Android.bp b/healthd/Android.bp
new file mode 100644
index 0000000..56f5148
--- /dev/null
+++ b/healthd/Android.bp
@@ -0,0 +1,7 @@
+cc_library_headers {
+    name: "libhealthd_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    header_libs: ["libbatteryservice_headers"],
+    export_header_lib_headers: ["libbatteryservice_headers"],
+}
diff --git a/init/init.cpp b/init/init.cpp
index e84d069..55d5fa8 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -910,7 +910,6 @@
     selinux_android_restorecon("/dev/urandom", 0);
     selinux_android_restorecon("/dev/__properties__", 0);
 
-    selinux_android_restorecon("/file_contexts.bin", 0);
     selinux_android_restorecon("/plat_file_contexts", 0);
     selinux_android_restorecon("/nonplat_file_contexts", 0);
     selinux_android_restorecon("/plat_property_contexts", 0);
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 0792307..8b0c53e 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -179,7 +179,11 @@
         }
 
         const uint32_t opcode = buffer_.request.header.opcode;
-        LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode;
+        const uint64_t unique = buffer_.request.header.unique;
+        LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
+        if (unique == 0) {
+            return FuseBridgeState::kWaitToReadEither;
+        }
         switch (opcode) {
             case FUSE_FORGET:
                 // Do not reply to FUSE_FORGET.
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index 51d6051..0a28451 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -67,6 +67,7 @@
     memset(&request_, 0, sizeof(FuseRequest));
     request_.header.opcode = opcode;
     request_.header.len = sizeof(fuse_in_header);
+    request_.header.unique = 1;
     ASSERT_TRUE(request_.Write(dev_sockets_[0]));
 
     memset(&response_, 0, sizeof(FuseResponse));
diff --git a/liblog/Android.bp b/liblog/Android.bp
index e74aa82..b98d18f 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -42,6 +42,24 @@
     "logd_writer.c",
 ]
 
+cc_library_headers {
+    name: "liblog_headers",
+    host_supported: true,
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    target: {
+        windows: {
+            enabled: true,
+        },
+        linux_bionic: {
+            enabled: true,
+        },
+        vendor: {
+            export_include_dirs: ["include_vndk"],
+        },
+    },
+}
+
 // Shared and static library for host and device
 // ========================================================
 cc_library {
@@ -81,7 +99,8 @@
         },
     },
 
-    export_include_dirs: ["include"],
+    header_libs: ["liblog_headers"],
+    export_header_lib_headers: ["liblog_headers"],
 
     cflags: [
         "-Werror",
@@ -100,7 +119,7 @@
 }
 
 ndk_headers {
-    name: "liblog_headers",
+    name: "liblog_ndk_headers",
     from: "include/android",
     to: "android",
     srcs: ["include/android/log.h"],
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
index da16158..68c2e9a 100644
--- a/liblog/include/log/log_main.h
+++ b/liblog/include/log/log_main.h
@@ -18,10 +18,9 @@
 #define _LIBS_LOG_LOG_MAIN_H
 
 #include <android/log.h>
+#include <sys/cdefs.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
 /*
  * Normally we strip the effects of ALOGV (VERBOSE messages),
@@ -385,8 +384,6 @@
 #pragma clang diagnostic pop
 #endif
 
-#ifdef __cplusplus
-}
-#endif
+__END_DECLS
 
 #endif /* _LIBS_LOG_LOG_MAIN_H */
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index ab96429..91044ab 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -89,7 +89,7 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
 LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 LOCAL_CTS_TEST_PACKAGE := android.core.liblog
 include $(BUILD_CTS_EXECUTABLE)
 
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index daa28ae..f9057bd 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -17,8 +17,8 @@
 LIBSYNC {
   global:
     sync_merge; # introduced=26
-    sync_get_fence_info; # introduced=26
-    sync_free_fence_info; # introduced=26
+    sync_file_info; # introduced=26
+    sync_file_info_free; # introduced=26
   local:
     *;
 };
diff --git a/libutils/Android.bp b/libutils/Android.bp
index a1bdbf3..9e7cc13 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -18,10 +18,12 @@
     host_supported: true,
 
     header_libs: [
+        "liblog_headers",
         "libsystem_headers",
         "libcutils_headers"
     ],
     export_header_lib_headers: [
+        "liblog_headers",
         "libsystem_headers",
         "libcutils_headers"
     ],
@@ -78,6 +80,10 @@
         "libutils_headers",
     ],
 
+    shared_libs: [
+        "liblog",
+    ],
+
     arch: {
         mips: {
             cflags: ["-DALIGN_DOUBLE"],
@@ -98,7 +104,6 @@
                 "libbacktrace",
                 "libcutils",
                 "libdl",
-                "liblog",
                 "libvndksupport",
             ],
 
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 8a6168c..c095315 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -40,7 +40,8 @@
 #endif
 
 #define MEMCG_SYSFS_PATH "/dev/memcg/"
-#define MEMPRESSURE_WATCH_LEVEL "low"
+#define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium"
+#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
 #define ZONEINFO_PATH "/proc/zoneinfo"
 #define LINE_MAX 128
 
@@ -48,6 +49,7 @@
 #define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
 
 #define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*(x)))
+#define EIGHT_MEGA (1 << 23)
 
 enum lmk_cmd {
     LMK_TARGET,
@@ -66,15 +68,17 @@
 static int use_inkernel_interface = 1;
 
 /* memory pressure level medium event */
-static int mpevfd;
+static int mpevfd[2];
+#define CRITICAL_INDEX 1
+#define MEDIUM_INDEX 0
 
 /* control socket listen and data */
 static int ctrl_lfd;
 static int ctrl_dfd = -1;
 static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */
 
-/* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */
-#define MAX_EPOLL_EVENTS 3
+/* 2 memory pressure levels, 1 ctrl listen socket, 1 ctrl data socket */
+#define MAX_EPOLL_EVENTS 4
 static int epollfd;
 static int maxevents;
 
@@ -113,14 +117,6 @@
 #define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN)
 static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
 
-/*
- * Wait 1-2 seconds for the death report of a killed process prior to
- * considering killing more processes.
- */
-#define KILL_TIMEOUT 2
-/* Time of last process kill we initiated, stop me before I kill again */
-static time_t kill_lasttime;
-
 /* PAGE_SIZE / 1024 */
 static long page_k;
 
@@ -241,6 +237,7 @@
     struct proc *procp;
     char path[80];
     char val[20];
+    int soft_limit_mult;
 
     if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
         ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
@@ -254,6 +251,36 @@
     if (use_inkernel_interface)
         return;
 
+    if (oomadj >= 900) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 800) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 700) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 600) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 500) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 400) {
+        soft_limit_mult = 0;
+    } else if (oomadj >= 300) {
+        soft_limit_mult = 1;
+    } else if (oomadj >= 200) {
+        soft_limit_mult = 2;
+    } else if (oomadj >= 100) {
+        soft_limit_mult = 10;
+    } else if (oomadj >=   0) {
+        soft_limit_mult = 20;
+    } else {
+        // Persistent processes will have a large
+        // soft limit 512MB.
+        soft_limit_mult = 64;
+    }
+
+    snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid);
+    snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
+    writefilestring(path, val);
+
     procp = pid_lookup(pid);
     if (!procp) {
             procp = malloc(sizeof(struct proc));
@@ -278,7 +305,6 @@
         return;
 
     pid_remove(pid);
-    kill_lasttime = 0;
 }
 
 static void cmd_target(int ntargets, int *params) {
@@ -574,7 +600,6 @@
           first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj,
           first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below");
     r = kill(pid, SIGKILL);
-    killProcessGroup(uid, pid, SIGKILL);
     pid_remove(pid);
 
     if (r) {
@@ -589,24 +614,12 @@
  * Find a process to kill based on the current (possibly estimated) free memory
  * and cached memory sizes.  Returns the size of the killed processes.
  */
-static int find_and_kill_process(int other_free, int other_file, bool first)
+static int find_and_kill_process(int other_free, int other_file, bool first, int min_score_adj)
 {
     int i;
-    int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
     int minfree = 0;
     int killed_size = 0;
 
-    for (i = 0; i < lowmem_targets_size; i++) {
-        minfree = lowmem_minfree[i];
-        if (other_free < minfree && other_file < minfree) {
-            min_score_adj = lowmem_adj[i];
-            break;
-        }
-    }
-
-    if (min_score_adj == OOM_SCORE_ADJ_MAX + 1)
-        return 0;
-
     for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
         struct proc *procp;
 
@@ -626,42 +639,33 @@
     return 0;
 }
 
-static void mp_event(uint32_t events __unused) {
+static void mp_event_common(bool is_critical) {
     int ret;
     unsigned long long evcount;
-    struct sysmeminfo mi;
-    int other_free;
-    int other_file;
-    int killed_size;
     bool first = true;
+    int min_adj_score = is_critical ? 0 : 800;
+    int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
 
-    ret = read(mpevfd, &evcount, sizeof(evcount));
+    ret = read(mpevfd[index], &evcount, sizeof(evcount));
     if (ret < 0)
         ALOGE("Error reading memory pressure event fd; errno=%d",
               errno);
 
-    if (time(NULL) - kill_lasttime < KILL_TIMEOUT)
-        return;
-
-    while (zoneinfo_parse(&mi) < 0) {
-        // Failed to read /proc/zoneinfo, assume ENOMEM and kill something
-        find_and_kill_process(0, 0, true);
+    if (find_and_kill_process(0, 0, first, min_adj_score) == 0) {
+        ALOGI("Nothing to kill");
     }
-
-    other_free = mi.nr_free_pages - mi.totalreserve_pages;
-    other_file = mi.nr_file_pages - mi.nr_shmem;
-
-    do {
-        killed_size = find_and_kill_process(other_free, other_file, first);
-        if (killed_size > 0) {
-            first = false;
-            other_free += killed_size;
-            other_file += killed_size;
-        }
-    } while (killed_size > 0);
 }
 
-static int init_mp(char *levelstr, void *event_handler)
+static void mp_event(uint32_t events __unused) {
+    mp_event_common(false);
+}
+
+static void mp_event_critical(uint32_t events __unused) {
+    ALOGI("Memory pressure critical");
+    mp_event_common(true);
+}
+
+static int init_mp_common(char *levelstr, void *event_handler, bool is_critical)
 {
     int mpfd;
     int evfd;
@@ -669,6 +673,7 @@
     char buf[256];
     struct epoll_event epev;
     int ret;
+    int mpevfd_index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
 
     mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
     if (mpfd < 0) {
@@ -709,7 +714,7 @@
         goto err;
     }
     maxevents++;
-    mpevfd = evfd;
+    mpevfd[mpevfd_index] = evfd;
     return 0;
 
 err:
@@ -722,6 +727,16 @@
     return -1;
 }
 
+static int init_mp_medium()
+{
+    return init_mp_common(MEMPRESSURE_WATCH_MEDIUM_LEVEL, (void *)&mp_event, false);
+}
+
+static int init_mp_critical()
+{
+    return init_mp_common(MEMPRESSURE_WATCH_CRITICAL_LEVEL, (void *)&mp_event_critical, true);
+}
+
 static int init(void) {
     struct epoll_event epev;
     int i;
@@ -763,7 +778,8 @@
     if (use_inkernel_interface) {
         ALOGI("Using in-kernel low memory killer interface");
     } else {
-        ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event);
+        ret = init_mp_medium();
+        ret |= init_mp_critical();
         if (ret)
             ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer");
     }
diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk
index 1915677..a0875ea 100644
--- a/logd/tests/Android.mk
+++ b/logd/tests/Android.mk
@@ -63,7 +63,7 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
 LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
 LOCAL_CTS_TEST_PACKAGE := android.core.logd
 include $(BUILD_CTS_EXECUTABLE)
 
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 2e5575f..046557e 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -194,7 +194,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := ld.config.txt
-ifeq ($(PRODUCT_FULL_TREBLE),true)
+ifeq ($(PRODUCT_FULL_TREBLE)|$(SANITIZE_TARGET),true|)
 LOCAL_SRC_FILES := etc/ld.config.txt
 else
 LOCAL_SRC_FILES := etc/ld.config.legacy.txt
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 859fcd2..7ba7bde 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -95,10 +95,10 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
-namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB}
+namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
 namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
 
-namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
 namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl
 
 # When these NDK libs are required inside this namespace, then it is redirected
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 424dbee..901d066 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -321,7 +321,6 @@
     # Make sure /sys/kernel/debug (if present) is labeled properly
     # Note that tracefs may be mounted under debug, so we need to cross filesystems
     restorecon --recursive --cross-filesystems /sys/kernel/debug
-    chmod 0755 /sys/kernel/debug/tracing
 
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
@@ -359,6 +358,10 @@
     mkdir /cache/lost+found 0770 root root
 
 on late-fs
+    # Ensure that tracefs has the correct permissions.
+    # This does not work correctly if it is called in post-fs.
+    chmod 0755 /sys/kernel/debug/tracing
+
     # HALs required before storage encryption can get unlocked (FBE/FDE)
     class_start early_hal
 
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 514798b..fa68406 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -256,6 +256,7 @@
     uid_monitor mUidm;
     time_t mStarttime;
     sp<IBatteryPropertiesRegistrar> battery_properties;
+    std::unique_ptr<storage_info_t> storage_info;
 public:
     storaged_t(void);
     ~storaged_t() {}
@@ -285,6 +286,8 @@
     void init_battery_service();
     virtual void batteryPropertiesChanged(struct BatteryProperties props);
     void binderDied(const wp<IBinder>& who);
+
+    void report_storage_info();
 };
 
 // Eventlog tag
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index 913c814..7d04c7a 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -27,39 +27,46 @@
 class storage_info_t {
 protected:
     FRIEND_TEST(storaged_test, storage_info_t);
+    // emmc lifetime
     uint16_t eol;                   // pre-eol (end of life) information
     uint16_t lifetime_a;            // device life time estimation (type A)
     uint16_t lifetime_b;            // device life time estimation (type B)
     string version;                 // version string
+    // free space
+    const string userdata_path = "/data";
+    uint64_t userdata_total_kb;
+    uint64_t userdata_free_kb;
+
+    storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0),
+        userdata_total_kb(0), userdata_free_kb(0) {}
     void publish();
+    storage_info_t* s_info;
 public:
-    storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {}
+    static storage_info_t* get_storage_info();
     virtual ~storage_info_t() {}
-    virtual bool report() = 0;
+    virtual void report() {};
+    void refresh();
 };
 
 class emmc_info_t : public storage_info_t {
 private:
-    const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
-    const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
-    const char* emmc_ver_str[9] = {
-        "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
-    };
-public:
-    virtual ~emmc_info_t() {}
-    bool report();
     bool report_sysfs();
     bool report_debugfs();
+public:
+    static const string emmc_sysfs;
+    static const string emmc_debugfs;
+    static const char* emmc_ver_str[];
+
+    virtual ~emmc_info_t() {}
+    virtual void report();
 };
 
 class ufs_info_t : public storage_info_t {
-private:
-    const string health_file = "/sys/devices/soc/624000.ufshc/health";
 public:
-    virtual ~ufs_info_t() {}
-    bool report();
-};
+    static const string health_file;
 
-void report_storage_health();
+    virtual ~ufs_info_t() {}
+    virtual void report();
+};
 
 #endif /* _STORAGED_INFO_H_ */
diff --git a/storaged/main.cpp b/storaged/main.cpp
index 4d1e430..6b82904 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -49,6 +49,7 @@
     storaged = new storaged_t();
 
     storaged->init_battery_service();
+    storaged->report_storage_info();
 
     LOG_TO(SYSTEM, INFO) << "storaged: Start";
 
@@ -113,7 +114,6 @@
     }
 
     if (flag_main_service) { // start main thread
-        report_storage_health();
         // Start the main thread of storaged
         pthread_t storaged_main_thread;
         errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL);
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 54d429c..06afea6 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -200,6 +200,10 @@
     }
 }
 
+void storaged_t::report_storage_info() {
+    storage_info->report();
+}
+
 /* storaged_t */
 storaged_t::storaged_t(void) {
     if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) {
@@ -222,6 +226,8 @@
     mConfig.periodic_chores_interval_uid_io =
         property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO);
 
+    storage_info.reset(storage_info_t::get_storage_info());
+
     mStarttime = time(NULL);
 }
 
@@ -229,6 +235,7 @@
     if (mConfig.diskstats_available) {
         mDiskStats.update();
         mDsm.update();
+        storage_info->refresh();
         if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) {
             mDiskStats.publish();
         }
diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp
index 434bd74..b5fb13e 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -18,6 +18,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <sys/statvfs.h>
 
 #include <android-base/file.h>
 #include <android-base/parseint.h>
@@ -30,13 +31,42 @@
 using namespace std;
 using namespace android::base;
 
-void report_storage_health()
-{
-    emmc_info_t mmc;
-    ufs_info_t ufs;
+const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
+const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
+const char* emmc_info_t::emmc_ver_str[9] = {
+    "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
+};
 
-    mmc.report();
-    ufs.report();
+const string ufs_info_t::health_file = "/sys/devices/soc/624000.ufshc/health";
+
+static bool FileExists(const std::string& filename)
+{
+  struct stat buffer;
+  return stat(filename.c_str(), &buffer) == 0;
+}
+
+storage_info_t* storage_info_t::get_storage_info()
+{
+    if (FileExists(emmc_info_t::emmc_sysfs) ||
+        FileExists(emmc_info_t::emmc_debugfs)) {
+        return new emmc_info_t;
+    }
+    if (FileExists(ufs_info_t::health_file)) {
+        return new ufs_info_t;
+    }
+    return new storage_info_t;
+}
+
+void storage_info_t::refresh()
+{
+    struct statvfs buf;
+    if (statvfs(userdata_path.c_str(), &buf) != 0) {
+        PLOG_TO(SYSTEM, WARNING) << "Failed to get userdata info";
+        return;
+    }
+
+    userdata_total_kb = buf.f_bsize * buf.f_blocks >> 10;
+    userdata_free_kb = buf.f_bfree * buf.f_blocks >> 10;
 }
 
 void storage_info_t::publish()
@@ -46,13 +76,12 @@
         << LOG_ID_EVENTS;
 }
 
-bool emmc_info_t::report()
+void emmc_info_t::report()
 {
     if (!report_sysfs() && !report_debugfs())
-        return false;
+        return;
 
     publish();
-    return true;
 }
 
 bool emmc_info_t::report_sysfs()
@@ -136,21 +165,21 @@
     return true;
 }
 
-bool ufs_info_t::report()
+void ufs_info_t::report()
 {
     string buffer;
     if (!ReadFileToString(health_file, &buffer)) {
-        return false;
+        return;
     }
 
     vector<string> lines = Split(buffer, "\n");
     if (lines.empty()) {
-        return false;
+        return;
     }
 
     char rev[8];
     if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) {
-        return false;
+        return;
     }
 
     version = "ufs " + string(rev);
@@ -175,10 +204,9 @@
     }
 
     if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) {
-        return false;
+        return;
     }
 
     publish();
-    return true;
 }