Merge "Support mouse pointer on external displays (1/2)"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 53b3a00..bd3d2d8 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -99,30 +99,31 @@
 
 /* Tracing categories */
 static const TracingCategory k_categories[] = {
-    { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, { } },
-    { "input",      "Input",            ATRACE_TAG_INPUT, { } },
-    { "view",       "View System",      ATRACE_TAG_VIEW, { } },
-    { "webview",    "WebView",          ATRACE_TAG_WEBVIEW, { } },
-    { "wm",         "Window Manager",   ATRACE_TAG_WINDOW_MANAGER, { } },
-    { "am",         "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } },
-    { "sm",         "Sync Manager",     ATRACE_TAG_SYNC_MANAGER, { } },
-    { "audio",      "Audio",            ATRACE_TAG_AUDIO, { } },
-    { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
-    { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
-    { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
-    { "res",        "Resource Loading", ATRACE_TAG_RESOURCES, { } },
-    { "dalvik",     "Dalvik VM",        ATRACE_TAG_DALVIK, { } },
-    { "rs",         "RenderScript",     ATRACE_TAG_RS, { } },
-    { "bionic",     "Bionic C Library", ATRACE_TAG_BIONIC, { } },
-    { "power",      "Power Management", ATRACE_TAG_POWER, { } },
-    { "pm",         "Package Manager",  ATRACE_TAG_PACKAGE_MANAGER, { } },
-    { "ss",         "System Server",    ATRACE_TAG_SYSTEM_SERVER, { } },
-    { "database",   "Database",         ATRACE_TAG_DATABASE, { } },
-    { "network",    "Network",          ATRACE_TAG_NETWORK, { } },
-    { "adb",        "ADB",              ATRACE_TAG_ADB, { } },
-    { "vibrator",   "Vibrator",         ATRACE_TAG_VIBRATOR, { } },
-    { "aidl",       "AIDL calls",       ATRACE_TAG_AIDL, { } },
-    { "nnapi",      "NNAPI",            ATRACE_TAG_NNAPI, { } },
+    { "gfx",        "Graphics",                 ATRACE_TAG_GRAPHICS, { } },
+    { "input",      "Input",                    ATRACE_TAG_INPUT, { } },
+    { "view",       "View System",              ATRACE_TAG_VIEW, { } },
+    { "webview",    "WebView",                  ATRACE_TAG_WEBVIEW, { } },
+    { "wm",         "Window Manager",           ATRACE_TAG_WINDOW_MANAGER, { } },
+    { "am",         "Activity Manager",         ATRACE_TAG_ACTIVITY_MANAGER, { } },
+    { "sm",         "Sync Manager",             ATRACE_TAG_SYNC_MANAGER, { } },
+    { "audio",      "Audio",                    ATRACE_TAG_AUDIO, { } },
+    { "video",      "Video",                    ATRACE_TAG_VIDEO, { } },
+    { "camera",     "Camera",                   ATRACE_TAG_CAMERA, { } },
+    { "hal",        "Hardware Modules",         ATRACE_TAG_HAL, { } },
+    { "res",        "Resource Loading",         ATRACE_TAG_RESOURCES, { } },
+    { "dalvik",     "Dalvik VM",                ATRACE_TAG_DALVIK, { } },
+    { "rs",         "RenderScript",             ATRACE_TAG_RS, { } },
+    { "bionic",     "Bionic C Library",         ATRACE_TAG_BIONIC, { } },
+    { "power",      "Power Management",         ATRACE_TAG_POWER, { } },
+    { "pm",         "Package Manager",          ATRACE_TAG_PACKAGE_MANAGER, { } },
+    { "ss",         "System Server",            ATRACE_TAG_SYSTEM_SERVER, { } },
+    { "database",   "Database",                 ATRACE_TAG_DATABASE, { } },
+    { "network",    "Network",                  ATRACE_TAG_NETWORK, { } },
+    { "adb",        "ADB",                      ATRACE_TAG_ADB, { } },
+    { "vibrator",   "Vibrator",                 ATRACE_TAG_VIBRATOR, { } },
+    { "aidl",       "AIDL calls",               ATRACE_TAG_AIDL, { } },
+    { "nnapi",      "NNAPI",                    ATRACE_TAG_NNAPI, { } },
+    { "rro",        "Runtime Resource Overlay", ATRACE_TAG_RRO, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
     { k_pdxServiceCategory, "PDX services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
diff --git a/cmds/cmd/Android.bp b/cmds/cmd/Android.bp
index d91184a..8ea71cd 100644
--- a/cmds/cmd/Android.bp
+++ b/cmds/cmd/Android.bp
@@ -1,7 +1,31 @@
+cc_library_static {
+    name: "libcmd",
+
+    srcs: ["cmd.cpp"],
+    export_include_dirs: ["."],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+        "libselinux",
+        "libbinder",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-DXP_UNIX",
+    ],
+}
+
 cc_binary {
     name: "cmd",
 
-    srcs: ["cmd.cpp"],
+    srcs: ["main.cpp"],
+
+    static_libs: [
+        "libcmd",
+    ],
 
     shared_libs: [
         "libutils",
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 0616add..7b4aeb2 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -40,6 +40,8 @@
 #include "selinux/selinux.h"
 #include "selinux/android.h"
 
+#include "cmd.h"
+
 #define DEBUG 0
 
 using namespace android;
@@ -59,8 +61,11 @@
 class MyShellCallback : public BnShellCallback
 {
 public:
+    TextOutput& mErrorLog;
     bool mActive = true;
 
+    MyShellCallback(TextOutput& errorLog) : mErrorLog(errorLog) {}
+
     virtual int openFile(const String16& path, const String16& seLinuxContext,
             const String16& mode) {
         String8 path8(path);
@@ -69,7 +74,7 @@
         String8 fullPath(cwd);
         fullPath.appendPath(path8);
         if (!mActive) {
-            aerr << "Open attempt after active for: " << fullPath << endl;
+            mErrorLog << "Open attempt after active for: " << fullPath << endl;
             return -EPERM;
         }
 #if DEBUG
@@ -78,20 +83,20 @@
         int flags = 0;
         bool checkRead = false;
         bool checkWrite = false;
-        if (mode == String16("w")) {
+        if (mode == u"w") {
             flags = O_WRONLY|O_CREAT|O_TRUNC;
             checkWrite = true;
-        } else if (mode == String16("w+")) {
+        } else if (mode == u"w+") {
             flags = O_RDWR|O_CREAT|O_TRUNC;
             checkRead = checkWrite = true;
-        } else if (mode == String16("r")) {
+        } else if (mode == u"r") {
             flags = O_RDONLY;
             checkRead = true;
-        } else if (mode == String16("r+")) {
+        } else if (mode == u"r+") {
             flags = O_RDWR;
             checkRead = checkWrite = true;
         } else {
-            aerr << "Invalid mode requested: " << mode.string() << endl;
+            mErrorLog << "Invalid mode requested: " << mode.string() << endl;
             return -EINVAL;
         }
         int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG);
@@ -114,9 +119,7 @@
                     ALOGD("openFile: failed selinux write check!");
 #endif
                     close(fd);
-                    aerr << "System server has no access to write file context " << context.get()
-                            << " (from path " << fullPath.string() << ", context "
-                            << seLinuxContext8.string() << ")" << endl;
+                    mErrorLog << "System server has no access to write file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
                     return -EPERM;
                 }
             }
@@ -128,9 +131,7 @@
                     ALOGD("openFile: failed selinux read check!");
 #endif
                     close(fd);
-                    aerr << "System server has no access to read file context " << context.get()
-                            << " (from path " << fullPath.string() << ", context "
-                            << seLinuxContext8.string() << ")" << endl;
+                    mErrorLog << "System server has no access to read file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
                     return -EPERM;
                 }
             }
@@ -163,9 +164,8 @@
     }
 };
 
-int main(int argc, char* const argv[])
-{
-    signal(SIGPIPE, SIG_IGN);
+int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,
+            int in, int out, int err, RunMode runMode) {
     sp<ProcessState> proc = ProcessState::self();
     proc->startThreadPool();
 
@@ -173,68 +173,77 @@
     ALOGD("cmd: starting");
 #endif
     sp<IServiceManager> sm = defaultServiceManager();
-    fflush(stdout);
+    if (runMode == RunMode::kStandalone) {
+        fflush(stdout);
+    }
     if (sm == nullptr) {
         ALOGW("Unable to get default service manager!");
-        aerr << "cmd: Unable to get default service manager!" << endl;
+        errorLog << "cmd: Unable to get default service manager!" << endl;
         return 20;
     }
 
-    if (argc == 1) {
-        aerr << "cmd: No service specified; use -l to list all services" << endl;
+    int argc = argv.size();
+
+    if (argc == 0) {
+        errorLog << "cmd: No service specified; use -l to list all services" << endl;
         return 20;
     }
 
-    if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
+    if ((argc == 1) && (argv[0] == "-l")) {
         Vector<String16> services = sm->listServices();
         services.sort(sort_func);
-        aout << "Currently running services:" << endl;
+        outputLog << "Currently running services:" << endl;
 
         for (size_t i=0; i<services.size(); i++) {
             sp<IBinder> service = sm->checkService(services[i]);
             if (service != nullptr) {
-                aout << "  " << services[i] << endl;
+                outputLog << "  " << services[i] << endl;
             }
         }
         return 0;
     }
 
+    const auto cmd = argv[0];
+
     Vector<String16> args;
-    for (int i=2; i<argc; i++) {
-        args.add(String16(argv[i]));
+    String16 serviceName = String16(cmd.data(), cmd.size());
+    for (int i = 1; i < argc; i++) {
+        args.add(String16(argv[i].data(), argv[i].size()));
     }
-    String16 cmd = String16(argv[1]);
-    sp<IBinder> service = sm->checkService(cmd);
+    sp<IBinder> service = sm->checkService(serviceName);
     if (service == nullptr) {
-        ALOGW("Can't find service %s", argv[1]);
-        aerr << "cmd: Can't find service: " << argv[1] << endl;
+        if (runMode == RunMode::kStandalone) {
+            ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());
+        }
+        errorLog << "cmd: Can't find service: " << cmd << endl;
         return 20;
     }
 
-    sp<MyShellCallback> cb = new MyShellCallback();
+    sp<MyShellCallback> cb = new MyShellCallback(errorLog);
     sp<MyResultReceiver> result = new MyResultReceiver();
 
 #if DEBUG
-    ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", argv[1], STDIN_FILENO, STDOUT_FILENO,
-            STDERR_FILENO);
+    ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", cmd, in, out, err);
 #endif
 
     // TODO: block until a result is returned to MyResultReceiver.
-    status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args,
-            cb, result);
-    if (err < 0) {
+    status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);
+    if (error < 0) {
         const char* errstr;
-        switch (err) {
+        switch (error) {
             case BAD_TYPE: errstr = "Bad type"; break;
             case FAILED_TRANSACTION: errstr = "Failed transaction"; break;
             case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break;
             case UNEXPECTED_NULL: errstr = "Unexpected null"; break;
-            default: errstr = strerror(-err); break;
+            default: errstr = strerror(-error); break;
         }
-        ALOGW("Failure calling service %s: %s (%d)", argv[1], errstr, -err);
-        aout << "cmd: Failure calling service " << argv[1] << ": " << errstr << " ("
-                << (-err) << ")" << endl;
-        return err;
+        if (runMode == RunMode::kStandalone) {
+            ALOGW("Failure calling service %.*s: %s (%d)", static_cast<int>(cmd.size()), cmd.data(),
+                  errstr, -error);
+        }
+        outputLog << "cmd: Failure calling service " << cmd << ": " << errstr << " (" << (-error)
+                  << ")" << endl;
+        return error;
     }
 
     cb->mActive = false;
diff --git a/cmds/cmd/cmd.h b/cmds/cmd/cmd.h
new file mode 100644
index 0000000..a91e009
--- /dev/null
+++ b/cmds/cmd/cmd.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <binder/TextOutput.h>
+
+#include <string_view>
+#include <vector>
+
+enum class RunMode {
+    kStandalone,
+    kLibrary,
+};
+
+int cmdMain(const std::vector<std::string_view>& argv, android::TextOutput& outputLog,
+            android::TextOutput& errorLog, int in, int out, int err, RunMode runMode);
diff --git a/cmds/cmd/main.cpp b/cmds/cmd/main.cpp
new file mode 100644
index 0000000..2256e2a
--- /dev/null
+++ b/cmds/cmd/main.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+
+#include "cmd.h"
+
+int main(int argc, char* const argv[]) {
+    signal(SIGPIPE, SIG_IGN);
+
+    std::vector<std::string_view> arguments;
+    arguments.reserve(argc - 1);
+    // 0th argument is a program name, skipping.
+    for (int i = 1; i < argc; ++i) {
+        arguments.emplace_back(argv[i]);
+    }
+
+    return cmdMain(arguments, android::aout, android::aerr, STDIN_FILENO, STDOUT_FILENO,
+                   STDERR_FILENO, RunMode::kStandalone);
+}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 516e3d8..8a05c43 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1572,6 +1572,15 @@
     RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
                SEC_TO_MSEC(10));
 
+    if (ds.IsZipping()) {
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z"},
+                   CommandOptions::WithTimeout(2).AsRootIfAvailable().Build());
+        DumpHals();
+    } else {
+        RunCommand("HARDWARE HALS", {"lshal", "-lVSietrpc", "--types=b,c,l,z", "--debug"},
+                   CommandOptions::WithTimeout(10).AsRootIfAvailable().Build());
+    }
+
     printf("========================================================\n");
     printf("== dumpstate: done (id %d)\n", ds.id_);
     printf("========================================================\n");
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index d97ffbf..990fd43 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -871,7 +871,11 @@
             is_java_process ? 5 : 20, fd);
 
         if (ret == -1) {
-            dprintf(fd, "dumping failed, likely due to a timeout\n");
+            // For consistency, the header and footer to this message match those
+            // dumped by debuggerd in the success case.
+            dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
+            dprintf(fd, "Dump failed, likely due to a timeout.\n");
+            dprintf(fd, "---- end %d ----", pid);
             timeout_failures++;
             continue;
         }
diff --git a/cmds/servicemanager/binder.c b/cmds/servicemanager/binder.c
index fade8cf..a2b4da2 100644
--- a/cmds/servicemanager/binder.c
+++ b/cmds/servicemanager/binder.c
@@ -146,7 +146,21 @@
 
 int binder_become_context_manager(struct binder_state *bs)
 {
-    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
+    struct flat_binder_object obj;
+    memset(&obj, 0, sizeof(obj));
+    obj.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
+
+    int result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR_EXT, &obj);
+
+    // fallback to original method
+    if (result != 0) {
+#ifndef VENDORSERVICEMANAGER
+        android_errorWriteLog(0x534e4554, "121035042");
+#endif
+
+        result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
+    }
+    return result;
 }
 
 int binder_write(struct binder_state *bs, void *data, size_t len)
@@ -240,13 +254,28 @@
 #endif
             ptr += sizeof(struct binder_ptr_cookie);
             break;
+        case BR_TRANSACTION_SEC_CTX:
         case BR_TRANSACTION: {
-            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
-            if ((end - ptr) < sizeof(*txn)) {
-                ALOGE("parse: txn too small!\n");
-                return -1;
+            struct binder_transaction_data_secctx txn;
+            if (cmd == BR_TRANSACTION_SEC_CTX) {
+                if ((end - ptr) < sizeof(struct binder_transaction_data_secctx)) {
+                    ALOGE("parse: txn too small (binder_transaction_data_secctx)!\n");
+                    return -1;
+                }
+                memcpy(&txn, (void*) ptr, sizeof(struct binder_transaction_data_secctx));
+                ptr += sizeof(struct binder_transaction_data_secctx);
+            } else /* BR_TRANSACTION */ {
+                if ((end - ptr) < sizeof(struct binder_transaction_data)) {
+                    ALOGE("parse: txn too small (binder_transaction_data)!\n");
+                    return -1;
+                }
+                memcpy(&txn.transaction_data, (void*) ptr, sizeof(struct binder_transaction_data));
+                ptr += sizeof(struct binder_transaction_data);
+
+                txn.secctx = 0;
             }
-            binder_dump_txn(txn);
+
+            binder_dump_txn(&txn.transaction_data);
             if (func) {
                 unsigned rdata[256/4];
                 struct binder_io msg;
@@ -254,15 +283,14 @@
                 int res;
 
                 bio_init(&reply, rdata, sizeof(rdata), 4);
-                bio_init_from_txn(&msg, txn);
-                res = func(bs, txn, &msg, &reply);
-                if (txn->flags & TF_ONE_WAY) {
-                    binder_free_buffer(bs, txn->data.ptr.buffer);
+                bio_init_from_txn(&msg, &txn.transaction_data);
+                res = func(bs, &txn, &msg, &reply);
+                if (txn.transaction_data.flags & TF_ONE_WAY) {
+                    binder_free_buffer(bs, txn.transaction_data.data.ptr.buffer);
                 } else {
-                    binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
+                    binder_send_reply(bs, &reply, txn.transaction_data.data.ptr.buffer, res);
                 }
             }
-            ptr += sizeof(*txn);
             break;
         }
         case BR_REPLY: {
diff --git a/cmds/servicemanager/binder.h b/cmds/servicemanager/binder.h
index c95b33f..70be3b4 100644
--- a/cmds/servicemanager/binder.h
+++ b/cmds/servicemanager/binder.h
@@ -5,7 +5,8 @@
 #define _BINDER_H_
 
 #include <sys/ioctl.h>
-#include <linux/android/binder.h>
+
+#include "binder_kernel.h"
 
 struct binder_state;
 
@@ -42,7 +43,7 @@
 };
 
 typedef int (*binder_handler)(struct binder_state *bs,
-                              struct binder_transaction_data *txn,
+                              struct binder_transaction_data_secctx *txn,
                               struct binder_io *msg,
                               struct binder_io *reply);
 
diff --git a/cmds/servicemanager/binder_kernel.h b/cmds/servicemanager/binder_kernel.h
new file mode 100644
index 0000000..19fd773
--- /dev/null
+++ b/cmds/servicemanager/binder_kernel.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_BINDER_KERNEL_H
+#define ANDROID_BINDER_KERNEL_H
+
+#include <linux/android/binder.h>
+
+/**
+ * This file exists because the uapi kernel headers in bionic are built
+ * from upstream kernel headers only, and not all of the hwbinder kernel changes
+ * have made it upstream yet. Therefore, the modifications to the
+ * binder header are added locally in this file.
+ */
+
+enum {
+        FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
+};
+
+#define BINDER_SET_CONTEXT_MGR_EXT      _IOW('b', 13, struct flat_binder_object)
+
+struct binder_transaction_data_secctx {
+        struct binder_transaction_data transaction_data;
+        binder_uintptr_t secctx;
+};
+
+enum {
+        BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
+                              struct binder_transaction_data_secctx),
+};
+
+
+#endif // ANDROID_BINDER_KERNEL_H
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 79cd6b5..ca004e9 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -61,14 +61,14 @@
 static char *service_manager_context;
 static struct selabel_handle* sehandle;
 
-static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name)
+static bool check_mac_perms(pid_t spid, const char* sid, uid_t uid, const char *tctx, const char *perm, const char *name)
 {
-    char *sctx = NULL;
+    char *lookup_sid = NULL;
     const char *class = "service_manager";
     bool allowed;
     struct audit_data ad;
 
-    if (getpidcon(spid, &sctx) < 0) {
+    if (sid == NULL && getpidcon(spid, &lookup_sid) < 0) {
         ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid);
         return false;
     }
@@ -77,19 +77,25 @@
     ad.uid = uid;
     ad.name = name;
 
-    int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad);
+#ifndef VENDORSERVICEMANAGER
+    if (sid == NULL) {
+        android_errorWriteLog(0x534e4554, "121035042");
+    }
+#endif
+
+    int result = selinux_check_access(sid ? sid : lookup_sid, tctx, class, perm, (void *) &ad);
     allowed = (result == 0);
 
-    freecon(sctx);
+    freecon(lookup_sid);
     return allowed;
 }
 
-static bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm)
+static bool check_mac_perms_from_getcon(pid_t spid, const char* sid, uid_t uid, const char *perm)
 {
-    return check_mac_perms(spid, uid, service_manager_context, perm, NULL);
+    return check_mac_perms(spid, sid, uid, service_manager_context, perm, NULL);
 }
 
-static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name)
+static bool check_mac_perms_from_lookup(pid_t spid, const char* sid, uid_t uid, const char *perm, const char *name)
 {
     bool allowed;
     char *tctx = NULL;
@@ -104,12 +110,12 @@
         return false;
     }
 
-    allowed = check_mac_perms(spid, uid, tctx, perm, name);
+    allowed = check_mac_perms(spid, sid, uid, tctx, perm, name);
     freecon(tctx);
     return allowed;
 }
 
-static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "add";
 
@@ -117,19 +123,19 @@
         return 0; /* Don't allow apps to register services */
     }
 
-    return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+    return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
 }
 
-static int svc_can_list(pid_t spid, uid_t uid)
+static int svc_can_list(pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "list";
-    return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0;
+    return check_mac_perms_from_getcon(spid, sid, uid, perm) ? 1 : 0;
 }
 
-static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "find";
-    return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+    return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
 }
 
 struct svcinfo
@@ -175,7 +181,7 @@
 };
 
 
-uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
+uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid)
 {
     struct svcinfo *si = find_svc(s, len);
 
@@ -192,7 +198,7 @@
         }
     }
 
-    if (!svc_can_find(s, len, spid, uid)) {
+    if (!svc_can_find(s, len, spid, sid, uid)) {
         return 0;
     }
 
@@ -200,7 +206,7 @@
 }
 
 int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
-                   uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
+                   uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid, const char* sid) {
     struct svcinfo *si;
 
     //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
@@ -209,7 +215,7 @@
     if (!handle || (len == 0) || (len > 127))
         return -1;
 
-    if (!svc_can_register(s, len, spid, uid)) {
+    if (!svc_can_register(s, len, spid, sid, uid)) {
         ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
              str8(s, len), handle, uid);
         return -1;
@@ -248,7 +254,7 @@
 }
 
 int svcmgr_handler(struct binder_state *bs,
-                   struct binder_transaction_data *txn,
+                   struct binder_transaction_data_secctx *txn_secctx,
                    struct binder_io *msg,
                    struct binder_io *reply)
 {
@@ -260,6 +266,8 @@
     int allow_isolated;
     uint32_t dumpsys_priority;
 
+    struct binder_transaction_data *txn = &txn_secctx->transaction_data;
+
     //ALOGI("target=%p code=%d pid=%d uid=%d\n",
     //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
 
@@ -305,7 +313,8 @@
         if (s == NULL) {
             return -1;
         }
-        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
+        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid,
+                                 (const char*) txn_secctx->secctx);
         if (!handle)
             break;
         bio_put_ref(reply, handle);
@@ -320,7 +329,7 @@
         allow_isolated = bio_get_uint32(msg) ? 1 : 0;
         dumpsys_priority = bio_get_uint32(msg);
         if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
-                           txn->sender_pid))
+                           txn->sender_pid, (const char*) txn_secctx->secctx))
             return -1;
         break;
 
@@ -328,7 +337,7 @@
         uint32_t n = bio_get_uint32(msg);
         uint32_t req_dumpsys_priority = bio_get_uint32(msg);
 
-        if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
+        if (!svc_can_list(txn->sender_pid, (const char*) txn_secctx->secctx, txn->sender_euid)) {
             ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                     txn->sender_euid);
             return -1;
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index 384f21f..34886a9 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -286,10 +286,6 @@
             std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event)
                     .detach();
         } break;
-        case increment.kSurfaceDeletion: {
-            std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), event)
-                    .detach();
-        } break;
         case increment.kBufferUpdate: {
             std::lock_guard<std::mutex> lock1(mLayerLock);
             std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock);
@@ -628,47 +624,10 @@
     return NO_ERROR;
 }
 
-status_t Replayer::deleteSurfaceControl(
-        const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) {
-    ALOGV("Deleting %d Surface Control", delete_.id());
-    event->readyToExecute();
-
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-
-    mLayersPendingRemoval.push_back(delete_.id());
-
-    const auto& iterator = mBufferQueueSchedulers.find(delete_.id());
-    if (iterator != mBufferQueueSchedulers.end()) {
-        (*iterator).second->stopScheduling();
-    }
-
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (mLayers[delete_.id()] != nullptr) {
-        mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle());
-    }
-
-    return NO_ERROR;
-}
-
-void Replayer::doDeleteSurfaceControls() {
-    std::lock_guard<std::mutex> lock1(mPendingLayersLock);
-    std::lock_guard<std::mutex> lock2(mLayerLock);
-    if (!mLayersPendingRemoval.empty()) {
-        for (int id : mLayersPendingRemoval) {
-            mLayers.erase(id);
-            mColors.erase(id);
-            mBufferQueueSchedulers.erase(id);
-        }
-        mLayersPendingRemoval.clear();
-    }
-}
-
 status_t Replayer::injectVSyncEvent(
         const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) {
     ALOGV("Injecting VSync Event");
 
-    doDeleteSurfaceControls();
-
     event->readyToExecute();
 
     SurfaceComposerClient::injectVSync(vSyncEvent.when());
diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h
index 120dd9b..ad807ee 100644
--- a/cmds/surfacereplayer/replayer/Replayer.h
+++ b/cmds/surfacereplayer/replayer/Replayer.h
@@ -70,8 +70,6 @@
     status_t doTransaction(const Transaction& transaction, const std::shared_ptr<Event>& event);
     status_t createSurfaceControl(const SurfaceCreation& create,
             const std::shared_ptr<Event>& event);
-    status_t deleteSurfaceControl(const SurfaceDeletion& delete_,
-            const std::shared_ptr<Event>& event);
     status_t injectVSyncEvent(const VSyncEvent& vsyncEvent, const std::shared_ptr<Event>& event);
     void createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event);
     void deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event);
@@ -120,7 +118,6 @@
     void setDisplayProjection(SurfaceComposerClient::Transaction& t,
             display_id id, const ProjectionChange& pc);
 
-    void doDeleteSurfaceControls();
     void waitUntilTimestamp(int64_t timestamp);
     void waitUntilDeferredTransactionLayerExists(
             const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock);
diff --git a/include/OWNERS b/include/OWNERS
new file mode 100644
index 0000000..22be776
--- /dev/null
+++ b/include/OWNERS
@@ -0,0 +1,14 @@
+alexeykuzmin@google.com
+dangittik@google.com
+lajos@google.com
+mathias@google.com
+michaelwr@google.com
+racarr@google.com
+romainguy@android.com
+santoscordon@google.com
+stoza@google.com
+svv@google.com
+
+# For multinetwork.h only.
+lorenzo@google.com
+
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index fa7d908..05d96ff 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -112,26 +112,43 @@
 
 #if __ANDROID_API__ >= 29
 
+enum ResNsendFlags : uint32_t {
+    // Send a single request to a single resolver and fail on timeout or network errors
+    ANDROID_RESOLV_NO_RETRY = 1 << 0,
+
+    // Do not cache the result of the lookup. The lookup may return a result that is already
+    // in the cache, unless the ANDROID_RESOLV_NO_CACHE_LOOKUP flag is also specified.
+    ANDROID_RESOLV_NO_CACHE_STORE = 1 << 1,
+
+    // Don't lookup the request in cache, do not write back the response into the cache
+    ANDROID_RESOLV_NO_CACHE_LOOKUP = 1 << 2,
+};
+
 /**
  * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated
  * with Domain Name |dname| on the given |network|.
  * The typical value for |ns_class| is ns_c_in, while |type| can be any
  * record type (for instance, ns_t_aaaa or ns_t_txt).
+ * |flags| is a additional config to control actual querying behavior, see
+ * ResNsendFlags for detail.
  *
  * Returns a file descriptor to watch for read events, or a negative
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nquery(net_handle_t network,
-        const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29);
+        const char *dname, int ns_class, int ns_type,
+        enum ResNsendFlags flags) __INTRODUCED_IN(29);
 
 /**
  * Issue the query |msg| on the given |network|.
+ * |flags| is a additional config to control actual querying behavior, see
+ * ResNsendFlags for detail.
  *
  * Returns a file descriptor to watch for read events, or a negative
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nsend(net_handle_t network,
-        const uint8_t *msg, size_t msglen) __INTRODUCED_IN(29);
+        const uint8_t *msg, size_t msglen, enum ResNsendFlags flags) __INTRODUCED_IN(29);
 
 /**
  * Read a result for the query associated with the |fd| descriptor.
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index 610834d..ff443c6 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -36,7 +36,7 @@
     DECLARE_META_INTERFACE(InputFlinger)
 
     virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles) = 0;
-
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
     virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
     virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;
 };
@@ -50,7 +50,8 @@
     enum {
         SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
         REGISTER_INPUT_CHANNEL_TRANSACTION,
-        UNREGISTER_INPUT_CHANNEL_TRANSACTION
+        UNREGISTER_INPUT_CHANNEL_TRANSACTION,
+        TRANSFER_TOUCH_FOCUS
     };
 
     virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/FrameTimestamps.cpp b/libs/gui/FrameTimestamps.cpp
index 96e9a85..c04d907 100644
--- a/libs/gui/FrameTimestamps.cpp
+++ b/libs/gui/FrameTimestamps.cpp
@@ -158,7 +158,7 @@
 namespace {
 
 struct FrameNumberEqual {
-    FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
+    explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
     bool operator()(const FrameEvents& frame) {
         return frame.valid && mFrameNumber == frame.frameNumber;
     }
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 68a6b1f..d997674 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -536,7 +536,7 @@
 class HpGraphicBufferProducer : public HpInterface<
         BpGraphicBufferProducer, H2BGraphicBufferProducer> {
 public:
-    HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {}
+    explicit HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {}
 
     status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override {
         return mBase->requestBuffer(slot, buf);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 799151a..a481e81 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -63,19 +63,10 @@
         return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
-    virtual sp<ISurfaceComposerClient> createScopedConnection(
-            const sp<IGraphicBufferProducer>& parent)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(parent));
-        remote()->transact(BnSurfaceComposer::CREATE_SCOPED_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
-    }
-
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken) {
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& commands) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
 
@@ -91,6 +82,7 @@
 
         data.writeUint32(flags);
         data.writeStrongBinder(applyToken);
+        commands.write(data);
         remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
     }
 
@@ -709,14 +701,6 @@
             reply->writeStrongBinder(b);
             return NO_ERROR;
         }
-        case CREATE_SCOPED_CONNECTION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IGraphicBufferProducer> bufferProducer =
-                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
-            sp<IBinder> b = IInterface::asBinder(createScopedConnection(bufferProducer));
-            reply->writeStrongBinder(b);
-            return NO_ERROR;
-        }
         case SET_TRANSACTION_STATE: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
 
@@ -750,7 +734,9 @@
 
             uint32_t stateFlags = data.readUint32();
             sp<IBinder> applyToken = data.readStrongBinder();
-            setTransactionState(state, displays, stateFlags, applyToken);
+            InputWindowCommands inputWindowCommands;
+            inputWindowCommands.read(data);
+            setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands);
             return NO_ERROR;
         }
         case BOOT_FINISHED: {
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index a6890ee..369f523 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -31,7 +31,6 @@
 
 enum class Tag : uint32_t {
     CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
-    DESTROY_SURFACE,
     CLEAR_LAYER_FRAME_STATS,
     GET_LAYER_FRAME_STATS,
     LAST = GET_LAYER_FRAME_STATS,
@@ -57,11 +56,6 @@
                                                                             handle, gbp);
     }
 
-    status_t destroySurface(const sp<IBinder>& handle) override {
-        return callRemote<decltype(&ISurfaceComposerClient::destroySurface)>(Tag::DESTROY_SURFACE,
-                                                                             handle);
-    }
-
     status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
         return callRemote<decltype(
                 &ISurfaceComposerClient::clearLayerFrameStats)>(Tag::CLEAR_LAYER_FRAME_STATS,
@@ -92,8 +86,6 @@
     switch (tag) {
         case Tag::CREATE_SURFACE:
             return callLocal(data, reply, &ISurfaceComposerClient::createSurface);
-        case Tag::DESTROY_SURFACE:
-            return callLocal(data, reply, &ISurfaceComposerClient::destroySurface);
         case Tag::CLEAR_LAYER_FRAME_STATS:
             return callLocal(data, reply, &ISurfaceComposerClient::clearLayerFrameStats);
         case Tag::GET_LAYER_FRAME_STATS:
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 35ce6e3..e5170ab 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -379,4 +379,36 @@
     }
 }
 
+// ------------------------------- InputWindowCommands ----------------------------------------
+
+void InputWindowCommands::merge(const InputWindowCommands& other) {
+    transferTouchFocusCommands
+            .insert(transferTouchFocusCommands.end(),
+                    std::make_move_iterator(other.transferTouchFocusCommands.begin()),
+                    std::make_move_iterator(other.transferTouchFocusCommands.end()));
+}
+
+void InputWindowCommands::clear() {
+    transferTouchFocusCommands.clear();
+}
+
+void InputWindowCommands::write(Parcel& output) const {
+    output.writeUint32(static_cast<uint32_t>(transferTouchFocusCommands.size()));
+    for (const auto& transferTouchFocusCommand : transferTouchFocusCommands) {
+        output.writeStrongBinder(transferTouchFocusCommand.fromToken);
+        output.writeStrongBinder(transferTouchFocusCommand.toToken);
+    }
+}
+
+void InputWindowCommands::read(const Parcel& input) {
+    size_t count = input.readUint32();
+    transferTouchFocusCommands.clear();
+    for (size_t i = 0; i < count; i++) {
+        TransferTouchFocusCommand transferTouchFocusCommand;
+        transferTouchFocusCommand.fromToken = input.readStrongBinder();
+        transferTouchFocusCommand.toToken = input.readStrongBinder();
+        transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+    }
+}
+
 }; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5b004e2..6c39d6f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -166,6 +166,7 @@
     mEarlyWakeup(other.mEarlyWakeup) {
     mDisplayStates = other.mDisplayStates;
     mComposerStates = other.mComposerStates;
+    mInputWindowCommands = other.mInputWindowCommands;
 }
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
@@ -199,9 +200,27 @@
     }
     other.mListenerCallbacks.clear();
 
+    mInputWindowCommands.merge(other.mInputWindowCommands);
+
     return *this;
 }
 
+void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle,
+        const sp<ISurfaceComposerClient>& client) {
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    Vector<ComposerState> composerStates;
+    Vector<DisplayState> displayStates;
+
+    ComposerState s;
+    s.client = client;
+    s.state.surface = handle;
+    s.state.what |= layer_state_t::eReparent;
+    s.state.parentHandleForChild = nullptr;
+
+    composerStates.add(s);
+    sf->setTransactionState(composerStates, displayStates, 0, nullptr, {});
+}
+
 status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
     if (mStatus != NO_ERROR) {
         return mStatus;
@@ -265,8 +284,8 @@
     mEarlyWakeup = false;
 
     sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
-
-    sf->setTransactionState(composerStates, displayStates, flags, applyToken);
+    sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands);
+    mInputWindowCommands.clear();
     mStatus = NO_ERROR;
     return NO_ERROR;
 }
@@ -804,19 +823,18 @@
     s->what |= layer_state_t::eInputInfoChanged;
     return *this;
 }
-#endif
 
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
-        const sp<SurfaceControl>& sc) {
-    layer_state_t* s = getLayerState(sc);
-    if (!s) {
-        mStatus = BAD_INDEX;
-        return *this;
-    }
-    s->what |= layer_state_t::eDestroySurface;
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::transferTouchFocus(
+        const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    InputWindowCommands::TransferTouchFocusCommand transferTouchFocusCommand;
+    transferTouchFocusCommand.fromToken = fromToken;
+    transferTouchFocusCommand.toToken = toToken;
+    mInputWindowCommands.transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
     return *this;
 }
 
+#endif
+
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform(
     const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) {
     layer_state_t* s = getLayerState(sc);
@@ -897,11 +915,6 @@
 {
 }
 
-SurfaceComposerClient::SurfaceComposerClient(const sp<IGraphicBufferProducer>& root)
-    : mStatus(NO_INIT), mParent(root)
-{
-}
-
 SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
     : mStatus(NO_ERROR), mClient(client)
 {
@@ -910,10 +923,8 @@
 void SurfaceComposerClient::onFirstRef() {
     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
     if (sf != nullptr && mStatus == NO_INIT) {
-        auto rootProducer = mParent.promote();
         sp<ISurfaceComposerClient> conn;
-        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
-                sf->createConnection();
+        conn = sf->createConnection();
         if (conn != nullptr) {
             mClient = conn;
             mStatus = NO_ERROR;
@@ -998,13 +1009,6 @@
     return err;
 }
 
-status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) {
-    if (mStatus != NO_ERROR)
-        return mStatus;
-    status_t err = mClient->destroySurface(sid);
-    return err;
-}
-
 status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const {
     if (mStatus != NO_ERROR) {
         return mStatus;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 3a6dfda..8e500a4 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -54,9 +54,22 @@
 {
 }
 
+SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
+    mClient = other->mClient;
+    mHandle = other->mHandle;
+    mGraphicBufferProducer = other->mGraphicBufferProducer;
+    mOwned = false;
+}
+
 SurfaceControl::~SurfaceControl()
 {
-    destroy();
+    if (mClient != nullptr && mHandle != nullptr && mOwned) {
+        SurfaceComposerClient::doDropReferenceTransaction(mHandle, mClient->getClient());
+    }
+    mClient.clear();
+    mHandle.clear();
+    mGraphicBufferProducer.clear();
+    IPCThreadState::self()->flushCommands();
 }
 
 void SurfaceControl::destroy()
@@ -64,7 +77,7 @@
     // Avoid destroying the server-side surface if we are not the owner of it, meaning that we
     // retrieved it from another process.
     if (isValid() && mOwned) {
-        mClient->destroySurface(mHandle);
+        SurfaceComposerClient::Transaction().reparent(this, nullptr).apply();
     }
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h
index d108120..aa13c0c 100644
--- a/libs/gui/include/gui/BufferQueueConsumer.h
+++ b/libs/gui/include/gui/BufferQueueConsumer.h
@@ -31,7 +31,7 @@
 class BufferQueueConsumer : public BnGraphicBufferConsumer {
 
 public:
-    BufferQueueConsumer(const sp<BufferQueueCore>& core);
+    explicit BufferQueueConsumer(const sp<BufferQueueCore>& core);
     ~BufferQueueConsumer() override;
 
     // acquireBuffer attempts to acquire ownership of the next pending buffer in
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index 5c7ffb4..73bc5dd 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -29,7 +29,8 @@
 public:
     friend class BufferQueue; // Needed to access binderDied
 
-    BufferQueueProducer(const sp<BufferQueueCore>& core, bool consumerIsSurfaceFlinger = false);
+    explicit BufferQueueProducer(const sp<BufferQueueCore>& core,
+                                 bool consumerIsSurfaceFlinger = false);
     ~BufferQueueProducer() override;
 
     // requestBuffer returns the GraphicBuffer for slot N.
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 32ce59a..a4102df 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -84,7 +84,7 @@
      * or requestNextVsync to receive them.
      * Other events start being delivered immediately.
      */
-    DisplayEventReceiver(
+    explicit DisplayEventReceiver(
             ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
 
     /*
diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h
index 46a99e1..ddd868d 100644
--- a/libs/gui/include/gui/GLConsumer.h
+++ b/libs/gui/include/gui/GLConsumer.h
@@ -301,7 +301,7 @@
     // also only creating new EGLImages from buffers when required.
     class EglImage : public LightRefBase<EglImage>  {
     public:
-        EglImage(sp<GraphicBuffer> graphicBuffer);
+        explicit EglImage(sp<GraphicBuffer> graphicBuffer);
 
         // createIfNeeded creates an EGLImage if required (we haven't created
         // one yet, or the EGLDisplay or crop-rect has changed).
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8cb40e7..1534fca 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -42,6 +42,7 @@
 struct DisplayState;
 struct DisplayInfo;
 struct DisplayStatInfo;
+struct InputWindowCommands;
 class LayerDebugInfo;
 class HdrCapabilities;
 class IDisplayEventConnection;
@@ -86,22 +87,11 @@
         eVsyncSourceSurfaceFlinger = 1
     };
 
-    /* create connection with surface flinger, requires
-     * ACCESS_SURFACE_FLINGER permission
+    /* 
+     * Create a connection with SurfaceFlinger.
      */
     virtual sp<ISurfaceComposerClient> createConnection() = 0;
 
-    /** create a scoped connection with surface flinger.
-     * Surfaces produced with this connection will act
-     * as children of the passed in GBP. That is to say
-     * SurfaceFlinger will draw them relative and confined to
-     * drawing of buffers from the layer associated with parent.
-     * As this is graphically equivalent in reach to just drawing
-     * pixels into the parent buffers, it requires no special permission.
-     */
-    virtual sp<ISurfaceComposerClient> createScopedConnection(
-            const sp<IGraphicBufferProducer>& parent) = 0;
-
     /* return an IDisplayEventConnection */
     virtual sp<IDisplayEventConnection> createDisplayEventConnection(
             VsyncSource vsyncSource = eVsyncSourceApp) = 0;
@@ -125,7 +115,8 @@
     /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken) = 0;
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& inputWindowCommands) = 0;
 
     /* signal that we're done booting.
      * Requires ACCESS_SURFACE_FLINGER permission
@@ -354,7 +345,6 @@
         ENABLE_VSYNC_INJECTIONS,
         INJECT_VSYNC,
         GET_LAYER_DEBUG_INFO,
-        CREATE_SCOPED_CONNECTION,
         GET_COMPOSITION_PREFERENCE,
         GET_COLOR_MANAGEMENT,
         GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index 82b01b8..56ca197 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -58,11 +58,6 @@
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
-    virtual status_t destroySurface(const sp<IBinder>& handle) = 0;
-
-    /*
-     * Requires ACCESS_SURFACE_FLINGER permission
-     */
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0;
 
     /*
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 02c6be2..e7564f5 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -228,6 +228,20 @@
     status_t read(const Parcel& input);
 };
 
+struct InputWindowCommands {
+    struct TransferTouchFocusCommand {
+        sp<IBinder> fromToken;
+        sp<IBinder> toToken;
+    };
+
+    std::vector<TransferTouchFocusCommand> transferTouchFocusCommands;
+
+    void merge(const InputWindowCommands& other);
+    void clear();
+    void write(Parcel& output) const;
+    void read(const Parcel& input);
+};
+
 static inline int compare_type(const ComposerState& lhs, const ComposerState& rhs) {
     if (lhs.client < rhs.client) return -1;
     if (lhs.client > rhs.client) return 1;
diff --git a/libs/gui/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h
index 8f47eb4..b4eef29 100644
--- a/libs/gui/include/gui/StreamSplitter.h
+++ b/libs/gui/include/gui/StreamSplitter.h
@@ -128,7 +128,7 @@
 
     class BufferTracker : public LightRefBase<BufferTracker> {
     public:
-        BufferTracker(const sp<GraphicBuffer>& buffer);
+        explicit BufferTracker(const sp<GraphicBuffer>& buffer);
 
         const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
         const sp<Fence>& getMergedFence() const { return mMergedFence; }
@@ -154,7 +154,7 @@
     };
 
     // Only called from createSplitter
-    StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue);
+    explicit StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue);
 
     // Must be accessed through RefBase
     virtual ~StreamSplitter();
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8e3ba78..e0cbb70 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -90,7 +90,6 @@
 public:
                 SurfaceComposerClient();
                 SurfaceComposerClient(const sp<ISurfaceComposerClient>& client);
-                SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent);
     virtual     ~SurfaceComposerClient();
 
     // Always make sure we could initialize
@@ -146,6 +145,13 @@
                                              ui::Dataspace* wideColorGamutDataspace,
                                              ui::PixelFormat* wideColorGamutPixelFormat);
 
+    /**
+     * Called from SurfaceControl d'tor to 'destroy' the surface (or rather, reparent it
+     * to null), but without needing an sp<SurfaceControl> to avoid infinite ressurection.
+     */
+    static void doDropReferenceTransaction(const sp<IBinder>& handle,
+            const sp<ISurfaceComposerClient>& client);
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
@@ -219,6 +225,7 @@
         bool                        mAnimation = false;
         bool                        mEarlyWakeup = false;
 
+        InputWindowCommands mInputWindowCommands;
         int mStatus = NO_ERROR;
 
         layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -335,10 +342,9 @@
 
 #ifndef NO_INPUT
         Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
+        Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 #endif
 
-        Transaction& destroySurface(const sp<SurfaceControl>& sc);
-
         // Set a color transform matrix on the given layer on the built-in display.
         Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
                                        const vec3& translation);
@@ -367,8 +373,6 @@
         void setEarlyWakeup();
     };
 
-    status_t    destroySurface(const sp<IBinder>& id);
-
     status_t clearLayerFrameStats(const sp<IBinder>& token) const;
     status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
     static status_t clearAnimationFrameStats();
@@ -400,7 +404,6 @@
     mutable     Mutex                       mLock;
                 status_t                    mStatus;
                 sp<ISurfaceComposerClient>  mClient;
-                wp<IGraphicBufferProducer>  mParent;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index ccb30fa..9bba766 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -75,6 +75,8 @@
     status_t getLayerFrameStats(FrameStats* outStats) const;
 
     sp<SurfaceComposerClient> getClient() const;
+    
+    explicit SurfaceControl(const sp<SurfaceControl>& other);
 
 private:
     // can't be copied
diff --git a/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
index fa6c2d9..0f6fb45 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
@@ -50,7 +50,7 @@
 
 struct B2HProducerListener : public HProducerListener {
     sp<BProducerListener> mBase;
-    B2HProducerListener(sp<BProducerListener> const& base);
+    explicit B2HProducerListener(sp<BProducerListener> const& base);
     Return<void> onBufferReleased() override;
     Return<bool> needsReleaseNotify() override;
 };
diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
index 74850b4..c92fa9d 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
@@ -59,7 +59,7 @@
         HGraphicBufferProducer,
         BGraphicBufferProducer,
         BnGraphicBufferProducer> {
-    H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {}
+    explicit H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {}
 
     status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
     status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override;
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 60542bd..7fc69ff 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -133,6 +133,27 @@
         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
     }
 
+    void expectMotionEvent(int motionEventType, int x, int y) {
+        InputEvent *ev = consumeEvent();
+        ASSERT_NE(ev, nullptr);
+        ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION);
+        MotionEvent *mev = static_cast<MotionEvent *>(ev);
+        EXPECT_EQ(motionEventType, mev->getAction());
+        EXPECT_EQ(x, mev->getX(0));
+        EXPECT_EQ(y, mev->getY(0));
+    }
+
+    void expectNoMotionEvent(int motionEventType) {
+        InputEvent *ev = consumeEvent();
+        if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) {
+            // Didn't find an event or a motion event so assume action didn't occur.
+            return;
+        }
+
+        MotionEvent *mev = static_cast<MotionEvent *>(ev);
+        EXPECT_NE(motionEventType, mev->getAction());
+    }
+
     ~InputSurface() {
         mInputFlinger->unregisterInputChannel(mServerChannel);
     }
@@ -255,6 +276,15 @@
     }
 }
 
+void injectMotionEvent(std::string event, int x, int y) {
+    char *buf1, *buf2;
+    asprintf(&buf1, "%d", x);
+    asprintf(&buf2, "%d", y);
+    if (fork() == 0) {
+        execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL);
+    }
+}
+
 TEST_F(InputSurfacesTest, can_receive_input) {
     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
     surface->showAt(100, 100);
@@ -439,5 +469,25 @@
     injectTap(11, 11);
     bgSurface->expectTap(1, 1);
 }
+
+TEST_F(InputSurfacesTest, transfer_touch_focus) {
+    std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100);
+
+    fromSurface->showAt(10, 10);
+    injectMotionEvent("DOWN", 11, 11);
+    fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1);
+
+    std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100);
+    toSurface->showAt(10, 10);
+
+    sp<IBinder> fromToken = fromSurface->mServerChannel->getToken();
+    sp<IBinder> toToken = toSurface->mServerChannel->getToken();
+    SurfaceComposerClient::Transaction t;
+    t.transferTouchFocus(fromToken, toToken).apply(true);
+
+    injectMotionEvent("UP", 11, 11);
+    toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1);
+    fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP);
+}
 }
 }
diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp
index bb6b8a5..acd4297 100644
--- a/libs/gui/tests/Malicious.cpp
+++ b/libs/gui/tests/Malicious.cpp
@@ -27,7 +27,7 @@
 
 class ProxyBQP : public BnGraphicBufferProducer {
 public:
-    ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {}
+    explicit ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {}
 
     // Pass through calls to mProducer
     status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override {
@@ -102,7 +102,7 @@
 
 class MaliciousBQP : public ProxyBQP {
 public:
-    MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {}
+    explicit MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {}
 
     void beMalicious(int32_t value) { mMaliciousValue = value; }
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index c56304f..60173dc 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -545,10 +545,6 @@
     }
 
     sp<ISurfaceComposerClient> createConnection() override { return nullptr; }
-    sp<ISurfaceComposerClient> createScopedConnection(
-            const sp<IGraphicBufferProducer>& /* parent */) override {
-        return nullptr;
-    }
     sp<IDisplayEventConnection> createDisplayEventConnection(ISurfaceComposer::VsyncSource)
             override {
         return nullptr;
@@ -559,7 +555,8 @@
     sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; }
     void setTransactionState(const Vector<ComposerState>& /*state*/,
                              const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
-                             const sp<IBinder>& /*applyToken*/) override {}
+                             const sp<IBinder>& /*applyToken*/,
+                             const InputWindowCommands& /*inputWindowCommands*/) override {}
     void bootFinished() override {}
     bool authenticateSurfaceTexture(
             const sp<IGraphicBufferProducer>& /*surface*/) const override {
@@ -669,8 +666,7 @@
 
 class FakeProducerFrameEventHistory : public ProducerFrameEventHistory {
 public:
-    FakeProducerFrameEventHistory(FenceToFenceTimeMap* fenceMap)
-        : mFenceMap(fenceMap) {}
+    explicit FakeProducerFrameEventHistory(FenceToFenceTimeMap* fenceMap) : mFenceMap(fenceMap) {}
 
     ~FakeProducerFrameEventHistory() {}
 
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index 139570a..acf40bc 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -42,6 +42,16 @@
                 IBinder::FLAG_ONEWAY);
     }
 
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
+
+        data.writeStrongBinder(fromToken);
+        data.writeStrongBinder(toToken);
+        remote()->transact(BnInputFlinger::TRANSFER_TOUCH_FOCUS, data, &reply,
+                IBinder::FLAG_ONEWAY);
+    }
+
     virtual void registerInputChannel(const sp<InputChannel>& channel) {
         Parcel data, reply;
         data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
@@ -90,6 +100,13 @@
         unregisterInputChannel(channel);
         break;
     }
+    case TRANSFER_TOUCH_FOCUS: {
+        CHECK_INTERFACE(IInputFlinger, data, reply);
+        sp<IBinder> fromToken = data.readStrongBinder();
+        sp<IBinder> toToken = data.readStrongBinder();
+        transferTouchFocus(fromToken, toToken);
+        break;
+    }
     default:
         return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index a19fe17..6ea1270 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -268,7 +268,11 @@
     AHardwareBuffer_Desc trialDesc = *desc;
     trialDesc.width = 4;
     trialDesc.height = desc->format == AHARDWAREBUFFER_FORMAT_BLOB ? 1 : 4;
-    trialDesc.layers = desc->layers == 1 ? 1 : 2;
+    if (desc->usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
+        trialDesc.layers = desc->layers == 6 ? 6 : 12;
+    } else {
+        trialDesc.layers = desc->layers == 1 ? 1 : 2;
+    }
     AHardwareBuffer* trialBuffer = nullptr;
     int result = AHardwareBuffer_allocate(&trialDesc, &trialBuffer);
     if (result == NO_ERROR) {
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 03545a6..2796c75 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -208,6 +208,17 @@
      */
     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT       = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
     /**
+     * The buffer will be used as a composer HAL overlay layer.
+     *
+     * This flag is currently only needed when using ASurfaceTransaction_setBuffer
+     * to set a buffer. In all other cases, the framework adds this flag
+     * internally to buffers that could be presented in a composer overlay.
+     * ASurfaceTransaction_setBuffer is special because it uses buffers allocated
+     * directly through AHardwareBuffer_allocate instead of buffers allocated
+     * by the framework.
+     */
+    AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY       = 1ULL << 11,
+    /**
      * The buffer is protected from direct CPU access or being read by
      * non-secure hardware, such as video encoders.
      *
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index d872f02..36211ca 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -26,6 +26,7 @@
         "libgui",
         "liblog",
         "libnativewindow",
+        "libsync",
         "libui",
         "libutils",
     ],
@@ -79,3 +80,19 @@
         thin: true,
     },
 }
+
+cc_library_static {
+    name: "librenderengine_mocks",
+    defaults: ["librenderengine_defaults"],
+    srcs: [
+        "mock/Framebuffer.cpp",
+        "mock/Image.cpp",
+        "mock/RenderEngine.cpp",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 51cf188..2915bb8 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -24,14 +24,17 @@
 #include <math.h>
 #include <fstream>
 #include <sstream>
+#include <unordered_set>
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #include <android-base/stringprintf.h>
 #include <cutils/compiler.h>
+#include <cutils/properties.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/Texture.h>
 #include <renderengine/private/Description.h>
+#include <sync/sync.h>
 #include <ui/ColorSpace.h>
 #include <ui/DebugUtils.h>
 #include <ui/Rect.h>
@@ -414,6 +417,13 @@
         mBt2020ToSrgb = mXyzToSrgb * mBt2020ToXyz;
         mBt2020ToDisplayP3 = mXyzToDisplayP3 * mBt2020ToXyz;
     }
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.egl.traceGpuCompletion", value, "0");
+    if (atoi(value)) {
+        mTraceGpuCompletion = true;
+        mFlushTracer = std::make_unique<FlushTracer>(this);
+    }
 }
 
 GLESRenderEngine::~GLESRenderEngine() {
@@ -459,6 +469,12 @@
         ALOGW("failed to dup EGL native fence sync: %#x", eglGetError());
     }
 
+    // Only trace if we have a valid fence, as current usage falls back to
+    // calling finish() if the fence fd is invalid.
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer) && fenceFd.get() >= 0) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
     return fenceFd;
 }
 
@@ -474,8 +490,15 @@
         return false;
     }
 
-    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
-                                         2000000000 /*2 sec*/);
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer)) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
+    return waitSync(sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR);
+}
+
+bool GLESRenderEngine::waitSync(EGLSyncKHR sync, EGLint flags) {
+    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, flags, 2000000000 /*2 sec*/);
     EGLint error = eglGetError();
     eglDestroySyncKHR(mEGLDisplay, sync);
     if (result != EGL_CONDITION_SATISFIED_KHR) {
@@ -584,6 +607,65 @@
     }
 }
 
+status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
+                                                     sp<Fence> bufferFence) {
+    std::unique_ptr<Image> newImage = createImage();
+
+    bool created = newImage->setNativeWindowBuffer(buffer->getNativeBuffer(),
+                                                   buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+    if (!created) {
+        ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d",
+              buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(),
+              buffer->getPixelFormat());
+        bindExternalTextureImage(texName, *createImage());
+        return NO_INIT;
+    }
+
+    bindExternalTextureImage(texName, *newImage);
+
+    // Wait for the new buffer to be ready.
+    if (bufferFence != nullptr && bufferFence->isValid()) {
+        if (GLExtensions::getInstance().hasWaitSync()) {
+            base::unique_fd fenceFd(bufferFence->dup());
+            if (fenceFd == -1) {
+                ALOGE("error dup'ing fence fd: %d", errno);
+                return -errno;
+            }
+            if (!waitFence(std::move(fenceFd))) {
+                ALOGE("failed to wait on fence fd");
+                return UNKNOWN_ERROR;
+            }
+        } else {
+            status_t err = bufferFence->waitForever("RenderEngine::bindExternalTextureBuffer");
+            if (err != NO_ERROR) {
+                ALOGE("error waiting for fence: %d", err);
+                return err;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) {
+    // Translate win by the rounded corners rect coordinates, to have all values in
+    // layer coordinate space.
+    FloatRect cropWin = layer.geometry.boundaries;
+    const FloatRect& roundedCornersCrop = layer.geometry.roundedCornersCrop;
+    cropWin.left -= roundedCornersCrop.left;
+    cropWin.right -= roundedCornersCrop.left;
+    cropWin.top -= roundedCornersCrop.top;
+    cropWin.bottom -= roundedCornersCrop.top;
+    Mesh::VertexArray<vec2> cropCoords(mesh.getCropCoordArray<vec2>());
+    cropCoords[0] = vec2(cropWin.left, cropWin.top);
+    cropCoords[1] = vec2(cropWin.left, cropWin.top + cropWin.getHeight());
+    cropCoords[2] = vec2(cropWin.right, cropWin.top + cropWin.getHeight());
+    cropCoords[3] = vec2(cropWin.right, cropWin.top);
+
+    setupCornerRadiusCropSize(roundedCornersCrop.getWidth(), roundedCornersCrop.getHeight());
+    return cropWin;
+}
+
 status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
     GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
     EGLImageKHR eglImage = glFramebuffer->getEGLImage();
@@ -672,33 +754,68 @@
     setDisplayMaxLuminance(display.maxLuminance);
 
     mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform;
+    mState.projectionMatrix = projectionMatrix;
+    if (!display.clearRegion.isEmpty()) {
+        fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
+    }
 
-    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
+    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
     for (auto layer : layers) {
-        // for now, assume that all pixel sources are solid colors.
-        // TODO(alecmouri): support buffer sources
-        if (layer.source.buffer.buffer != nullptr) {
-            continue;
-        }
-
-        setColorTransform(display.colorTransform * layer.colorTransform);
-
         mState.projectionMatrix = projectionMatrix * layer.geometry.positionTransform;
 
-        FloatRect bounds = layer.geometry.boundaries;
+        const FloatRect bounds = layer.geometry.boundaries;
         Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
         position[0] = vec2(bounds.left, bounds.top);
         position[1] = vec2(bounds.left, bounds.bottom);
         position[2] = vec2(bounds.right, bounds.bottom);
         position[3] = vec2(bounds.right, bounds.top);
 
-        half3 solidColor = layer.source.solidColor;
-        half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
-        setupLayerBlending(/*premultipliedAlpha=*/true, /*opaque=*/false, /*disableTexture=*/true,
-                           color, /*cornerRadius=*/0.0);
+        setupLayerCropping(layer, mesh);
+        setColorTransform(display.colorTransform * layer.colorTransform);
+
+        bool usePremultipliedAlpha = true;
+        bool disableTexture = true;
+
+        if (layer.source.buffer.buffer != nullptr) {
+            disableTexture = false;
+
+            sp<GraphicBuffer> gBuf = layer.source.buffer.buffer;
+
+            bindExternalTextureBuffer(layer.source.buffer.textureName, gBuf,
+                                      layer.source.buffer.fence);
+
+            usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha;
+            Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName);
+            texture.setMatrix(layer.source.buffer.textureTransform.asArray());
+            texture.setFiltering(layer.source.buffer.useTextureFiltering);
+
+            texture.setDimensions(gBuf->getWidth(), gBuf->getHeight());
+            setSourceY410BT2020(layer.source.buffer.isY410BT2020);
+
+            renderengine::Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
+            texCoords[0] = vec2(0.0, 1.0);
+            texCoords[1] = vec2(0.0, 0.0);
+            texCoords[2] = vec2(1.0, 0.0);
+            texCoords[3] = vec2(1.0, 1.0);
+            setupLayerTexturing(texture);
+        }
+
+        const half3 solidColor = layer.source.solidColor;
+        const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
+        // Buffer sources will have a black solid color ignored in the shader,
+        // so in that scenario the solid color passed here is arbitrary.
+        setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture,
+                           color, layer.geometry.roundedCornersRadius);
         setSourceDataSpace(layer.sourceDataspace);
 
         drawMesh(mesh);
+
+        // Cleanup if there's a buffer source
+        if (layer.source.buffer.buffer != nullptr) {
+            disableBlending();
+            setSourceY410BT2020(false);
+            disableTexturing();
+        }
     }
 
     *drawFence = flush();
@@ -1128,6 +1245,61 @@
     return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
 }
 
+// FlushTracer implementation
+GLESRenderEngine::FlushTracer::FlushTracer(GLESRenderEngine* engine) : mEngine(engine) {
+    mThread = std::thread(&GLESRenderEngine::FlushTracer::loop, this);
+}
+
+GLESRenderEngine::FlushTracer::~FlushTracer() {
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mRunning = false;
+    }
+    mCondition.notify_all();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
+void GLESRenderEngine::FlushTracer::queueSync(EGLSyncKHR sync) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    char name[64];
+    const uint64_t frameNum = mFramesQueued++;
+    snprintf(name, sizeof(name), "Queueing sync for frame: %lu",
+             static_cast<unsigned long>(frameNum));
+    ATRACE_NAME(name);
+    mQueue.push({sync, frameNum});
+    ATRACE_INT("GPU Frames Outstanding", mQueue.size());
+    mCondition.notify_one();
+}
+
+void GLESRenderEngine::FlushTracer::loop() {
+    while (mRunning) {
+        QueueEntry entry;
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+
+            mCondition.wait(mMutex,
+                            [&]() REQUIRES(mMutex) { return !mQueue.empty() && !mRunning; });
+
+            if (!mRunning) {
+                // if mRunning is false, then FlushTracer is being destroyed, so
+                // bail out now.
+                break;
+            }
+            entry = mQueue.front();
+            mQueue.pop();
+        }
+        {
+            char name[64];
+            snprintf(name, sizeof(name), "waiting for frame %lu",
+                     static_cast<unsigned long>(entry.mFrameNum));
+            ATRACE_NAME(name);
+            mEngine->waitSync(entry.mSync, 0);
+        }
+    }
+}
+
 } // namespace gl
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index b6fff33..b596242 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -17,8 +17,13 @@
 #ifndef SF_GLESRENDERENGINE_H_
 #define SF_GLESRENDERENGINE_H_
 
+#include <android-base/thread_annotations.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -119,6 +124,7 @@
                                        Protection protection);
     static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
                                                    int hwcFormat, Protection protection);
+    bool waitSync(EGLSyncKHR sync, EGLint flags);
 
     // A data space is considered HDR data space if it has BT2020 color space
     // with PQ or HLG transfer function.
@@ -127,6 +133,10 @@
     // Defines the viewport, and sets the projection matrix to the projection
     // defined by the clip.
     void setViewportAndProjection(Rect viewport, Rect clip);
+    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence);
+    // Computes the cropping window for the layer and sets up cropping
+    // coordinates for the mesh.
+    FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh);
 
     EGLDisplay mEGLDisplay;
     EGLConfig mEGLConfig;
@@ -155,6 +165,8 @@
     mat4 mBt2020ToDisplayP3;
 
     bool mInProtectedContext = false;
+    // If set to true, then enables tracing flush() and finish() to systrace.
+    bool mTraceGpuCompletion = false;
     int32_t mFboHeight = 0;
 
     // Current dataspace of layer being rendered
@@ -166,6 +178,30 @@
     // Whether device supports color management, currently color management
     // supports sRGB, DisplayP3 color spaces.
     const bool mUseColorManagement = false;
+
+    class FlushTracer {
+    public:
+        FlushTracer(GLESRenderEngine* engine);
+        ~FlushTracer();
+        void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex);
+
+        struct QueueEntry {
+            EGLSyncKHR mSync = nullptr;
+            uint64_t mFrameNum = 0;
+        };
+
+    private:
+        void loop();
+        GLESRenderEngine* const mEngine;
+        std::thread mThread;
+        std::condition_variable_any mCondition;
+        std::mutex mMutex;
+        std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);
+        uint64_t mFramesQueued GUARDED_BY(mMutex) = 0;
+        bool mRunning = true;
+    };
+    friend class FlushTracer;
+    std::unique_ptr<FlushTracer> mFlushTracer;
 };
 
 } // namespace gl
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index 0c92353..af8de23 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -51,9 +51,10 @@
     // to the output dataspace.
     mat4 colorTransform = mat4();
 
-    // Region that will be cleared to (0, 0, 0, 0) prior to rendering.
-    // clearRegion will first be transformed by globalTransform so that it will
-    // be in the same coordinate space as the rendered layers.
+    // Region that will be cleared to (0, 0, 0, 1) prior to rendering.
+    // RenderEngine will transform the clearRegion passed in here, by
+    // globalTransform, so that it will be in the same coordinate space as the
+    // rendered layers.
     Region clearRegion = Region::INVALID_REGION;
 };
 
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index 93abf5c..4d53205 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -19,6 +19,7 @@
 #include <math/mat4.h>
 #include <math/vec3.h>
 #include <renderengine/Texture.h>
+#include <ui/Fence.h>
 #include <ui/FloatRect.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicTypes.h>
@@ -36,6 +37,9 @@
     // ignored.
     sp<GraphicBuffer> buffer = nullptr;
 
+    // Fence that will fire when the buffer is ready to be bound.
+    sp<Fence> fence = nullptr;
+
     // Texture identifier to bind the external texture to.
     // TODO(alecmouri): This is GL-specific...make the type backend-agnostic.
     uint32_t textureName = 0;
@@ -49,6 +53,11 @@
     // Wheteher to use pre-multiplied alpha
     bool usePremultipliedAlpha = true;
 
+    // Override flag that alpha for each pixel in the buffer *must* be 1.0.
+    // LayerSettings::alpha is still used if isOpaque==true - this flag only
+    // overrides the alpha channel of the buffer.
+    bool isOpaque = false;
+
     // HDR color-space setting for Y410.
     bool isY410BT2020 = false;
 };
@@ -60,6 +69,20 @@
 
     // Transform matrix to apply to mesh coordinates.
     mat4 positionTransform = mat4();
+
+    // Radius of rounded corners, if greater than 0. Otherwise, this layer's
+    // corners are not rounded.
+    // Having corner radius will force GPU composition on the layer and its children, drawing it
+    // with a special shader. The shader will receive the radius and the crop rectangle as input,
+    // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1.
+    // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop
+    // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be
+    // in local layer coordinate space, so we have to take the layer transform into account when
+    // walking up the tree.
+    float roundedCornersRadius = 0.0;
+
+    // Rectangle within which corners will be rounded.
+    FloatRect roundedCornersCrop = FloatRect();
 };
 
 // Descriptor of the source pixels for this layer.
@@ -81,15 +104,15 @@
     // Source pixels for this layer.
     PixelSource source = PixelSource();
 
-    // Alpha option to apply to the source pixels
+    // Alpha option to blend with the source pixels
     half alpha = half(0.0);
 
     // Color space describing how the source pixels should be interpreted.
-    ui::Dataspace sourceDataspace;
+    ui::Dataspace sourceDataspace = ui::Dataspace::UNKNOWN;
 
     // Additional layer-specific color transform to be applied before the global
     // transform.
-    mat4 colorTransform;
+    mat4 colorTransform = mat4();
 };
 
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/include/renderengine/mock/Framebuffer.h
similarity index 63%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/include/renderengine/mock/Framebuffer.h
index fbfbc3f..7695885 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/include/renderengine/mock/Framebuffer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -14,23 +14,22 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
+#pragma once
 
-#include <ui/Region.h>
+#include <gmock/gmock.h>
+#include <renderengine/Framebuffer.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
+class Framebuffer : public renderengine::Framebuffer {
+public:
+    Framebuffer();
+    ~Framebuffer() override;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
+    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
+};
 
 } // namespace mock
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/include/renderengine/mock/Image.h
similarity index 63%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/include/renderengine/mock/Image.h
index fbfbc3f..2b0eed1 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/include/renderengine/mock/Image.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -14,23 +14,22 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
+#pragma once
 
-#include <ui/Region.h>
+#include <gmock/gmock.h>
+#include <renderengine/Image.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
+class Image : public renderengine::Image {
+public:
+    Image();
+    ~Image() override;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
+    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer* buffer, bool isProtected));
+};
 
 } // namespace mock
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
similarity index 82%
rename from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
rename to libs/renderengine/include/renderengine/mock/RenderEngine.h
index 81a7768..b4c7c96 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -18,13 +18,12 @@
 
 #include <gmock/gmock.h>
 #include <renderengine/DisplaySettings.h>
-#include <renderengine/Framebuffer.h>
-#include <renderengine/Image.h>
 #include <renderengine/LayerSettings.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/RenderEngine.h>
 #include <renderengine/Texture.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/Region.h>
 
 namespace android {
 namespace renderengine {
@@ -35,7 +34,7 @@
     RenderEngine();
     ~RenderEngine() override;
 
-    MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
+    MOCK_METHOD0(createFramebuffer, std::unique_ptr<renderengine::Framebuffer>());
     MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
     MOCK_CONST_METHOD0(primeCache, void());
     MOCK_METHOD1(dump, void(std::string&));
@@ -69,9 +68,9 @@
     MOCK_METHOD1(setSourceDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setOutputDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setDisplayMaxLuminance, void(const float));
-    MOCK_METHOD1(bindFrameBuffer, status_t(Framebuffer*));
-    MOCK_METHOD1(unbindFrameBuffer, void(Framebuffer*));
-    MOCK_METHOD1(drawMesh, void(const Mesh&));
+    MOCK_METHOD1(bindFrameBuffer, status_t(renderengine::Framebuffer*));
+    MOCK_METHOD1(unbindFrameBuffer, void(renderengine::Framebuffer*));
+    MOCK_METHOD1(drawMesh, void(const renderengine::Mesh&));
     MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
     MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
     MOCK_CONST_METHOD0(isProtected, bool());
@@ -82,22 +81,6 @@
                           ANativeWindowBuffer*, base::unique_fd*));
 };
 
-class Image : public renderengine::Image {
-public:
-    Image();
-    ~Image() override;
-
-    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
-};
-
-class Framebuffer : public renderengine::Framebuffer {
-public:
-    Framebuffer();
-    ~Framebuffer() override;
-
-    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
-};
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/Framebuffer.cpp
similarity index 70%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/mock/Framebuffer.cpp
index fbfbc3f..fbdcaab 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/Framebuffer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -14,21 +14,14 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/Framebuffer.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
-
-Image::Image() = default;
-Image::~Image() = default;
-
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 Framebuffer::Framebuffer() = default;
 Framebuffer::~Framebuffer() = default;
 
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/Image.cpp
similarity index 68%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/mock/Image.cpp
index fbfbc3f..57f4346 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/Image.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -14,24 +14,17 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/Image.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
-
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 Image::Image() = default;
 Image::~Image() = default;
 
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/RenderEngine.cpp
similarity index 71%
rename from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
rename to libs/renderengine/mock/RenderEngine.cpp
index fbfbc3f..261636d 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/RenderEngine.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2018 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.
@@ -14,24 +14,17 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/RenderEngine.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 RenderEngine::RenderEngine() = default;
 RenderEngine::~RenderEngine() = default;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index a0542dd..bef25a8 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -27,15 +27,30 @@
 namespace android {
 
 struct RenderEngineTest : public ::testing::Test {
-    sp<GraphicBuffer> allocateDefaultBuffer() {
+    static sp<GraphicBuffer> allocateDefaultBuffer() {
         return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
                                  HAL_PIXEL_FORMAT_RGBA_8888, 1,
-                                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                         GRALLOC_USAGE_HW_RENDER,
                                  "output");
     }
 
+    // Allocates a 1x1 buffer to fill with a solid color
+    static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) {
+        return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+                                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                         GRALLOC_USAGE_HW_TEXTURE,
+                                 "input");
+    }
+
     RenderEngineTest() { mBuffer = allocateDefaultBuffer(); }
 
+    ~RenderEngineTest() {
+        for (uint32_t texName : mTexNames) {
+            sRE->deleteTextures(1, &texName);
+        }
+    }
+
     void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
                            uint8_t tolerance = 0) {
         uint8_t* pixels;
@@ -146,27 +161,112 @@
     void fillBufferCheckersRotate270();
 
     template <typename SourceVariant>
+    void fillBufferWithLayerTransform();
+
+    template <typename SourceVariant>
     void fillBufferLayerTransform();
 
     template <typename SourceVariant>
+    void fillBufferWithColorTransform();
+
+    template <typename SourceVariant>
     void fillBufferColorTransform();
 
+    template <typename SourceVariant>
+    void fillRedBufferWithRoundedCorners();
+
+    template <typename SourceVariant>
+    void fillBufferWithRoundedCorners();
+
+    void fillRedBufferTextureTransform();
+
+    void fillBufferTextureTransform();
+
+    void fillRedBufferWithPremultiplyAlpha();
+
+    void fillBufferWithPremultiplyAlpha();
+
+    void fillRedBufferWithoutPremultiplyAlpha();
+
+    void fillBufferWithoutPremultiplyAlpha();
+
+    void fillGreenColorBufferThenClearRegion();
+
+    void clearLeftRegion();
+
+    void fillBufferThenClearRegion();
+
     // Dumb hack to get aroud the fact that tear-down for renderengine isn't
     // well defined right now, so we can't create multiple instances
     static std::unique_ptr<renderengine::RenderEngine> sRE;
 
     sp<GraphicBuffer> mBuffer;
+
+    std::vector<uint32_t> mTexNames;
 };
 
 std::unique_ptr<renderengine::RenderEngine> RenderEngineTest::sRE =
         renderengine::RenderEngine::create(static_cast<int32_t>(ui::PixelFormat::RGBA_8888), 0);
 
 struct ColorSourceVariant {
-    static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b) {
+    static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
+                          RenderEngineTest* /*fixture*/) {
         layer.source.solidColor = half3(r, g, b);
     }
 };
 
+struct RelaxOpaqueBufferVariant {
+    static void setOpaqueBit(renderengine::LayerSettings& layer) {
+        layer.source.buffer.isOpaque = false;
+    }
+
+    static uint8_t getAlphaChannel() { return 255; }
+};
+
+struct ForceOpaqueBufferVariant {
+    static void setOpaqueBit(renderengine::LayerSettings& layer) {
+        layer.source.buffer.isOpaque = true;
+    }
+
+    static uint8_t getAlphaChannel() {
+        // The isOpaque bit will override the alpha channel, so this should be
+        // arbitrary.
+        return 10;
+    }
+};
+
+template <typename OpaquenessVariant>
+struct BufferSourceVariant {
+    static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
+                          RenderEngineTest* fixture) {
+        sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
+        uint32_t texName;
+        RenderEngineTest::sRE->genTextures(1, &texName);
+        fixture->mTexNames.push_back(texName);
+
+        uint8_t* pixels;
+        buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                  reinterpret_cast<void**>(&pixels));
+
+        for (int32_t j = 0; j < buf->getHeight(); j++) {
+            uint8_t* iter = pixels + (buf->getStride() * j) * 4;
+            for (int32_t i = 0; i < buf->getWidth(); i++) {
+                iter[0] = uint8_t(r * 255);
+                iter[1] = uint8_t(g * 255);
+                iter[2] = uint8_t(b * 255);
+                iter[3] = OpaquenessVariant::getAlphaChannel();
+                iter += 4;
+            }
+        }
+
+        buf->unlock();
+
+        layer.source.buffer.buffer = buf;
+        layer.source.buffer.textureName = texName;
+        OpaquenessVariant::setOpaqueBit(layer);
+    }
+};
+
 template <typename SourceVariant>
 void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
     renderengine::DisplaySettings settings;
@@ -177,7 +277,7 @@
 
     renderengine::LayerSettings layer;
     layer.geometry.boundaries = fullscreenRect().toFloatRect();
-    SourceVariant::fillColor(layer, r, g, b);
+    SourceVariant::fillColor(layer, r, g, b, this);
     layer.alpha = a;
 
     layers.push_back(layer);
@@ -219,7 +319,7 @@
 
     renderengine::LayerSettings layer;
     layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
-    SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f);
+    SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
     layer.alpha = 1.0f;
 
     layers.push_back(layer);
@@ -253,19 +353,19 @@
     renderengine::LayerSettings layerOne;
     Rect rectOne(0, 0, 1, 1);
     layerOne.geometry.boundaries = rectOne.toFloatRect();
-    SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f);
+    SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
     layerOne.alpha = 1.0f;
 
     renderengine::LayerSettings layerTwo;
     Rect rectTwo(0, 1, 1, 2);
     layerTwo.geometry.boundaries = rectTwo.toFloatRect();
-    SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f);
+    SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
     layerTwo.alpha = 1.0f;
 
     renderengine::LayerSettings layerThree;
     Rect rectThree(1, 0, 2, 1);
     layerThree.geometry.boundaries = rectThree.toFloatRect();
-    SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f);
+    SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
     layerThree.alpha = 1.0f;
 
     layers.push_back(layerOne);
@@ -343,7 +443,7 @@
 }
 
 template <typename SourceVariant>
-void RenderEngineTest::fillBufferLayerTransform() {
+void RenderEngineTest::fillBufferWithLayerTransform() {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
     // Here logical space is 2x2
@@ -355,13 +455,18 @@
     layer.geometry.boundaries = Rect(1, 1).toFloatRect();
     // Translate one pixel diagonally
     layer.geometry.positionTransform = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1);
+    SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
     layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
     layer.alpha = 1.0f;
 
     layers.push_back(layer);
 
     invokeDraw(settings, layers, mBuffer);
+}
 
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferLayerTransform() {
+    fillBufferWithLayerTransform<SourceVariant>();
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
@@ -370,7 +475,7 @@
 }
 
 template <typename SourceVariant>
-void RenderEngineTest::fillBufferColorTransform() {
+void RenderEngineTest::fillBufferWithColorTransform() {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
     settings.clip = Rect(1, 1);
@@ -379,7 +484,7 @@
 
     renderengine::LayerSettings layer;
     layer.geometry.boundaries = Rect(1, 1).toFloatRect();
-    layer.source.solidColor = half3(0.5f, 0.25f, 0.125f);
+    SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
     layer.alpha = 1.0f;
 
     // construct a fake color matrix
@@ -388,13 +493,208 @@
     // set red channel to red + green
     layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
 
+    layer.alpha = 1.0f;
+    layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
     layers.push_back(layer);
 
     invokeDraw(settings, layers, mBuffer);
+}
 
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferColorTransform() {
+    fillBufferWithColorTransform<SourceVariant>();
     expectBufferColor(fullscreenRect(), 191, 0, 0, 255);
 }
 
+template <typename SourceVariant>
+void RenderEngineTest::fillRedBufferWithRoundedCorners() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    settings.clip = fullscreenRect();
+
+    std::vector<renderengine::LayerSettings> layers;
+
+    renderengine::LayerSettings layer;
+    layer.geometry.boundaries = fullscreenRect().toFloatRect();
+    layer.geometry.roundedCornersRadius = 5.0f;
+    layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
+    SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
+    layer.alpha = 1.0f;
+
+    layers.push_back(layer);
+
+    invokeDraw(settings, layers, mBuffer);
+}
+
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferWithRoundedCorners() {
+    fillRedBufferWithRoundedCorners<SourceVariant>();
+    // Corners should be ignored...
+    expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
+    expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
+                           DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                      0, 0, 0, 0);
+    // ...And the non-rounded portion should be red.
+    // Other pixels may be anti-aliased, so let's not check those.
+    expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
+                      255);
+}
+
+void RenderEngineTest::fillRedBufferTextureTransform() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    settings.clip = Rect(1, 1);
+
+    std::vector<renderengine::LayerSettings> layers;
+
+    renderengine::LayerSettings layer;
+    // Here will allocate a checker board texture, but transform texture
+    // coordinates so that only the upper left is applied.
+    sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2);
+    uint32_t texName;
+    RenderEngineTest::sRE->genTextures(1, &texName);
+    this->mTexNames.push_back(texName);
+
+    uint8_t* pixels;
+    buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+              reinterpret_cast<void**>(&pixels));
+    // Red top left, Green top right, Blue bottom left, Black bottom right
+    pixels[0] = 255;
+    pixels[1] = 0;
+    pixels[2] = 0;
+    pixels[3] = 255;
+    pixels[4] = 0;
+    pixels[5] = 255;
+    pixels[6] = 0;
+    pixels[7] = 255;
+    pixels[8] = 0;
+    pixels[9] = 0;
+    pixels[10] = 255;
+    pixels[11] = 255;
+    buf->unlock();
+
+    layer.source.buffer.buffer = buf;
+    layer.source.buffer.textureName = texName;
+    // Transform coordinates to only be inside the red quadrant.
+    layer.source.buffer.textureTransform = mat4::scale(vec4(0.2, 0.2, 1, 1));
+    layer.alpha = 1.0f;
+    layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+    layers.push_back(layer);
+
+    invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferTextureTransform() {
+    fillRedBufferTextureTransform();
+    expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
+}
+
+void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    // Here logical space is 1x1
+    settings.clip = Rect(1, 1);
+
+    std::vector<renderengine::LayerSettings> layers;
+
+    renderengine::LayerSettings layer;
+    sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+    uint32_t texName;
+    RenderEngineTest::sRE->genTextures(1, &texName);
+    this->mTexNames.push_back(texName);
+
+    uint8_t* pixels;
+    buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+              reinterpret_cast<void**>(&pixels));
+    pixels[0] = 255;
+    pixels[1] = 0;
+    pixels[2] = 0;
+    pixels[3] = 255;
+    buf->unlock();
+
+    layer.source.buffer.buffer = buf;
+    layer.source.buffer.textureName = texName;
+    layer.source.buffer.usePremultipliedAlpha = true;
+    layer.alpha = 0.5f;
+    layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+    layers.push_back(layer);
+
+    invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
+    fillRedBufferWithPremultiplyAlpha();
+    expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
+}
+
+void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    // Here logical space is 1x1
+    settings.clip = Rect(1, 1);
+
+    std::vector<renderengine::LayerSettings> layers;
+
+    renderengine::LayerSettings layer;
+    sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+    uint32_t texName;
+    RenderEngineTest::sRE->genTextures(1, &texName);
+    this->mTexNames.push_back(texName);
+
+    uint8_t* pixels;
+    buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+              reinterpret_cast<void**>(&pixels));
+    pixels[0] = 255;
+    pixels[1] = 0;
+    pixels[2] = 0;
+    pixels[3] = 255;
+    buf->unlock();
+
+    layer.source.buffer.buffer = buf;
+    layer.source.buffer.textureName = texName;
+    layer.source.buffer.usePremultipliedAlpha = false;
+    layer.alpha = 0.5f;
+    layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+    layers.push_back(layer);
+
+    invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
+    fillRedBufferWithoutPremultiplyAlpha();
+    expectBufferColor(fullscreenRect(), 128, 0, 0, 64, 1);
+}
+
+void RenderEngineTest::clearLeftRegion() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    // Here logical space is 4x4
+    settings.clip = Rect(4, 4);
+    settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1));
+    settings.clearRegion = Region(Rect(1, 1));
+    std::vector<renderengine::LayerSettings> layers;
+    // dummy layer, without bounds should not render anything
+    renderengine::LayerSettings layer;
+    layers.push_back(layer);
+    invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferThenClearRegion() {
+    fillGreenBuffer<ColorSourceVariant>();
+    // Reuse mBuffer
+    clearLeftRegion();
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 255);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
+                           DEFAULT_DISPLAY_HEIGHT),
+                      0, 255, 0, 255);
+}
+
 TEST_F(RenderEngineTest, drawLayers_noLayersToDraw) {
     drawEmptyLayers();
 }
@@ -443,4 +743,120 @@
     fillBufferLayerTransform<ColorSourceVariant>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
+    fillBufferWithRoundedCorners<ColorSourceVariant>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
+    fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
+    fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
+    fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
+    fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
+    fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
+    fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
+    fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
+    fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
+    fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
+    fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
+    fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
+    fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
+    fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
+    fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
+    fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
+    fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
+    fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
+    fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
+    fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
+    fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
+    fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
+    fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
+    fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
+    fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
+    fillBufferTextureTransform();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
+    fillBufferWithPremultiplyAlpha();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
+    fillBufferWithoutPremultiplyAlpha();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferThenClearRegion) {
+    fillBufferThenClearRegion();
+}
+
 } // namespace android
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 0582e1a..1184960 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -64,7 +64,6 @@
 
 using BufferHubDefs::AnyClientAcquired;
 using BufferHubDefs::AnyClientGained;
-using BufferHubDefs::AnyClientPosted;
 using BufferHubDefs::IsClientAcquired;
 using BufferHubDefs::IsClientGained;
 using BufferHubDefs::IsClientPosted;
@@ -226,8 +225,7 @@
 
 int BufferHubBuffer::Post() {
     uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    uint32_t current_active_clients_bit_mask = 0U;
-    uint32_t updated_buffer_state = 0U;
+    uint32_t updated_buffer_state = (~mClientStateMask) & kHighBitsMask;
     do {
         if (!IsClientGained(current_buffer_state, mClientStateMask)) {
             ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
@@ -236,9 +234,7 @@
             return -EBUSY;
         }
         // Set the producer client buffer state to released, other clients' buffer state to posted.
-        current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire);
-        updated_buffer_state =
-                current_active_clients_bit_mask & (~mClientStateMask) & kHighBitsMask;
+        // Post to all existing and non-existing clients.
     } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
                                                    std::memory_order_acq_rel,
                                                    std::memory_order_acquire));
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index 1b339a0..69b9590 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -67,9 +67,9 @@
     }
 
     std::unique_ptr<BufferHubBuffer> b1;
-    uint64_t b1ClientMask = 0U;
+    uint32_t b1ClientMask = 0U;
     std::unique_ptr<BufferHubBuffer> b2;
-    uint64_t b2ClientMask = 0U;
+    uint32_t b2ClientMask = 0U;
 
 private:
     // Creates b1 and b2 as the clients of the same buffer for testing.
@@ -125,7 +125,7 @@
     auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       kUserMetadataSize);
     int id1 = b1->id();
-    uint64_t bufferStateMask1 = b1->client_state_mask();
+    uint32_t bufferStateMask1 = b1->client_state_mask();
     EXPECT_NE(bufferStateMask1, 0U);
     EXPECT_TRUE(b1->IsValid());
     EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
@@ -148,7 +148,7 @@
     EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
 
     int id2 = b2->id();
-    uint64_t bufferStateMask2 = b2->client_state_mask();
+    uint32_t bufferStateMask2 = b2->client_state_mask();
     EXPECT_NE(bufferStateMask2, 0U);
 
     // These two buffer instances are based on the same physical buffer under the
@@ -340,5 +340,53 @@
     EXPECT_EQ(b2->Release(), 0);
 }
 
+TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) {
+    // 1 producer buffer and 1 consumer buffer initialised in testcase setup.
+    // Test if this set of basic operation succeed:
+    // Producer post three times to the consumer, and released by consumer.
+    for (int i = 0; i < 3; ++i) {
+        ASSERT_EQ(b1->Gain(), 0);
+        ASSERT_EQ(b1->Post(), 0);
+        ASSERT_EQ(b2->Acquire(), 0);
+        ASSERT_EQ(b2->Release(), 0);
+    }
+}
+
+TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) {
+    // Create a poducer buffer and gain.
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+                                    kUserMetadataSize);
+    ASSERT_EQ(b1->Gain(), 0);
+
+    // Create a consumer of the buffer and test if the consumer can acquire the
+    // buffer if producer posts.
+    auto statusOrHandle = b1->Duplicate();
+    ASSERT_TRUE(statusOrHandle);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(statusOrHandle.take()));
+    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+
+    ASSERT_EQ(b1->Post(), 0);
+    EXPECT_EQ(b2->Acquire(), 0);
+}
+
+TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) {
+    // Create a poducer buffer and post.
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+                                    kUserMetadataSize);
+    ASSERT_EQ(b1->Gain(), 0);
+    ASSERT_EQ(b1->Post(), 0);
+
+    // Create a consumer of the buffer and test if the consumer can acquire the
+    // buffer if producer posts.
+    auto statusOrHandle = b1->Duplicate();
+    ASSERT_TRUE(statusOrHandle);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(statusOrHandle.take()));
+    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+
+    EXPECT_EQ(b2->Acquire(), 0);
+}
+
 } // namespace
 } // namespace android
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 1359f4c..487a604 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -361,9 +361,11 @@
   ASSERT_TRUE(p.get() != nullptr);
   ASSERT_EQ(0, p->GainAsync());
   ASSERT_EQ(0, p->Post(LocalHandle()));
-  // Producer state bit is in released state after post. The overall state of
-  // the buffer is also released because there is no consumer of this buffer.
-  ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
+  // Producer state bit is in released state after post, other clients shall be
+  // in posted state although there is no consumer of this buffer yet.
+  ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
+  ASSERT_FALSE(IsBufferReleased(p->buffer_state()));
+  ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
 
   // Gain in released state should succeed.
   LocalHandle invalid_fence;
@@ -450,27 +452,17 @@
   LocalHandle invalid_fence;
 
   // Post the gained buffer before any consumer gets created.
-  // The buffer should be in released state because it is not expected to be
-  // read by any clients.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
+  EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
   EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
-  // Newly created consumer will not be signalled for the posted buffer before
-  // its creation. It cannot acquire the buffer immediately.
+  // Newly created consumer will be signalled for the posted buffer although it
+  // is created after producer posting.
   std::unique_ptr<ConsumerBuffer> c =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-
-  // Producer should be able to gain back and post the buffer
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-
-  // Consumer should be able to pick up the buffer this time.
+  EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
 }
 
 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index 440a59d..889763a 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -94,6 +94,12 @@
     return buffer_state_->load(std::memory_order_acquire);
   };
 
+  // Returns whether the buffer is already released by all current clients.
+  bool is_released() {
+    return (buffer_state() &
+            active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
+  }
+
   // A state mask which is unique to a buffer hub client among all its siblings
   // sharing the same concrete graphic buffer.
   uint32_t client_state_mask() const { return client_state_mask_; }
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index 5274bf2..edfdddf 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -89,13 +89,10 @@
     return -EBUSY;
   }
 
-  // Set the producer client buffer state to released, other clients' buffer
-  // state to posted.
-  uint32_t current_active_clients_bit_mask =
-      active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint32_t updated_buffer_state = current_active_clients_bit_mask &
-                                  (~client_state_mask()) &
-                                  BufferHubDefs::kHighBitsMask;
+  // Set the producer client buffer state to released, that of all other clients
+  // (both existing and non-existing clients) to posted.
+  uint32_t updated_buffer_state =
+      (~client_state_mask()) & BufferHubDefs::kHighBitsMask;
   while (!buffer_state_->compare_exchange_weak(
       current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
       std::memory_order_acquire)) {
@@ -176,7 +173,9 @@
   }
   if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
       BufferHubDefs::AnyClientGained(current_buffer_state) ||
-      (BufferHubDefs::AnyClientPosted(current_buffer_state) &&
+      (BufferHubDefs::AnyClientPosted(
+           current_buffer_state &
+           active_clients_bit_mask_->load(std::memory_order_acquire)) &&
        !gain_posted_buffer)) {
     ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
           current_buffer_state);
@@ -198,7 +197,9 @@
 
     if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
         BufferHubDefs::AnyClientGained(current_buffer_state) ||
-        (BufferHubDefs::AnyClientPosted(current_buffer_state) &&
+        (BufferHubDefs::AnyClientPosted(
+             current_buffer_state &
+             active_clients_bit_mask_->load(std::memory_order_acquire)) &&
          !gain_posted_buffer)) {
       ALOGE(
           "%s: Failed to gain the buffer. The buffer is no longer released. "
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index d1f0564..74b4b3d 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -131,8 +131,8 @@
   bool hung_up() const { return hung_up_; }
 
  protected:
-  BufferHubQueue(pdx::LocalChannelHandle channel);
-  BufferHubQueue(const std::string& endpoint_path);
+  explicit BufferHubQueue(pdx::LocalChannelHandle channel);
+  explicit BufferHubQueue(const std::string& endpoint_path);
 
   // Imports the queue parameters by querying BufferHub for the parameters for
   // this channel.
@@ -458,7 +458,7 @@
  private:
   friend BufferHubQueue;
 
-  ConsumerQueue(pdx::LocalChannelHandle handle);
+  explicit ConsumerQueue(pdx::LocalChannelHandle handle);
 
   // Add a consumer buffer to populate the queue. Once added, a consumer buffer
   // is NOT available to use until the producer side |Post| it. |WaitForBuffers|
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
index ad3f56b..36ab5f6 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
@@ -35,7 +35,7 @@
   }
 
   // Constructs an parcelable contains the channel parcelable.
-  BufferHubQueueParcelable(
+  explicit BufferHubQueueParcelable(
       std::unique_ptr<pdx::ChannelParcelable> channel_parcelable)
       : channel_parcelable_(std::move(channel_parcelable)) {}
 
diff --git a/libs/vr/libdisplay/include/private/dvr/display_protocol.h b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
index eff50ba..3786d1d 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_protocol.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
@@ -60,11 +60,13 @@
   using Base = Flags<Integer>;
   using Type = Integer;
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Flags(const Integer& value) : value_{value} {}
   Flags(const Flags&) = default;
   Flags& operator=(const Flags&) = default;
 
   Integer value() const { return value_; }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator Integer() const { return value_; }
 
   bool IsSet(Integer bits) const { return (value_ & bits) == bits; }
diff --git a/libs/vr/libpdx/private/pdx/channel_handle.h b/libs/vr/libpdx/private/pdx/channel_handle.h
index daa08f4..bd04305 100644
--- a/libs/vr/libpdx/private/pdx/channel_handle.h
+++ b/libs/vr/libpdx/private/pdx/channel_handle.h
@@ -26,7 +26,7 @@
 class ChannelHandleBase {
  public:
   ChannelHandleBase() = default;
-  ChannelHandleBase(const int32_t& value) : value_{value} {}
+  explicit ChannelHandleBase(const int32_t& value) : value_{value} {}
 
   ChannelHandleBase(const ChannelHandleBase&) = delete;
   ChannelHandleBase& operator=(const ChannelHandleBase&) = delete;
diff --git a/libs/vr/libpdx/private/pdx/client.h b/libs/vr/libpdx/private/pdx/client.h
index c35dabd..7e2d55c 100644
--- a/libs/vr/libpdx/private/pdx/client.h
+++ b/libs/vr/libpdx/private/pdx/client.h
@@ -206,7 +206,7 @@
 class Transaction final : public OutputResourceMapper,
                           public InputResourceMapper {
  public:
-  Transaction(Client& client);
+  explicit Transaction(Client& client);
   ~Transaction();
 
   template <typename T>
diff --git a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
index 0421220..43184dd 100644
--- a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
+++ b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
@@ -110,10 +110,10 @@
   using const_iterator = typename BufferType::const_iterator;
 
   BufferWrapper() {}
-  BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
+  explicit BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
   BufferWrapper(const BufferType& buffer, const Allocator& allocator)
       : buffer_(buffer, allocator) {}
-  BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
+  explicit BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
   BufferWrapper(BufferType&& buffer, const Allocator& allocator)
       : buffer_(std::move(buffer), allocator) {}
   BufferWrapper(const BufferWrapper&) = default;
diff --git a/libs/vr/libpdx/private/pdx/rpc/payload.h b/libs/vr/libpdx/private/pdx/rpc/payload.h
index a48a64c..d2df14f 100644
--- a/libs/vr/libpdx/private/pdx/rpc/payload.h
+++ b/libs/vr/libpdx/private/pdx/rpc/payload.h
@@ -83,7 +83,7 @@
                        public MessageWriter,
                        public MessageReader {
  public:
-  ServicePayload(Message& message) : message_(message) {}
+  explicit ServicePayload(Message& message) : message_(message) {}
 
   // MessageWriter
   void* GetNextWriteBufferSection(size_t size) override {
@@ -120,7 +120,8 @@
       MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
   using BufferType = typename ContainerType::BufferType;
 
-  ClientPayload(Transaction& transaction) : transaction_{transaction} {}
+  explicit ClientPayload(Transaction& transaction)
+      : transaction_{transaction} {}
 
   // MessageWriter
   void* GetNextWriteBufferSection(size_t size) override {
diff --git a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
index 1cb85de..88868fe 100644
--- a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
+++ b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
@@ -13,7 +13,7 @@
  public:
   using BaseType = T;
 
-  PointerWrapper(T* pointer) : pointer_(pointer) {}
+  explicit PointerWrapper(T* pointer) : pointer_(pointer) {}
   PointerWrapper(const PointerWrapper&) = default;
   PointerWrapper(PointerWrapper&&) noexcept = default;
   PointerWrapper& operator=(const PointerWrapper&) = default;
diff --git a/libs/vr/libpdx/private/pdx/rpc/serialization.h b/libs/vr/libpdx/private/pdx/rpc/serialization.h
index f12aef1..914ea66 100644
--- a/libs/vr/libpdx/private/pdx/rpc/serialization.h
+++ b/libs/vr/libpdx/private/pdx/rpc/serialization.h
@@ -134,7 +134,7 @@
 
   // ErrorType constructor for generic error codes. Explicitly not explicit,
   // implicit conversion from ErrorCode to ErrorType is desirable behavior.
-  // NOLINTNEXTLINE(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
   ErrorType(ErrorCode error_code) : error_code_(error_code) {}
 
   // ErrorType constructor for encoding type errors.
@@ -148,6 +148,7 @@
   // Evaluates to true if the ErrorType represents an error.
   explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator ErrorCode() const { return error_code_; }
   ErrorCode error_code() const { return error_code_; }
 
@@ -159,6 +160,7 @@
     return unexpected_encoding_.encoding_type;
   }
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator std::string() const {
     std::ostringstream stream;
 
diff --git a/libs/vr/libpdx/private/pdx/service.h b/libs/vr/libpdx/private/pdx/service.h
index d38b174..f5a2d5e 100644
--- a/libs/vr/libpdx/private/pdx/service.h
+++ b/libs/vr/libpdx/private/pdx/service.h
@@ -95,7 +95,7 @@
 class Message : public OutputResourceMapper, public InputResourceMapper {
  public:
   Message();
-  Message(const MessageInfo& info);
+  explicit Message(const MessageInfo& info);
   ~Message();
 
   /*
diff --git a/libs/vr/libpdx/private/pdx/status.h b/libs/vr/libpdx/private/pdx/status.h
index 7e51a52..498dd6d 100644
--- a/libs/vr/libpdx/private/pdx/status.h
+++ b/libs/vr/libpdx/private/pdx/status.h
@@ -11,6 +11,7 @@
 // This is a helper class for constructing Status<T> with an error code.
 struct ErrorStatus {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   ErrorStatus(int error) : error_{error} {}
   int error() const { return error_; }
 
@@ -31,12 +32,14 @@
   // Value copy/move constructors. These are intentionally not marked as
   // explicit to allow direct value returns from functions without having
   // to explicitly wrap them into Status<T>().
-  Status(const T& value) : value_{value} {}        // NOLINT(runtime/explicit)
-  Status(T&& value) : value_{std::move(value)} {}  // NOLINT(runtime/explicit)
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const T& value) : value_{value} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(T&& value) : value_{std::move(value)} {}
 
   // Constructor for storing an error code inside the Status object.
-  Status(const ErrorStatus& error_status)  // NOLINT(runtime/explicit)
-      : error_{error_status.error()} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
 
   // Copy/move constructors. Move constructor leaves |other| object in empty
   // state.
@@ -135,8 +138,8 @@
 class Status<void> {
  public:
   Status() = default;
-  Status(const ErrorStatus& error_status)  // NOLINT(runtime/explicit)
-      : error_{error_status.error()} {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
   void SetValue() { error_ = 0; }
   void SetError(int error) { error_ = error; }
 
diff --git a/libs/vr/libpdx/serialization_tests.cpp b/libs/vr/libpdx/serialization_tests.cpp
index 5ad1047..ee800f6 100644
--- a/libs/vr/libpdx/serialization_tests.cpp
+++ b/libs/vr/libpdx/serialization_tests.cpp
@@ -70,7 +70,7 @@
   FileHandleType fd;
 
   TestTemplateType() {}
-  TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
+  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
 
   bool operator==(const TestTemplateType& other) const {
     return fd.Get() == other.fd.Get();
diff --git a/libs/vr/libpdx/variant_tests.cpp b/libs/vr/libpdx/variant_tests.cpp
index e3520f5..a977fd3 100644
--- a/libs/vr/libpdx/variant_tests.cpp
+++ b/libs/vr/libpdx/variant_tests.cpp
@@ -14,18 +14,22 @@
 namespace {
 
 struct BaseType {
+  // NOLINTNEXTLINE(google-explicit-constructor)
   BaseType(int value) : value(value) {}
   int value;
 };
 
 struct DerivedType : BaseType {
+  // NOLINTNEXTLINE(google-explicit-constructor)
   DerivedType(int value) : BaseType{value} {};
 };
 
 template <typename T>
 class TestType {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   TestType(const T& value) : value_(value) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   TestType(T&& value) : value_(std::move(value)) {}
   TestType(const TestType&) = default;
   TestType(TestType&&) = default;
@@ -43,7 +47,9 @@
 template <typename T>
 class InstrumentType {
  public:
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(const T& value) : value_(value) { constructor_count_++; }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(T&& value) : value_(std::move(value)) { constructor_count_++; }
   InstrumentType(const InstrumentType& other) : value_(other.value_) {
     constructor_count_++;
@@ -51,9 +57,11 @@
   InstrumentType(InstrumentType&& other) : value_(std::move(other.value_)) {
     constructor_count_++;
   }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(const TestType<T>& other) : value_(other.get()) {
     constructor_count_++;
   }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   InstrumentType(TestType<T>&& other) : value_(other.take()) {
     constructor_count_++;
   }
@@ -1101,6 +1109,7 @@
 TEST(Variant, IsConstructible) {
   using ArrayType = const float[3];
   struct ImplicitBool {
+    // NOLINTNEXTLINE(google-explicit-constructor)
     operator bool() const { return true; }
   };
   struct ExplicitBool {
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
index f72dabc..5c9e74c 100644
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
@@ -82,7 +82,7 @@
 class SchedStats {
  public:
   SchedStats() : SchedStats(gettid()) {}
-  SchedStats(pid_t task_id) : task_id_(task_id) {}
+  explicit SchedStats(pid_t task_id) : task_id_(task_id) {}
   SchedStats(const SchedStats&) = default;
   SchedStats& operator=(const SchedStats&) = default;
 
@@ -379,7 +379,7 @@
  private:
   friend BASE;
 
-  BenchmarkService(std::unique_ptr<Endpoint> endpoint)
+  explicit BenchmarkService(std::unique_ptr<Endpoint> endpoint)
       : BASE("BenchmarkService", std::move(endpoint)),
         send_buffer(kMaxMessageSize),
         receive_buffer(kMaxMessageSize) {}
@@ -492,7 +492,7 @@
  private:
   friend BASE;
 
-  BenchmarkClient(const std::string& service_path)
+  explicit BenchmarkClient(const std::string& service_path)
       : BASE(ClientChannelFactory::Create(service_path),
              ProgramOptions.timeout) {}
 
diff --git a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
index 81bb17b..3ebab86 100644
--- a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
+++ b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
@@ -41,7 +41,8 @@
  private:
   friend BASE;
 
-  ServiceUtility(const std::string& endpoint_path, int* error = nullptr)
+  explicit ServiceUtility(const std::string& endpoint_path,
+                          int* error = nullptr)
       : BASE(ClientChannelFactory::Create(endpoint_path), 0) {
     if (error)
       *error = Client::error();
diff --git a/libs/vr/libpdx_uds/client_channel_tests.cpp b/libs/vr/libpdx_uds/client_channel_tests.cpp
index 1560030..c9c5d15 100644
--- a/libs/vr/libpdx_uds/client_channel_tests.cpp
+++ b/libs/vr/libpdx_uds/client_channel_tests.cpp
@@ -45,7 +45,7 @@
 
 class TestService : public ServiceBase<TestService> {
  public:
-  TestService(std::unique_ptr<Endpoint> endpoint)
+  explicit TestService(std::unique_ptr<Endpoint> endpoint)
       : ServiceBase{"TestService", std::move(endpoint)} {}
 
   Status<void> HandleMessage(Message& message) override {
@@ -78,7 +78,7 @@
 
 class TestServiceRunner {
  public:
-  TestServiceRunner(LocalHandle channel_socket) {
+  explicit TestServiceRunner(LocalHandle channel_socket) {
     auto endpoint = Endpoint::CreateFromSocketFd(LocalHandle{});
     endpoint->RegisterNewChannelForTests(std::move(channel_socket));
     service_ = TestService::Create(std::move(endpoint));
diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
index 63b5b10..704a569 100644
--- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h
+++ b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
@@ -57,7 +57,7 @@
 
 class SendPayload : public MessageWriter, public OutputResourceMapper {
  public:
-  SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
+  explicit SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
   Status<void> Send(const BorrowedHandle& socket_fd);
   Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred,
                     const iovec* data_vec = nullptr, size_t vec_count = 0);
@@ -85,7 +85,8 @@
 
 class ReceivePayload : public MessageReader, public InputResourceMapper {
  public:
-  ReceivePayload(RecvInterface* receiver = nullptr) : receiver_{receiver} {}
+  explicit ReceivePayload(RecvInterface* receiver = nullptr)
+      : receiver_{receiver} {}
   Status<void> Receive(const BorrowedHandle& socket_fd);
   Status<void> Receive(const BorrowedHandle& socket_fd, ucred* cred);
 
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
index 01ebf65..50fc484 100644
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
@@ -117,7 +117,7 @@
   // This class must be instantiated using Create() static methods above.
   Endpoint(const std::string& endpoint_path, bool blocking,
            bool use_init_socket_fd = true);
-  Endpoint(LocalHandle socket_fd);
+  explicit Endpoint(LocalHandle socket_fd);
 
   void Init(LocalHandle socket_fd);
 
diff --git a/libs/vr/libpdx_uds/remote_method_tests.cpp b/libs/vr/libpdx_uds/remote_method_tests.cpp
index 3f25776..4f0670e 100644
--- a/libs/vr/libpdx_uds/remote_method_tests.cpp
+++ b/libs/vr/libpdx_uds/remote_method_tests.cpp
@@ -94,7 +94,7 @@
   FileHandleType fd;
 
   TestTemplateType() {}
-  TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
+  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
 
  private:
   PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
@@ -328,7 +328,7 @@
  private:
   friend BASE;
 
-  TestClient(LocalChannelHandle channel_handle)
+  explicit TestClient(LocalChannelHandle channel_handle)
       : BASE{android::pdx::uds::ClientChannel::Create(
             std::move(channel_handle))} {}
   TestClient()
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 6d259bd..e1240d6 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -104,7 +104,7 @@
 class TraceArgs {
  public:
   template <typename... Args>
-  TraceArgs(const char* format, Args&&... args) {
+  explicit TraceArgs(const char* format, Args&&... args) {
     std::array<char, 1024> buffer;
     snprintf(buffer.data(), buffer.size(), format, std::forward<Args>(args)...);
     atrace_begin(ATRACE_TAG, buffer.data());
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index 6c25b3e..db0d6a7 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -195,7 +195,7 @@
     AcquiredBuffer acquired_buffer;
     pdx::LocalHandle release_fence;
 
-    SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
+    explicit SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
         : surface(surface) {}
 
     // Attempts to acquire a new buffer from the surface and return a tuple with
diff --git a/libs/vr/libvrflinger/hwc_types.h b/libs/vr/libvrflinger/hwc_types.h
index cbf636c..8b5c3b3 100644
--- a/libs/vr/libvrflinger/hwc_types.h
+++ b/libs/vr/libvrflinger/hwc_types.h
@@ -116,19 +116,24 @@
   Wrapper(const Wrapper&) = default;
 
   // Implicit conversion from ValueType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(ValueType value) : value(value) {}
 
   // Implicit conversion from BaseType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(BaseType value) : value(static_cast<ValueType>(value)) {}
 
   // Implicit conversion from an enum type of the same underlying type.
   template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Wrapper(const T& value) : value(static_cast<ValueType>(value)) {}
 
   // Implicit conversion to BaseType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator BaseType() const { return static_cast<BaseType>(value); }
 
   // Implicit conversion to ValueType.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator ValueType() const { return value; }
 
   template <typename T, typename = EnableIfMatchingEnum<T, ValueType>>
@@ -275,8 +280,10 @@
 struct Color final {
   Color(const Color&) = default;
   Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Color(hwc_color_t color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
 
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator hwc_color_t() const { return {r, g, b, a}; }
 
   uint8_t r __attribute__((aligned(1)));
diff --git a/libs/vr/libvrflinger/include/dvr/vr_flinger.h b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
index c740dde..ae52076 100644
--- a/libs/vr/libvrflinger/include/dvr/vr_flinger.h
+++ b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
@@ -49,7 +49,8 @@
   // Needs to be a separate class for binder's ref counting
   class PersistentVrStateCallback : public BnPersistentVrStateCallbacks {
    public:
-    PersistentVrStateCallback(RequestDisplayCallback request_display_callback)
+    explicit PersistentVrStateCallback(
+        RequestDisplayCallback request_display_callback)
         : request_display_callback_(request_display_callback) {}
     void onPersistentVrStateChanged(bool enabled) override;
    private:
diff --git a/libs/vr/libvrsensor/include/private/dvr/latency_model.h b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
index 40b4638..bf0e687 100644
--- a/libs/vr/libvrsensor/include/private/dvr/latency_model.h
+++ b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
@@ -10,7 +10,7 @@
 // window_size measurements and return their average after that.
 class LatencyModel {
  public:
-  LatencyModel(size_t window_size);
+  explicit LatencyModel(size_t window_size);
   ~LatencyModel() = default;
 
   void AddLatency(int64_t latency_ns);
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 297e0c4..00caff2 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -106,7 +106,7 @@
             .flags = ANDROID_DLEXT_USE_NAMESPACE,
             .library_namespace = ns,
     };
-    void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+    void* so = android_dlopen_ext("libGLESv2_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
     angleGetDisplayPlatform =
             reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
 
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 2663812..54796a2 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -14,10 +14,17 @@
  * limitations under the License.
  */
 
+#include <iomanip>
+#include <sstream>
+
 #include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubService.h>
 #include <cutils/native_handle.h>
 #include <log/log.h>
+#include <system/graphics-base.h>
+
+using ::android::BufferHubDefs::MetadataHeader;
+using ::android::hardware::Void;
 
 namespace android {
 namespace frameworks {
@@ -25,8 +32,6 @@
 namespace V1_0 {
 namespace implementation {
 
-using hardware::Void;
-
 Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
                                               const uint32_t userMetadataSize,
                                               allocateBuffer_cb _hidl_cb) {
@@ -124,6 +129,138 @@
     return Void();
 }
 
+Return<void> BufferHubService::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
+    if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
+        ALOGE("%s: missing fd for writing.", __FUNCTION__);
+        return Void();
+    }
+
+    FILE* out = fdopen(dup(fd->data[0]), "w");
+
+    if (args.size() != 0) {
+        fprintf(out,
+                "Note: lshal bufferhub currently does not support args. Input arguments are "
+                "ignored.\n");
+    }
+
+    std::ostringstream stream;
+
+    // Get the number of clients of each buffer.
+    // Map from bufferId to bufferNode_clientCount pair.
+    std::map<int, std::pair<const std::shared_ptr<BufferNode>, uint32_t>> clientCount;
+    {
+        std::lock_guard<std::mutex> lock(mClientSetMutex);
+        for (auto iter = mClientSet.begin(); iter != mClientSet.end(); ++iter) {
+            sp<BufferClient> client = iter->promote();
+            if (client != nullptr) {
+                const std::shared_ptr<BufferNode> node = client->getBufferNode();
+                auto mapIter = clientCount.find(node->id());
+                if (mapIter != clientCount.end()) {
+                    ++mapIter->second.second;
+                } else {
+                    clientCount.emplace(node->id(),
+                                        std::pair<std::shared_ptr<BufferNode>, uint32_t>(node, 1U));
+                }
+            }
+        }
+    }
+
+    stream << "Active Buffers:\n";
+    stream << std::right;
+    stream << std::setw(6) << "Id";
+    stream << " ";
+    stream << std::setw(9) << "Clients";
+    stream << " ";
+    stream << std::setw(14) << "Geometry";
+    stream << " ";
+    stream << std::setw(6) << "Format";
+    stream << " ";
+    stream << std::setw(10) << "Usage";
+    stream << " ";
+    stream << std::setw(10) << "State";
+    stream << " ";
+    stream << std::setw(10) << "Index";
+    stream << std::endl;
+
+    for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) {
+        const std::shared_ptr<BufferNode> node = std::move(iter->second.first);
+        const uint32_t clientCount = iter->second.second;
+        AHardwareBuffer_Desc desc = node->buffer_desc();
+
+        MetadataHeader* metadataHeader =
+                const_cast<BufferHubMetadata*>(&node->metadata())->metadata_header();
+        const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
+        const uint64_t index = metadataHeader->queue_index;
+
+        stream << std::right;
+        stream << std::setw(6) << /*Id=*/node->id();
+        stream << " ";
+        stream << std::setw(9) << /*Clients=*/clientCount;
+        stream << " ";
+        if (desc.format == HAL_PIXEL_FORMAT_BLOB) {
+            std::string size = std::to_string(desc.width) + " B";
+            stream << std::setw(14) << /*Geometry=*/size;
+        } else {
+            std::string dimensions = std::to_string(desc.width) + "x" +
+                    std::to_string(desc.height) + "x" + std::to_string(desc.layers);
+            stream << std::setw(14) << /*Geometry=*/dimensions;
+        }
+        stream << " ";
+        stream << std::setw(6) << /*Format=*/desc.format;
+        stream << " ";
+        stream << "0x" << std::hex << std::setfill('0');
+        stream << std::setw(8) << /*Usage=*/desc.usage;
+        stream << std::dec << std::setfill(' ');
+        stream << " ";
+        stream << "0x" << std::hex << std::setfill('0');
+        stream << std::setw(8) << /*State=*/state;
+        stream << " ";
+        stream << std::setw(8) << /*Index=*/index;
+        stream << std::endl;
+    }
+
+    stream << std::endl;
+
+    // Get the number of tokens of each buffer.
+    // Map from bufferId to tokenCount
+    std::map<int, uint32_t> tokenCount;
+    {
+        std::lock_guard<std::mutex> lock(mTokenMapMutex);
+        for (auto iter = mTokenMap.begin(); iter != mTokenMap.end(); ++iter) {
+            sp<BufferClient> client = iter->second.promote();
+            if (client != nullptr) {
+                const std::shared_ptr<BufferNode> node = client->getBufferNode();
+                auto mapIter = tokenCount.find(node->id());
+                if (mapIter != tokenCount.end()) {
+                    ++mapIter->second;
+                } else {
+                    tokenCount.emplace(node->id(), 1U);
+                }
+            }
+        }
+    }
+
+    stream << "Unused Tokens:\n";
+    stream << std::right;
+    stream << std::setw(8) << "Buffer Id";
+    stream << " ";
+    stream << std::setw(6) << "Tokens";
+    stream << std::endl;
+
+    for (auto iter = tokenCount.begin(); iter != tokenCount.end(); ++iter) {
+        stream << std::right;
+        stream << std::setw(8) << /*Buffer Id=*/iter->first;
+        stream << " ";
+        stream << std::setw(6) << /*Tokens=*/iter->second;
+        stream << std::endl;
+    }
+
+    fprintf(out, "%s", stream.str().c_str());
+
+    fclose(out);
+    return Void();
+}
+
 hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
     uint32_t token;
     std::lock_guard<std::mutex> lock(mTokenMapMutex);
diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h
index f2c8ef8..255f329 100644
--- a/services/bufferhub/include/bufferhub/BufferHubService.h
+++ b/services/bufferhub/include/bufferhub/BufferHubService.h
@@ -32,6 +32,8 @@
 namespace implementation {
 
 using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
 using hardware::Return;
 using hardware::graphics::common::V1_2::HardwareBufferDescription;
 
@@ -42,6 +44,8 @@
                                 allocateBuffer_cb _hidl_cb) override;
     Return<void> importBuffer(const hidl_handle& tokenHandle, importBuffer_cb _hidl_cb) override;
 
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
+
     // Non-binder functions
     // Internal help function for IBufferClient::duplicate.
     hidl_handle registerToken(const wp<BufferClient>& client);
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 0d8d34f..843eb37 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -22,6 +22,7 @@
 
     shared_libs: [
         "libinputflinger_base",
+        "libinputreporter",
         "libinputreader",
         "libbase",
         "libbinder",
@@ -125,6 +126,35 @@
     ],
 }
 
+cc_library_shared {
+    name: "libinputreporter",
+
+    srcs: [
+        "InputReporter.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+    ],
+
+    header_libs: [
+        "libinputflinger_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libinputflinger_headers",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+}
+
 subdirs = [
     "host",
     "tests",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 7fa9cb6..7997928 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -257,6 +257,7 @@
     mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
     mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
     mLooper = new Looper(false);
+    mReporter = createInputReporter();
 
     mKeyRepeatState.lastKeyEntry = nullptr;
 
@@ -841,6 +842,7 @@
     if (*dropReason != DROP_REASON_NOT_DROPPED) {
         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+        mReporter->reportDroppedKey(entry->sequenceNum);
         return true;
     }
 
@@ -2384,7 +2386,8 @@
             }
 
             InputTarget target;
-            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
+            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
+                    connection->inputChannel->getToken());
             if (windowHandle != nullptr) {
                 const InputWindowInfo* windowInfo = windowHandle->getInfo();
                 target.xOffset = -windowInfo->frameLeft;
@@ -3022,13 +3025,13 @@
 }
 
 sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
-        const sp<InputChannel>& inputChannel) const {
+        const sp<IBinder>& windowHandleToken) const {
     for (auto& it : mWindowHandlesByDisplay) {
         const Vector<sp<InputWindowHandle>> windowHandles = it.second;
         size_t numWindows = windowHandles.size();
         for (size_t i = 0; i < numWindows; i++) {
             const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
-            if (windowHandle->getToken() == inputChannel->getToken()) {
+            if (windowHandle->getToken() == windowHandleToken) {
                 return windowHandle;
             }
         }
@@ -3373,27 +3376,30 @@
 
 bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
         const sp<InputChannel>& toChannel) {
+    return transferTouchFocus(fromChannel->getToken(), toChannel->getToken());
+}
+
+bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    if (fromToken == toToken) {
 #if DEBUG_FOCUS
-    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
-            fromChannel->getName().c_str(), toChannel->getName().c_str());
+        ALOGD("Trivial transfer to same window.");
 #endif
+        return true;
+    }
+
     { // acquire lock
         AutoMutex _l(mLock);
 
-        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
-        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
+        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
+        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
+#if DEBUG_FOCUS
+        ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
+            fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
+#endif
         if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
-#if DEBUG_FOCUS
-            ALOGD("Cannot transfer focus because from or to window not found.");
-#endif
+            ALOGW("Cannot transfer focus because from or to window not found.");
             return false;
         }
-        if (fromWindowHandle == toWindowHandle) {
-#if DEBUG_FOCUS
-            ALOGD("Trivial transfer to same window.");
-#endif
-            return true;
-        }
         if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
 #if DEBUG_FOCUS
             ALOGD("Cannot transfer focus because windows are on different displays.");
@@ -3431,6 +3437,9 @@
             return false;
         }
 
+
+        sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
+        sp<InputChannel> toChannel = getInputChannelLocked(toToken);
         ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
         ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
         if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
@@ -4025,6 +4034,10 @@
 bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
         DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
     if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
+        if (!handled) {
+            // Report the key as unhandled, since the fallback was not handled.
+            mReporter->reportUnhandledKey(keyEntry->sequenceNum);
+        }
         return false;
     }
 
@@ -4192,6 +4205,9 @@
 #if DEBUG_OUTBOUND_EVENT_DETAILS
             ALOGD("Unhandled key event: No fallback key.");
 #endif
+
+            // Report the key as unhandled, since there is no fallback key.
+            mReporter->reportUnhandledKey(keyEntry->sequenceNum);
         }
     }
     return false;
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 05b5dad..970632e 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -37,6 +37,7 @@
 #include <unordered_map>
 
 #include "InputListener.h"
+#include "InputReporter.h"
 
 
 namespace android {
@@ -342,11 +343,12 @@
      */
     virtual void setInputFilterEnabled(bool enabled) = 0;
 
-    /* Transfers touch focus from the window associated with one channel to the
-     * window associated with the other channel.
+    /* Transfers touch focus from one window to another window.
      *
      * Returns true on success.  False if the window did not actually have touch focus.
      */
+    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
+
     virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
             const sp<InputChannel>& toChannel) = 0;
 
@@ -413,6 +415,7 @@
     virtual void setInputDispatchMode(bool enabled, bool frozen);
     virtual void setInputFilterEnabled(bool enabled);
 
+    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
     virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
             const sp<InputChannel>& toChannel);
 
@@ -994,7 +997,7 @@
     std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay;
     // Get window handles by display, return an empty vector if not found.
     Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const;
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
+    sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const;
     sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const;
     bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
 
@@ -1186,6 +1189,8 @@
     void traceInboundQueueLengthLocked();
     void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
     void traceWaitQueueLengthLocked(const sp<Connection>& connection);
+
+    sp<InputReporter> mReporter;
 };
 
 /* Enqueues and dispatches input events, endlessly. */
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 15d8070..1d7ea00 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,6 +111,10 @@
     }
 }
 
+void InputManager::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    mDispatcher->transferTouchFocus(fromToken, toToken);
+}
+
 // Used by tests only.
 void InputManager::registerInputChannel(const sp<InputChannel>& channel) {
     IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 8f7551e..ab309b1 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -91,6 +91,7 @@
     virtual sp<InputDispatcherInterface> getDispatcher();
 
     virtual void setInputWindows(const Vector<InputWindowInfo>& handles);
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 
     virtual void registerInputChannel(const sp<InputChannel>& channel);
     virtual void unregisterInputChannel(const sp<InputChannel>& channel);
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/services/inputflinger/InputReporter.cpp
similarity index 60%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to services/inputflinger/InputReporter.cpp
index fbfbc3f..cf4220f 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/services/inputflinger/InputReporter.cpp
@@ -14,24 +14,22 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include "InputReporter.h"
 
 namespace android {
-namespace renderengine {
-namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
+// --- InputReporter ---
 
-Image::Image() = default;
-Image::~Image() = default;
+void InputReporter::reportUnhandledKey(uint32_t sequenceNum) {
+  // do nothing
+}
 
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
+void InputReporter::reportDroppedKey(uint32_t sequenceNum) {
+  // do nothing
+}
 
-} // namespace mock
-} // namespace renderengine
+sp<InputReporter> createInputReporter() {
+  return new InputReporter();
+}
+
 } // namespace android
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 82ff089..9d0be95 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -40,6 +40,7 @@
 
     virtual status_t dump(int fd, const Vector<String16>& args);
     void setInputWindows(const Vector<InputWindowInfo>&) {}
+    void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}
     void registerInputChannel(const sp<InputChannel>&) {}
     void unregisterInputChannel(const sp<InputChannel>&) {}
 
diff --git a/services/inputflinger/include/InputReporter.h b/services/inputflinger/include/InputReporter.h
new file mode 100644
index 0000000..c86dcda
--- /dev/null
+++ b/services/inputflinger/include/InputReporter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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 _UI_INPUT_REPORTER_H
+#define _UI_INPUT_REPORTER_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+/*
+ * The interface used by the InputDispatcher to report information about input events after
+ * it is sent to the application, such as if a key is unhandled or dropped.
+ */
+class InputReporter: public virtual RefBase {
+protected:
+    virtual ~InputReporter() { }
+
+public:
+    // Report a key that was not handled by the system or apps.
+    // A key event is unhandled if:
+    //   - The event was not handled and there is no fallback key; or
+    //   - The event was not handled and it has a fallback key,
+    //       but the fallback key was not handled.
+    virtual void reportUnhandledKey(uint32_t sequenceNum);
+
+    // Report a key that was dropped by InputDispatcher.
+    // A key can be dropped for several reasons. See the enum
+    // InputDispatcher::DropReason for details.
+    virtual void reportDroppedKey(uint32_t sequenceNum);
+};
+
+/*
+ * Factory method for InputReporter.
+ */
+sp<InputReporter> createInputReporter();
+
+} // namespace android
+
+#endif // _UI_INPUT_REPORTER_H
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 0c1ea44..3dee0c0 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -1,7 +1,6 @@
 cc_defaults {
     name: "surfaceflinger_defaults",
     cflags: [
-        "-DLOG_TAG=\"SurfaceFlinger\"",
         "-Wall",
         "-Werror",
         "-Wformat",
@@ -15,6 +14,7 @@
     name: "libsurfaceflinger_defaults",
     defaults: ["surfaceflinger_defaults"],
     cflags: [
+        "-DLOG_TAG=\"SurfaceFlinger\"",
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
     ],
@@ -57,6 +57,7 @@
         "libutils",
     ],
     static_libs: [
+        "libcompositionengine",
         "librenderengine",
         "libserviceutils",
         "libtrace_proto",
@@ -69,6 +70,7 @@
         "android.hardware.graphics.composer@2.3-command-buffer",
     ],
     export_static_lib_headers: [
+        "libcompositionengine",
         "librenderengine",
         "libserviceutils",
     ],
@@ -171,6 +173,9 @@
 cc_defaults {
     name: "libsurfaceflinger_binary",
     defaults: ["surfaceflinger_defaults"],
+    cflags: [
+        "-DLOG_TAG=\"SurfaceFlinger\"",
+    ],
     whole_static_libs: [
         "libsigchain",
     ],
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 0a3be71..4e4d7dd 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -396,7 +396,6 @@
     }
 
     // Capture the old state of the layer for comparisons later
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     const bool oldOpacity = isOpaque(s);
     sp<GraphicBuffer> oldBuffer = mActiveBuffer;
@@ -503,7 +502,7 @@
 
     // FIXME: postedRegion should be dirty & bounds
     // transform the dirty region to window-manager space
-    return getTransformLocked().transform(Region(getBufferSize(s)));
+    return getTransform().transform(Region(getBufferSize(s)));
 }
 
 // transaction
@@ -551,7 +550,7 @@
 
 // h/w composer set-up
 bool BufferLayer::allTransactionsSignaled() {
-    auto headFrameNumber = getHeadFrameNumberLocked();
+    auto headFrameNumber = getHeadFrameNumber();
     bool matchingFramesFound = false;
     bool allTransactionsApplied = true;
     Mutex::Autolock lock(mLocalSyncPointMutex);
@@ -604,7 +603,6 @@
 
 void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
     ATRACE_CALL();
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
 
     computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
@@ -623,9 +621,9 @@
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
-    const Rect bounds{computeBoundsLocked()}; // Rounds from FloatRect
+    const Rect bounds{computeBounds()}; // Rounds from FloatRect
 
-    ui::Transform t = getTransformLocked();
+    ui::Transform t = getTransform();
     Rect win = bounds;
     const int bufferWidth = getBufferSize(s).getWidth();
     const int bufferHeight = getBufferSize(s).getHeight();
@@ -644,7 +642,7 @@
     texCoords[2] = vec2(right, 1.0f - bottom);
     texCoords[3] = vec2(right, 1.0f - top);
 
-    const auto roundedCornerState = getRoundedCornerStateLocked();
+    const auto roundedCornerState = getRoundedCornerState();
     const auto cropRect = roundedCornerState.cropRect;
     setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -666,12 +664,7 @@
 }
 
 uint64_t BufferLayer::getHeadFrameNumber() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getHeadFrameNumberLocked();
-}
-
-uint64_t BufferLayer::getHeadFrameNumberLocked() const {
-    if (hasFrameUpdateLocked()) {
+    if (hasFrameUpdate()) {
         return getFrameNumber();
     } else {
         return mCurrentFrameNumber;
@@ -698,7 +691,7 @@
         std::swap(bufWidth, bufHeight);
     }
 
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
         if (invTransform & ui::Transform::ROT_90) {
             std::swap(bufWidth, bufHeight);
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 98ae286..be16cf5 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -69,7 +69,7 @@
     bool isOpaque(const Layer::State& s) const override;
 
     // isVisible - true if this layer is visible, false otherwise
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    bool isVisible() const override;
 
     // isProtected - true if the layer may contain protected content in the
     // GRALLOC_USAGE_PROTECTED sense.
@@ -91,7 +91,7 @@
     bool onPostComposition(const std::optional<DisplayId>& displayId,
                            const std::shared_ptr<FenceTime>& glDoneFence,
                            const std::shared_ptr<FenceTime>& presentFence,
-                           const CompositorTiming& compositorTiming) override EXCLUDES(mStateMutex);
+                           const CompositorTiming& compositorTiming) override;
 
     // latchBuffer - called each time the screen is redrawn and returns whether
     // the visible regions need to be recomputed (this is a fairly heavy
@@ -101,13 +101,13 @@
     // releaseFence will be populated with a native fence that fires when
     // composition has completed.
     Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                       const sp<Fence>& releaseFence) override EXCLUDES(mStateMutex);
+                       const sp<Fence>& releaseFence) override;
 
     bool isBufferLatched() const override { return mRefreshPending; }
 
     void notifyAvailableFrames() override;
 
-    bool hasReadyFrame() const override EXCLUDES(mStateMutex);
+    bool hasReadyFrame() const override;
 
     // Returns the current scaling mode, unless mOverrideScalingMode
     // is set, in which case, it returns mOverrideScalingMode
@@ -118,24 +118,19 @@
     // Functions that must be implemented by derived classes
     // -----------------------------------------------------------------------
 private:
-    virtual bool fenceHasSignaled() const EXCLUDES(mStateMutex) = 0;
+    virtual bool fenceHasSignaled() const = 0;
 
     virtual nsecs_t getDesiredPresentTime() = 0;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getCurrentFenceTimeLocked();
-    }
-
-    virtual std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const REQUIRES(mStateMutex) = 0;
+    virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
 
     virtual void getDrawingTransformMatrix(float *matrix) = 0;
-    virtual uint32_t getDrawingTransform() const REQUIRES(mStateMutex) = 0;
-    virtual ui::Dataspace getDrawingDataSpace() const REQUIRES(mStateMutex) = 0;
-    virtual Rect getDrawingCrop() const REQUIRES(mStateMutex) = 0;
+    virtual uint32_t getDrawingTransform() const = 0;
+    virtual ui::Dataspace getDrawingDataSpace() const = 0;
+    virtual Rect getDrawingCrop() const = 0;
     virtual uint32_t getDrawingScalingMode() const = 0;
-    virtual Region getDrawingSurfaceDamage() const EXCLUDES(mStateMutex) = 0;
-    virtual const HdrMetadata& getDrawingHdrMetadata() const EXCLUDES(mStateMutex) = 0;
-    virtual int getDrawingApi() const EXCLUDES(mStateMutex) = 0;
+    virtual Region getDrawingSurfaceDamage() const = 0;
+    virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
+    virtual int getDrawingApi() const = 0;
     virtual PixelFormat getPixelFormat() const = 0;
 
     virtual uint64_t getFrameNumber() const = 0;
@@ -143,21 +138,20 @@
     virtual bool getAutoRefresh() const = 0;
     virtual bool getSidebandStreamChanged() const = 0;
 
-    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions)
-            EXCLUDES(mStateMutex) = 0;
+    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0;
 
-    virtual bool hasFrameUpdateLocked() const REQUIRES(mStateMutex) = 0;
+    virtual bool hasFrameUpdate() const = 0;
 
     virtual void setFilteringEnabled(bool enabled) = 0;
 
-    virtual status_t bindTextureImage() EXCLUDES(mStateMutex) = 0;
+    virtual status_t bindTextureImage() = 0;
     virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                                    const sp<Fence>& flushFence) REQUIRES(mStateMutex) = 0;
+                                    const sp<Fence>& flushFence) = 0;
 
-    virtual status_t updateActiveBuffer() REQUIRES(mStateMutex) = 0;
+    virtual status_t updateActiveBuffer() = 0;
     virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
 
-    virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0;
+    virtual void setHwcLayerBuffer(DisplayId displayId) = 0;
 
 protected:
     // Loads the corresponding system property once per process
@@ -166,15 +160,10 @@
     // Check all of the local sync points to ensure that all transactions
     // which need to have been applied prior to the frame which is about to
     // be latched have signaled
-    bool allTransactionsSignaled() REQUIRES(mStateMutex);
+    bool allTransactionsSignaled();
 
     static bool getOpacityForFormat(uint32_t format);
 
-    bool hasFrameUpdate() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return hasFrameUpdateLocked();
-    }
-
     // from GLES
     const uint32_t mTextureName;
 
@@ -183,12 +172,9 @@
     bool needsFiltering(const RenderArea& renderArea) const;
 
     // drawing
-    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const
-            EXCLUDES(mStateMutex);
+    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
 
-    uint64_t getHeadFrameNumber() const EXCLUDES(mStateMutex);
-
-    uint64_t getHeadFrameNumberLocked() const REQUIRES(mStateMutex);
+    uint64_t getHeadFrameNumber() const;
 
     uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
@@ -200,7 +186,7 @@
 
     bool mRefreshPending{false};
 
-    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
+    Rect getBufferSize(const State& s) const override;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 3341b98..5a61122 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -51,7 +51,7 @@
     return history;
 }
 
-bool BufferQueueLayer::getTransformToDisplayInverseLocked() const {
+bool BufferQueueLayer::getTransformToDisplayInverse() const {
     return mConsumer->getTransformToDisplayInverse();
 }
 
@@ -131,7 +131,7 @@
     return mConsumer->getTimestamp();
 }
 
-std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTimeLocked() const {
+std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
     return mConsumer->getCurrentFenceTime();
 }
 
@@ -192,7 +192,6 @@
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     bool sidebandStreamChanged = true;
-    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
@@ -201,15 +200,15 @@
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
-
         recomputeVisibleRegions = true;
+
         const State& s(getDrawingState());
-        return getTransformLocked().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
+        return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
     }
     return {};
 }
 
-bool BufferQueueLayer::hasFrameUpdateLocked() const {
+bool BufferQueueLayer::hasFrameUpdate() const {
     return mQueuedFrames > 0;
 }
 
@@ -229,18 +228,16 @@
     // buffer mode.
     bool queuedBuffer = false;
     const int32_t layerID = getSequence();
-    status_t updateResult;
-    LayerRejecter r(mState.drawing, getCurrentState(), recomputeVisibleRegions,
+    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
-                    getTransformToDisplayInverseLocked(), mFreezeGeometryUpdates);
+                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);
 
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
-
-    updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                             mLastFrameNumberReceived, releaseFence);
-
+    status_t updateResult =
+            mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
+                                      mLastFrameNumberReceived, releaseFence);
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index f9da044..ae0b705 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -44,7 +44,7 @@
 
     std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
 
-    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
+    bool getTransformToDisplayInverse() const override;
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -64,12 +64,12 @@
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
-    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
-    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
+    uint32_t getDrawingTransform() const override;
+    ui::Dataspace getDrawingDataSpace() const override;
+    Rect getDrawingCrop() const override;
     uint32_t getDrawingScalingMode() const override;
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
@@ -81,18 +81,17 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
-            EXCLUDES(mStateMutex);
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
 
-    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
+    bool hasFrameUpdate() const override;
 
     void setFilteringEnabled(bool enabled) override;
 
     status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
+                            const sp<Fence>& releaseFence) override;
 
-    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
+    status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
     void setHwcLayerBuffer(DisplayId displayId) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0e46928..e0d9d23 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -72,31 +72,30 @@
 }
 
 bool BufferStateLayer::willPresentCurrentTransaction() const {
-    Mutex::Autolock lock(mStateMutex);
     // Returns true if the most recent Transaction applied to CurrentState will be presented.
     return getSidebandStreamChanged() || getAutoRefresh() ||
-            (mState.current.modified && mState.current.buffer != nullptr);
+            (mCurrentState.modified && mCurrentState.buffer != nullptr);
 }
 
-bool BufferStateLayer::getTransformToDisplayInverseLocked() const {
-    return mState.current.transformToDisplayInverse;
+bool BufferStateLayer::getTransformToDisplayInverse() const {
+    return mCurrentState.transformToDisplayInverse;
 }
 
-void BufferStateLayer::pushPendingStateLocked() {
-    if (!mState.current.modified) {
+void BufferStateLayer::pushPendingState() {
+    if (!mCurrentState.modified) {
         return;
     }
-    mState.pending.push_back(mState.current);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.push_back(mCurrentState);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
-    const bool stateUpdateAvailable = !mState.pending.empty();
-    while (!mState.pending.empty()) {
+    const bool stateUpdateAvailable = !mPendingStates.empty();
+    while (!mPendingStates.empty()) {
         popPendingState(stateToCommit);
     }
-    mCurrentStateModified = stateUpdateAvailable && mState.current.modified;
-    mState.current.modified = false;
+    mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
+    mCurrentState.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -106,31 +105,28 @@
 }
 
 bool BufferStateLayer::setTransform(uint32_t transform) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.transform == transform) return false;
-    mState.current.sequence++;
-    mState.current.transform = transform;
-    mState.current.modified = true;
+    if (mCurrentState.transform == transform) return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform = transform;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false;
-    mState.current.sequence++;
-    mState.current.transformToDisplayInverse = transformToDisplayInverse;
-    mState.current.modified = true;
+    if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
+    mCurrentState.sequence++;
+    mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setCrop(const Rect& crop) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.crop == crop) return false;
-    mState.current.sequence++;
-    mState.current.crop = crop;
-    mState.current.modified = true;
+    if (mCurrentState.crop == crop) return false;
+    mCurrentState.sequence++;
+    mCurrentState.crop = crop;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -141,94 +137,96 @@
     int w = frame.getWidth();
     int h = frame.getHeight();
 
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y &&
-        mState.current.active.w == w && mState.current.active.h == h) {
+    if (x < 0) {
+        x = 0;
+        w = frame.right;
+    }
+
+    if (y < 0) {
+        y = 0;
+        h = frame.bottom;
+    }
+
+    if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
+        mCurrentState.active.w == w && mCurrentState.active.h == h) {
         return false;
     }
 
     if (!frame.isValid()) {
         x = y = w = h = 0;
     }
-    mState.current.active.transform.set(x, y);
-    mState.current.active.w = w;
-    mState.current.active.h = h;
+    mCurrentState.active.transform.set(x, y);
+    mCurrentState.active.w = w;
+    mCurrentState.active.h = h;
 
-    mState.current.sequence++;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.buffer) {
+    if (mCurrentState.buffer) {
         mReleasePreviousBuffer = true;
     }
 
-    mState.current.sequence++;
-    mState.current.buffer = buffer;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.buffer = buffer;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
-    Mutex::Autolock lock(mStateMutex);
     // The acquire fences of BufferStateLayers have already signaled before they are set
     mCallbackHandleAcquireTime = fence->getSignalTime();
 
-    mState.current.acquireFence = fence;
-    mState.current.modified = true;
+    mCurrentState.acquireFence = fence;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.dataspace == dataspace) return false;
-    mState.current.sequence++;
-    mState.current.dataspace = dataspace;
-    mState.current.modified = true;
+    if (mCurrentState.dataspace == dataspace) return false;
+    mCurrentState.sequence++;
+    mCurrentState.dataspace = dataspace;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.hdrMetadata == hdrMetadata) return false;
-    mState.current.sequence++;
-    mState.current.hdrMetadata = hdrMetadata;
-    mState.current.modified = true;
+    if (mCurrentState.hdrMetadata == hdrMetadata) return false;
+    mCurrentState.sequence++;
+    mCurrentState.hdrMetadata = hdrMetadata;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.sequence++;
-    mState.current.surfaceDamageRegion = surfaceDamage;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.surfaceDamageRegion = surfaceDamage;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setApi(int32_t api) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.api == api) return false;
-    mState.current.sequence++;
-    mState.current.api = api;
-    mState.current.modified = true;
+    if (mCurrentState.api == api) return false;
+    mCurrentState.sequence++;
+    mCurrentState.api = api;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.sidebandStream == sidebandStream) return false;
-    mState.current.sequence++;
-    mState.current.sidebandStream = sidebandStream;
-    mState.current.modified = true;
+    if (mCurrentState.sidebandStream == sidebandStream) return false;
+    mCurrentState.sequence++;
+    mCurrentState.sidebandStream = sidebandStream;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     if (!mSidebandStreamChanged.exchange(true)) {
@@ -262,10 +260,7 @@
             mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
 
             // Store so latched time and release fence can be set
-            {
-                Mutex::Autolock lock(mStateMutex);
-                mState.current.callbackHandles.push_back(handle);
-            }
+            mCurrentState.callbackHandles.push_back(handle);
 
         } else { // If this layer will NOT need to be relatched and presented this frame
             // Notify the transaction completed thread this handle is done
@@ -280,9 +275,8 @@
 }
 
 bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.transparentRegionHint = transparent;
-    mState.current.modified = true;
+    mCurrentState.transparentRegionHint = transparent;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -318,7 +312,6 @@
         return true;
     }
 
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
 }
 
@@ -327,7 +320,7 @@
     return 0;
 }
 
-std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const {
+std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
     return std::make_shared<FenceTime>(getDrawingState().acquireFence);
 }
 
@@ -374,17 +367,14 @@
 }
 
 Region BufferStateLayer::getDrawingSurfaceDamage() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().surfaceDamageRegion;
 }
 
 const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().hdrMetadata;
 }
 
 int BufferStateLayer::getDrawingApi() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().api;
 }
 
@@ -409,7 +399,6 @@
 }
 
 std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
-    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
@@ -421,12 +410,12 @@
         }
         recomputeVisibleRegions = true;
 
-        return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h)));
+        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
     }
     return {};
 }
 
-bool BufferStateLayer::hasFrameUpdateLocked() const {
+bool BufferStateLayer::hasFrameUpdate() const {
     return mCurrentStateModified && getCurrentState().buffer != nullptr;
 }
 
@@ -436,10 +425,6 @@
 }
 
 status_t BufferStateLayer::bindTextureImage() {
-    Mutex::Autolock lock(mStateMutex);
-    return bindTextureImageLocked();
-}
-status_t BufferStateLayer::bindTextureImageLocked() {
     const State& s(getDrawingState());
     auto& engine(mFlinger->getRenderEngine());
 
@@ -544,7 +529,7 @@
         auto incomingStatus = releaseFence->getStatus();
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
-            mState.drawing.acquireFence = releaseFence;
+            mDrawingState.acquireFence = releaseFence;
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
         }
@@ -555,16 +540,16 @@
             char fenceName[32] = {};
             snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
             sp<Fence> mergedFence =
-                    Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence);
+                    Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
             if (!mergedFence.get()) {
                 ALOGE("failed to merge release fences");
                 // synchronization is broken, the best we can do is hope fences
                 // signal in order so the new fence will act like a union
-                mState.drawing.acquireFence = releaseFence;
+                mDrawingState.acquireFence = releaseFence;
                 mFlinger->mTimeStats->onDestroy(layerID);
                 return BAD_VALUE;
             }
-            mState.drawing.acquireFence = mergedFence;
+            mDrawingState.acquireFence = mergedFence;
         } else if (incomingStatus == Fence::Status::Unsignaled) {
             // If one fence has signaled and the other hasn't, the unsignaled
             // fence will approximately correspond with the correct timestamp.
@@ -573,7 +558,7 @@
             // by this point, they will have both signaled and only the timestamp
             // will be slightly off; any dependencies after this point will
             // already have been met.
-            mState.drawing.acquireFence = releaseFence;
+            mDrawingState.acquireFence = releaseFence;
         }
     } else {
         // Bind the new buffer to the GL texture.
@@ -582,7 +567,7 @@
         // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
         // devices will either call this in Layer::onDraw, or (if it's not
         // a GL-composited layer) not at all.
-        status_t err = bindTextureImageLocked();
+        status_t err = bindTextureImage();
         if (err != NO_ERROR) {
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
@@ -591,7 +576,7 @@
 
     // TODO(marissaw): properly support mTimeStats
     mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
-    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked());
+    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
     mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
 
     return NO_ERROR;
@@ -618,7 +603,6 @@
 }
 
 void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
-    Mutex::Autolock lock(mStateMutex);
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
 
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 655353c..3f891d3 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -41,14 +41,13 @@
 
     bool shouldPresentNow(nsecs_t expectedPresentTime) const override;
 
-    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
+    bool getTransformToDisplayInverse() const override;
 
     uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
         return flags;
     }
-
-    void pushPendingStateLocked() override REQUIRES(mStateMutex);
-    bool applyPendingStates(Layer::State* stateToCommit) override REQUIRES(mStateMutex);
+    void pushPendingState() override;
+    bool applyPendingStates(Layer::State* stateToCommit) override;
 
     uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; }
     uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; }
@@ -60,20 +59,18 @@
     }
     Rect getCrop(const Layer::State& s) const;
 
-    bool setTransform(uint32_t transform) override EXCLUDES(mStateMutex);
-    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override
-            EXCLUDES(mStateMutex);
-    bool setCrop(const Rect& crop) override EXCLUDES(mStateMutex);
-    bool setFrame(const Rect& frame) override EXCLUDES(mStateMutex);
-    bool setBuffer(const sp<GraphicBuffer>& buffer) override EXCLUDES(mStateMutex);
-    bool setAcquireFence(const sp<Fence>& fence) override EXCLUDES(mStateMutex);
-    bool setDataspace(ui::Dataspace dataspace) override EXCLUDES(mStateMutex);
-    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override EXCLUDES(mStateMutex);
-    bool setSurfaceDamageRegion(const Region& surfaceDamage) override EXCLUDES(mStateMutex);
-    bool setApi(int32_t api) override EXCLUDES(mStateMutex);
-    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override EXCLUDES(mStateMutex);
-    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override
-            EXCLUDES(mStateMutex);
+    bool setTransform(uint32_t transform) override;
+    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
+    bool setCrop(const Rect& crop) override;
+    bool setFrame(const Rect& frame) override;
+    bool setBuffer(const sp<GraphicBuffer>& buffer) override;
+    bool setAcquireFence(const sp<Fence>& fence) override;
+    bool setDataspace(ui::Dataspace dataspace) override;
+    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
+    bool setSurfaceDamageRegion(const Region& surfaceDamage) override;
+    bool setApi(int32_t api) override;
+    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override;
+    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override;
 
     // Override to ignore legacy layer state properties that are not used by BufferStateLayer
     bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; }
@@ -90,26 +87,26 @@
     void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
                                       uint64_t /*frameNumber*/) override {}
 
-    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
+    Rect getBufferSize(const State& s) const override;
     // -----------------------------------------------------------------------
 
     // -----------------------------------------------------------------------
     // Interface implementation for BufferLayer
     // -----------------------------------------------------------------------
-    bool fenceHasSignaled() const override EXCLUDES(mStateMutex);
+    bool fenceHasSignaled() const override;
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
-    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
-    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
+    uint32_t getDrawingTransform() const override;
+    ui::Dataspace getDrawingDataSpace() const override;
+    Rect getDrawingCrop() const override;
     uint32_t getDrawingScalingMode() const override;
-    Region getDrawingSurfaceDamage() const override EXCLUDES(mStateMutex);
-    const HdrMetadata& getDrawingHdrMetadata() const override EXCLUDES(mStateMutex);
-    int getDrawingApi() const override EXCLUDES(mStateMutex);
+    Region getDrawingSurfaceDamage() const override;
+    const HdrMetadata& getDrawingHdrMetadata() const override;
+    int getDrawingApi() const override;
     PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
@@ -117,26 +114,24 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
-            EXCLUDES(mStateMutex);
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
 
-    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
+    bool hasFrameUpdate() const override;
 
     void setFilteringEnabled(bool enabled) override;
 
-    status_t bindTextureImage() override EXCLUDES(mStateMutex);
+    status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
+                            const sp<Fence>& releaseFence) override;
 
-    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
+    status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void setHwcLayerBuffer(DisplayId displayId) override EXCLUDES(mStateMutex);
+    void setHwcLayerBuffer(DisplayId displayId) override;
 
 private:
     void onFirstRef() override;
     bool willPresentCurrentTransaction() const;
-    status_t bindTextureImageLocked() REQUIRES(mStateMutex);
 
     static const std::array<float, 16> IDENTITY_MATRIX;
 
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0b59147..4f6fb1c 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -35,55 +35,10 @@
 // ---------------------------------------------------------------------------
 
 Client::Client(const sp<SurfaceFlinger>& flinger)
-    : Client(flinger, nullptr)
+    : mFlinger(flinger)
 {
 }
 
-Client::Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer)
-    : mFlinger(flinger),
-      mParentLayer(parentLayer)
-{
-}
-
-Client::~Client()
-{
-    // We need to post a message to remove our remaining layers rather than
-    // do so directly by acquiring the SurfaceFlinger lock. If we were to
-    // attempt to directly call the lock it becomes effectively impossible
-    // to use sp<Client> while holding the SF lock as descoping it could
-    // then trigger a dead-lock.
-
-    const size_t count = mLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        sp<Layer> l = mLayers.valueAt(i).promote();
-        if (l == nullptr) {
-            continue;
-        }
-        mFlinger->postMessageAsync(new LambdaMessage([flinger = mFlinger, l]() {
-            flinger->removeLayer(l);
-        }));
-    }
-}
-
-void Client::updateParent(const sp<Layer>& parentLayer) {
-    Mutex::Autolock _l(mLock);
-
-    // If we didn't ever have a parent, then we must instead be
-    // relying on permissions and we never need a parent.
-    if (mParentLayer != nullptr) {
-        mParentLayer = parentLayer;
-    }
-}
-
-sp<Layer> Client::getParentLayer(bool* outParentDied) const {
-    Mutex::Autolock _l(mLock);
-    sp<Layer> parent = mParentLayer.promote();
-    if (outParentDied != nullptr) {
-        *outParentDied = (mParentLayer != nullptr && parent == nullptr);
-    }
-    return parent;
-}
-
 status_t Client::initCheck() const {
     return NO_ERROR;
 }
@@ -119,32 +74,6 @@
 }
 
 
-status_t Client::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // these must be checked
-     IPCThreadState* ipc = IPCThreadState::self();
-     const int pid = ipc->getCallingPid();
-     const int uid = ipc->getCallingUid();
-     const int self_pid = getpid();
-     // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT
-     // uid we require the sAccessSurfaceFlinger permission.
-     // We grant an exception in the case that the Client has a "parent layer", as its
-     // effects will be scoped to that layer.
-     if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)
-             && (getParentLayer() == nullptr)) {
-         // we're called from a different process, do the real check
-         if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
-         {
-             ALOGE("Permission Denial: "
-                     "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid);
-             return PERMISSION_DENIED;
-         }
-     }
-     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
-}
-
-
 status_t Client::createSurface(
         const String8& name,
         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
@@ -160,24 +89,12 @@
             return NAME_NOT_FOUND;
         }
     }
-    if (parent == nullptr) {
-        bool parentDied;
-        parent = getParentLayer(&parentDied);
-        // If we had a parent, but it died, we've lost all
-        // our capabilities.
-        if (parentDied) {
-            return NAME_NOT_FOUND;
-        }
-    }
 
+    // We rely on createLayer to check permissions.
     return mFlinger->createLayer(name, this, w, h, format, flags, windowType,
                                  ownerUid, handle, gbp, &parent);
 }
 
-status_t Client::destroySurface(const sp<IBinder>& handle) {
-    return mFlinger->onLayerRemoved(this, handle);
-}
-
 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
     sp<Layer> layer = getLayerUser(handle);
     if (layer == nullptr) {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 49437ed..d0051de 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -39,20 +39,16 @@
 {
 public:
     explicit Client(const sp<SurfaceFlinger>& flinger);
-    Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer);
-    ~Client();
+    ~Client() = default;
 
     status_t initCheck() const;
 
     // protected by SurfaceFlinger::mStateLock
     void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
-
     void detachLayer(const Layer* layer);
 
     sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
 
-    void updateParent(const sp<Layer>& parentLayer);
-
 private:
     // ISurfaceComposerClient interface
     virtual status_t createSurface(
@@ -62,23 +58,15 @@
             sp<IBinder>* handle,
             sp<IGraphicBufferProducer>* gbp);
 
-    virtual status_t destroySurface(const sp<IBinder>& handle);
-
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
 
-    virtual status_t onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-
-    sp<Layer> getParentLayer(bool* outParentDied = nullptr) const;
-
     // constant
     sp<SurfaceFlinger> mFlinger;
 
     // protected by mLock
     DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
-    wp<Layer> mParentLayer;
 
     // thread-safe
     mutable Mutex mLock;
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index cb7642e..f27f6aa 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -40,16 +40,15 @@
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) {
-    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     if (color.a > 0) {
         renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2);
         computeGeometry(renderArea, mesh, useIdentityTransform);
         auto& engine(mFlinger->getRenderEngine());
 
-        Rect win{computeBoundsLocked()};
+        Rect win{computeBounds()};
 
-        const auto roundedCornerState = getRoundedCornerStateLocked();
+        const auto roundedCornerState = getRoundedCornerState();
         const auto cropRect = roundedCornerState.cropRect;
         setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -92,7 +91,6 @@
     }
     getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
 
-    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                                 static_cast<uint8_t>(std::round(255.0f * color.g)),
@@ -113,12 +111,12 @@
     }
     getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
 
-    error = hwcLayer->setColorTransform(getColorTransformLocked());
+    error = hwcLayer->setColorTransform(getColorTransform());
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
-    getBE().compositionInfo.hwc.colorTransform = getColorTransformLocked();
+    getBE().compositionInfo.hwc.colorTransform = getColorTransform();
 
     error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
     if (error != HWC2::Error::None) {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 5850a2e..d1b1697 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -29,12 +29,12 @@
     ~ColorLayer() override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
-            EXCLUDES(mStateMutex);
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
+                        bool useIdentityTransform);
+    bool isVisible() const override;
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
-                         int32_t supportedPerFrameMetadata) override EXCLUDES(mStateMutex);
+                         int32_t supportedPerFrameMetadata) override;
 
     bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
 
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
new file mode 100644
index 0000000..ec5e131
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -0,0 +1,88 @@
+cc_defaults {
+    name: "libcompositionengine_defaults",
+    defaults: ["surfaceflinger_defaults"],
+    cflags: [
+        "-DLOG_TAG=\"CompositionEngine\"",
+    ],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.composer@2.1",
+        "android.hardware.graphics.composer@2.2",
+        "android.hardware.graphics.composer@2.3",
+        "android.hardware.power@1.0",
+        "android.hardware.power@1.3",
+        "libbase",
+        "libcutils",
+        "libgui",
+        "liblayers_proto",
+        "liblog",
+        "libtimestats_proto",
+        "libui",
+        "libutils",
+    ],
+    static_libs: [
+        "libmath",
+        "librenderengine",
+        "libtrace_proto",
+    ],
+    header_libs: [
+        "libsurfaceflinger_headers",
+    ],
+}
+
+cc_library {
+    name: "libcompositionengine",
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "src/CompositionEngine.cpp",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
+
+cc_library {
+    name: "libcompositionengine_mocks",
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "mock/CompositionEngine.cpp",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+        "libcompositionengine",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
+
+cc_test {
+    name: "libcompositionengine_test",
+    test_suites: ["device-tests"],
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "tests/CompositionEngineTest.cpp",
+        "tests/MockHWComposer.cpp",
+    ],
+    static_libs: [
+        "libcompositionengine",
+        "libcompositionengine_mocks",
+        "librenderengine_mocks",
+        "libgmock",
+        "libgtest",
+    ],
+    sanitize: {
+        // By using the address sanitizer, we not only uncover any issues
+        // with the test, but also any issues with the code under test.
+        //
+        // Note: If you get an runtime link error like:
+        //
+        //   CANNOT LINK EXECUTABLE "/data/local/tmp/libcompositionengine_test": library "libclang_rt.asan-aarch64-android.so" not found
+        //
+        // it is because the address sanitizer shared objects are not installed
+        // by default in the system image.
+        //
+        // You can either "make dist tests" before flashing, or set this
+        // option to false temporarily.
+        address: true,
+    },
+}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
new file mode 100644
index 0000000..af8515f
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace android {
+
+class HWComposer;
+
+namespace renderengine {
+class RenderEngine;
+} // namespace renderengine
+
+namespace compositionengine {
+
+/**
+ * Encapsulates all the interfaces and implementation details for performing
+ * display output composition.
+ */
+class CompositionEngine {
+public:
+    virtual ~CompositionEngine();
+
+    virtual HWComposer& getHwComposer() const = 0;
+    virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0;
+
+    virtual renderengine::RenderEngine& getRenderEngine() const = 0;
+    virtual void setRenderEngine(std::unique_ptr<renderengine::RenderEngine>) = 0;
+};
+
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
new file mode 100644
index 0000000..86d1774
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <compositionengine/CompositionEngine.h>
+
+namespace android::compositionengine::impl {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+    CompositionEngine();
+    ~CompositionEngine() override;
+
+    HWComposer& getHwComposer() const override;
+    void setHwComposer(std::unique_ptr<HWComposer>) override;
+
+    renderengine::RenderEngine& getRenderEngine() const override;
+    void setRenderEngine(std::unique_ptr<renderengine::RenderEngine>) override;
+
+private:
+    std::unique_ptr<HWComposer> mHwComposer;
+    std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
+};
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine();
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
new file mode 100644
index 0000000..9ba213e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <compositionengine/CompositionEngine.h>
+#include <gmock/gmock.h>
+#include <renderengine/RenderEngine.h>
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android::compositionengine::mock {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+    CompositionEngine();
+    ~CompositionEngine() override;
+
+    MOCK_CONST_METHOD0(getHwComposer, HWComposer&());
+    MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>));
+
+    MOCK_CONST_METHOD0(getRenderEngine, renderengine::RenderEngine&());
+    MOCK_METHOD1(setRenderEngine, void(std::unique_ptr<renderengine::RenderEngine>));
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
new file mode 100644
index 0000000..778a09e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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 <compositionengine/mock/CompositionEngine.h>
+
+namespace android::compositionengine::mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
new file mode 100644
index 0000000..fbf71b5
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 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 <compositionengine/impl/CompositionEngine.h>
+#include <renderengine/RenderEngine.h>
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android::compositionengine {
+
+CompositionEngine::~CompositionEngine() = default;
+
+namespace impl {
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
+    return std::make_unique<CompositionEngine>();
+}
+
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+HWComposer& CompositionEngine::getHwComposer() const {
+    return *mHwComposer.get();
+}
+
+void CompositionEngine::setHwComposer(std::unique_ptr<HWComposer> hwComposer) {
+    mHwComposer = std::move(hwComposer);
+}
+
+renderengine::RenderEngine& CompositionEngine::getRenderEngine() const {
+    return *mRenderEngine.get();
+}
+
+void CompositionEngine::setRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) {
+    mRenderEngine = std::move(renderEngine);
+}
+
+} // namespace impl
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
new file mode 100644
index 0000000..3766f27
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018 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 <compositionengine/impl/CompositionEngine.h>
+#include <gtest/gtest.h>
+#include <renderengine/mock/RenderEngine.h>
+
+#include "MockHWComposer.h"
+
+namespace android::compositionengine {
+namespace {
+
+using ::testing::StrictMock;
+
+class CompositionEngineTest : public testing::Test {
+public:
+    ~CompositionEngineTest() override;
+    mock::HWComposer* mHwc = new StrictMock<mock::HWComposer>();
+    renderengine::mock::RenderEngine* mRenderEngine =
+            new StrictMock<renderengine::mock::RenderEngine>();
+    impl::CompositionEngine mEngine;
+};
+
+CompositionEngineTest::~CompositionEngineTest() = default;
+
+TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
+    auto engine = impl::createCompositionEngine();
+    EXPECT_TRUE(engine.get() != nullptr);
+}
+
+TEST_F(CompositionEngineTest, canSetHWComposer) {
+    mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(mHwc));
+
+    EXPECT_EQ(mHwc, &mEngine.getHwComposer());
+}
+
+TEST_F(CompositionEngineTest, canSetRenderEngine) {
+    mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
+
+    EXPECT_EQ(mRenderEngine, &mEngine.getRenderEngine());
+}
+
+} // namespace
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp
new file mode 100644
index 0000000..ae52670
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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 "MockHWComposer.h"
+
+namespace android {
+
+// This will go away once HWComposer is moved into the "backend" library
+HWComposer::~HWComposer() = default;
+
+namespace mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+HWComposer::HWComposer() = default;
+HWComposer::~HWComposer() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
new file mode 100644
index 0000000..ece412f
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include "LayerBE.h"
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android {
+namespace mock {
+
+class HWComposer : public android::HWComposer {
+public:
+    HWComposer();
+    ~HWComposer() override;
+
+    MOCK_METHOD2(registerCallback, void(HWC2::ComposerCallback*, int32_t));
+    MOCK_CONST_METHOD3(getDisplayIdentificationData,
+                       bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*));
+    MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability));
+    MOCK_CONST_METHOD2(hasDisplayCapability,
+                       bool(const std::optional<DisplayId>&, HWC2::DisplayCapability));
+
+    MOCK_METHOD3(allocateVirtualDisplay,
+                 std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
+    MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
+    MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
+    MOCK_METHOD2(prepare, status_t(DisplayId, std::vector<CompositionInfo>&));
+    MOCK_METHOD5(setClientTarget,
+                 status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
+                          ui::Dataspace));
+    MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
+    MOCK_METHOD2(setPowerMode, status_t(DisplayId, int));
+    MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
+    MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
+    MOCK_METHOD1(disconnectDisplay, void(DisplayId));
+    MOCK_CONST_METHOD1(hasDeviceComposition, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(hasFlipClientTargetRequest, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(hasClientComposition, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(DisplayId));
+    MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(DisplayId, HWC2::Layer*));
+    MOCK_METHOD3(setOutputBuffer, status_t(DisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
+    MOCK_METHOD1(clearReleaseFences, void(DisplayId));
+    MOCK_METHOD2(getHdrCapabilities, status_t(DisplayId, HdrCapabilities*));
+    MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(DisplayId));
+    MOCK_CONST_METHOD2(getRenderIntents, std::vector<ui::RenderIntent>(DisplayId, ui::ColorMode));
+    MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(DisplayId, ui::Dataspace));
+    MOCK_METHOD4(getDisplayedContentSamplingAttributes,
+                 status_t(DisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
+    MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
+    MOCK_METHOD4(getDisplayedContentSample,
+                 status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+
+    MOCK_METHOD2(onHotplug,
+                 std::optional<DisplayIdentificationInfo>(hwc2_display_t, HWC2::Connection));
+    MOCK_METHOD2(onVsync, bool(hwc2_display_t, int64_t));
+    MOCK_METHOD2(setVsyncEnabled, void(DisplayId, HWC2::Vsync));
+    MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
+    MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
+    MOCK_CONST_METHOD1(getConfigs,
+                       std::vector<std::shared_ptr<const HWC2::Display::Config>>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfigIndex, int(DisplayId));
+    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
+    MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
+    MOCK_CONST_METHOD0(isUsingVrComposer, bool());
+
+    MOCK_CONST_METHOD1(dump, void(std::string&));
+    MOCK_CONST_METHOD0(getComposer, android::Hwc2::Composer*());
+    MOCK_CONST_METHOD1(getHwcDisplayId, std::optional<hwc2_display_t>(int32_t));
+    MOCK_CONST_METHOD0(getInternalHwcDisplayId, std::optional<hwc2_display_t>());
+    MOCK_CONST_METHOD0(getExternalHwcDisplayId, std::optional<hwc2_display_t>());
+    MOCK_CONST_METHOD1(toPhysicalDisplayId, std::optional<DisplayId>(hwc2_display_t));
+    MOCK_CONST_METHOD1(fromPhysicalDisplayId, std::optional<hwc2_display_t>(DisplayId));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 6c4f7c8..413844b 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,7 +31,7 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    bool isVisible() const override;
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                          int32_t supportedPerFrameMetadata) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0497571..5b4d347 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -66,6 +66,10 @@
 
 namespace android {
 
+HWComposer::~HWComposer() = default;
+
+namespace impl {
+
 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
       : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
 
@@ -98,6 +102,10 @@
 bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
                                       HWC2::DisplayCapability capability) const {
     if (!displayId) {
+        // Checkout global capabilities for displays without a corresponding HWC display.
+        if (capability == HWC2::DisplayCapability::SkipClientColorTransform) {
+            return hasCapability(HWC2::Capability::SkipClientColorTransform);
+        }
         return false;
     }
     RETURN_IF_INVALID_DISPLAY(*displayId, false);
@@ -854,4 +862,5 @@
                                                                            : "External display"};
 }
 
+} // namespace impl
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index d9a0916..f42f860 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -45,134 +45,273 @@
 class Composer;
 } // namespace Hwc2
 
-class HWComposer
-{
+class HWComposer {
+public:
+    virtual ~HWComposer();
+
+    virtual void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
+
+    virtual bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+                                              DisplayIdentificationData* outData) const = 0;
+
+    virtual bool hasCapability(HWC2::Capability capability) const = 0;
+    virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+                                      HWC2::DisplayCapability capability) const = 0;
+
+    // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
+    virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
+                                                            ui::PixelFormat* format) = 0;
+
+    // Attempts to create a new layer on this display
+    virtual HWC2::Layer* createLayer(DisplayId displayId) = 0;
+    // Destroy a previously created layer
+    virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
+
+    // Asks the HAL what it can do
+    virtual status_t prepare(DisplayId displayId,
+                             std::vector<CompositionInfo>& compositionData) = 0;
+
+    virtual status_t setClientTarget(DisplayId displayId, uint32_t slot,
+                                     const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
+                                     ui::Dataspace dataspace) = 0;
+
+    // Present layers to the display and read releaseFences.
+    virtual status_t presentAndGetReleaseFences(DisplayId displayId) = 0;
+
+    // set power mode
+    virtual status_t setPowerMode(DisplayId displayId, int mode) = 0;
+
+    // set active config
+    virtual status_t setActiveConfig(DisplayId displayId, size_t configId) = 0;
+
+    // Sets a color transform to be applied to the result of composition
+    virtual status_t setColorTransform(DisplayId displayId, const mat4& transform) = 0;
+
+    // reset state when an external, non-virtual display is disconnected
+    virtual void disconnectDisplay(DisplayId displayId) = 0;
+
+    // does this display have layers handled by HWC
+    virtual bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const = 0;
+
+    // does this display have pending request to flip client target
+    virtual bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const = 0;
+
+    // does this display have layers handled by GLES
+    virtual bool hasClientComposition(const std::optional<DisplayId>& displayId) const = 0;
+
+    // get the present fence received from the last call to present.
+    virtual sp<Fence> getPresentFence(DisplayId displayId) const = 0;
+
+    // Get last release fence for the given layer
+    virtual sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const = 0;
+
+    // Set the output buffer and acquire fence for a virtual display.
+    // Returns INVALID_OPERATION if displayId is not a virtual display.
+    virtual status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
+                                     const sp<GraphicBuffer>& buffer) = 0;
+
+    // After SurfaceFlinger has retrieved the release fences for all the frames,
+    // it can call this to clear the shared pointers in the release fence map
+    virtual void clearReleaseFences(DisplayId displayId) = 0;
+
+    // Fetches the HDR capabilities of the given display
+    virtual status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) = 0;
+
+    virtual int32_t getSupportedPerFrameMetadata(DisplayId displayId) const = 0;
+
+    // Returns the available RenderIntent of the given display.
+    virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
+                                                           ui::ColorMode colorMode) const = 0;
+
+    virtual mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) = 0;
+
+    // Returns the attributes of the color sampling engine.
+    virtual status_t getDisplayedContentSamplingAttributes(DisplayId displayId,
+                                                           ui::PixelFormat* outFormat,
+                                                           ui::Dataspace* outDataspace,
+                                                           uint8_t* outComponentMask) = 0;
+    virtual status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+                                                      uint8_t componentMask,
+                                                      uint64_t maxFrames) = 0;
+    virtual status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
+                                               uint64_t timestamp,
+                                               DisplayedFrameStats* outStats) = 0;
+
+    // Events handling ---------------------------------------------------------
+
+    // Returns stable display ID (and display name on connection of new or previously disconnected
+    // display), or std::nullopt if hotplug event was ignored.
+    virtual std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
+                                                               HWC2::Connection connection) = 0;
+
+    virtual bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) = 0;
+    virtual void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) = 0;
+
+    virtual nsecs_t getRefreshTimestamp(DisplayId displayId) const = 0;
+    virtual bool isConnected(DisplayId displayId) const = 0;
+
+    // Non-const because it can update configMap inside of mDisplayData
+    virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+            DisplayId displayId) const = 0;
+
+    virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+            DisplayId displayId) const = 0;
+    virtual int getActiveConfigIndex(DisplayId displayId) const = 0;
+
+    virtual std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const = 0;
+
+    virtual status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
+                                        ui::RenderIntent renderIntent) = 0;
+
+    virtual bool isUsingVrComposer() const = 0;
+
+    // for debugging ----------------------------------------------------------
+    virtual void dump(std::string& out) const = 0;
+
+    virtual Hwc2::Composer* getComposer() const = 0;
+
+    // TODO(b/74619554): Remove special cases for internal/external display.
+    virtual std::optional<hwc2_display_t> getInternalHwcDisplayId() const = 0;
+    virtual std::optional<hwc2_display_t> getExternalHwcDisplayId() const = 0;
+
+    virtual std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const = 0;
+    virtual std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const = 0;
+};
+
+namespace impl {
+
+class HWComposer final : public android::HWComposer {
 public:
     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
 
-    ~HWComposer();
+    ~HWComposer() override;
 
-    void registerCallback(HWC2::ComposerCallback* callback,
-                          int32_t sequenceId);
+    void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) override;
 
     bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
-                                      DisplayIdentificationData* outData) const;
+                                      DisplayIdentificationData* outData) const override;
 
-    bool hasCapability(HWC2::Capability capability) const;
+    bool hasCapability(HWC2::Capability capability) const override;
     bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
-                              HWC2::DisplayCapability capability) const;
+                              HWC2::DisplayCapability capability) const override;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
-                                                    ui::PixelFormat* format);
+                                                    ui::PixelFormat* format) override;
 
     // Attempts to create a new layer on this display
-    HWC2::Layer* createLayer(DisplayId displayId);
+    HWC2::Layer* createLayer(DisplayId displayId) override;
     // Destroy a previously created layer
-    void destroyLayer(DisplayId displayId, HWC2::Layer* layer);
+    void destroyLayer(DisplayId displayId, HWC2::Layer* layer) override;
 
     // Asks the HAL what it can do
-    status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData);
+    status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) override;
 
     status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence,
-                             const sp<GraphicBuffer>& target, ui::Dataspace dataspace);
+                             const sp<GraphicBuffer>& target, ui::Dataspace dataspace) override;
 
     // Present layers to the display and read releaseFences.
-    status_t presentAndGetReleaseFences(DisplayId displayId);
+    status_t presentAndGetReleaseFences(DisplayId displayId) override;
 
     // set power mode
-    status_t setPowerMode(DisplayId displayId, int mode);
+    status_t setPowerMode(DisplayId displayId, int mode) override;
 
     // set active config
-    status_t setActiveConfig(DisplayId displayId, size_t configId);
+    status_t setActiveConfig(DisplayId displayId, size_t configId) override;
 
     // Sets a color transform to be applied to the result of composition
-    status_t setColorTransform(DisplayId displayId, const mat4& transform);
+    status_t setColorTransform(DisplayId displayId, const mat4& transform) override;
 
     // reset state when an external, non-virtual display is disconnected
-    void disconnectDisplay(DisplayId displayId);
+    void disconnectDisplay(DisplayId displayId) override;
 
     // does this display have layers handled by HWC
-    bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const;
+    bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const override;
 
     // does this display have pending request to flip client target
-    bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const;
+    bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const override;
 
     // does this display have layers handled by GLES
-    bool hasClientComposition(const std::optional<DisplayId>& displayId) const;
+    bool hasClientComposition(const std::optional<DisplayId>& displayId) const override;
 
     // get the present fence received from the last call to present.
-    sp<Fence> getPresentFence(DisplayId displayId) const;
+    sp<Fence> getPresentFence(DisplayId displayId) const override;
 
     // Get last release fence for the given layer
-    sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const;
+    sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const override;
 
     // Set the output buffer and acquire fence for a virtual display.
     // Returns INVALID_OPERATION if displayId is not a virtual display.
     status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
-                             const sp<GraphicBuffer>& buffer);
+                             const sp<GraphicBuffer>& buffer) override;
 
     // After SurfaceFlinger has retrieved the release fences for all the frames,
     // it can call this to clear the shared pointers in the release fence map
-    void clearReleaseFences(DisplayId displayId);
+    void clearReleaseFences(DisplayId displayId) override;
 
     // Fetches the HDR capabilities of the given display
-    status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities);
+    status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) override;
 
-    int32_t getSupportedPerFrameMetadata(DisplayId displayId) const;
+    int32_t getSupportedPerFrameMetadata(DisplayId displayId) const override;
 
     // Returns the available RenderIntent of the given display.
     std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
-                                                   ui::ColorMode colorMode) const;
+                                                   ui::ColorMode colorMode) const override;
 
-    mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace);
+    mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) override;
 
     // Returns the attributes of the color sampling engine.
     status_t getDisplayedContentSamplingAttributes(DisplayId displayId, ui::PixelFormat* outFormat,
                                                    ui::Dataspace* outDataspace,
-                                                   uint8_t* outComponentMask);
+                                                   uint8_t* outComponentMask) override;
     status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
-                                              uint8_t componentMask, uint64_t maxFrames);
+                                              uint8_t componentMask, uint64_t maxFrames) override;
     status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
-                                       DisplayedFrameStats* outStats);
+                                       DisplayedFrameStats* outStats) override;
 
     // Events handling ---------------------------------------------------------
 
     // Returns stable display ID (and display name on connection of new or previously disconnected
     // display), or std::nullopt if hotplug event was ignored.
     std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
-                                                       HWC2::Connection connection);
+                                                       HWC2::Connection connection) override;
 
-    bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp);
-    void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled);
+    bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) override;
+    void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) override;
 
-    nsecs_t getRefreshTimestamp(DisplayId displayId) const;
-    bool isConnected(DisplayId displayId) const;
+    nsecs_t getRefreshTimestamp(DisplayId displayId) const override;
+    bool isConnected(DisplayId displayId) const override;
 
     // Non-const because it can update configMap inside of mDisplayData
-    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(DisplayId displayId) const;
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+            DisplayId displayId) const override;
 
-    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId displayId) const;
-    int getActiveConfigIndex(DisplayId displayId) const;
+    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+            DisplayId displayId) const override;
+    int getActiveConfigIndex(DisplayId displayId) const override;
 
-    std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const;
+    std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const override;
 
     status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
-                                ui::RenderIntent renderIntent);
+                                ui::RenderIntent renderIntent) override;
 
-    bool isUsingVrComposer() const;
+    bool isUsingVrComposer() const override;
 
     // for debugging ----------------------------------------------------------
-    void dump(std::string& out) const;
+    void dump(std::string& out) const override;
 
-    Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
+    Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); }
 
     // TODO(b/74619554): Remove special cases for internal/external display.
-    std::optional<hwc2_display_t> getInternalHwcDisplayId() const { return mInternalHwcDisplayId; }
-    std::optional<hwc2_display_t> getExternalHwcDisplayId() const { return mExternalHwcDisplayId; }
+    std::optional<hwc2_display_t> getInternalHwcDisplayId() const override {
+        return mInternalHwcDisplayId;
+    }
+    std::optional<hwc2_display_t> getExternalHwcDisplayId() const override {
+        return mExternalHwcDisplayId;
+    }
 
-    std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const;
-    std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const;
+    std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const override;
+    std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const override;
 
 private:
     // For unit tests
@@ -223,6 +362,7 @@
     uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
 };
 
+} // namespace impl
 } // namespace android
 
 #endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f4b3cdd..3f2d10a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,35 +83,35 @@
 
     mTransactionName = String8("TX - ") + mName;
 
-    mState.current.active_legacy.w = args.w;
-    mState.current.active_legacy.h = args.h;
-    mState.current.flags = layerFlags;
-    mState.current.active_legacy.transform.set(0, 0);
-    mState.current.crop_legacy.makeInvalid();
-    mState.current.requestedCrop_legacy = mState.current.crop_legacy;
-    mState.current.z = 0;
-    mState.current.color.a = 1.0f;
-    mState.current.layerStack = 0;
-    mState.current.sequence = 0;
-    mState.current.requested_legacy = mState.current.active_legacy;
-    mState.current.appId = 0;
-    mState.current.type = 0;
-    mState.current.active.w = UINT32_MAX;
-    mState.current.active.h = UINT32_MAX;
-    mState.current.active.transform.set(0, 0);
-    mState.current.transform = 0;
-    mState.current.transformToDisplayInverse = false;
-    mState.current.crop.makeInvalid();
-    mState.current.acquireFence = new Fence(-1);
-    mState.current.dataspace = ui::Dataspace::UNKNOWN;
-    mState.current.hdrMetadata.validTypes = 0;
-    mState.current.surfaceDamageRegion.clear();
-    mState.current.cornerRadius = 0.0f;
-    mState.current.api = -1;
-    mState.current.hasColorTransform = false;
+    mCurrentState.active_legacy.w = args.w;
+    mCurrentState.active_legacy.h = args.h;
+    mCurrentState.flags = layerFlags;
+    mCurrentState.active_legacy.transform.set(0, 0);
+    mCurrentState.crop_legacy.makeInvalid();
+    mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
+    mCurrentState.z = 0;
+    mCurrentState.color.a = 1.0f;
+    mCurrentState.layerStack = 0;
+    mCurrentState.sequence = 0;
+    mCurrentState.requested_legacy = mCurrentState.active_legacy;
+    mCurrentState.appId = 0;
+    mCurrentState.type = 0;
+    mCurrentState.active.w = UINT32_MAX;
+    mCurrentState.active.h = UINT32_MAX;
+    mCurrentState.active.transform.set(0, 0);
+    mCurrentState.transform = 0;
+    mCurrentState.transformToDisplayInverse = false;
+    mCurrentState.crop.makeInvalid();
+    mCurrentState.acquireFence = new Fence(-1);
+    mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
+    mCurrentState.hdrMetadata.validTypes = 0;
+    mCurrentState.surfaceDamageRegion.clear();
+    mCurrentState.cornerRadius = 0.0f;
+    mCurrentState.api = -1;
+    mCurrentState.hasColorTransform = false;
 
     // drawing state & current state are identical
-    mState.drawing = mState.current;
+    mDrawingState = mCurrentState;
 
     CompositorTiming compositorTiming;
     args.flinger->getCompositorTiming(&compositorTiming);
@@ -148,17 +148,14 @@
 void Layer::onRemovedFromCurrentState() {
     mRemovedFromCurrentState = true;
 
-    {
-        Mutex::Autolock lock(mStateMutex);
-        // the layer is removed from SF mState.current to mLayersPendingRemoval
-        if (mState.current.zOrderRelativeOf != nullptr) {
-            sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
-            if (strongRelative != nullptr) {
-                strongRelative->removeZOrderRelative(this);
-                mFlinger->setTransactionFlags(eTraversalNeeded);
-            }
-            mState.current.zOrderRelativeOf = nullptr;
+    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+        if (strongRelative != nullptr) {
+            strongRelative->removeZOrderRelative(this);
+            mFlinger->setTransactionFlags(eTraversalNeeded);
         }
+        mCurrentState.zOrderRelativeOf = nullptr;
     }
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
@@ -182,6 +179,8 @@
     for (const auto& child : mCurrentChildren) {
         child->onRemovedFromCurrentState();
     }
+
+    mFlinger->markLayerPendingRemovalLocked(this);
 }
 
 void Layer::addToCurrentState() {
@@ -297,32 +296,21 @@
 }
 
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
-    FloatRect bounds = computeBoundsLocked(transparentRegion);
-    ui::Transform t = getTransformLocked();
+    FloatRect bounds = computeBounds(transparentRegion);
+    ui::Transform t = getTransform();
     // Transform to screen space.
     bounds = t.transform(bounds);
     return Rect{bounds};
 }
 
 FloatRect Layer::computeBounds() const {
-    Mutex::Autolock lock(mStateMutex);
-    return computeBoundsLocked();
-}
-
-FloatRect Layer::computeBoundsLocked() const {
     const State& s(getDrawingState());
-    return computeBoundsLocked(getActiveTransparentRegion(s));
+    return computeBounds(getActiveTransparentRegion(s));
 }
 
 FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
-    Mutex::Autolock lock(mStateMutex);
-    return computeBoundsLocked(activeTransparentRegion);
-}
-
-FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const {
     const State& s(getDrawingState());
     Rect bounds = getCroppedBufferSize(s);
     FloatRect floatBounds = bounds.toFloatRect();
@@ -375,7 +363,6 @@
         // child bounds as well.
         ui::Transform t = s.active_legacy.transform;
         croppedBounds = t.transform(croppedBounds);
-        Mutex::Autolock lock(p->mStateMutex);
         croppedBounds = p->cropChildBounds(croppedBounds);
         croppedBounds = t.inverse().transform(croppedBounds);
     }
@@ -403,8 +390,8 @@
     // if there are no window scaling involved, this operation will map to full
     // pixels in the buffer.
 
-    FloatRect activeCropFloat = computeBoundsLocked();
-    ui::Transform t = getTransformLocked();
+    FloatRect activeCropFloat = computeBounds();
+    ui::Transform t = getTransform();
     // Transform to screen space.
     activeCropFloat = t.transform(activeCropFloat);
     activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
@@ -454,7 +441,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -505,7 +492,6 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
-    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     RETURN_IF_NO_HWC_LAYER(*displayId);
@@ -514,7 +500,7 @@
     // enable this layer
     hwcInfo.forceClientComposition = false;
 
-    if (isSecureLocked() && !display->isSecure()) {
+    if (isSecure() && !display->isSecure()) {
         hwcInfo.forceClientComposition = true;
     }
 
@@ -524,7 +510,7 @@
     const State& s(getDrawingState());
     const Rect bufferSize = getBufferSize(s);
     auto blendMode = HWC2::BlendMode::None;
-    if (!isOpaque(s) || getAlphaLocked() != 1.0f) {
+    if (!isOpaque(s) || getAlpha() != 1.0f) {
         blendMode =
                 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
@@ -539,7 +525,7 @@
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
     Region activeTransparentRegion(getActiveTransparentRegion(s));
-    ui::Transform t = getTransformLocked();
+    ui::Transform t = getTransform();
     Rect activeCrop = getCrop(s);
     if (!activeCrop.isEmpty() && bufferSize.isValid()) {
         activeCrop = t.transform(activeCrop);
@@ -567,7 +553,7 @@
 
     // computeBounds returns a FloatRect to provide more accuracy during the
     // transformation. We then round upon constructing 'frame'.
-    Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))};
+    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
     if (!frame.intersect(display->getViewport(), &frame)) {
         frame.clear();
     }
@@ -595,7 +581,7 @@
     }
     getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
-    float alpha = static_cast<float>(getAlphaLocked());
+    float alpha = static_cast<float>(getAlpha());
     error = hwcLayer->setPlaneAlpha(alpha);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set plane alpha %.3f: "
@@ -612,7 +598,6 @@
     int appId = s.appId;
     sp<Layer> parent = mDrawingParent.promote();
     if (parent.get()) {
-        Mutex::Autolock lock(parent->mStateMutex);
         auto& parentState = parent->getDrawingState();
         if (parentState.type >= 0 || parentState.appId >= 0) {
             type = parentState.type;
@@ -638,7 +623,7 @@
     const ui::Transform bufferOrientation(mCurrentTransform);
     ui::Transform transform(tr * t * bufferOrientation);
 
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -688,7 +673,6 @@
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
-    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
@@ -703,7 +687,7 @@
     Rect win = getCroppedBufferSize(s);
     // Subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, getActiveTransparentRegion(s));
-    Rect frame(getTransformLocked().transform(bounds));
+    Rect frame(getTransform().transform(bounds));
     frame.intersect(display->getViewport(), &frame);
     auto& displayTransform = display->getTransform();
     auto position = displayTransform.transform(frame);
@@ -733,7 +717,6 @@
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
                             float alpha) const {
     auto& engine(mFlinger->getRenderEngine());
-    Mutex::Autolock lock(mStateMutex);
     computeGeometry(renderArea, getBE().mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(getBE().mMesh);
@@ -818,14 +801,14 @@
                             renderengine::Mesh& mesh,
                             bool useIdentityTransform) const {
     const ui::Transform renderAreaTransform(renderArea.getTransform());
-    FloatRect win = computeBoundsLocked();
+    FloatRect win = computeBounds();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
     vec2 rb = vec2(win.right, win.bottom);
     vec2 rt = vec2(win.right, win.top);
 
-    ui::Transform layerTransform = getTransformLocked();
+    ui::Transform layerTransform = getTransform();
     if (!useIdentityTransform) {
         lt = layerTransform.transform(lt);
         lb = layerTransform.transform(lb);
@@ -841,12 +824,7 @@
 }
 
 bool Layer::isSecure() const {
-    Mutex::Autolock lock(mStateMutex);
-    return isSecureLocked();
-}
-
-bool Layer::isSecureLocked() const {
-    const State& s(mState.drawing);
+    const State& s(mDrawingState);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
@@ -874,13 +852,9 @@
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
-void Layer::pushPendingState() {
-    Mutex::Autolock lock(mStateMutex);
-    pushPendingStateLocked();
-}
 
-void Layer::pushPendingStateLocked() {
-    if (!mState.current.modified) {
+void Layer::pushPendingState() {
+    if (!mCurrentState.modified) {
         return;
     }
 
@@ -888,22 +862,22 @@
     // point and send it to the remote layer.
     // We don't allow installing sync points after we are removed from the current state
     // as we won't be able to signal our end.
-    if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
-        sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote();
+    if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
+        sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote();
         if (barrierLayer == nullptr) {
             ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mState.current.barrierLayer_legacy = nullptr;
+            mCurrentState.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mState.current.barrierLayer_legacy = nullptr;
+                mCurrentState.barrierLayer_legacy = nullptr;
             }
         }
 
@@ -911,21 +885,21 @@
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
-    mState.pending.push_back(mState.current);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.push_back(mCurrentState);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 void Layer::popPendingState(State* stateToCommit) {
-    *stateToCommit = mState.pending[0];
+    *stateToCommit = mPendingStates[0];
 
-    mState.pending.removeAt(0);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.removeAt(0);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
-    while (!mState.pending.empty()) {
-        if (mState.pending[0].barrierLayer_legacy != nullptr) {
+    while (!mPendingStates.empty()) {
+        if (mPendingStates[0].barrierLayer_legacy != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -937,7 +911,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mState.pending[0].frameNumber_legacy) {
+                mPendingStates[0].frameNumber_legacy) {
                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
@@ -965,12 +939,12 @@
 
     // If we still have pending updates, wake SurfaceFlinger back up and point
     // it at this layer so we can process them
-    if (!mState.pending.empty()) {
+    if (!mPendingStates.empty()) {
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
 
-    mState.current.modified = false;
+    mCurrentState.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -1067,8 +1041,7 @@
         return 0;
     }
 
-    Mutex::Autolock lock(mStateMutex);
-    pushPendingStateLocked();
+    pushPendingState();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
         return 0;
@@ -1100,60 +1073,49 @@
         clearSyncPoints();
     }
 
-    if (mState.current.inputInfoChanged) {
+    if (mCurrentState.inputInfoChanged) {
         flags |= eInputInfoChanged;
-        mState.current.inputInfoChanged = false;
+        mCurrentState.inputInfoChanged = false;
     }
 
     // Commit the transaction
     commitTransaction(c);
-    mState.current.callbackHandles = {};
+    mCurrentState.callbackHandles = {};
     return flags;
 }
 
 void Layer::commitTransaction(const State& stateToCommit) {
-    mState.drawing = stateToCommit;
-}
-
-uint32_t Layer::getTransactionFlags() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.transactionFlags;
+    mDrawingState = stateToCommit;
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    Mutex::Autolock lock(mStateMutex);
-    uint32_t and_flags = mState.transactionFlags & flags;
-    mState.transactionFlags &= ~flags;
-    return and_flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    uint32_t old_flags = mState.transactionFlags;
-    mState.transactionFlags |= flags;
-    return old_flags;
+    return mTransactionFlags.fetch_or(flags);
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requested_legacy.transform.tx() == x &&
-        mState.current.requested_legacy.transform.ty() == y)
+    if (mCurrentState.requested_legacy.transform.tx() == x &&
+        mCurrentState.requested_legacy.transform.ty() == y)
         return false;
-    mState.current.sequence++;
+    mCurrentState.sequence++;
 
     // We update the requested and active position simultaneously because
     // we want to apply the position portion of the transform matrix immediately,
     // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
-    mState.current.requested_legacy.transform.set(x, y);
+    mCurrentState.requested_legacy.transform.set(x, y);
     if (immediate && !mFreezeGeometryUpdates) {
         // Here we directly update the active state
         // unlike other setters, because we store it within
         // the transform, but use different latching rules.
         // b/38182305
-        mState.current.active_legacy.transform.set(x, y);
+        mCurrentState.active_legacy.transform.set(x, y);
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mState.current.modified = true;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1186,44 +1148,38 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current))
-        return false;
-
-    mState.current.sequence++;
-    mState.current.z = z;
-    mState.current.modified = true;
+    if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    mCurrentState.modified = true;
 
     // Discard all relative layering.
-    if (mState.current.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
             strongRelative->removeZOrderRelative(this);
         }
-        mState.current.zOrderRelativeOf = nullptr;
+        mCurrentState.zOrderRelativeOf = nullptr;
     }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::removeZOrderRelative(const wp<Layer>& relative) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.zOrderRelatives.remove(relative);
-    mState.current.sequence++;
-    mState.current.modified = true;
+    mCurrentState.zOrderRelatives.remove(relative);
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::addZOrderRelative(const wp<Layer>& relative) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.zOrderRelatives.add(relative);
-    mState.current.modified = true;
-    mState.current.sequence++;
+    mCurrentState.zOrderRelatives.add(relative);
+    mCurrentState.modified = true;
+    mCurrentState.sequence++;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
-    Mutex::Autolock lock(mStateMutex);
     sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
     if (handle == nullptr) {
         return false;
@@ -1233,20 +1189,20 @@
         return false;
     }
 
-    if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) &&
-        mState.current.zOrderRelativeOf == relative) {
+    if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
+        mCurrentState.zOrderRelativeOf == relative) {
         return false;
     }
 
-    mState.current.sequence++;
-    mState.current.modified = true;
-    mState.current.z = relativeZ;
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
+    mCurrentState.z = relativeZ;
 
-    auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote();
+    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
     if (oldZOrderRelativeOf != nullptr) {
         oldZOrderRelativeOf->removeZOrderRelative(this);
     }
-    mState.current.zOrderRelativeOf = relative;
+    mCurrentState.zOrderRelativeOf = relative;
     relative->addZOrderRelative(this);
 
     setTransactionFlags(eTransactionNeeded);
@@ -1255,51 +1211,47 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h)
+    if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
         return false;
-    mState.current.requested_legacy.w = w;
-    mState.current.requested_legacy.h = h;
-    mState.current.modified = true;
+    mCurrentState.requested_legacy.w = w;
+    mCurrentState.requested_legacy.h = h;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     // record the new size, from this point on, when the client request
     // a buffer, it'll get the new size.
-    setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h);
+    setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.color.a == alpha) return false;
-    mState.current.sequence++;
-    mState.current.color.a = alpha;
-    mState.current.modified = true;
+    if (mCurrentState.color.a == alpha) return false;
+    mCurrentState.sequence++;
+    mCurrentState.color.a = alpha;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setColor(const half3& color) {
-    Mutex::Autolock lock(mStateMutex);
-    if (color.r == mState.current.color.r && color.g == mState.current.color.g &&
-        color.b == mState.current.color.b)
+    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
+        color.b == mCurrentState.color.b)
         return false;
 
-    mState.current.sequence++;
-    mState.current.color.r = color.r;
-    mState.current.color.g = color.g;
-    mState.current.color.b = color.b;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.color.r = color.r;
+    mCurrentState.color.g = color.g;
+    mCurrentState.color.b = color.b;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCornerRadius(float cornerRadius) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.cornerRadius == cornerRadius) return false;
+    if (mCurrentState.cornerRadius == cornerRadius) return false;
 
-    mState.current.sequence++;
-    mState.current.cornerRadius = cornerRadius;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.cornerRadius = cornerRadius;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1313,50 +1265,45 @@
         ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored");
         return false;
     }
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.sequence++;
-    mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
-                                                  matrix.dsdy);
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
+                                                 matrix.dsdy);
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.requestedTransparentRegion_legacy = transparent;
-    mState.current.modified = true;
+    mCurrentState.requestedTransparentRegion_legacy = transparent;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
-    Mutex::Autolock lock(mStateMutex);
-    const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask);
-    if (mState.current.flags == newFlags) return false;
-    mState.current.sequence++;
-    mState.current.flags = newFlags;
-    mState.current.modified = true;
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags) return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requestedCrop_legacy == crop) return false;
-    mState.current.sequence++;
-    mState.current.requestedCrop_legacy = crop;
+    if (mCurrentState.requestedCrop_legacy == crop) return false;
+    mCurrentState.sequence++;
+    mCurrentState.requestedCrop_legacy = crop;
     if (immediate && !mFreezeGeometryUpdates) {
-        mState.current.crop_legacy = crop;
+        mCurrentState.crop_legacy = crop;
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mState.current.modified = true;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
-    Mutex::Autolock lock(mStateMutex);
     if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
@@ -1364,29 +1311,22 @@
 }
 
 void Layer::setInfo(int32_t type, int32_t appId) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.appId = appId;
-    mState.current.type = type;
-    mState.current.modified = true;
+    mCurrentState.appId = appId;
+    mCurrentState.type = type;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.layerStack == layerStack) return false;
-    mState.current.sequence++;
-    mState.current.layerStack = layerStack;
-    mState.current.modified = true;
+    if (mCurrentState.layerStack == layerStack) return false;
+    mCurrentState.sequence++;
+    mCurrentState.layerStack = layerStack;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 uint32_t Layer::getLayerStack() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getLayerStackLocked();
-}
-
-uint32_t Layer::getLayerStackLocked() const {
     auto p = mDrawingParent.promote();
     if (p == nullptr) {
         return getDrawingState().layerStack;
@@ -1395,16 +1335,15 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.barrierLayer_legacy = barrierLayer;
-    mState.current.frameNumber_legacy = frameNumber;
+    mCurrentState.barrierLayer_legacy = barrierLayer;
+    mCurrentState.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
-    mState.current.modified = true;
-    pushPendingStateLocked();
-    mState.current.barrierLayer_legacy = nullptr;
-    mState.current.frameNumber_legacy = 0;
-    mState.current.modified = false;
+    mCurrentState.modified = true;
+    pushPendingState();
+    mCurrentState.barrierLayer_legacy = nullptr;
+    mCurrentState.frameNumber_legacy = 0;
+    mCurrentState.modified = false;
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
@@ -1417,8 +1356,7 @@
 // ----------------------------------------------------------------------------
 
 bool Layer::isHiddenByPolicy() const {
-    Mutex::Autolock lock(mStateMutex);
-    const State& s(mState.drawing);
+    const State& s(mDrawingState);
     const auto& parent = mDrawingParent.promote();
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
@@ -1463,7 +1401,6 @@
 
 // TODO(marissaw): add new layer state info to layer debugging
 LayerDebugInfo Layer::getLayerDebugInfo() const {
-    Mutex::Autolock lock(mStateMutex);
     LayerDebugInfo info;
     const State& ds = getDrawingState();
     info.mName = getName();
@@ -1473,7 +1410,7 @@
     info.mTransparentRegion = ds.activeTransparentRegion_legacy;
     info.mVisibleRegion = visibleRegion;
     info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStackLocked();
+    info.mLayerStack = getLayerStack();
     info.mX = ds.active_legacy.transform.tx();
     info.mY = ds.active_legacy.transform.ty();
     info.mZ = ds.z;
@@ -1509,13 +1446,6 @@
     return info;
 }
 
-std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
-    const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-
-    return {state.layerStack, state.z};
-}
-
 void Layer::miniDumpHeader(std::string& result) {
     result.append("-------------------------------");
     result.append("-------------------------------");
@@ -1532,7 +1462,6 @@
 }
 
 void Layer::miniDump(std::string& result, DisplayId displayId) const {
-    Mutex::Autolock lock(mStateMutex);
     if (!hasHwcLayer(displayId)) {
         return;
     }
@@ -1644,6 +1573,7 @@
 
 ssize_t Layer::removeChild(const sp<Layer>& layer) {
     layer->setParent(nullptr);
+
     return mCurrentChildren.remove(layer);
 }
 
@@ -1661,16 +1591,10 @@
     }
 
     if (attachChildren()) {
-        Mutex::Autolock lock(mStateMutex);
         setTransactionFlags(eTransactionNeeded);
     }
     for (const sp<Layer>& child : mCurrentChildren) {
         newParent->addChild(child);
-
-        sp<Client> client(child->mClientRef.promote());
-        if (client != nullptr) {
-            client->updateParent(newParent);
-        }
     }
     mCurrentChildren.clear();
 
@@ -1684,14 +1608,14 @@
 }
 
 bool Layer::reparent(const sp<IBinder>& newParentHandle) {
-    if (newParentHandle == nullptr) {
-        return false;
-    }
+    bool callSetTransactionFlags = false;
 
-    auto handle = static_cast<Handle*>(newParentHandle.get());
-    sp<Layer> newParent = handle->owner.promote();
-    if (newParent == nullptr) {
-        ALOGE("Unable to promote Layer handle");
+    // While layers are detached, we allow most operations
+    // and simply halt performing the actual transaction. However
+    // for reparent != null we would enter the mRemovedFromCurrentState
+    // state, regardless of whether doTransaction was called, and
+    // so we need to prevent the update here.
+    if (mLayerDetached && newParentHandle == nullptr) {
         return false;
     }
 
@@ -1699,25 +1623,31 @@
     if (parent != nullptr) {
         parent->removeChild(this);
     }
-    newParent->addChild(this);
 
-    if (!newParent->isRemovedFromCurrentState()) {
-        addToCurrentState();
+    if (newParentHandle != nullptr) {
+        auto handle = static_cast<Handle*>(newParentHandle.get());
+        sp<Layer> newParent = handle->owner.promote();
+        if (newParent == nullptr) {
+            ALOGE("Unable to promote Layer handle");
+            return false;
+        }
+
+        newParent->addChild(this);
+        if (!newParent->isRemovedFromCurrentState()) {
+            addToCurrentState();
+        } else {
+            onRemovedFromCurrentState();
+        }
+
+        if (mLayerDetached) {
+            mLayerDetached = false;
+            callSetTransactionFlags = true;
+        }
+    } else {
+        onRemovedFromCurrentState();
     }
 
-    sp<Client> client(mClientRef.promote());
-    sp<Client> newParentClient(newParent->mClientRef.promote());
-
-    if (client != newParentClient) {
-        client->updateParent(newParent);
-    }
-
-    Mutex::Autolock lock(mStateMutex);
-    if (mLayerDetached) {
-        mLayerDetached = false;
-        setTransactionFlags(eTransactionNeeded);
-    }
-    if (attachChildren()) {
+    if (callSetTransactionFlags || attachChildren()) {
         setTransactionFlags(eTransactionNeeded);
     }
     return true;
@@ -1756,24 +1686,18 @@
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.colorTransform == matrix) {
+    if (mCurrentState.colorTransform == matrix) {
         return false;
     }
-    ++mState.current.sequence;
-    mState.current.colorTransform = matrix;
-    mState.current.hasColorTransform = matrix != identityMatrix;
-    mState.current.modified = true;
+    ++mCurrentState.sequence;
+    mCurrentState.colorTransform = matrix;
+    mCurrentState.hasColorTransform = matrix != identityMatrix;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 mat4 Layer::getColorTransform() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getColorTransformLocked();
-}
-
-mat4 Layer::getColorTransformLocked() const {
     mat4 colorTransform = mat4(getDrawingState().colorTransform);
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         colorTransform = parent->getColorTransform() * colorTransform;
@@ -1782,7 +1706,6 @@
 }
 
 bool Layer::hasColorTransform() const {
-    Mutex::Autolock lock(mStateMutex);
     bool hasColorTransform = getDrawingState().hasColorTransform;
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         hasColorTransform = hasColorTransform || parent->hasColorTransform();
@@ -1813,18 +1736,12 @@
 }
 
 int32_t Layer::getZ() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.drawing.z;
+    return mDrawingState.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
-    return usingRelativeZLocked(stateSet);
-}
-
-bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
     return state.zOrderRelativeOf != nullptr;
 }
 
@@ -1834,7 +1751,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     if (state.zOrderRelatives.size() == 0) {
         *outSkipRelativeZUsers = true;
@@ -1850,7 +1767,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
+        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
         if (childState.zOrderRelativeOf != nullptr) {
             continue;
         }
@@ -1889,6 +1806,7 @@
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
+
         if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
             continue;
         }
@@ -1936,7 +1854,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     LayerVector traverse(stateSet);
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1949,7 +1867,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
+        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
         // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
         // descendent of the top most parent of the tree. If it's not a descendent, then just add
         // the child here since it won't be added later as a relative.
@@ -2006,16 +1924,10 @@
 }
 
 ui::Transform Layer::getTransform() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getTransformLocked();
-}
-
-ui::Transform Layer::getTransformLocked() const {
     ui::Transform t;
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        Mutex::Autolock lock(p->mStateMutex);
-        t = p->getTransformLocked();
+        t = p->getTransform();
 
         // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
         // it isFixedSize) then there may be additional scaling not accounted
@@ -2043,27 +1955,18 @@
 }
 
 half Layer::getAlpha() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getAlphaLocked();
-}
-
-half Layer::getAlphaLocked() const {
     const auto& p = mDrawingParent.promote();
+
     half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
     return parentAlpha * getDrawingState().color.a;
 }
 
 half4 Layer::getColor() const {
     const half4 color(getDrawingState().color);
-    return half4(color.r, color.g, color.b, getAlphaLocked());
+    return half4(color.r, color.g, color.b, getAlpha());
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getRoundedCornerStateLocked();
-}
-
-Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
         RoundedCornerState parentState = p->getRoundedCornerState();
@@ -2080,7 +1983,7 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState();
+    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -2093,21 +1996,19 @@
 }
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.inputInfo = info;
-    mState.current.modified = true;
-    mState.current.inputInfoChanged = true;
+    mCurrentState.inputInfo = info;
+    mCurrentState.modified = true;
+    mCurrentState.inputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     ui::Transform requestedTransform = state.active_legacy.transform;
-    ui::Transform transform = getTransformLocked();
+    ui::Transform transform = getTransform();
 
     layerInfo->set_id(sequence);
     layerInfo->set_name(getName().c_str());
@@ -2129,7 +2030,7 @@
     LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
     LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
 
-    layerInfo->set_layer_stack(getLayerStackLocked());
+    layerInfo->set_layer_stack(getLayerStack());
     layerInfo->set_z(state.z);
 
     PositionProto* position = layerInfo->mutable_position();
@@ -2145,7 +2046,7 @@
     size->set_h(state.active_legacy.h);
 
     LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
-    layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius);
+    layerInfo->set_corner_radius(getRoundedCornerState().radius);
 
     layerInfo->set_is_opaque(isOpaque(state));
     layerInfo->set_invalidate(contentDirty);
@@ -2186,7 +2087,7 @@
     layerInfo->set_curr_frame(mCurrentFrameNumber);
     layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    for (const auto& pendingState : mState.pending) {
+    for (const auto& pendingState : mPendingStates) {
         auto barrierLayer = pendingState.barrierLayer_legacy.promote();
         if (barrierLayer != nullptr) {
             BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
@@ -2230,25 +2131,19 @@
 }
 
 InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
-    InputWindowInfo info;
-    ui::Transform t;
-    Rect layerBounds;
-    {
-        Mutex::Autolock lock(mStateMutex);
-        info = mState.drawing.inputInfo;
-        t = getTransformLocked();
-        const float xScale = t.sx();
-        const float yScale = t.sy();
-        if (xScale != 1.0f || yScale != 1.0f) {
-            info.windowXScale *= 1.0f / xScale;
-            info.windowYScale *= 1.0f / yScale;
-            info.touchableRegion.scaleSelf(xScale, yScale);
-        }
+    InputWindowInfo info = mDrawingState.inputInfo;
 
-        // Transform layer size to screen space and inset it by surface insets.
-        layerBounds = getCroppedBufferSize(getDrawingState());
+    ui::Transform t = getTransform();
+    const float xScale = t.sx();
+    const float yScale = t.sy();
+    if (xScale != 1.0f || yScale != 1.0f) {
+        info.windowXScale *= 1.0f / xScale;
+        info.windowYScale *= 1.0f / yScale;
+        info.touchableRegion.scaleSelf(xScale, yScale);
     }
 
+    // Transform layer size to screen space and inset it by surface insets.
+    Rect layerBounds = getCroppedBufferSize(getDrawingState());
     layerBounds = t.transform(layerBounds);
     layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
 
@@ -2271,8 +2166,7 @@
 }
 
 bool Layer::hasInput() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.drawing.inputInfo.token != nullptr;
+    return mDrawingState.inputInfo.token != nullptr;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index fb75e4c..2e75088 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -55,7 +55,6 @@
 #include "RenderArea.h"
 
 using namespace android::surfaceflinger;
-using StateSet = android::LayerVector::StateSet;
 
 namespace android {
 
@@ -240,7 +239,7 @@
     // also the rendered size of the layer prior to any transformations. Parent
     // or local matrix transformations will not affect the size of the buffer,
     // but may affect it's on-screen size or clipping.
-    virtual bool setSize(uint32_t w, uint32_t h) EXCLUDES(mStateMutex);
+    virtual bool setSize(uint32_t w, uint32_t h);
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
@@ -255,76 +254,58 @@
 
     // setPosition operates in parent buffer space (pre parent-transform) or display
     // space for top-level layers.
-    virtual bool setPosition(float x, float y, bool immediate) EXCLUDES(mStateMutex);
+    virtual bool setPosition(float x, float y, bool immediate);
     // Buffer space
-    virtual bool setCrop_legacy(const Rect& crop, bool immediate) EXCLUDES(mStateMutex);
+    virtual bool setCrop_legacy(const Rect& crop, bool immediate);
 
     // TODO(b/38182121): Could we eliminate the various latching modes by
     // using the layer hierarchy?
     // -----------------------------------------------------------------------
-    virtual bool setLayer(int32_t z) EXCLUDES(mStateMutex);
-    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ)
-            EXCLUDES(mStateMutex);
+    virtual bool setLayer(int32_t z);
+    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
 
-    virtual bool setAlpha(float alpha) EXCLUDES(mStateMutex);
-    virtual bool setColor(const half3& color) EXCLUDES(mStateMutex);
+    virtual bool setAlpha(float alpha);
+    virtual bool setColor(const half3& color);
 
     // Set rounded corner radius for this layer and its children.
     //
     // We only support 1 radius per layer in the hierarchy, where parent layers have precedence.
     // The shape of the rounded corner rectangle is specified by the crop rectangle of the layer
     // from which we inferred the rounded corner radius.
-    virtual bool setCornerRadius(float cornerRadius) EXCLUDES(mStateMutex);
-    virtual bool setTransparentRegionHint(const Region& transparent) EXCLUDES(mStateMutex);
-    virtual bool setFlags(uint8_t flags, uint8_t mask) EXCLUDES(mStateMutex);
-    virtual bool setLayerStack(uint32_t layerStack) EXCLUDES(mStateMutex);
-    virtual uint32_t getLayerStack() const EXCLUDES(mStateMutex);
+    virtual bool setCornerRadius(float cornerRadius);
+    virtual bool setTransparentRegionHint(const Region& transparent);
+    virtual bool setFlags(uint8_t flags, uint8_t mask);
+    virtual bool setLayerStack(uint32_t layerStack);
+    virtual uint32_t getLayerStack() const;
     virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle,
                                               uint64_t frameNumber);
-    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber)
-            EXCLUDES(mStateMutex);
-    virtual bool setOverrideScalingMode(int32_t overrideScalingMode) EXCLUDES(mStateMutex);
-    virtual void setInfo(int32_t type, int32_t appId) EXCLUDES(mStateMutex);
-    virtual bool reparentChildren(const sp<IBinder>& layer) EXCLUDES(mStateMutex);
+    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber);
+    virtual bool setOverrideScalingMode(int32_t overrideScalingMode);
+    virtual void setInfo(int32_t type, int32_t appId);
+    virtual bool reparentChildren(const sp<IBinder>& layer);
     virtual void setChildrenDrawingParent(const sp<Layer>& layer);
-    virtual bool reparent(const sp<IBinder>& newParentHandle) EXCLUDES(mStateMutex);
+    virtual bool reparent(const sp<IBinder>& newParentHandle);
     virtual bool detachChildren();
     bool attachChildren();
     bool isLayerDetached() const { return mLayerDetached; }
-    virtual bool setColorTransform(const mat4& matrix) EXCLUDES(mStateMutex);
-    mat4 getColorTransform() const EXCLUDES(mStateMutex);
-    virtual mat4 getColorTransformLocked() const REQUIRES(mStateMutex);
-    virtual bool hasColorTransform() const EXCLUDES(mStateMutex);
-    ;
+    virtual bool setColorTransform(const mat4& matrix);
+    virtual mat4 getColorTransform() const;
+    virtual bool hasColorTransform() const;
 
     // Used only to set BufferStateLayer state
-    virtual bool setTransform(uint32_t /*transform*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/)
-            EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setCrop(const Rect& /*crop*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setFrame(const Rect& /*frame*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setDataspace(ui::Dataspace /*dataspace*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setApi(int32_t /*api*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/)
-            EXCLUDES(mStateMutex) {
-        return false;
-    };
+    virtual bool setTransform(uint32_t /*transform*/) { return false; };
+    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
+    virtual bool setCrop(const Rect& /*crop*/) { return false; };
+    virtual bool setFrame(const Rect& /*frame*/) { return false; };
+    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) { return false; };
+    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
+    virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; };
+    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; };
+    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; };
+    virtual bool setApi(int32_t /*api*/) { return false; };
+    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
     virtual bool setTransactionCompletedListeners(
-            const std::vector<sp<CallbackHandle>>& /*handles*/) EXCLUDES(mStateMutex) {
+            const std::vector<sp<CallbackHandle>>& /*handles*/) {
         return false;
     };
 
@@ -343,21 +324,18 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
-    uint32_t getTransactionFlags() const EXCLUDES(mStateMutex);
-    uint32_t getTransactionFlags(uint32_t flags) EXCLUDES(mStateMutex);
-    uint32_t setTransactionFlags(uint32_t flags) REQUIRES(mStateMutex);
+    uint32_t getTransactionFlags() const { return mTransactionFlags; }
+    uint32_t getTransactionFlags(uint32_t flags);
+    uint32_t setTransactionFlags(uint32_t flags);
 
-    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const EXCLUDES(mStateMutex) {
+    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
         return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
     }
 
     void computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh,
-                         bool useIdentityTransform) const REQUIRES(mStateMutex);
-    FloatRect computeBounds(const Region& activeTransparentRegion) const EXCLUDES(mStateMutex);
-    FloatRect computeBoundsLocked(const Region& activeTransparentRegion) const
-            REQUIRES(mStateMutex);
-    FloatRect computeBounds() const EXCLUDES(mStateMutex);
-    FloatRect computeBoundsLocked() const REQUIRES(mStateMutex);
+                         bool useIdentityTransform) const;
+    FloatRect computeBounds(const Region& activeTransparentRegion) const;
+    FloatRect computeBounds() const;
 
     int32_t getSequence() const { return sequence; }
 
@@ -374,21 +352,16 @@
      */
     virtual bool isOpaque(const Layer::State&) const { return false; }
 
-    virtual bool isDrawingOpaque() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return isOpaque(mState.drawing);
-    }
-
     /*
      * isSecure - true if this surface is secure, that is if it prevents
      * screenshots or VNC servers.
      */
-    bool isSecure() const EXCLUDES(mStateMutex);
+    bool isSecure() const;
 
     /*
      * isVisible - true if this layer is visible, false otherwise
      */
-    virtual bool isVisible() const EXCLUDES(mStateMutex) = 0;
+    virtual bool isVisible() const = 0;
 
     /*
      * isHiddenByPolicy - true if this layer has been forced invisible.
@@ -396,7 +369,7 @@
      * For example if this layer has no active buffer, it may not be hidden by
      * policy, but it still can not be visible.
      */
-    bool isHiddenByPolicy() const EXCLUDES(mStateMutex);
+    bool isHiddenByPolicy() const;
 
     /*
      * isProtected - true if the layer may contain protected content in the
@@ -417,8 +390,7 @@
     bool isRemovedFromCurrentState() const;
 
     void writeToProto(LayerProto* layerInfo,
-                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing)
-            EXCLUDES(mStateMutex);
+                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
 
     void writeToProto(LayerProto* layerInfo, DisplayId displayId);
 
@@ -431,32 +403,25 @@
     virtual Region getActiveTransparentRegion(const Layer::State& s) const {
         return s.activeTransparentRegion_legacy;
     }
-
-    virtual Region getDrawingActiveTransparentRegion() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getActiveTransparentRegion(mState.drawing);
-    }
-
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
 
 protected:
     /*
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
-            EXCLUDES(mStateMutex) = 0;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
+                        bool useIdentityTransform) = 0;
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
 
     virtual bool isHdrY410() const { return false; }
 
-    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z) EXCLUDES(mStateMutex);
+    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z);
     void forceClientComposition(DisplayId displayId);
     bool getForceClientComposition(DisplayId displayId);
     virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform,
-                                 const Rect& viewport, int32_t supportedPerFrameMetadata)
-            EXCLUDES(mStateMutex) = 0;
+                                 const Rect& viewport, int32_t supportedPerFrameMetadata) = 0;
 
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
@@ -464,7 +429,7 @@
     HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const;
     void setClearClientTarget(DisplayId displayId, bool clear);
     bool getClearClientTarget(DisplayId displayId) const;
-    void updateCursorPosition(const sp<const DisplayDevice>& display) EXCLUDES(mStateMutex);
+    void updateCursorPosition(const sp<const DisplayDevice>& display);
 
     /*
      * called after page-flip
@@ -487,8 +452,7 @@
     virtual bool onPostComposition(const std::optional<DisplayId>& /*displayId*/,
                                    const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                    const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                   const CompositorTiming& /*compositorTiming*/)
-            EXCLUDES(mStateMutex) {
+                                   const CompositorTiming& /*compositorTiming*/) {
         return false;
     }
 
@@ -500,14 +464,14 @@
      * draw - performs some global clipping optimizations
      * and calls onDraw().
      */
-    void draw(const RenderArea& renderArea, const Region& clip) EXCLUDES(mStateMutex);
-    void draw(const RenderArea& renderArea, bool useIdentityTransform) EXCLUDES(mStateMutex);
+    void draw(const RenderArea& renderArea, const Region& clip);
+    void draw(const RenderArea& renderArea, bool useIdentityTransform);
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
-    uint32_t doTransaction(uint32_t transactionFlags) EXCLUDES(mStateMutex);
+    uint32_t doTransaction(uint32_t transactionFlags);
 
     /*
      * setVisibleRegion - called to set the new visible region. This gives
@@ -540,17 +504,17 @@
      * to figure out if the content or size of a surface has changed.
      */
     virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
-                               const sp<Fence>& /*releaseFence*/) EXCLUDES(mStateMutex) {
+                               const sp<Fence>& /*releaseFence*/) {
         return {};
     }
 
     virtual bool isBufferLatched() const { return false; }
 
     /*
-     * called with SurfaceFlinger mStateLock a binder thread when the layer is
+     * called with the state lock from a binder thread when the layer is
      * removed from the current list to the pending removal list
      */
-    void onRemovedFromCurrentState() EXCLUDES(mStateMutex);
+    void onRemovedFromCurrentState();
 
     /*
      * Called when the layer is added back to the current state list.
@@ -570,7 +534,7 @@
     /*
      * Returns if a frame is ready
      */
-    virtual bool hasReadyFrame() const EXCLUDES(mStateMutex) { return false; }
+    virtual bool hasReadyFrame() const { return false; }
 
     virtual int32_t getQueuedFrameCount() const { return 0; }
 
@@ -599,32 +563,17 @@
     }
 
     // -----------------------------------------------------------------------
-    void clearWithOpenGL(const RenderArea& renderArea) const EXCLUDES(mStateMutex);
+    void clearWithOpenGL(const RenderArea& renderArea) const;
 
-    inline const State& getDrawingState() const REQUIRES(mStateMutex) { return mState.drawing; }
+    inline const State& getDrawingState() const { return mDrawingState; }
+    inline const State& getCurrentState() const { return mCurrentState; }
+    inline State& getCurrentState() { return mCurrentState; }
 
-    inline const State& getCurrentState() const REQUIRES(mStateMutex) { return mState.current; }
-
-    inline State& getCurrentState() REQUIRES(mStateMutex) { return mState.current; }
-
-    std::tuple<uint32_t, int32_t> getLayerStackAndZ(StateSet stateSet) EXCLUDES(mStateMutex);
-    wp<Layer> getZOrderRelativeOf(StateSet stateSet) EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-
-        return state.zOrderRelativeOf;
-    }
-
-    uint8_t getCurrentFlags() EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return mState.current.flags;
-    }
-
-    LayerDebugInfo getLayerDebugInfo() const EXCLUDES(mStateMutex);
+    LayerDebugInfo getLayerDebugInfo() const;
 
     /* always call base class first */
     static void miniDumpHeader(std::string& result);
-    void miniDump(std::string& result, DisplayId displayId) const EXCLUDES(mStateMutex);
+    void miniDump(std::string& result, DisplayId displayId) const;
     void dumpFrameStats(std::string& result) const;
     void dumpFrameEvents(std::string& result);
     void clearFrameStats();
@@ -639,29 +588,22 @@
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
                                   FrameEventHistoryDelta* outDelta);
 
-    bool getTransformToDisplayInverse() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getTransformToDisplayInverseLocked();
-    }
+    virtual bool getTransformToDisplayInverse() const { return false; }
 
-    virtual bool getTransformToDisplayInverseLocked() const REQUIRES(mStateMutex) { return false; }
-
-    ui::Transform getTransform() const EXCLUDES(mStateMutex);
-    ui::Transform getTransformLocked() const REQUIRES(mStateMutex);
+    ui::Transform getTransform() const;
 
     // Returns the Alpha of the Surface, accounting for the Alpha
     // of parent Surfaces in the hierarchy (alpha's will be multiplied
     // down the hierarchy).
-    half getAlpha() const EXCLUDES(mStateMutex);
-    half4 getColor() const REQUIRES(mStateMutex);
+    half getAlpha() const;
+    half4 getColor() const;
 
     // Returns how rounded corners should be drawn for this layer.
     // This will traverse the hierarchy until it reaches its root, finding topmost rounded
     // corner definition and converting it into current layer's coordinates.
     // As of now, only 1 corner radius per display list is supported. Subsequent ones will be
     // ignored.
-    RoundedCornerState getRoundedCornerState() const EXCLUDES(mStateMutex);
-    RoundedCornerState getRoundedCornerStateLocked() const REQUIRES(mStateMutex);
+    RoundedCornerState getRoundedCornerState() const;
 
     void traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                  const LayerVector::Visitor& visitor);
@@ -681,7 +623,7 @@
     ssize_t removeChild(const sp<Layer>& layer);
     sp<Layer> getParent() const { return mCurrentParent.promote(); }
     bool hasParent() const { return getParent() != nullptr; }
-    Rect computeScreenBounds(bool reduceTransparentRegion = true) const EXCLUDES(mStateMutex);
+    Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
     bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
     bool setChildRelativeLayer(const sp<Layer>& childLayer,
             const sp<IBinder>& relativeToHandle, int32_t relativeZ);
@@ -689,23 +631,14 @@
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-    int32_t getZ() const EXCLUDES(mStateMutex);
-    void pushPendingState() EXCLUDES(mStateMutex);
-    virtual void pushPendingStateLocked() REQUIRES(mStateMutex);
+    int32_t getZ() const;
+    virtual void pushPendingState();
 
     /**
      * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
      * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
      */
-    virtual Rect getBufferSize(const Layer::State&) const REQUIRES(mStateMutex) {
-        return Rect::INVALID_RECT;
-    }
-
-    virtual Rect getBufferSize(StateSet stateSet) const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-        return getBufferSize(state);
-    }
+    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
 
 protected:
     // constant
@@ -734,17 +667,16 @@
     // For unit tests
     friend class TestableSurfaceFlinger;
 
-    void commitTransaction(const State& stateToCommit) REQUIRES(mStateMutex);
+    void commitTransaction(const State& stateToCommit);
 
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
-    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const
-            REQUIRES(mStateMutex);
+    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
     // Compute the initial crop as specified by parent layers and the
     // SurfaceControl for this layer. Does not include buffer crop from the
     // IGraphicBufferProducer client, as that should not affect child clipping.
     // Returns in screen space.
-    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const REQUIRES(mStateMutex);
+    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
     /**
      * Setup rounded corners coordinates of this layer, taking into account the layer bounds and
      * crop coordinates, transforming them into layer space.
@@ -752,13 +684,13 @@
     void setupRoundedCornersCropCoordinates(Rect win, const FloatRect& roundedCornersCrop) const;
 
     // drawing
-    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, float alpha) const
-            EXCLUDES(mStateMutex);
+    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
+                         float alpha) const;
     void setParent(const sp<Layer>& layer);
 
     LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
-    void addZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
-    void removeZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
+    void addZOrderRelative(const wp<Layer>& relative);
+    void removeZOrderRelative(const wp<Layer>& relative);
 
     class SyncPoint {
     public:
@@ -794,10 +726,9 @@
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
-    void popPendingState(State* stateToCommit) REQUIRES(mStateMutex);
-    virtual bool applyPendingStates(State* stateToCommit) REQUIRES(mStateMutex);
-    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit)
-            REQUIRES(mStateMutex);
+    void popPendingState(State* stateToCommit);
+    virtual bool applyPendingStates(State* stateToCommit);
+    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit);
 
     void clearSyncPoints();
 
@@ -830,15 +761,14 @@
     bool getPremultipledAlpha() const;
 
     bool mPendingHWCDestroy{false};
-    void setInputInfo(const InputWindowInfo& info) EXCLUDES(mStateMutex);
+    void setInputInfo(const InputWindowInfo& info);
 
-    InputWindowInfo fillInputInfo(const Rect& screenBounds) EXCLUDES(mStateMutex);
-    bool hasInput() const EXCLUDES(mStateMutex);
+    InputWindowInfo fillInputInfo(const Rect& screenBounds);
+    bool hasInput() const;
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet) EXCLUDES(mStateMutex);
-    bool usingRelativeZLocked(LayerVector::StateSet stateSet) REQUIRES(mStateMutex);
+    bool usingRelativeZ(LayerVector::StateSet stateSet);
 
     bool mPremultipliedAlpha{true};
     String8 mName;
@@ -846,14 +776,14 @@
 
     bool mPrimaryDisplayOnly = false;
 
+    // these are protected by an external lock
+    State mCurrentState;
+    State mDrawingState;
+    std::atomic<uint32_t> mTransactionFlags{0};
+
     // Accessed from main thread and binder threads
-    mutable Mutex mStateMutex;
-    struct {
-        State current;
-        State drawing;
-        uint32_t transactionFlags{0};
-        Vector<State> pending;
-    } mState GUARDED_BY(mStateMutex);
+    Mutex mPendingStateMutex;
+    Vector<State> mPendingStates;
 
     // Timestamp history for UIAutomation. Thread safe.
     FrameTracker mFrameTracker;
@@ -926,7 +856,7 @@
      * The cropped bounds must be transformed back from parent layer space to child layer space by
      * applying the inverse of the child's transformation.
      */
-    FloatRect cropChildBounds(const FloatRect& childBounds) const REQUIRES(mStateMutex);
+    FloatRect cropChildBounds(const FloatRect& childBounds) const;
 
     /**
      * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return
@@ -934,12 +864,7 @@
      * A layer with an invalid buffer size and no crop is considered to be boundless. The layer
      * bounds are constrained by its parent bounds.
      */
-    Rect getCroppedBufferSize(const Layer::State& s) const REQUIRES(mStateMutex);
-
-    // locked version of public methods
-    bool isSecureLocked() const REQUIRES(mStateMutex);
-    virtual uint32_t getLayerStackLocked() const REQUIRES(mStateMutex);
-    half getAlphaLocked() const REQUIRES(mStateMutex);
+    Rect getCroppedBufferSize(const Layer::State& s) const;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index a7db23e..8494524 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -38,12 +38,18 @@
     const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
     const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
 
-    const auto& [ls, lz] = l->getLayerStackAndZ(mStateSet);
-    const auto& [rs, rz] = r->getLayerStackAndZ(mStateSet);
+    const auto& lState =
+            (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
+    const auto& rState =
+            (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
 
+    uint32_t ls = lState.layerStack;
+    uint32_t rs = rState.layerStack;
     if (ls != rs)
         return (ls > rs) ? 1 : -1;
 
+    int32_t lz = lState.z;
+    int32_t rz = rState.z;
     if (lz != rz)
         return (lz > rz) ? 1 : -1;
 
@@ -56,8 +62,9 @@
 void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (size_t i = 0; i < size(); i++) {
         const auto& layer = (*this)[i];
-        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
-        if (zOrderRelativeOf != nullptr) {
+        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
+                                                      : layer->getDrawingState();
+        if (state.zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInZOrder(stateSet, visitor);
@@ -67,8 +74,9 @@
 void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
         const auto& layer = (*this)[i];
-        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
-        if (zOrderRelativeOf != nullptr) {
+        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
+                                                      : layer->getDrawingState();
+        if (state.zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInReverseZOrder(stateSet, visitor);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02cd9d9..dc82b32 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -35,32 +35,29 @@
 #include <binder/IServiceManager.h>
 #include <binder/PermissionCache.h>
 
+#include <compositionengine/CompositionEngine.h>
 #include <dvr/vr_flinger.h>
-
-#include <input/IInputFlinger.h>
-
-#include <ui/ColorSpace.h>
-#include <ui/DebugUtils.h>
-#include <ui/DisplayInfo.h>
-#include <ui/DisplayStatInfo.h>
-
 #include <gui/BufferQueue.h>
 #include <gui/GuiConfig.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/IProducerListener.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
+#include <input/IInputFlinger.h>
 #include <renderengine/RenderEngine.h>
+#include <ui/ColorSpace.h>
+#include <ui/DebugUtils.h>
+#include <ui/DisplayInfo.h>
+#include <ui/DisplayStatInfo.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
 #include <ui/UiConfig.h>
-
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
 #include <utils/StopWatch.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Trace.h>
+#include <utils/misc.h>
 
 #include <private/android_filesystem_config.h>
 #include <private/gui/SyncFeatures.h>
@@ -238,7 +235,6 @@
 
 SurfaceFlingerBE::SurfaceFlingerBE()
       : mHwcServiceName(getHwcServiceName()),
-        mRenderEngine(nullptr),
         mFrameBuckets(),
         mTotalTime(0),
         mLastSwapTime(0),
@@ -272,7 +268,8 @@
         mHasPoweredOff(false),
         mNumLayers(0),
         mVrFlingerRequestsDisplay(false),
-        mMainThreadId(std::this_thread::get_id()) {}
+        mMainThreadId(std::this_thread::get_id()),
+        mCompositionEngine{getFactory().createCompositionEngine()} {}
 
 SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
       : SurfaceFlinger(factory, SkipInitialization) {
@@ -458,19 +455,6 @@
     return initClient(new Client(this));
 }
 
-sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
-        const sp<IGraphicBufferProducer>& gbp) {
-    if (authenticateSurfaceTexture(gbp) == false) {
-        return nullptr;
-    }
-    const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
-    if (layer == nullptr) {
-        return nullptr;
-    }
-
-   return initClient(new Client(this, layer));
-}
-
 sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
         bool secure)
 {
@@ -544,6 +528,18 @@
     return NO_ERROR;
 }
 
+HWComposer& SurfaceFlinger::getHwComposer() const {
+    return mCompositionEngine->getHwComposer();
+}
+
+renderengine::RenderEngine& SurfaceFlinger::getRenderEngine() const {
+    return mCompositionEngine->getRenderEngine();
+}
+
+compositionengine::CompositionEngine& SurfaceFlinger::getCompositionEngine() const {
+    return *mCompositionEngine.get();
+}
+
 void SurfaceFlinger::bootFinished()
 {
     if (mStartPropertySetThread->join() != NO_ERROR) {
@@ -673,15 +669,14 @@
                             renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
 
     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
-    getBE().mRenderEngine =
+    mCompositionEngine->setRenderEngine(
             renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
-                                               renderEngineFeature);
-    LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
+                                               renderEngineFeature));
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
             "Starting with vr flinger active is not currently supported.");
-    getBE().mHwc = getFactory().createHWComposer(getBE().mHwcServiceName);
-    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
+    mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
+    mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
     // Process any initial hotplug and resulting display changes.
     processDisplayHotplugEventsLocked();
     const auto display = getDefaultDisplayDeviceLocked();
@@ -722,7 +717,7 @@
     // set initial conditions (e.g. unblank default device)
     initializeDisplays();
 
-    getBE().mRenderEngine->primeCache();
+    getRenderEngine().primeCache();
 
     // Inform native graphics APIs whether the present timestamp is supported:
 
@@ -762,11 +757,11 @@
 }
 
 size_t SurfaceFlinger::getMaxTextureSize() const {
-    return getBE().mRenderEngine->getMaxTextureSize();
+    return getRenderEngine().getMaxTextureSize();
 }
 
 size_t SurfaceFlinger::getMaxViewportDims() const {
-    return getBE().mRenderEngine->getMaxViewportDims();
+    return getRenderEngine().getMaxViewportDims();
 }
 
 // ----------------------------------------------------------------------------
@@ -1449,11 +1444,11 @@
     if (!mVrFlinger)
         return;
     bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
-    if (vrFlingerRequestsDisplay == getBE().mHwc->isUsingVrComposer()) {
+    if (vrFlingerRequestsDisplay == getHwComposer().isUsingVrComposer()) {
         return;
     }
 
-    if (vrFlingerRequestsDisplay && !getBE().mHwc->getComposer()->isRemote()) {
+    if (vrFlingerRequestsDisplay && !getHwComposer().getComposer()->isRemote()) {
         ALOGE("Vr flinger is only supported for remote hardware composer"
               " service connections. Ignoring request to transition to vr"
               " flinger.");
@@ -1476,12 +1471,13 @@
     }
 
     resetDisplayState();
-    getBE().mHwc.reset(); // Delete the current instance before creating the new one
-    getBE().mHwc = getFactory().createHWComposer(
-            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName);
-    getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId);
+    // Delete the current instance before creating the new one
+    mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
+    mCompositionEngine->setHwComposer(getFactory().createHWComposer(
+            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName));
+    getHwComposer().registerCallback(this, ++getBE().mComposerSequenceId);
 
-    LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(),
+    LOG_ALWAYS_FATAL_IF(!getHwComposer().getComposer()->isRemote(),
                         "Switched to non-remote hardware composer");
 
     if (vrFlingerRequestsDisplay) {
@@ -1504,9 +1500,10 @@
     // The present fences returned from vr_hwc are not an accurate
     // representation of vsync times.
     if (mUseScheduler) {
-        mScheduler->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() || !hasSyncFramework);
+        mScheduler->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
+                                           !hasSyncFramework);
     } else {
-        mPrimaryDispSync->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() ||
+        mPrimaryDispSync->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
                                                  !hasSyncFramework);
     }
 
@@ -1611,12 +1608,12 @@
 
     mHadClientComposition = false;
     for (const auto& [token, display] : mDisplays) {
-        mHadClientComposition = mHadClientComposition ||
-                getBE().mHwc->hasClientComposition(display->getId());
+        mHadClientComposition =
+                mHadClientComposition || getHwComposer().hasClientComposition(display->getId());
     }
 
     // Setup RenderEngine sync fences if native sync is supported.
-    if (getBE().mRenderEngine->useNativeFenceSync()) {
+    if (getRenderEngine().useNativeFenceSync()) {
         if (mHadClientComposition) {
             base::unique_fd flushFence(getRenderEngine().flush());
             ALOGE_IF(flushFence < 0, "Failed to flush RenderEngine!");
@@ -2285,7 +2282,7 @@
         // supply them with the present fence.
         if (!display->getLayersNeedingFences().isEmpty()) {
             sp<Fence> presentFence =
-                    displayId ? getBE().mHwc->getPresentFence(*displayId) : Fence::NO_FENCE;
+                    displayId ? getHwComposer().getPresentFence(*displayId) : Fence::NO_FENCE;
             for (auto& layer : display->getLayersNeedingFences()) {
                 layer->getBE().onLayerDisplayed(presentFence);
             }
@@ -2751,6 +2748,7 @@
     if (inputChanged || mVisibleRegionsDirty) {
         updateInputWindows();
     }
+    executeInputWindowCommands();
 
     updateCursorAsync();
 }
@@ -2775,6 +2773,23 @@
     mInputFlinger->setInputWindows(inputHandles);
 }
 
+void SurfaceFlinger::executeInputWindowCommands() {
+    if (!mInputFlinger) {
+        return;
+    }
+
+    for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
+        if (transferTouchFocusCommand.fromToken != nullptr &&
+            transferTouchFocusCommand.toToken != nullptr &&
+            transferTouchFocusCommand.fromToken != transferTouchFocusCommand.toToken) {
+            mInputFlinger->transferTouchFocus(transferTouchFocusCommand.fromToken,
+                                              transferTouchFocusCommand.toToken);
+        }
+    }
+
+    mInputWindowCommands.clear();
+}
+
 void SurfaceFlinger::updateCursorAsync()
 {
     for (const auto& [token, display] : mDisplays) {
@@ -2812,10 +2827,8 @@
             // showing at its last configured state until we eventually
             // abandon the buffer queue.
             if (l->isRemovedFromCurrentState()) {
-                l->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* child) {
-                    child->destroyHwcLayersForAllDisplays();
-                    latchAndReleaseBuffer(child);
-                });
+                l->destroyHwcLayersForAllDisplays();
+                latchAndReleaseBuffer(l);
             }
         }
         mLayersPendingRemoval.clear();
@@ -2849,6 +2862,9 @@
     outDirtyRegion.clear();
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
+        // start with the whole surface at its current location
+        const Layer::State& s(layer->getDrawingState());
+
         // only consider the layers on the given layer stack
         if (!layer->belongsToDisplay(display->getLayerStack(), display->isPrimary())) {
             return;
@@ -2886,7 +2902,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isDrawingOpaque();
+            const bool translucent = !layer->isOpaque(s);
             Rect bounds(layer->computeScreenBounds());
 
             visibleRegion.set(bounds);
@@ -2896,8 +2912,7 @@
                 if (translucent) {
                     if (tr.preserveRects()) {
                         // transform the transparent region
-                        transparentRegion =
-                                tr.transform(layer->getDrawingActiveTransparentRegion());
+                        transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
                     } else {
                         // transformation too complex, can't do the
                         // transparent region optimization.
@@ -3015,12 +3030,18 @@
         }
     });
 
-    for (auto& layer : mLayersWithQueuedFrames) {
-        const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
-        layer->useSurfaceDamage();
-        invalidateLayerStack(layer, dirty);
-        if (layer->isBufferLatched()) {
-            newDataLatched = true;
+    if (!mLayersWithQueuedFrames.empty()) {
+        // mStateLock is needed for latchBuffer as LayerRejecter::reject()
+        // writes to Layer current state. See also b/119481871
+        Mutex::Autolock lock(mStateLock);
+
+        for (auto& layer : mLayersWithQueuedFrames) {
+            const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
+            layer->useSurfaceDamage();
+            invalidateLayerStack(layer, dirty);
+            if (layer->isBufferLatched()) {
+                newDataLatched = true;
+            }
         }
     }
 
@@ -3082,7 +3103,7 @@
     const Region bounds(display->bounds());
     const DisplayRenderArea renderArea(display);
     const auto displayId = display->getId();
-    const bool hasClientComposition = getBE().mHwc->hasClientComposition(displayId);
+    const bool hasClientComposition = getHwComposer().hasClientComposition(displayId);
     ATRACE_INT("hasClientComposition", hasClientComposition);
 
     mat4 colorMatrix;
@@ -3117,15 +3138,15 @@
         if (display->hasWideColorGamut()) {
             outputDataspace = display->getCompositionDataSpace();
         }
-        getBE().mRenderEngine->setOutputDataSpace(outputDataspace);
-        getBE().mRenderEngine->setDisplayMaxLuminance(
+        getRenderEngine().setOutputDataSpace(outputDataspace);
+        getRenderEngine().setDisplayMaxLuminance(
                 display->getHdrCapabilities().getDesiredMaxLuminance());
 
-        const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(displayId);
+        const bool hasDeviceComposition = getHwComposer().hasDeviceComposition(displayId);
         const bool skipClientColorTransform =
-                getBE().mHwc
-                        ->hasDisplayCapability(displayId,
-                                               HWC2::DisplayCapability::SkipClientColorTransform);
+                getHwComposer()
+                        .hasDisplayCapability(displayId,
+                                              HWC2::DisplayCapability::SkipClientColorTransform);
 
         // Compute the global color transform matrix.
         applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
@@ -3142,7 +3163,7 @@
             // remove where there are opaque FB layers. however, on some
             // GPUs doing a "clean slate" clear might be more efficient.
             // We'll revisit later if needed.
-            getBE().mRenderEngine->clearWithColor(0, 0, 0, 0);
+            getRenderEngine().clearWithColor(0, 0, 0, 0);
         } else {
             // we start with the whole screen area and remove the scissor part
             // we're left with the letterbox region
@@ -3167,7 +3188,7 @@
             // the GL scissor so we don't draw anything where we shouldn't
 
             // enable scissor for this frame
-            getBE().mRenderEngine->setScissor(scissor);
+            getRenderEngine().setScissor(scissor);
         }
     }
 
@@ -3190,8 +3211,9 @@
                 case HWC2::Composition::Sideband:
                 case HWC2::Composition::SolidColor: {
                     LOG_ALWAYS_FATAL_IF(!displayId);
+                    const Layer::State& state(layer->getDrawingState());
                     if (layer->getClearClientTarget(*displayId) && !firstLayer &&
-                        layer->isDrawingOpaque() && (layer->getAlpha() == 1.0f) &&
+                        layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
                         layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
@@ -3225,7 +3247,7 @@
     // Perform some cleanup steps if we used client composition.
     if (hasClientComposition) {
         getRenderEngine().setColorTransform(mat4());
-        getBE().mRenderEngine->disableScissor();
+        getRenderEngine().disableScissor();
         display->finishBuffer();
         // Clear out error flags here so that we don't wait until next
         // composition to log.
@@ -3243,7 +3265,8 @@
         const sp<IBinder>& handle,
         const sp<IGraphicBufferProducer>& gbc,
         const sp<Layer>& lbc,
-        const sp<Layer>& parent)
+        const sp<Layer>& parent,
+        bool addToCurrentState)
 {
     // add this layer to the current state list
     {
@@ -3253,13 +3276,12 @@
                   MAX_LAYERS);
             return NO_MEMORY;
         }
-        if (parent == nullptr) {
+        if (parent == nullptr && addToCurrentState) {
             mCurrentState.layersSortedByZ.add(lbc);
-        } else {
-            if (parent->isRemovedFromCurrentState()) {
+        } else if (parent == nullptr || parent->isRemovedFromCurrentState()) {
                 ALOGE("addClientLayer called with a removed parent");
                 lbc->onRemovedFromCurrentState();
-            }
+        } else {
             parent->addChild(lbc);
         }
 
@@ -3280,30 +3302,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
-    Mutex::Autolock _l(mStateLock);
-    return removeLayerLocked(mStateLock, layer);
-}
-
-status_t SurfaceFlinger::removeLayerLocked(const Mutex& lock, const sp<Layer>& layer) {
-    if (layer->isLayerDetached()) {
-        return NO_ERROR;
-    }
-
-    const auto& p = layer->getParent();
-    ssize_t index;
-    if (p != nullptr) {
-        index = p->removeChild(layer);
-    } else {
-        index = mCurrentState.layersSortedByZ.remove(layer);
-    }
-
-    layer->onRemovedFromCurrentState();
-
-    markLayerPendingRemovalLocked(lock, layer);
-    return NO_ERROR;
-}
-
 uint32_t SurfaceFlinger::peekTransactionFlags() {
     return mTransactionFlags;
 }
@@ -3337,7 +3335,7 @@
             if (composerStateContainsUnsignaledFences(states)) {
                 break;
             }
-            applyTransactionState(states, displays, flags);
+            applyTransactionState(states, displays, flags, mInputWindowCommands);
             transactionQueue.pop();
         }
 
@@ -3383,7 +3381,8 @@
 
 void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
                                          const Vector<DisplayState>& displays, uint32_t flags,
-                                         const sp<IBinder>& applyToken) {
+                                         const sp<IBinder>& applyToken,
+                                         const InputWindowCommands& inputWindowCommands) {
     ATRACE_CALL();
     Mutex::Autolock _l(mStateLock);
 
@@ -3399,11 +3398,12 @@
         return;
     }
 
-    applyTransactionState(states, displays, flags);
+    applyTransactionState(states, displays, flags, inputWindowCommands);
 }
 
 void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
-                                           const Vector<DisplayState>& displays, uint32_t flags) {
+                                           const Vector<DisplayState>& displays, uint32_t flags,
+                                           const InputWindowCommands& inputWindowCommands) {
     uint32_t transactionFlags = 0;
 
     if (flags & eAnimation) {
@@ -3436,13 +3436,7 @@
     }
     transactionFlags |= clientStateFlags;
 
-    // Iterate through all layers again to determine if any need to be destroyed. Marking layers
-    // as destroyed should only occur after setting all other states. This is to allow for a
-    // child re-parent to happen before marking its original parent as destroyed (which would
-    // then mark the child as destroyed).
-    for (const ComposerState& state : states) {
-        setDestroyStateLocked(state);
-    }
+    transactionFlags |= addInputWindowCommands(inputWindowCommands);
 
     // If a synchronous transaction is explicitly requested without any changes, force a transaction
     // anyway. This can be used as a flush mechanism for previous async transactions.
@@ -3767,18 +3761,14 @@
     return flags;
 }
 
-void SurfaceFlinger::setDestroyStateLocked(const ComposerState& composerState) {
-    const layer_state_t& state = composerState.state;
-    sp<Client> client(static_cast<Client*>(composerState.client.get()));
-
-    sp<Layer> layer(client->getLayerUser(state.surface));
-    if (layer == nullptr) {
-        return;
+uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
+    uint32_t flags = 0;
+    if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
+        flags |= eTraversalNeeded;
     }
 
-    if (state.what & layer_state_t::eDestroySurface) {
-        removeLayerLocked(mStateLock, layer);
-    }
+    mInputWindowCommands.merge(inputWindowCommands);
+    return flags;
 }
 
 status_t SurfaceFlinger::createLayer(
@@ -3850,7 +3840,9 @@
 
     layer->setInfo(windowType, ownerUid);
 
-    result = addClientLayer(client, *handle, *gbp, layer, *parent);
+    bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
+    result = addClientLayer(client, *handle, *gbp, layer, *parent,
+            addToCurrentState);
     if (result != NO_ERROR) {
         return result;
     }
@@ -3948,21 +3940,7 @@
 }
 
 
-status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
-{
-    // called by a client when it wants to remove a Layer
-    status_t err = NO_ERROR;
-    sp<Layer> l(client->getLayerUser(handle));
-    if (l != nullptr) {
-        mInterceptor->saveSurfaceDeletion(l);
-        err = removeLayer(l);
-        ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                "error removing layer=%p (%s)", l.get(), strerror(-err));
-    }
-    return err;
-}
-
-void SurfaceFlinger::markLayerPendingRemovalLocked(const Mutex&, const sp<Layer>& layer) {
+void SurfaceFlinger::markLayerPendingRemovalLocked(const sp<Layer>& layer) {
     mLayersPendingRemoval.add(layer);
     mLayersRemoved = true;
     setTransactionFlags(eTransactionNeeded);
@@ -3971,7 +3949,14 @@
 void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer)
 {
     Mutex::Autolock lock(mStateLock);
-    markLayerPendingRemovalLocked(mStateLock, layer);
+    // If a layer has a parent, we allow it to out-live it's handle
+    // with the idea that the parent holds a reference and will eventually
+    // be cleaned up. However no one cleans up the top-level so we do so
+    // here.
+    if (layer->getParent() == nullptr) {
+        mCurrentState.layersSortedByZ.remove(layer);
+    }
+    markLayerPendingRemovalLocked(layer);
     layer.clear();
 }
 
@@ -3995,7 +3980,7 @@
     d.width = 0;
     d.height = 0;
     displays.add(d);
-    setTransactionState(state, displays, 0, nullptr);
+    setTransactionState(state, displays, 0, nullptr, mInputWindowCommands);
 
     const auto display = getDisplayDevice(displayToken);
     if (!display) return;
@@ -4668,7 +4653,7 @@
     result.append("SurfaceFlinger global state:\n");
     colorizer.reset(result);
 
-    getBE().mRenderEngine->dump(result);
+    getRenderEngine().dump(result);
 
     if (const auto display = getDefaultDisplayDeviceLocked()) {
         display->undefinedRegion.dump(result, "undefinedRegion");
@@ -4814,7 +4799,6 @@
         // access to SF.
         case BOOT_FINISHED:
         case CLEAR_ANIMATION_FRAME_STATS:
-        case CREATE_CONNECTION:
         case CREATE_DISPLAY:
         case DESTROY_DISPLAY:
         case ENABLE_VSYNC_INJECTIONS:
@@ -4861,8 +4845,7 @@
         // Calling setTransactionState is safe, because you need to have been
         // granted a reference to Client* and Handle* to do anything with it.
         case SET_TRANSACTION_STATE:
-        // Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
-        case CREATE_SCOPED_CONNECTION:
+        case CREATE_CONNECTION:
         case GET_COLOR_MANAGEMENT:
         case GET_COMPOSITION_PREFERENCE: {
             return OK;
@@ -5144,7 +5127,7 @@
             // Is VrFlinger active?
             case 1028: {
                 Mutex::Autolock _l(mStateLock);
-                reply->writeBool(getBE().mHwc->isUsingVrComposer());
+                reply->writeBool(getHwComposer().isUsingVrComposer());
                 return NO_ERROR;
             }
             // Is device color managed?
@@ -5261,12 +5244,15 @@
                 mFlinger(flinger),
                 mChildrenOnly(childrenOnly) {}
         const ui::Transform& getTransform() const override { return mTransform; }
-        Rect getBounds() const override { return mLayer->getBufferSize(StateSet::Drawing); }
+        Rect getBounds() const override {
+            const Layer::State& layerState(mLayer->getDrawingState());
+            return mLayer->getBufferSize(layerState);
+        }
         int getHeight() const override {
-            return mLayer->getBufferSize(StateSet::Drawing).getHeight();
+            return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
         }
         int getWidth() const override {
-            return mLayer->getBufferSize(StateSet::Drawing).getWidth();
+            return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
         }
         bool isSecure() const override { return false; }
         bool needsFiltering() const override { return mNeedsFiltering; }
@@ -5333,7 +5319,7 @@
 
     const int uid = IPCThreadState::self()->getCallingUid();
     const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
-    if (!forSystem && parent->getCurrentFlags() & layer_state_t::eLayerSecure) {
+    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
         ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
@@ -5341,12 +5327,12 @@
     Rect crop(sourceCrop);
     if (sourceCrop.width() <= 0) {
         crop.left = 0;
-        crop.right = parent->getBufferSize(StateSet::Current).getWidth();
+        crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
     }
 
     if (sourceCrop.height() <= 0) {
         crop.top = 0;
-        crop.bottom = parent->getBufferSize(StateSet::Current).getHeight();
+        crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
     }
 
     int32_t reqWidth = crop.width() * frameScale;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 822bb18..ac730ab 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -146,32 +146,9 @@
 public:
     SurfaceFlingerBE();
 
-    // The current hardware composer interface.
-    //
-    // The following thread safety rules apply when accessing mHwc, either
-    // directly or via getHwComposer():
-    //
-    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
-    //    only when switching into and out of vr. Recreating mHwc must only be
-    //    done on the main thread.
-    //
-    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
-    //    mStateLock.
-    //
-    // 3. When accessing mHwc on a thread other than the main thread, we always
-    //    need to acquire mStateLock. This is because the main thread could be
-    //    in the process of destroying the current mHwc instance.
-    //
-    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
-    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
-    // destroy it, so it's always safe to access mHwc from any thread without
-    // acquiring mStateLock.
-    std::unique_ptr<HWComposer> mHwc;
-
     const std::string mHwcServiceName; // "default" for real use, something else for testing.
 
     // constant members (no synchronization needed for access)
-    std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
     EGLContext mEGLContext;
     EGLDisplay mEGLDisplay;
 
@@ -336,6 +313,9 @@
 
     surfaceflinger::Factory& getFactory() { return mFactory; }
 
+    // The CompositionEngine encapsulates all composition related interfaces and actions.
+    compositionengine::CompositionEngine& getCompositionEngine() const;
+
     // returns the default Display
     sp<const DisplayDevice> getDefaultDisplayDevice() const {
         Mutex::Autolock _l(mStateLock);
@@ -362,7 +342,7 @@
     // TODO: this should be made accessible only to HWComposer
     const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);
 
-    renderengine::RenderEngine& getRenderEngine() const { return *getBE().mRenderEngine; }
+    renderengine::RenderEngine& getRenderEngine() const;
 
     bool authenticateSurfaceTextureLocked(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -437,13 +417,13 @@
      * ISurfaceComposer interface
      */
     virtual sp<ISurfaceComposerClient> createConnection();
-    virtual sp<ISurfaceComposerClient> createScopedConnection(const sp<IGraphicBufferProducer>& gbp);
     virtual sp<IBinder> createDisplay(const String8& displayName, bool secure);
     virtual void destroyDisplay(const sp<IBinder>& displayToken);
     virtual sp<IBinder> getBuiltInDisplay(int32_t id);
     virtual void setTransactionState(const Vector<ComposerState>& state,
                                      const Vector<DisplayState>& displays, uint32_t flags,
-                                     const sp<IBinder>& applyToken);
+                                     const sp<IBinder>& applyToken,
+                                     const InputWindowCommands& inputWindowCommands);
     virtual void bootFinished();
     virtual bool authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -543,6 +523,7 @@
     void handleTransactionLocked(uint32_t transactionFlags);
 
     void updateInputWindows();
+    void executeInputWindowCommands();
     void updateCursorAsync();
 
     /* handlePageFlip - latch a new buffer if available and compute the dirty
@@ -555,8 +536,8 @@
      * Transactions
      */
     void applyTransactionState(const Vector<ComposerState>& state,
-                               const Vector<DisplayState>& displays, uint32_t flags)
-            REQUIRES(mStateLock);
+                               const Vector<DisplayState>& displays, uint32_t flags,
+                               const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock);
     bool flushTransactionQueues();
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t peekTransactionFlags();
@@ -569,7 +550,7 @@
     bool composerStateContainsUnsignaledFences(const Vector<ComposerState>& states);
     uint32_t setClientStateLocked(const ComposerState& composerState);
     uint32_t setDisplayStateLocked(const DisplayState& s);
-    void setDestroyStateLocked(const ComposerState& composerState);
+    uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
 
     /* ------------------------------------------------------------------------
      * Layer management
@@ -598,27 +579,19 @@
 
     String8 getUniqueLayerName(const String8& name);
 
-    // called in response to the window-manager calling
-    // ISurfaceComposerClient::destroySurface()
-    status_t onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle);
-
-    void markLayerPendingRemovalLocked(const Mutex& /* mStateLock */, const sp<Layer>& layer);
-
     // called when all clients have released all their references to
     // this layer meaning it is entirely safe to destroy all
     // resources associated to this layer.
     void onHandleDestroyed(sp<Layer>& layer);
-
-    // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const sp<Layer>& layer);
-    status_t removeLayerLocked(const Mutex&, const sp<Layer>& layer);
+    void markLayerPendingRemovalLocked(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     status_t addClientLayer(const sp<Client>& client,
             const sp<IBinder>& handle,
             const sp<IGraphicBufferProducer>& gbc,
             const sp<Layer>& lbc,
-            const sp<Layer>& parent);
+            const sp<Layer>& parent,
+            bool addToCurrentState);
 
     /* ------------------------------------------------------------------------
      * Boot animation, on/off animations and screen capture
@@ -697,7 +670,27 @@
      * H/W composer
      */
 
-    HWComposer& getHwComposer() const { return *getBE().mHwc; }
+    // The current hardware composer interface.
+    //
+    // The following thread safety rules apply when accessing mHwc, either
+    // directly or via getHwComposer():
+    //
+    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
+    //    only when switching into and out of vr. Recreating mHwc must only be
+    //    done on the main thread.
+    //
+    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
+    //    mStateLock.
+    //
+    // 3. When accessing mHwc on a thread other than the main thread, we always
+    //    need to acquire mStateLock. This is because the main thread could be
+    //    in the process of destroying the current mHwc instance.
+    //
+    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
+    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
+    // destroy it, so it's always safe to access mHwc from any thread without
+    // acquiring mStateLock.
+    HWComposer& getHwComposer() const;
 
     /* ------------------------------------------------------------------------
      * Compositing
@@ -1013,6 +1006,7 @@
     ui::Dataspace mWideColorGamutCompositionDataspace;
 
     SurfaceFlingerBE mBE;
+    std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
 
     bool mUseScheduler = false;
     std::unique_ptr<Scheduler> mScheduler;
@@ -1020,6 +1014,8 @@
     sp<Scheduler::ConnectionHandle> mSfConnectionHandle;
 
     sp<IInputFlinger> mInputFlinger;
+
+    InputWindowCommands mInputWindowCommands;
 };
 }; // namespace android
 
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.cpp b/services/surfaceflinger/SurfaceFlingerFactory.cpp
index 88649e3..77679e3 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerFactory.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <compositionengine/impl/CompositionEngine.h>
 #include <ui/GraphicBuffer.h>
 
 #include "BufferQueueLayer.h"
@@ -59,7 +60,7 @@
         }
 
         std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override {
-            return std::make_unique<HWComposer>(
+            return std::make_unique<android::impl::HWComposer>(
                     std::make_unique<Hwc2::impl::Composer>(serviceName));
         }
 
@@ -102,6 +103,10 @@
             return surfaceflinger::impl::createNativeWindowSurface(producer);
         }
 
+        std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+            return compositionengine::impl::createCompositionEngine();
+        }
+
         sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) override {
             return new ContainerLayer(args);
         }
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 1c27cc7..f747684 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -49,6 +49,9 @@
 struct DisplayDeviceCreationArgs;
 struct LayerCreationArgs;
 
+namespace compositionengine {
+class CompositionEngine;
+} // namespace compositionengine
 namespace surfaceflinger {
 
 class NativeWindowSurface;
@@ -78,6 +81,8 @@
     virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
             const sp<IGraphicBufferProducer>&) = 0;
 
+    virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;
+
     virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
     virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
     virtual sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) = 0;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index a6dcb7e..7bfe033 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -101,23 +101,22 @@
     transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
-    Mutex::Autolock lock(layer->mStateMutex);
-    addPositionLocked(transaction, layerId, layer->mState.current.active_legacy.transform.tx(),
-                      layer->mState.current.active_legacy.transform.ty());
-    addDepthLocked(transaction, layerId, layer->mState.current.z);
-    addAlphaLocked(transaction, layerId, layer->mState.current.color.a);
+    addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
+                      layer->mCurrentState.active_legacy.transform.ty());
+    addDepthLocked(transaction, layerId, layer->mCurrentState.z);
+    addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
     addTransparentRegionLocked(transaction, layerId,
-                               layer->mState.current.activeTransparentRegion_legacy);
-    addLayerStackLocked(transaction, layerId, layer->mState.current.layerStack);
-    addCropLocked(transaction, layerId, layer->mState.current.crop_legacy);
-    addCornerRadiusLocked(transaction, layerId, layer->mState.current.cornerRadius);
-    if (layer->mState.current.barrierLayer_legacy != nullptr) {
+                               layer->mCurrentState.activeTransparentRegion_legacy);
+    addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
+    addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy);
+    addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
+    if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
         addDeferTransactionLocked(transaction, layerId,
-                                  layer->mState.current.barrierLayer_legacy.promote(),
-                                  layer->mState.current.frameNumber_legacy);
+                                  layer->mCurrentState.barrierLayer_legacy.promote(),
+                                  layer->mCurrentState.frameNumber_legacy);
     }
     addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode());
-    addFlagsLocked(transaction, layerId, layer->mState.current.flags);
+    addFlagsLocked(transaction, layerId, layer->mCurrentState.flags);
 }
 
 void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -427,9 +426,8 @@
     SurfaceCreation* creation(increment->mutable_surface_creation());
     creation->set_id(getLayerId(layer));
     creation->set_name(getLayerName(layer));
-    Mutex::Autolock lock(layer->mStateMutex);
-    creation->set_w(layer->mState.current.active_legacy.w);
-    creation->set_h(layer->mState.current.active_legacy.h);
+    creation->set_w(layer->mCurrentState.active_legacy.w);
+    creation->set_h(layer->mCurrentState.active_legacy.h);
 }
 
 void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment,
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
new file mode 100644
index 0000000..cab33ae
--- /dev/null
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "libsurfaceflinger_unittest"
+    },
+    {
+      "name": "libcompositionengine_test"
+    }
+  ]
+}
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index a73ec6c..8560f5e 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -162,10 +162,10 @@
     setSystemUID();
     ASSERT_NO_FATAL_FAILURE(initClient());
 
-    // No one else can init the client.
+    // Anyone else can init the client.
     setBinUID();
     mComposerClient = new SurfaceComposerClient;
-    ASSERT_EQ(NO_INIT, mComposerClient->initCheck());
+    ASSERT_NO_FATAL_FAILURE(initClient());
 }
 
 TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
@@ -222,22 +222,6 @@
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
 
-TEST_F(CredentialsTest, CreateSurfaceTest) {
-    sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
-    DisplayInfo info;
-    SurfaceComposerClient::getDisplayInfo(display, &info);
-    const ssize_t displayWidth = info.w;
-    const ssize_t displayHeight = info.h;
-
-    std::function<bool()> condition = [=]() {
-        mBGSurfaceControl =
-                mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
-                                               PIXEL_FORMAT_RGBA_8888, 0);
-        return mBGSurfaceControl != nullptr && mBGSurfaceControl->isValid();
-    };
-    ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
-}
-
 TEST_F(CredentialsTest, CreateDisplayTest) {
     std::function<bool()> condition = [=]() {
         sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 3e1be8e..89c26f4 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -34,7 +34,7 @@
             auto surf = client->createSurface(String8("t"), 100, 100,
                     PIXEL_FORMAT_RGBA_8888, 0);
             ASSERT_TRUE(surf != nullptr);
-            client->destroySurface(surf->getHandle());
+            surf->clear();
         }
     };
 
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index e506757..8ec3e15 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -806,18 +806,6 @@
             Increment::IncrementCase::kSurfaceCreation);
 }
 
-TEST_F(SurfaceInterceptorTest, InterceptSurfaceDeletionWorks) {
-    enableInterceptor();
-    sp<SurfaceControl> layerToDelete = mComposerClient->createSurface(String8(LAYER_NAME),
-            SIZE_UPDATE, SIZE_UPDATE, PIXEL_FORMAT_RGBA_8888, 0);
-    mComposerClient->destroySurface(layerToDelete->getHandle());
-    disableInterceptor();
-
-    Trace capturedTrace;
-    ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace));
-    ASSERT_TRUE(singleIncrementFound(capturedTrace, Increment::IncrementCase::kSurfaceDeletion));
-}
-
 TEST_F(SurfaceInterceptorTest, InterceptDisplayCreationWorks) {
     captureTest(&SurfaceInterceptorTest::displayCreation,
             Increment::IncrementCase::kDisplayCreation);
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index d118ad6..991ea36 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -1023,7 +1023,7 @@
             .setRelativeLayer(layerG, layerR->getHandle(), 1)
             .apply();
 
-    mClient->destroySurface(layerG->getHandle());
+    layerG->clear();
     // layerG should have been removed
     screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
 }
@@ -4030,9 +4030,9 @@
     asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
     {
         mCapture = screenshot();
-        // Nothing should have changed.
+        // The surface should now be offscreen.
         mCapture->expectFGColor(64, 64);
-        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(74, 74);
         mCapture->expectFGColor(84, 84);
     }
 }
@@ -4610,7 +4610,7 @@
     ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
 
     auto redLayerHandle = redLayer->getHandle();
-    mClient->destroySurface(redLayerHandle);
+    redLayer->clear();
     SurfaceComposerClient::Transaction().apply(true);
 
     sp<GraphicBuffer> outBuffer;
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 2f35ae5..f63c911 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -20,6 +20,16 @@
         // Using the address sanitizer not only helps uncover issues in the code
         // covered by the tests, but also covers some of the tricky injection of
         // fakes the unit tests currently do.
+        //
+        // Note: If you get an runtime link error like:
+        //
+        //   CANNOT LINK EXECUTABLE "/data/local/tmp/libsurfaceflinger_unittest": library "libclang_rt.asan-aarch64-android.so" not found
+        //
+        // it is because the address sanitizer shared objects are not installed
+        // by default in the system image.
+        //
+        // You can either "make dist tests" before flashing, or set this
+        // option to false temporarily.
         address: true,
     },
     srcs: [
@@ -46,11 +56,14 @@
         "mock/MockMessageQueue.cpp",
         "mock/MockNativeWindowSurface.cpp",
         "mock/MockSurfaceInterceptor.cpp",
-        "mock/RenderEngine/MockRenderEngine.cpp",
         "mock/system/window/MockNativeWindow.cpp",
     ],
     static_libs: [
         "libgmock",
+        "libcompositionengine",
+        "libcompositionengine_mocks",
+        "librenderengine_mocks",
+
     ],
     header_libs: [
         "libsurfaceflinger_headers",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index b7c09ed..e417350 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -19,9 +19,11 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-
 #include <gui/IProducerListener.h>
 #include <log/log.h>
+#include <renderengine/mock/Framebuffer.h>
+#include <renderengine/mock/Image.h>
+#include <renderengine/mock/RenderEngine.h>
 #include <system/window.h>
 #include <utils/String8.h>
 
@@ -36,7 +38,6 @@
 #include "mock/MockEventControlThread.h"
 #include "mock/MockEventThread.h"
 #include "mock/MockMessageQueue.h"
-#include "mock/RenderEngine/MockRenderEngine.h"
 #include "mock/system/window/MockNativeWindow.h"
 
 namespace android {
@@ -767,7 +768,7 @@
 
         const auto displayId = test->mDisplay->getId();
         ASSERT_TRUE(displayId);
-        layer->createHwcLayer(test->mFlinger.mFlinger->getBE().mHwc.get(), *displayId);
+        layer->createHwcLayer(&test->mFlinger.getHwComposer(), *displayId);
 
         Mock::VerifyAndClear(test->mComposer);
 
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index bd9b140..ff84a62 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -21,9 +21,8 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-
 #include <log/log.h>
-
+#include <renderengine/mock/RenderEngine.h>
 #include <ui/DebugUtils.h>
 
 #include "DisplayIdentificationTest.h"
@@ -36,7 +35,6 @@
 #include "mock/MockMessageQueue.h"
 #include "mock/MockNativeWindowSurface.h"
 #include "mock/MockSurfaceInterceptor.h"
-#include "mock/RenderEngine/MockRenderEngine.h"
 #include "mock/gui/MockGraphicBufferConsumer.h"
 #include "mock/gui/MockGraphicBufferProducer.h"
 #include "mock/system/window/MockNativeWindow.h"
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 4da08b8..9ff5e8d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <compositionengine/impl/CompositionEngine.h>
+
 #include "BufferQueueLayer.h"
 #include "BufferStateLayer.h"
 #include "ColorLayer.h"
@@ -113,6 +115,10 @@
         return mCreateNativeWindowSurface(producer);
     }
 
+    std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+        return compositionengine::impl::createCompositionEngine();
+    }
+
     sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
         // TODO: Use test-fixture controlled factory
         return nullptr;
@@ -148,6 +154,10 @@
             std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
                     const sp<IGraphicBufferProducer>&)>;
     CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
+
+    using CreateCompositionEngineFunction =
+            std::function<std::unique_ptr<compositionengine::CompositionEngine>()>;
+    CreateCompositionEngineFunction mCreateCompositionEngine;
 };
 
 } // namespace surfaceflinger::test
@@ -158,11 +168,12 @@
     // functions.
 
     void setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) {
-        mFlinger->getBE().mRenderEngine = std::move(renderEngine);
+        mFlinger->mCompositionEngine->setRenderEngine(std::move(renderEngine));
     }
 
     void setupComposer(std::unique_ptr<Hwc2::Composer> composer) {
-        mFlinger->getBE().mHwc.reset(new HWComposer(std::move(composer)));
+        mFlinger->mCompositionEngine->setHwComposer(
+                std::make_unique<impl::HWComposer>(std::move(composer)));
     }
 
     using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction;
@@ -178,12 +189,11 @@
 
     using HotplugEvent = SurfaceFlinger::HotplugEvent;
 
-    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mState.current; }
-    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mState.drawing; }
+    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; }
+    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; }
 
     void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
-        Mutex::Autolock lock(layer->mStateMutex);
-        layer->mState.drawing.sidebandStream = sidebandStream;
+        layer->mDrawingState.sidebandStream = sidebandStream;
         layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
     }
 
@@ -253,6 +263,9 @@
     const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
     const auto& getHWVsyncAvailable() const { return mFlinger->mHWVsyncAvailable; }
     const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
+    auto& getHwComposer() const {
+        return static_cast<impl::HWComposer&>(mFlinger->getHwComposer());
+    }
 
     const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; }
 
@@ -285,13 +298,10 @@
     auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
 
     auto& mutableComposerSequenceId() { return mFlinger->getBE().mComposerSequenceId; }
-    auto& mutableHwcDisplayData() { return mFlinger->getHwComposer().mDisplayData; }
-    auto& mutableHwcPhysicalDisplayIdMap() {
-        return mFlinger->getHwComposer().mPhysicalDisplayIdMap;
-    }
-
-    auto& mutableInternalHwcDisplayId() { return mFlinger->getHwComposer().mInternalHwcDisplayId; }
-    auto& mutableExternalHwcDisplayId() { return mFlinger->getHwComposer().mExternalHwcDisplayId; }
+    auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; }
+    auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
+    auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
+    auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
 
     ~TestableSurfaceFlinger() {
         // All these pointer and container clears help ensure that GMock does
@@ -304,8 +314,9 @@
         mutableEventThread().reset();
         mutableInterceptor().reset();
         mutablePrimaryDispSync().reset();
-        mFlinger->getBE().mHwc.reset();
-        mFlinger->getBE().mRenderEngine.reset();
+        mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
+        mFlinger->mCompositionEngine->setRenderEngine(
+                std::unique_ptr<renderengine::RenderEngine>());
     }
 
     /* ------------------------------------------------------------------------
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 2a6e9da..409bce9 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -369,7 +369,9 @@
           (consumer_state_mask & BufferHubDefs::kHighBitsMask);
     }
   }
-  if (update_buffer_state) {
+  if (update_buffer_state || BufferHubDefs::IsClientPosted(
+                                 buffer_state_->load(std::memory_order_acquire),
+                                 consumer_state_mask)) {
     consumer->OnProducerPosted();
   }
 
@@ -537,8 +539,13 @@
 
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
+  uint32_t current_active_clients_bit_mask =
+      active_clients_bit_mask_->load(std::memory_order_acquire);
+  // Signal producer if all current active consumers have released the buffer.
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
-                                      ~orphaned_consumer_bit_mask_)) {
+                                      ~orphaned_consumer_bit_mask_ &
+                                      current_active_clients_bit_mask)) {
+    buffer_state_->store(0U);
     SignalAvailable();
     if (orphaned_consumer_bit_mask_) {
       ALOGW(
@@ -564,8 +571,13 @@
 
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
+  uint32_t current_active_clients_bit_mask =
+      active_clients_bit_mask_->load(std::memory_order_acquire);
+  // Signal producer if all current active consumers have released the buffer.
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
-                                      ~orphaned_consumer_bit_mask_)) {
+                                      ~orphaned_consumer_bit_mask_ &
+                                      current_active_clients_bit_mask)) {
+    buffer_state_->store(0U);
     SignalAvailable();
   }
 
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
index b478bb5..a82df7f 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
@@ -10,7 +10,7 @@
 class ParcelableComposerFrame : public Parcelable {
  public:
   ParcelableComposerFrame();
-  ParcelableComposerFrame(const ComposerView::Frame& frame);
+  explicit ParcelableComposerFrame(const ComposerView::Frame& frame);
   ~ParcelableComposerFrame() override;
 
   ComposerView::Frame frame() const { return frame_; }
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
index 4cf48f1..6d2ac09 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
@@ -12,7 +12,7 @@
 class ParcelableComposerLayer : public Parcelable {
  public:
   ParcelableComposerLayer();
-  ParcelableComposerLayer(const ComposerView::ComposerLayer& layer);
+  explicit ParcelableComposerLayer(const ComposerView::ComposerLayer& layer);
   ~ParcelableComposerLayer() override;
 
   ComposerView::ComposerLayer layer() const { return layer_; }
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
index daf9e6d..c4216f6 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
@@ -13,7 +13,7 @@
 class ParcelableUniqueFd : public Parcelable {
  public:
   ParcelableUniqueFd();
-  ParcelableUniqueFd(const base::unique_fd& fence);
+  explicit ParcelableUniqueFd(const base::unique_fd& fence);
   ~ParcelableUniqueFd() override;
 
   void set_fence(const base::unique_fd& fence) {
diff --git a/services/vr/hardware_composer/impl/vr_composer_client.h b/services/vr/hardware_composer/impl/vr_composer_client.h
index de22640..0b7ce5e 100644
--- a/services/vr/hardware_composer/impl/vr_composer_client.h
+++ b/services/vr/hardware_composer/impl/vr_composer_client.h
@@ -35,13 +35,13 @@
 
 class VrComposerClient : public ComposerClient {
  public:
-  VrComposerClient(android::dvr::VrHwc& hal);
+  explicit VrComposerClient(android::dvr::VrHwc& hal);
   virtual ~VrComposerClient();
 
  private:
   class VrCommandEngine : public ComposerCommandEngine {
    public:
-    VrCommandEngine(VrComposerClient& client);
+    explicit VrCommandEngine(VrComposerClient& client);
     ~VrCommandEngine() override;
 
     bool executeCommand(IComposerClient::Command command,
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
index f9872b2..e8c0212 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.h
+++ b/services/vr/hardware_composer/impl/vr_hwc.h
@@ -113,9 +113,7 @@
   using Composition =
       hardware::graphics::composer::V2_1::IComposerClient::Composition;
 
-  HwcLayer(Layer new_id) {
-    info.id = new_id;
-  }
+  explicit HwcLayer(Layer new_id) { info.id = new_id; }
 
   void dumpDebugInfo(std::string* result) const;
 
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
index 2c46209..2c88aec 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.h
@@ -13,7 +13,7 @@
 //
 class VirtualTouchpadService : public BnVirtualTouchpadService {
  public:
-  VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
+  explicit VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
       : touchpad_(std::move(touchpad)), client_pid_(0) {}
   ~VirtualTouchpadService() override;