Merge "Add ANGLE support to getDisplay"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index f8f0265..2d780f5 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,7 @@
 [Hook Scripts]
 owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
 installd_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/installd/"
+dumpstate_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/dumpstate/"
+dumpsys_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/dumpsys/"
+# bugreports matches both cmds/bugreport and cmds/bugreportz
+bugreports_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/bugreport"
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index bb84a18..cc2a6f7 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -19,6 +19,7 @@
         "libz",
         "libbase",
         "libpdx_default_transport",
+        "android.hardware.atrace@1.0",
     ],
 
     init_rc: ["atrace.rc"],
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 94dbebc..e897482 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -37,6 +37,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/Parcel.h>
 
+#include <android/hardware/atrace/1.0/IAtraceDevice.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
@@ -52,6 +53,12 @@
 
 using namespace android;
 using pdx::default_transport::ServiceUtility;
+using hardware::hidl_vec;
+using hardware::hidl_string;
+using hardware::Return;
+using hardware::atrace::V1_0::IAtraceDevice;
+using hardware::atrace::V1_0::Status;
+using hardware::atrace::V1_0::toString;
 
 using std::string;
 
@@ -92,11 +99,7 @@
 
 /* Tracing categories */
 static const TracingCategory k_categories[] = {
-    { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, {
-        { OPT,      "events/mdss/enable" },
-        { OPT,      "events/sde/enable" },
-        { OPT,      "events/mali_systrace/enable" },
-    } },
+    { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, { } },
     { "input",      "Input",            ATRACE_TAG_INPUT, { } },
     { "view",       "View System",      ATRACE_TAG_VIEW, { } },
     { "webview",    "WebView",          ATRACE_TAG_WEBVIEW, { } },
@@ -223,6 +226,23 @@
     } },
 };
 
+struct TracingVendorCategory {
+    // The name identifying the category.
+    std::string name;
+
+    // A longer description of the category.
+    std::string description;
+
+    // If the category is enabled through command.
+    bool enabled;
+
+    TracingVendorCategory(string &&name, string &&description, bool enabled)
+            : name(std::move(name))
+            , description(std::move(description))
+            , enabled(enabled)
+    {}
+};
+
 /* Command line options */
 static int g_traceDurationSeconds = 5;
 static bool g_traceOverwrite = false;
@@ -240,6 +260,8 @@
 static bool g_traceAborted = false;
 static bool g_categoryEnables[arraysize(k_categories)] = {};
 static std::string g_traceFolder;
+static sp<IAtraceDevice> g_atraceHal;
+static std::vector<TracingVendorCategory> g_vendorCategories;
 
 /* Sys file paths */
 static const char* k_traceClockPath =
@@ -755,13 +777,20 @@
     return ok;
 }
 
-static bool setCategoryEnable(const char* name, bool enable)
+static bool setCategoryEnable(const char* name)
 {
+    bool vendor_found = false;
+    for (auto &c : g_vendorCategories) {
+        if (strcmp(name, c.name.c_str()) == 0) {
+            c.enabled = true;
+            vendor_found = true;
+        }
+    }
     for (size_t i = 0; i < arraysize(k_categories); i++) {
         const TracingCategory& c = k_categories[i];
         if (strcmp(name, c.name) == 0) {
             if (isCategorySupported(c)) {
-                g_categoryEnables[i] = enable;
+                g_categoryEnables[i] = true;
                 return true;
             } else {
                 if (isCategorySupportedForRoot(c)) {
@@ -775,6 +804,9 @@
             }
         }
     }
+    if (vendor_found) {
+        return true;
+    }
     fprintf(stderr, "error: unknown tracing category \"%s\"\n", name);
     return false;
 }
@@ -795,7 +827,7 @@
             tokenizer->skipDelimiters(" ");
             continue;
         }
-        ok &= setCategoryEnable(token.string(), true);
+        ok &= setCategoryEnable(token.string());
     }
     delete tokenizer;
     return ok;
@@ -1083,6 +1115,9 @@
             printf("  %10s - %s\n", c.name, c.longname);
         }
     }
+    for (const auto &c : g_vendorCategories) {
+        printf("  %10s - %s (HAL)\n", c.name.c_str(), c.description.c_str());
+    }
 }
 
 // Print the command usage help to stderr.
@@ -1139,6 +1174,79 @@
     return true;
 }
 
+void initVendorCategories()
+{
+    g_atraceHal = IAtraceDevice::getService();
+
+    if (g_atraceHal == nullptr) {
+        // No atrace HAL
+        return;
+    }
+
+    Return<void> ret = g_atraceHal->listCategories(
+        [](const auto& list) {
+            g_vendorCategories.reserve(list.size());
+            for (const auto& category : list) {
+                g_vendorCategories.emplace_back(category.name, category.description, false);
+            }
+        });
+    if (!ret.isOk()) {
+        fprintf(stderr, "calling atrace HAL failed: %s\n", ret.description().c_str());
+    }
+}
+
+static bool setUpVendorTracing()
+{
+    if (g_atraceHal == nullptr) {
+        // No atrace HAL
+        return true;
+    }
+
+    std::vector<hidl_string> categories;
+    for (const auto &c : g_vendorCategories) {
+        if (c.enabled) {
+            categories.emplace_back(c.name);
+        }
+    }
+
+    if (!categories.size()) {
+        return true;
+    }
+
+    auto ret = g_atraceHal->enableCategories(categories);
+    if (!ret.isOk()) {
+        fprintf(stderr, "calling atrace HAL failed: %s\n", ret.description().c_str());
+        return false;
+    } else if (ret != Status::SUCCESS) {
+        fprintf(stderr, "calling atrace HAL failed: %s\n", toString(ret).c_str());
+        return false;
+    }
+    return true;
+}
+
+static bool cleanUpVendorTracing()
+{
+    if (g_atraceHal == nullptr) {
+        // No atrace HAL
+        return true;
+    }
+
+    if (!g_vendorCategories.size()) {
+        // No vendor categories
+        return true;
+    }
+
+    auto ret = g_atraceHal->disableAllCategories();
+    if (!ret.isOk()) {
+        fprintf(stderr, "calling atrace HAL failed: %s\n", ret.description().c_str());
+        return false;
+    } else if (ret != Status::SUCCESS) {
+        fprintf(stderr, "calling atrace HAL failed: %s\n", toString(ret).c_str());
+        return false;
+    }
+    return true;
+}
+
 int main(int argc, char **argv)
 {
     bool async = false;
@@ -1158,6 +1266,8 @@
         exit(-1);
     }
 
+    initVendorCategories();
+
     for (;;) {
         int ret;
         int option_index = 0;
@@ -1176,7 +1286,7 @@
 
         if (ret < 0) {
             for (int i = optind; i < argc; i++) {
-                if (!setCategoryEnable(argv[i], true)) {
+                if (!setCategoryEnable(argv[i])) {
                     fprintf(stderr, "error enabling tracing category \"%s\"\n", argv[i]);
                     exit(1);
                 }
@@ -1279,6 +1389,7 @@
 
     if (ok && traceStart && !onlyUserspace) {
         ok &= setUpKernelTracing();
+        ok &= setUpVendorTracing();
         ok &= startTrace();
     }
 
@@ -1347,6 +1458,7 @@
 
     // Reset the trace buffer size to 1.
     if (traceStop) {
+        cleanUpVendorTracing();
         cleanUpUserspaceTracing();
         if (!onlyUserspace)
             cleanUpKernelTracing();
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 5903656..d950b7c 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -125,12 +125,6 @@
     chmod 0666 /sys/kernel/tracing/events/block/block_rq_complete/enable
     chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_complete/enable
 
-    # graphics
-    chmod 0666 /sys/kernel/tracing/events/sde/enable
-    chmod 0666 /sys/kernel/debug/tracing/events/sde/enable
-    chmod 0666 /sys/kernel/tracing/events/mdss/enable
-    chmod 0666 /sys/kernel/debug/tracing/events/mdss/enable
-
 # Tracing disabled by default
     write /sys/kernel/debug/tracing/tracing_on 0
     write /sys/kernel/tracing/tracing_on 0
diff --git a/cmds/bugreport/OWNERS b/cmds/bugreport/OWNERS
new file mode 100644
index 0000000..1ba7cff
--- /dev/null
+++ b/cmds/bugreport/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+
+felipeal@google.com
+nandana@google.com
+jsharkey@android.com
+enh@google.com
diff --git a/cmds/bugreportz/OWNERS b/cmds/bugreportz/OWNERS
new file mode 100644
index 0000000..1ba7cff
--- /dev/null
+++ b/cmds/bugreportz/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+
+felipeal@google.com
+nandana@google.com
+jsharkey@android.com
+enh@google.com
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index c852df1..5acc09d 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -133,6 +133,7 @@
     name: "dumpstate_test",
     defaults: ["dumpstate_defaults"],
     srcs: [
+        "dumpstate.cpp",
         "tests/dumpstate_test.cpp",
     ],
     static_libs: ["libgmock"],
diff --git a/cmds/dumpstate/OWNERS b/cmds/dumpstate/OWNERS
new file mode 100644
index 0000000..1ba7cff
--- /dev/null
+++ b/cmds/dumpstate/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+
+felipeal@google.com
+nandana@google.com
+jsharkey@android.com
+enh@google.com
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ff15794..d294d1e 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1716,24 +1716,118 @@
     // clang-format on
 }
 
-/** Main entry point for dumpstate. */
-int run_main(int argc, char* argv[]) {
-    int do_add_date = 0;
-    int do_zip_file = 0;
-    int do_vibrate = 1;
-    char* use_outfile = nullptr;
-    int use_socket = 0;
-    int use_control_socket = 0;
-    int do_fb = 0;
-    int do_broadcast = 0;
-    int is_remote_mode = 0;
-    bool show_header_only = false;
-    bool do_start_service = false;
-    bool telephony_only = false;
-    bool wifi_only = false;
-    int dup_stdout_fd;
-    int dup_stderr_fd;
+int Dumpstate::ParseCommandlineOptions(int argc, char* argv[]) {
+    int ret = -1;  // success
+    int c;
+    while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
+        switch (c) {
+            // clang-format off
+            case 'd': options_.do_add_date = true;            break;
+            case 'z': options_.do_zip_file = true;            break;
+            case 'o': options_.use_outfile = optarg;          break;
+            case 's': options_.use_socket = true;             break;
+            case 'S': options_.use_control_socket = true;     break;
+            case 'v': options_.show_header_only = true;       break;
+            case 'q': options_.do_vibrate = false;            break;
+            case 'p': options_.do_fb = true;                  break;
+            case 'P': update_progress_ = true;                break;
+            case 'R': options_.is_remote_mode = true;         break;
+            case 'B': options_.do_broadcast = true;           break;
+            case 'V':                                         break;  // compatibility no-op
+            case 'h':
+                ret = 0;
+                break;
+            default:
+                fprintf(stderr, "Invalid option: %c\n", c);
+                ret = 1;
+                break;
+                // clang-format on
+        }
+    }
 
+    // TODO: use helper function to convert argv into a string
+    for (int i = 0; i < argc; i++) {
+        args_ += argv[i];
+        if (i < argc - 1) {
+            args_ += " ";
+        }
+    }
+
+    // Reset next index used by getopt so this can be called multiple times, for eg, in tests.
+    optind = 1;
+    return ret;
+}
+
+// TODO: Move away from system properties when we have binder.
+void Dumpstate::SetOptionsFromProperties() {
+    extra_options_ = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
+    if (!extra_options_.empty()) {
+        // Framework uses a system property to override some command-line args.
+        // Currently, it contains the type of the requested bugreport.
+        if (extra_options_ == "bugreportplus") {
+            // Currently, the dumpstate binder is only used by Shell to update progress.
+            options_.do_start_service = true;
+            update_progress_ = true;
+            options_.do_fb = false;
+        } else if (extra_options_ == "bugreportremote") {
+            options_.do_vibrate = false;
+            options_.is_remote_mode = true;
+            options_.do_fb = false;
+        } else if (extra_options_ == "bugreportwear") {
+            options_.do_start_service = true;
+            update_progress_ = true;
+            options_.do_zip_file = true;
+        } else if (extra_options_ == "bugreporttelephony") {
+            options_.telephony_only = true;
+        } else if (extra_options_ == "bugreportwifi") {
+            options_.wifi_only = true;
+            options_.do_zip_file = true;
+        } else {
+            MYLOGE("Unknown extra option: %s\n", extra_options_.c_str());
+        }
+        // Reset the property
+        android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
+    }
+
+    notification_title = android::base::GetProperty(PROPERTY_EXTRA_TITLE, "");
+    if (!notification_title.empty()) {
+        // Reset the property
+        android::base::SetProperty(PROPERTY_EXTRA_TITLE, "");
+
+        notification_description = android::base::GetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
+        if (!notification_description.empty()) {
+            // Reset the property
+            android::base::SetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
+        }
+        MYLOGD("notification (title:  %s, description: %s)\n", notification_title.c_str(),
+               notification_description.c_str());
+    }
+}
+
+bool Dumpstate::ValidateOptions() {
+    if ((options_.do_zip_file || options_.do_add_date || ds.update_progress_ ||
+         options_.do_broadcast) &&
+        options_.use_outfile.empty()) {
+        return false;
+    }
+
+    if (options_.use_control_socket && !options_.do_zip_file) {
+        return false;
+    }
+
+    if (ds.update_progress_ && !options_.do_broadcast) {
+        return false;
+    }
+
+    if (options_.is_remote_mode && (ds.update_progress_ || !options_.do_broadcast ||
+                                    !options_.do_zip_file || !options_.do_add_date)) {
+        return false;
+    }
+    return true;
+}
+
+/* Main entry point for dumpstate. */
+int run_main(int argc, char* argv[]) {
     /* set as high priority, and protect from OOM killer */
     setpriority(PRIO_PROCESS, 0, -20);
 
@@ -1750,97 +1844,12 @@
         }
     }
 
-    /* parse arguments */
-    int c;
-    while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
-        switch (c) {
-            // clang-format off
-            case 'd': do_add_date = 1;            break;
-            case 'z': do_zip_file = 1;            break;
-            case 'o': use_outfile = optarg;       break;
-            case 's': use_socket = 1;             break;
-            case 'S': use_control_socket = 1;     break;
-            case 'v': show_header_only = true;    break;
-            case 'q': do_vibrate = 0;             break;
-            case 'p': do_fb = 1;                  break;
-            case 'P': ds.update_progress_ = true; break;
-            case 'R': is_remote_mode = 1;         break;
-            case 'B': do_broadcast = 1;           break;
-            case 'V':                             break; // compatibility no-op
-            case 'h':
-                ShowUsageAndExit(0);
-                break;
-            default:
-                fprintf(stderr, "Invalid option: %c\n", c);
-                ShowUsageAndExit();
-                // clang-format on
-        }
+    int status = ds.ParseCommandlineOptions(argc, argv);
+    if (status != -1) {
+        ShowUsageAndExit(status);
     }
-
-    // TODO: use helper function to convert argv into a string
-    for (int i = 0; i < argc; i++) {
-        ds.args_ += argv[i];
-        if (i < argc - 1) {
-            ds.args_ += " ";
-        }
-    }
-
-    ds.extra_options_ = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
-    if (!ds.extra_options_.empty()) {
-        // Framework uses a system property to override some command-line args.
-        // Currently, it contains the type of the requested bugreport.
-        if (ds.extra_options_ == "bugreportplus") {
-            // Currently, the dumpstate binder is only used by Shell to update progress.
-            do_start_service = true;
-            ds.update_progress_ = true;
-            do_fb = 0;
-        } else if (ds.extra_options_ == "bugreportremote") {
-            do_vibrate = 0;
-            is_remote_mode = 1;
-            do_fb = 0;
-        } else if (ds.extra_options_ == "bugreportwear") {
-            do_start_service = true;
-            ds.update_progress_ = true;
-            do_zip_file = 1;
-        } else if (ds.extra_options_ == "bugreporttelephony") {
-            telephony_only = true;
-        } else if (ds.extra_options_ == "bugreportwifi") {
-            wifi_only = true;
-            do_zip_file = 1;
-        } else {
-            MYLOGE("Unknown extra option: %s\n", ds.extra_options_.c_str());
-        }
-        // Reset the property
-        android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
-    }
-
-    ds.notification_title = android::base::GetProperty(PROPERTY_EXTRA_TITLE, "");
-    if (!ds.notification_title.empty()) {
-        // Reset the property
-        android::base::SetProperty(PROPERTY_EXTRA_TITLE, "");
-
-        ds.notification_description = android::base::GetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
-        if (!ds.notification_description.empty()) {
-            // Reset the property
-            android::base::SetProperty(PROPERTY_EXTRA_DESCRIPTION, "");
-        }
-        MYLOGD("notification (title:  %s, description: %s)\n",
-               ds.notification_title.c_str(), ds.notification_description.c_str());
-    }
-
-    if ((do_zip_file || do_add_date || ds.update_progress_ || do_broadcast) && !use_outfile) {
-        ExitOnInvalidArgs();
-    }
-
-    if (use_control_socket && !do_zip_file) {
-        ExitOnInvalidArgs();
-    }
-
-    if (ds.update_progress_ && !do_broadcast) {
-        ExitOnInvalidArgs();
-    }
-
-    if (is_remote_mode && (ds.update_progress_ || !do_broadcast || !do_zip_file || !do_add_date)) {
+    ds.SetOptionsFromProperties();
+    if (!ds.ValidateOptions()) {
         ExitOnInvalidArgs();
     }
 
@@ -1855,18 +1864,21 @@
         exit(1);
     }
 
-    if (show_header_only) {
+    // TODO: make const reference, but first avoid setting do_zip_file below.
+    Dumpstate::DumpOptions& options = ds.options_;
+    if (options.show_header_only) {
         ds.PrintHeader();
         exit(0);
     }
 
-    /* redirect output if needed */
-    bool is_redirecting = !use_socket && use_outfile;
+    // Redirect output if needed
+    bool is_redirecting = !options.use_socket && !options.use_outfile.empty();
 
     // TODO: temporarily set progress until it's part of the Dumpstate constructor
-    std::string stats_path =
-        is_redirecting ? android::base::StringPrintf("%s/dumpstate-stats.txt", dirname(use_outfile))
-                       : "";
+    std::string stats_path = is_redirecting
+                                 ? android::base::StringPrintf("%s/dumpstate-stats.txt",
+                                                               dirname(options.use_outfile.c_str()))
+                                 : "";
     ds.progress_.reset(new Progress(stats_path));
 
     /* gets the sequential id */
@@ -1878,7 +1890,7 @@
 
     register_sig_handler();
 
-    if (do_start_service) {
+    if (options.do_start_service) {
         MYLOGI("Starting 'dumpstate' service\n");
         android::status_t ret;
         if ((ret = android::os::DumpstateService::Start()) != android::OK) {
@@ -1899,23 +1911,24 @@
 
     // If we are going to use a socket, do it as early as possible
     // to avoid timeouts from bugreport.
-    if (use_socket) {
+    if (options.use_socket) {
         redirect_to_socket(stdout, "dumpstate");
     }
 
-    if (use_control_socket) {
+    if (options.use_control_socket) {
         MYLOGD("Opening control socket\n");
         ds.control_socket_fd_ = open_socket("dumpstate");
         ds.update_progress_ = 1;
     }
 
     if (is_redirecting) {
-        ds.bugreport_dir_ = dirname(use_outfile);
+        ds.bugreport_dir_ = dirname(options.use_outfile.c_str());
         std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
         std::string device_name = android::base::GetProperty("ro.product.name", "UNKNOWN_DEVICE");
-        ds.base_name_ = android::base::StringPrintf("%s-%s-%s", basename(use_outfile),
-                                                    device_name.c_str(), build_id.c_str());
-        if (do_add_date) {
+        ds.base_name_ =
+            android::base::StringPrintf("%s-%s-%s", basename(options.use_outfile.c_str()),
+                                        device_name.c_str(), build_id.c_str());
+        if (options.do_add_date) {
             char date[80];
             strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
             ds.name_ = date;
@@ -1923,13 +1936,13 @@
             ds.name_ = "undated";
         }
 
-        if (telephony_only) {
+        if (options.telephony_only) {
             ds.base_name_ += "-telephony";
-        } else if (wifi_only) {
+        } else if (options.wifi_only) {
             ds.base_name_ += "-wifi";
         }
 
-        if (do_fb) {
+        if (options.do_fb) {
             ds.screenshot_path_ = ds.GetPath(".png");
         }
         ds.tmp_path_ = ds.GetPath(".tmp");
@@ -1945,14 +1958,14 @@
             ds.bugreport_dir_.c_str(), ds.base_name_.c_str(), ds.name_.c_str(),
             ds.log_path_.c_str(), ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
 
-        if (do_zip_file) {
+        if (options.do_zip_file) {
             ds.path_ = ds.GetPath(".zip");
             MYLOGD("Creating initial .zip file (%s)\n", ds.path_.c_str());
             create_parent_dirs(ds.path_.c_str());
             ds.zip_file.reset(fopen(ds.path_.c_str(), "wb"));
             if (ds.zip_file == nullptr) {
                 MYLOGE("fopen(%s, 'wb'): %s\n", ds.path_.c_str(), strerror(errno));
-                do_zip_file = 0;
+                options.do_zip_file = false;
             } else {
                 ds.zip_writer_.reset(new ZipWriter(ds.zip_file.get()));
             }
@@ -1960,7 +1973,7 @@
         }
 
         if (ds.update_progress_) {
-            if (do_broadcast) {
+            if (options.do_broadcast) {
                 // clang-format off
 
                 std::vector<std::string> am_args = {
@@ -1973,7 +1986,7 @@
                 // clang-format on
                 SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
             }
-            if (use_control_socket) {
+            if (options.use_control_socket) {
                 dprintf(ds.control_socket_fd_, "BEGIN:%s\n", ds.path_.c_str());
             }
         }
@@ -1986,11 +1999,11 @@
         fclose(cmdline);
     }
 
-    if (do_vibrate) {
+    if (options.do_vibrate) {
         Vibrate(150);
     }
 
-    if (do_fb && ds.do_early_screenshot_) {
+    if (options.do_fb && ds.do_early_screenshot_) {
         if (ds.screenshot_path_.empty()) {
             // should not have happened
             MYLOGE("INTERNAL ERROR: skipping early screenshot because path was not set\n");
@@ -2000,13 +2013,15 @@
         }
     }
 
-    if (do_zip_file) {
+    if (options.do_zip_file) {
         if (chown(ds.path_.c_str(), AID_SHELL, AID_SHELL)) {
             MYLOGE("Unable to change ownership of zip file %s: %s\n", ds.path_.c_str(),
                    strerror(errno));
         }
     }
 
+    int dup_stdout_fd;
+    int dup_stderr_fd;
     if (is_redirecting) {
         TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
         redirect_to_file(stderr, const_cast<char*>(ds.log_path_.c_str()));
@@ -2033,10 +2048,10 @@
     // duration is logged into MYLOG instead.
     ds.PrintHeader();
 
-    if (telephony_only) {
+    if (options.telephony_only) {
         DumpstateTelephonyOnly();
         ds.DumpstateBoard();
-    } else if (wifi_only) {
+    } else if (options.wifi_only) {
         DumpstateWifiOnly();
     } else {
         // Dumps systrace right away, otherwise it will be filled with unnecessary events.
@@ -2092,12 +2107,11 @@
     }
 
     /* rename or zip the (now complete) .tmp file to its final location */
-    if (use_outfile) {
-
+    if (!options.use_outfile.empty()) {
         /* check if user changed the suffix using system properties */
         std::string name = android::base::GetProperty(
             android::base::StringPrintf("dumpstate.%d.name", ds.pid_), "");
-        bool change_suffix= false;
+        bool change_suffix = false;
         if (!name.empty()) {
             /* must whitelist which characters are allowed, otherwise it could cross directories */
             std::regex valid_regex("^[-_a-zA-Z0-9]+$");
@@ -2122,7 +2136,7 @@
         }
 
         bool do_text_file = true;
-        if (do_zip_file) {
+        if (options.do_zip_file) {
             if (!ds.FinishZipFile()) {
                 MYLOGE("Failed to finish zip file; sending text bugreport instead\n");
                 do_text_file = true;
@@ -2151,7 +2165,7 @@
                 ds.path_.clear();
             }
         }
-        if (use_control_socket) {
+        if (options.use_control_socket) {
             if (do_text_file) {
                 dprintf(ds.control_socket_fd_,
                         "FAIL:could not create zip file, check %s "
@@ -2164,7 +2178,7 @@
     }
 
     /* vibrate a few but shortly times to let user know it's finished */
-    if (do_vibrate) {
+    if (options.do_vibrate) {
         for (int i = 0; i < 3; i++) {
             Vibrate(75);
             usleep((75 + 50) * 1000);
@@ -2172,7 +2186,7 @@
     }
 
     /* tell activity manager we're done */
-    if (do_broadcast) {
+    if (options.do_broadcast) {
         if (!ds.path_.empty()) {
             MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
             // clang-format off
@@ -2186,7 +2200,7 @@
                  "--es", "android.intent.extra.DUMPSTATE_LOG", ds.log_path_
             };
             // clang-format on
-            if (do_fb) {
+            if (options.do_fb) {
                 am_args.push_back("--es");
                 am_args.push_back("android.intent.extra.SCREENSHOT");
                 am_args.push_back(ds.screenshot_path_);
@@ -2201,7 +2215,7 @@
                     am_args.push_back(ds.notification_description);
                 }
             }
-            if (is_remote_mode) {
+            if (options.is_remote_mode) {
                 am_args.push_back("--es");
                 am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
                 am_args.push_back(SHA256_file_hash(ds.path_));
@@ -2224,7 +2238,7 @@
         TEMP_FAILURE_RETRY(dup2(dup_stderr_fd, fileno(stderr)));
     }
 
-    if (use_control_socket && ds.control_socket_fd_ != -1) {
+    if (options.use_control_socket && ds.control_socket_fd_ != -1) {
         MYLOGD("Closing control socket\n");
         close(ds.control_socket_fd_);
     }
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b220013..389cc2e 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -290,14 +290,51 @@
     /* Returns true if the current version supports priority dump feature. */
     bool CurrentVersionSupportsPriorityDumps() const;
 
-    // TODO: initialize fields on constructor
+    // TODO: revisit the return values later.
+    /*
+     * Parses commandline arguments and sets runtime options accordingly.
+     *
+     * Returns 0 or positive number if the caller should exit with returned value as
+     * exit code, or returns -1 if caller should proceed with execution.
+     */
+    int ParseCommandlineOptions(int argc, char* argv[]);
 
+    /* Sets runtime options from the system properties. */
+    void SetOptionsFromProperties();
+
+    /* Returns true if the options set so far are consistent. */
+    bool ValidateOptions();
+
+    // TODO: add update_progress_ & other options from DumpState.
+    /*
+     * Structure to hold options that determine the behavior of dumpstate.
+     */
+    struct DumpOptions {
+        bool do_add_date = false;
+        bool do_zip_file = false;
+        bool do_vibrate = true;
+        bool use_socket = false;
+        bool use_control_socket = false;
+        bool do_fb = false;
+        bool do_broadcast = false;
+        bool is_remote_mode = false;
+        bool show_header_only = false;
+        bool do_start_service = false;
+        bool telephony_only = false;
+        bool wifi_only = false;
+        std::string use_outfile;
+    };
+
+    // TODO: initialize fields on constructor
     // dumpstate id - unique after each device reboot.
     uint32_t id_;
 
     // dumpstate pid
     pid_t pid_;
 
+    // Runtime options.
+    DumpOptions options_;
+
     // Whether progress updates should be published.
     bool update_progress_ = false;
 
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 838b385..c57535a 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -54,6 +54,8 @@
 using ::testing::internal::GetCapturedStderr;
 using ::testing::internal::GetCapturedStdout;
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
 class DumpstateListenerMock : public IDumpstateListener {
   public:
     MOCK_METHOD1(onProgressUpdated, binder::Status(int32_t progress));
@@ -144,6 +146,7 @@
         ds.progress_.reset(new Progress());
         ds.update_progress_ = false;
         ds.update_progress_threshold_ = 0;
+        ds.options_ = Dumpstate::DumpOptions();
     }
 
     // Runs a command and capture `stdout` and `stderr`.
@@ -201,6 +204,157 @@
     Dumpstate& ds = Dumpstate::GetInstance();
 };
 
+TEST_F(DumpstateTest, ParseCommandlineOptionsNone) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate")
+    };
+    // clang-format on
+
+    int ret = ds.ParseCommandlineOptions(ARRAY_SIZE(argv), argv);
+    EXPECT_EQ(-1, ret);
+    EXPECT_FALSE(ds.options_.do_add_date);
+    EXPECT_FALSE(ds.options_.do_zip_file);
+    EXPECT_EQ("", ds.options_.use_outfile);
+    EXPECT_FALSE(ds.options_.use_socket);
+    EXPECT_FALSE(ds.options_.use_control_socket);
+    EXPECT_FALSE(ds.options_.show_header_only);
+    EXPECT_TRUE(ds.options_.do_vibrate);
+    EXPECT_FALSE(ds.options_.do_fb);
+    EXPECT_FALSE(ds.update_progress_);
+    EXPECT_FALSE(ds.options_.is_remote_mode);
+    EXPECT_FALSE(ds.options_.do_broadcast);
+}
+
+TEST_F(DumpstateTest, ParseCommandlineOptionsPartial1) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+        const_cast<char*>("-s"),
+        const_cast<char*>("-S"),
+
+    };
+    // clang-format on
+    int ret = ds.ParseCommandlineOptions(ARRAY_SIZE(argv), argv);
+    EXPECT_EQ(-1, ret);
+    EXPECT_TRUE(ds.options_.do_add_date);
+    EXPECT_TRUE(ds.options_.do_zip_file);
+    // TODO: Maybe we should trim the filename
+    EXPECT_EQ(" abc", std::string(ds.options_.use_outfile));
+    EXPECT_TRUE(ds.options_.use_socket);
+    EXPECT_TRUE(ds.options_.use_control_socket);
+
+    // Other options retain default values
+    EXPECT_FALSE(ds.options_.show_header_only);
+    EXPECT_TRUE(ds.options_.do_vibrate);
+    EXPECT_FALSE(ds.options_.do_fb);
+    EXPECT_FALSE(ds.update_progress_);
+    EXPECT_FALSE(ds.options_.is_remote_mode);
+    EXPECT_FALSE(ds.options_.do_broadcast);
+}
+
+TEST_F(DumpstateTest, ParseCommandlineOptionsPartial2) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate"),
+        const_cast<char*>("-v"),
+        const_cast<char*>("-q"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-P"),
+        const_cast<char*>("-R"),
+        const_cast<char*>("-B"),
+    };
+    // clang-format on
+    int ret = ds.ParseCommandlineOptions(ARRAY_SIZE(argv), argv);
+    EXPECT_EQ(-1, ret);
+    EXPECT_TRUE(ds.options_.show_header_only);
+    EXPECT_FALSE(ds.options_.do_vibrate);
+    EXPECT_TRUE(ds.options_.do_fb);
+    EXPECT_TRUE(ds.update_progress_);
+    EXPECT_TRUE(ds.options_.is_remote_mode);
+    EXPECT_TRUE(ds.options_.do_broadcast);
+
+    // Other options retain default values
+    EXPECT_FALSE(ds.options_.do_add_date);
+    EXPECT_FALSE(ds.options_.do_zip_file);
+    EXPECT_EQ("", ds.options_.use_outfile);
+    EXPECT_FALSE(ds.options_.use_socket);
+    EXPECT_FALSE(ds.options_.use_control_socket);
+}
+
+TEST_F(DumpstateTest, ParseCommandlineOptionsHelp) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate"),
+        const_cast<char*>("-h")
+    };
+    // clang-format on
+    int ret = ds.ParseCommandlineOptions(ARRAY_SIZE(argv), argv);
+
+    // -h is for help. Caller exit with code = 0 after printing usage, so expect return = 0.
+    EXPECT_EQ(0, ret);
+}
+
+TEST_F(DumpstateTest, ParseCommandlineOptionsUnknown) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate"),
+        const_cast<char*>("-u")  // unknown flag
+    };
+    // clang-format on
+    int ret = ds.ParseCommandlineOptions(ARRAY_SIZE(argv), argv);
+
+    // -u is unknown. Caller exit with code = 1 to show execution failure, after printing usage,
+    // so expect return = 1.
+    EXPECT_EQ(1, ret);
+}
+
+TEST_F(DumpstateTest, ValidateOptionsNeedOutfile1) {
+    ds.options_.do_zip_file = true;
+    EXPECT_FALSE(ds.ValidateOptions());
+    ds.options_.use_outfile = "a/b/c";
+    EXPECT_TRUE(ds.ValidateOptions());
+}
+
+TEST_F(DumpstateTest, ValidateOptionsNeedOutfile2) {
+    ds.options_.do_broadcast = true;
+    EXPECT_FALSE(ds.ValidateOptions());
+    ds.options_.use_outfile = "a/b/c";
+    EXPECT_TRUE(ds.ValidateOptions());
+}
+
+TEST_F(DumpstateTest, ValidateOptionsNeedZipfile) {
+    ds.options_.use_control_socket = true;
+    EXPECT_FALSE(ds.ValidateOptions());
+
+    ds.options_.do_zip_file = true;
+    ds.options_.use_outfile = "a/b/c";  // do_zip_file needs outfile
+    EXPECT_TRUE(ds.ValidateOptions());
+}
+
+TEST_F(DumpstateTest, ValidateOptionsUpdateProgressNeedsBroadcast) {
+    ds.update_progress_ = true;
+    ds.options_.use_outfile = "a/b/c";  // update_progress_ needs outfile
+    EXPECT_FALSE(ds.ValidateOptions());
+
+    ds.options_.do_broadcast = true;
+    EXPECT_TRUE(ds.ValidateOptions());
+}
+
+TEST_F(DumpstateTest, ValidateOptionsRemoteMode) {
+    ds.options_.is_remote_mode = true;
+    EXPECT_FALSE(ds.ValidateOptions());
+
+    ds.options_.do_broadcast = true;
+    ds.options_.do_zip_file = true;
+    ds.options_.do_add_date = true;
+    ds.options_.use_outfile = "a/b/c";  // do_broadcast needs outfile
+    EXPECT_TRUE(ds.ValidateOptions());
+}
+
 TEST_F(DumpstateTest, RunCommandNoArgs) {
     EXPECT_EQ(-1, RunCommand("", {}));
 }
diff --git a/cmds/dumpsys/OWNERS b/cmds/dumpsys/OWNERS
new file mode 100644
index 0000000..1ba7cff
--- /dev/null
+++ b/cmds/dumpsys/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+
+felipeal@google.com
+nandana@google.com
+jsharkey@android.com
+enh@google.com
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index 3a17e03..820679f 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -16,33 +16,75 @@
 
 #include "PipeRelay.h"
 
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <atomic>
+
+#include <android-base/logging.h>
 #include <utils/Thread.h>
 
 namespace android {
 namespace lshal {
 
+static constexpr struct timeval READ_TIMEOUT { .tv_sec = 1, .tv_usec = 0 };
+
 struct PipeRelay::RelayThread : public Thread {
     explicit RelayThread(int fd, std::ostream &os);
 
     bool threadLoop() override;
+    void setFinished();
 
 private:
     int mFd;
     std::ostream &mOutStream;
 
+    // If we were to use requestExit() and exitPending() instead, threadLoop()
+    // may not run at all by the time ~PipeRelay is called (i.e. debug() has
+    // returned from HAL). By using our own flag, we ensure that select() and
+    // read() are executed until data are drained.
+    std::atomic_bool mFinished;
+
     DISALLOW_COPY_AND_ASSIGN(RelayThread);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os)
-    : mFd(fd),
-      mOutStream(os) {
-}
+      : mFd(fd), mOutStream(os), mFinished(false) {}
 
 bool PipeRelay::RelayThread::threadLoop() {
     char buffer[1024];
-    ssize_t n = read(mFd, buffer, sizeof(buffer));
+
+    fd_set set;
+    FD_ZERO(&set);
+    FD_SET(mFd, &set);
+
+    struct timeval timeout = READ_TIMEOUT;
+
+    int res = TEMP_FAILURE_RETRY(select(mFd + 1, &set, nullptr, nullptr, &timeout));
+    if (res < 0) {
+        PLOG(INFO) << "select() failed";
+        return false;
+    }
+
+    if (res == 0 || !FD_ISSET(mFd, &set)) {
+        if (mFinished) {
+            LOG(WARNING) << "debug: timeout reading from pipe, output may be truncated.";
+            return false;
+        }
+        // timeout, but debug() has not returned, so wait for HAL to finish.
+        return true;
+    }
+
+    // FD_ISSET(mFd, &set) == true. Data available, start reading
+    ssize_t n = TEMP_FAILURE_RETRY(read(mFd, buffer, sizeof(buffer)));
+
+    if (n < 0) {
+        PLOG(ERROR) << "read() failed";
+    }
 
     if (n <= 0) {
         return false;
@@ -53,6 +95,10 @@
     return true;
 }
 
+void PipeRelay::RelayThread::setFinished() {
+    mFinished = true;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 PipeRelay::PipeRelay(std::ostream &os)
@@ -77,12 +123,14 @@
 
 PipeRelay::~PipeRelay() {
     CloseFd(&mFds[1]);
-    CloseFd(&mFds[0]);
 
     if (mThread != nullptr) {
+        mThread->setFinished();
         mThread->join();
         mThread.clear();
     }
+
+    CloseFd(&mFds[0]);
 }
 
 status_t PipeRelay::initCheck() const {
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index a9d5055..e318a7f 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -136,7 +136,7 @@
     // Something really bad has happened, and we're not going to even
     // try returning rich error data.
     if (mException == EX_TRANSACTION_FAILED) {
-        return mErrorCode;
+        return mErrorCode == OK ? FAILED_TRANSACTION : mErrorCode;
     }
 
     status_t status = parcel->writeInt32(mException);
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 7870c7b..37237df 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -108,7 +108,7 @@
         OP_MANAGE_IPSEC_TUNNELS = 75,
         OP_START_FOREGROUND = 76,
         OP_BLUETOOTH_SCAN = 77,
-        OP_USE_FACE = 78,
+        OP_USE_BIOMETRIC = 78,
     };
 
     AppOpsManager();
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 3f3c4fa..5461b4f 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -25,6 +25,7 @@
 
     srcs: [
         "ibinder.cpp",
+        "ibinder_jni.cpp",
         "parcel.cpp",
         "process.cpp",
         "status.cpp",
@@ -32,6 +33,7 @@
     ],
 
     shared_libs: [
+        "libandroid_runtime",
         "libbase",
         "libbinder",
         "libutils",
diff --git a/libs/binder/ndk/ibinder_jni.cpp b/libs/binder/ndk/ibinder_jni.cpp
new file mode 100644
index 0000000..baea2e8
--- /dev/null
+++ b/libs/binder/ndk/ibinder_jni.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_ibinder_jni.h>
+#include "ibinder_internal.h"
+
+#include <android_util_Binder.h>
+
+using ::android::IBinder;
+using ::android::ibinderForJavaObject;
+using ::android::javaObjectForIBinder;
+using ::android::sp;
+
+AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder) {
+    sp<IBinder> ibinder = ibinderForJavaObject(env, binder);
+
+    sp<AIBinder> cbinder = ABpBinder::lookupOrCreateFromBinder(ibinder);
+    AIBinder_incStrong(cbinder.get());
+
+    return cbinder.get();
+}
+
+jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder) {
+    if (binder == nullptr) {
+        return nullptr;
+    }
+
+    return javaObjectForIBinder(env, binder->getBinder());
+}
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 871335d..f237e69 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -33,6 +33,7 @@
 #include <android/binder_status.h>
 
 __BEGIN_DECLS
+#if __ANDROID_API__ >= __ANDROID_API_Q__
 
 // Also see TF_* in kernel's binder.h
 typedef uint32_t binder_flags_t;
@@ -154,7 +155,8 @@
  */
 __attribute__((warn_unused_result)) AIBinder_Class* AIBinder_Class_define(
         const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
-        AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact);
+        AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact)
+        __INTRODUCED_IN(29);
 
 /**
  * Creates a new binder object of the appropriate class.
@@ -173,12 +175,13 @@
  * these two objects are actually equal using the AIBinder pointer alone (which they should be able
  * to do). Also see the suggested memory ownership model suggested above.
  */
-__attribute__((warn_unused_result)) AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args);
+__attribute__((warn_unused_result)) AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args)
+        __INTRODUCED_IN(29);
 
 /**
  * If this is hosted in a process other than the current one.
  */
-bool AIBinder_isRemote(const AIBinder* binder);
+bool AIBinder_isRemote(const AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * If this binder is known to be alive. This will not send a transaction to a remote process and
@@ -187,14 +190,14 @@
  * updated as the result of a transaction made using AIBinder_transact, but it will also be updated
  * based on the results of bookkeeping or other transactions made internally.
  */
-bool AIBinder_isAlive(const AIBinder* binder);
+bool AIBinder_isAlive(const AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * Built-in transaction for all binder objects. This sends a transaction which will immediately
  * return. Usually this is used to make sure that a binder is alive, as a placeholder call, or as a
  * sanity check.
  */
-binder_status_t AIBinder_ping(AIBinder* binder);
+binder_status_t AIBinder_ping(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * Registers for notifications that the associated binder is dead. The same death recipient may be
@@ -206,7 +209,7 @@
  * identification and holding user data.
  */
 binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
-                                     void* cookie);
+                                     void* cookie) __INTRODUCED_IN(29);
 
 /**
  * Stops registration for the associated binder dying. Does not delete the recipient. This function
@@ -214,22 +217,22 @@
  * returns STATUS_NAME_NOT_FOUND.
  */
 binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
-                                       void* cookie);
+                                       void* cookie) __INTRODUCED_IN(29);
 
 /**
  * This can only be called if a strong reference to this object already exists in process.
  */
-void AIBinder_incStrong(AIBinder* binder);
+void AIBinder_incStrong(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * This will delete the object and call onDestroy once the refcount reaches zero.
  */
-void AIBinder_decStrong(AIBinder* binder);
+void AIBinder_decStrong(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * For debugging only!
  */
-int32_t AIBinder_debugGetRefCount(AIBinder* binder);
+int32_t AIBinder_debugGetRefCount(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * This sets the class of an AIBinder object. This checks to make sure the remote object is of
@@ -240,18 +243,18 @@
  * This returns true if the class association succeeds. If it fails, no change is made to the
  * binder object.
  */
-bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz);
+bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) __INTRODUCED_IN(29);
 
 /**
  * Returns the class that this binder was constructed with or associated with.
  */
-const AIBinder_Class* AIBinder_getClass(AIBinder* binder);
+const AIBinder_Class* AIBinder_getClass(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * Value returned by onCreate for a local binder. For stateless classes (if onCreate returns
  * nullptr), this also returns nullptr. For a remote binder, this will always return nullptr.
  */
-void* AIBinder_getUserData(AIBinder* binder);
+void* AIBinder_getUserData(AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * A transaction is a series of calls to these functions which looks this
@@ -274,7 +277,7 @@
  * AIBinder_transact. Alternatively, if there is an error while filling out the parcel, it can be
  * deleted with AParcel_delete.
  */
-binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in);
+binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) __INTRODUCED_IN(29);
 
 /**
  * Transact using a parcel created from AIBinder_prepareTransaction. This actually communicates with
@@ -289,42 +292,45 @@
  * and must be released with AParcel_delete when finished reading.
  */
 binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
-                                  AParcel** out, binder_flags_t flags);
+                                  AParcel** out, binder_flags_t flags) __INTRODUCED_IN(29);
 
 /**
  * This does not take any ownership of the input binder, but it can be used to retrieve it if
  * something else in some process still holds a reference to it.
  */
-__attribute__((warn_unused_result)) AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder);
+__attribute__((warn_unused_result)) AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder)
+        __INTRODUCED_IN(29);
 
 /**
  * Deletes the weak reference. This will have no impact on the lifetime of the binder.
  */
-void AIBinder_Weak_delete(AIBinder_Weak* weakBinder);
+void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) __INTRODUCED_IN(29);
 
 /**
  * If promotion succeeds, result will have one strong refcount added to it. Otherwise, this returns
  * nullptr.
  */
-__attribute__((warn_unused_result)) AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder);
+__attribute__((warn_unused_result)) AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder)
+        __INTRODUCED_IN(29);
 
 /**
  * This function is executed on death receipt. See AIBinder_linkToDeath/AIBinder_unlinkToDeath.
  */
-typedef void (*AIBinder_DeathRecipient_onBinderDied)(void* cookie);
+typedef void (*AIBinder_DeathRecipient_onBinderDied)(void* cookie) __INTRODUCED_IN(29);
 
 /**
  * Creates a new binder death recipient. This can be attached to multiple different binder objects.
  */
 __attribute__((warn_unused_result)) AIBinder_DeathRecipient* AIBinder_DeathRecipient_new(
-        AIBinder_DeathRecipient_onBinderDied onBinderDied);
+        AIBinder_DeathRecipient_onBinderDied onBinderDied) __INTRODUCED_IN(29);
 
 /**
  * Deletes a binder death recipient. It is not necessary to call AIBinder_unlinkToDeath before
  * calling this as these will all be automatically unlinked.
  */
-void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient);
+void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) __INTRODUCED_IN(29);
 
+#endif //__ANDROID_API__ >= __ANDROID_API_Q__
 __END_DECLS
 
 /** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
new file mode 100644
index 0000000..81fb3c5
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_ibinder_jni.h
+ * @brief Conversions between AIBinder and android.os.IBinder
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+
+#include <jni.h>
+
+__BEGIN_DECLS
+#if __ANDROID_API__ >= __ANDROID_API_Q__
+
+/**
+ * Converts an android.os.IBinder object into an AIBinder* object.
+ *
+ * If either env or the binder is null, null is returned. If this binder object was originally an
+ * AIBinder object, the original object is returned. The returned object has one refcount
+ * associated with it, and so this should be accompanied with an AIBinder_decStrong call.
+ */
+__attribute__((warn_unused_result)) AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder)
+        __INTRODUCED_IN(29);
+
+/**
+ * Converts an AIBinder* object into an android.os.IBinder object.
+ *
+ * If either env or the binder is null, null is returned. If this binder object was originally an
+ * IBinder object, the original java object will be returned.
+ */
+__attribute__((warn_unused_result)) jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder)
+        __INTRODUCED_IN(29);
+
+#endif //__ANDROID_API__ >= __ANDROID_API_Q__
+__END_DECLS
+
+/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 271810a..a3800da 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -34,6 +34,7 @@
 typedef struct AIBinder AIBinder;
 
 __BEGIN_DECLS
+#if __ANDROID_API__ >= __ANDROID_API_Q__
 
 /**
  * This object represents a package of data that can be sent between processes. When transacting, an
@@ -47,129 +48,140 @@
 /**
  * Cleans up a parcel.
  */
-void AParcel_delete(AParcel* parcel);
+void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29);
 
 /**
  * Writes an AIBinder to the next location in a non-null parcel. Can be null.
  */
-binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder);
+binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) __INTRODUCED_IN(29);
 
 /**
  * Reads an AIBinder from the next location in a non-null parcel. This will fail if the binder is
  * non-null. One strong ref-count of ownership is passed to the caller of this function.
  */
-binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder);
+binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder)
+        __INTRODUCED_IN(29);
 
 /**
  * Reads an AIBinder from the next location in a non-null parcel. This may read a null. One strong
  * ref-count of ownership is passed to the caller of this function.
  */
-binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder);
+binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder)
+        __INTRODUCED_IN(29);
 
 /**
  * Writes an AStatus object to the next location in a non-null parcel.
+ *
+ * If the status is considered to be a low-level status and has no additional information other
+ * than a binder_status_t (for instance, if it is created with AStatus_fromStatus), then that
+ * status will be returned from this method and nothing will be written to the parcel. If either
+ * this happens or if writing the status object itself fails, the return value from this function
+ * should be propagated to the client, and AParcel_readStatusHeader shouldn't be called.
  */
-binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status);
+binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status)
+        __INTRODUCED_IN(29);
 
 /**
  * Reads an AStatus from the next location in a non-null parcel. Ownership is passed to the caller
  * of this function.
  */
-binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status);
+binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status)
+        __INTRODUCED_IN(29);
 
 // @START
 /**
  * Writes int32_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value);
+binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) __INTRODUCED_IN(29);
 
 /**
  * Writes uint32_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value);
+binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) __INTRODUCED_IN(29);
 
 /**
  * Writes int64_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value);
+binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) __INTRODUCED_IN(29);
 
 /**
  * Writes uint64_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value);
+binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) __INTRODUCED_IN(29);
 
 /**
  * Writes float value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeFloat(AParcel* parcel, float value);
+binder_status_t AParcel_writeFloat(AParcel* parcel, float value) __INTRODUCED_IN(29);
 
 /**
  * Writes double value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeDouble(AParcel* parcel, double value);
+binder_status_t AParcel_writeDouble(AParcel* parcel, double value) __INTRODUCED_IN(29);
 
 /**
  * Writes bool value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeBool(AParcel* parcel, bool value);
+binder_status_t AParcel_writeBool(AParcel* parcel, bool value) __INTRODUCED_IN(29);
 
 /**
  * Writes char16_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value);
+binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) __INTRODUCED_IN(29);
 
 /**
  * Writes int8_t value to the next location in a non-null parcel.
  */
-binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value);
+binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) __INTRODUCED_IN(29);
 
 /**
  * Reads into int32_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value);
+binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into uint32_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value);
+binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into int64_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value);
+binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into uint64_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value);
+binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into float value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readFloat(const AParcel* parcel, float* value);
+binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into double value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readDouble(const AParcel* parcel, double* value);
+binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into bool value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readBool(const AParcel* parcel, bool* value);
+binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into char16_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value);
+binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) __INTRODUCED_IN(29);
 
 /**
  * Reads into int8_t value from the next location in a non-null parcel.
  */
-binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value);
+binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) __INTRODUCED_IN(29);
 
 // @END
 
+#endif //__ANDROID_API__ >= __ANDROID_API_Q__
 __END_DECLS
 
 /** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 1a6a6f0..2d8b7fa 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -30,6 +30,7 @@
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
+#if __ANDROID_API__ >= __ANDROID_API_Q__
 
 enum {
     STATUS_OK = 0,
@@ -102,19 +103,19 @@
 /**
  * New status which is considered a success.
  */
-__attribute__((warn_unused_result)) AStatus* AStatus_newOk();
+__attribute__((warn_unused_result)) AStatus* AStatus_newOk() __INTRODUCED_IN(29);
 
 /**
  * New status with exception code.
  */
-__attribute__((warn_unused_result)) AStatus* AStatus_fromExceptionCode(
-        binder_exception_t exception);
+__attribute__((warn_unused_result)) AStatus* AStatus_fromExceptionCode(binder_exception_t exception)
+        __INTRODUCED_IN(29);
 
 /**
  * New status with exception code and message.
  */
 __attribute__((warn_unused_result)) AStatus* AStatus_fromExceptionCodeWithMessage(
-        binder_exception_t exception, const char* message);
+        binder_exception_t exception, const char* message) __INTRODUCED_IN(29);
 
 /**
  * New status with a service speciic error.
@@ -122,7 +123,7 @@
  * This is considered to be EX_TRANSACTION_FAILED with extra information.
  */
 __attribute__((warn_unused_result)) AStatus* AStatus_fromServiceSpecificError(
-        int32_t serviceSpecific);
+        int32_t serviceSpecific) __INTRODUCED_IN(29);
 
 /**
  * New status with a service specific error and message.
@@ -130,25 +131,26 @@
  * This is considered to be EX_TRANSACTION_FAILED with extra information.
  */
 __attribute__((warn_unused_result)) AStatus* AStatus_fromServiceSpecificErrorWithMessage(
-        int32_t serviceSpecific, const char* message);
+        int32_t serviceSpecific, const char* message) __INTRODUCED_IN(29);
 
 /**
  * New status with binder_status_t. This is typically for low level failures when a binder_status_t
  * is returned by an API on AIBinder or AParcel, and that is to be returned from a method returning
  * an AStatus instance.
  */
-__attribute__((warn_unused_result)) AStatus* AStatus_fromStatus(binder_status_t status);
+__attribute__((warn_unused_result)) AStatus* AStatus_fromStatus(binder_status_t status)
+        __INTRODUCED_IN(29);
 
 /**
  * Whether this object represents a successful transaction. If this function returns true, then
  * AStatus_getExceptionCode will return EX_NONE.
  */
-bool AStatus_isOk(const AStatus* status);
+bool AStatus_isOk(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
  * The exception that this status object represents.
  */
-binder_exception_t AStatus_getExceptionCode(const AStatus* status);
+binder_exception_t AStatus_getExceptionCode(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
  * The service specific error if this object represents one. This function will only ever return a
@@ -156,7 +158,7 @@
  * 0, the status object may still represent a different exception or status. To find out if this
  * transaction as a whole is okay, use AStatus_isOk instead.
  */
-int32_t AStatus_getServiceSpecificError(const AStatus* status);
+int32_t AStatus_getServiceSpecificError(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
  * The status if this object represents one. This function will only ever return a non-zero result
@@ -164,7 +166,7 @@
  * object may represent a different exception or a service specific error. To find out if this
  * transaction as a whole is okay, use AStatus_isOk instead.
  */
-binder_status_t AStatus_getStatus(const AStatus* status);
+binder_status_t AStatus_getStatus(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
  * If there is a message associated with this status, this will return that message. If there is no
@@ -172,13 +174,14 @@
  *
  * The returned string has the lifetime of the status object passed into this function.
  */
-const char* AStatus_getMessage(const AStatus* status);
+const char* AStatus_getMessage(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
  * Deletes memory associated with the status instance.
  */
-void AStatus_delete(AStatus* status);
+void AStatus_delete(AStatus* status) __INTRODUCED_IN(29);
 
+#endif //__ANDROID_API__ >= __ANDROID_API_Q__
 __END_DECLS
 
 /** @} */
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 14683b9..4f486c9 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -6,6 +6,7 @@
     AIBinder_DeathRecipient_new;
     AIBinder_debugGetRefCount;
     AIBinder_decStrong;
+    AIBinder_fromJavaBinder;
     AIBinder_getClass;
     AIBinder_getUserData;
     AIBinder_incStrong;
@@ -15,6 +16,7 @@
     AIBinder_new;
     AIBinder_ping;
     AIBinder_prepareTransaction;
+    AIBinder_toJavaBinder;
     AIBinder_transact;
     AIBinder_unlinkToDeath;
     AIBinder_Weak_delete;
diff --git a/libs/binder/ndk/scripts/gen_parcel_helper.py b/libs/binder/ndk/scripts/gen_parcel_helper.py
index 85ee755..bbd3e5d 100755
--- a/libs/binder/ndk/scripts/gen_parcel_helper.py
+++ b/libs/binder/ndk/scripts/gen_parcel_helper.py
@@ -66,7 +66,7 @@
         header += "/**\n"
         header += " * Writes " + cpp + " value to the next location in a non-null parcel.\n"
         header += " */\n"
-        header += "binder_status_t AParcel_write" + pretty + "(AParcel* parcel, " + cpp + " value);\n\n"
+        header += "binder_status_t AParcel_write" + pretty + "(AParcel* parcel, " + cpp + " value) __INTRODUCED_IN(29);\n\n"
         source += "binder_status_t AParcel_write" + pretty + "(AParcel* parcel, " + cpp + " value) {\n"
         source += "    status_t status = parcel->get()->write" + pretty + "(value);\n"
         source += "    return PruneStatusT(status);\n"
@@ -76,7 +76,7 @@
         header += "/**\n"
         header += " * Reads into " + cpp + " value from the next location in a non-null parcel.\n"
         header += " */\n"
-        header += "binder_status_t AParcel_read" + pretty + "(const AParcel* parcel, " + cpp + "* value);\n\n"
+        header += "binder_status_t AParcel_read" + pretty + "(const AParcel* parcel, " + cpp + "* value) __INTRODUCED_IN(29);\n\n"
         source += "binder_status_t AParcel_read" + pretty + "(const AParcel* parcel, " + cpp + "* value) {\n"
         source += "    status_t status = parcel->get()->read" + pretty + "(value);\n"
         source += "    return PruneStatusT(status);\n"
diff --git a/libs/binder/ndk/scripts/init_map.sh b/libs/binder/ndk/scripts/init_map.sh
index 132144b..1f74e43 100755
--- a/libs/binder/ndk/scripts/init_map.sh
+++ b/libs/binder/ndk/scripts/init_map.sh
@@ -6,6 +6,7 @@
 echo "  global:"
 {
     grep -oP "AIBinder_[a-zA-Z0-9_]+(?=\()" include_ndk/android/binder_ibinder.h;
+    grep -oP "AIBinder_[a-zA-Z0-9_]+(?=\()" include_ndk/android/binder_ibinder_jni.h;
     grep -oP "AParcel_[a-zA-Z0-9_]+(?=\()" include_ndk/android/binder_parcel.h;
     grep -oP "AStatus_[a-zA-Z0-9_]+(?=\()" include_ndk/android/binder_status.h;
 } | sort | uniq | awk '{ print "    " $0 ";"; }'
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index 549e4b3..e0ae469 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -71,8 +71,6 @@
 }
 
 binder_status_t PruneStatusT(status_t status) {
-    if (status > 0) return status;
-
     switch (status) {
         case ::android::OK:
             return STATUS_OK;
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index d242138..8e40a01 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -44,6 +44,7 @@
     name: "test_libbinder_ndk_test_defaults",
     defaults: ["test_libbinder_ndk_defaults"],
     shared_libs: [
+        "libandroid_runtime",
         "libbase",
         "libbinder",
         "libutils",
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
index c07462e..3fc096a 100644
--- a/libs/binder/ndk/test/main_client.cpp
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <android-base/logging.h>
+#include <android/binder_ibinder_jni.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <gtest/gtest.h>
@@ -102,6 +103,11 @@
     AIBinder_decStrong(binderB);
 }
 
+TEST(NdkBinder, ToFromJavaNullptr) {
+    EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
+    EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
+}
+
 TEST(NdkBinder, ABpBinderRefCount) {
     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
     AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 37b9a03..11b2211 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -795,8 +795,6 @@
   EXPECT_TRUE(d->IsConnected());
   EXPECT_TRUE(d->IsValid());
 
-  ASSERT_TRUE(d->buffer() != nullptr);
-  EXPECT_EQ(d->buffer()->initCheck(), 0);
   EXPECT_EQ(d->id(), p_id);
 }
 
@@ -808,7 +806,6 @@
 
   EXPECT_FALSE(b1->IsConnected());
   EXPECT_FALSE(b1->IsValid());
-  EXPECT_TRUE(b1->buffer() == nullptr);
 
   // Buffer Creation will fail: user metadata size too large.
   auto b2 = DetachedBuffer::Create(
@@ -817,7 +814,6 @@
 
   EXPECT_FALSE(b2->IsConnected());
   EXPECT_FALSE(b2->IsValid());
-  EXPECT_TRUE(b2->buffer() == nullptr);
 
   // Buffer Creation will fail: user metadata size too large.
   auto b3 = DetachedBuffer::Create(
@@ -827,50 +823,14 @@
 
   EXPECT_FALSE(b3->IsConnected());
   EXPECT_FALSE(b3->IsValid());
-  EXPECT_TRUE(b3->buffer() == nullptr);
 }
 
 TEST_F(LibBufferHubTest, TestCreateDetachedBuffer) {
   auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
                                    kUsage, kUserMetadataSize);
-  int b1_id = b1->id();
-
   EXPECT_TRUE(b1->IsConnected());
   EXPECT_TRUE(b1->IsValid());
-  ASSERT_TRUE(b1->buffer() != nullptr);
   EXPECT_NE(b1->id(), 0);
-  EXPECT_EQ(b1->buffer()->initCheck(), 0);
-  EXPECT_FALSE(b1->buffer()->isDetachedBuffer());
-
-  // Takes a standalone GraphicBuffer which still holds on an
-  // PDX::LocalChannelHandle towards BufferHub.
-  sp<GraphicBuffer> g1 = b1->TakeGraphicBuffer();
-  ASSERT_TRUE(g1 != nullptr);
-  EXPECT_TRUE(g1->isDetachedBuffer());
-
-  EXPECT_FALSE(b1->IsConnected());
-  EXPECT_FALSE(b1->IsValid());
-  EXPECT_TRUE(b1->buffer() == nullptr);
-
-  sp<GraphicBuffer> g2 = b1->TakeGraphicBuffer();
-  ASSERT_TRUE(g2 == nullptr);
-
-  auto h1 = g1->takeDetachedBufferHandle();
-  ASSERT_TRUE(h1 != nullptr);
-  ASSERT_TRUE(h1->isValid());
-  EXPECT_FALSE(g1->isDetachedBuffer());
-
-  auto b2 = DetachedBuffer::Import(std::move(h1->handle()));
-  ASSERT_FALSE(h1->isValid());
-  EXPECT_TRUE(b2->IsConnected());
-  EXPECT_TRUE(b2->IsValid());
-
-  ASSERT_TRUE(b2->buffer() != nullptr);
-  EXPECT_EQ(b2->buffer()->initCheck(), 0);
-
-  // The newly created DetachedBuffer should share the original buffer_id.
-  EXPECT_EQ(b2->id(), b1_id);
-  EXPECT_FALSE(b2->buffer()->isDetachedBuffer());
 }
 
 TEST_F(LibBufferHubTest, TestPromoteDetachedBuffer) {
diff --git a/libs/vr/libbufferhub/detached_buffer.cpp b/libs/vr/libbufferhub/detached_buffer.cpp
index 02abd91..7716cfa 100644
--- a/libs/vr/libbufferhub/detached_buffer.cpp
+++ b/libs/vr/libbufferhub/detached_buffer.cpp
@@ -162,22 +162,5 @@
   return status_or_handle;
 }
 
-sp<GraphicBuffer> DetachedBuffer::TakeGraphicBuffer() {
-  if (!client_.IsValid() || !buffer_.buffer()) {
-    ALOGE("DetachedBuffer::TakeGraphicBuffer: Invalid buffer.");
-    return nullptr;
-  }
-
-  // Technically this should never happen.
-  LOG_FATAL_IF(
-      buffer_.buffer()->isDetachedBuffer(),
-      "DetachedBuffer::TakeGraphicBuffer: GraphicBuffer is already detached.");
-
-  sp<GraphicBuffer> buffer = std::move(buffer_.buffer());
-  buffer->setDetachedBufferHandle(
-      DetachedBufferHandle::Create(client_.TakeChannelHandle()));
-  return buffer;
-}
-
 }  // namespace dvr
 }  // namespace android
diff --git a/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h b/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
index 1fc011b..e795f3b 100644
--- a/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/detached_buffer.h
@@ -28,8 +28,6 @@
   DetachedBuffer(const DetachedBuffer&) = delete;
   void operator=(const DetachedBuffer&) = delete;
 
-  const sp<GraphicBuffer>& buffer() const { return buffer_.buffer(); }
-
   // Gets ID of the buffer client. All DetachedBuffer clients derived from the
   // same buffer in bufferhubd share the same buffer id.
   int id() const { return id_; }
@@ -69,11 +67,6 @@
   // Creates a DetachedBuffer from an existing one.
   pdx::Status<pdx::LocalChannelHandle> Duplicate();
 
-  // Takes the underlying graphic buffer out of this DetachedBuffer. This call
-  // immediately invalidates this DetachedBuffer object and transfers the
-  // underlying pdx::LocalChannelHandle into the GraphicBuffer.
-  sp<GraphicBuffer> TakeGraphicBuffer();
-
  private:
   DetachedBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
                  uint32_t format, uint64_t usage, size_t user_metadata_size);
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index a6b9533..f87fcdc 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -46,6 +46,7 @@
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
+        "libfmq",
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
     ],
diff --git a/services/sensorservice/RecentEventLogger.cpp b/services/sensorservice/RecentEventLogger.cpp
index 1025a88..cec2ae5 100644
--- a/services/sensorservice/RecentEventLogger.cpp
+++ b/services/sensorservice/RecentEventLogger.cpp
@@ -26,6 +26,7 @@
 
 namespace {
     constexpr size_t LOG_SIZE = 10;
+    constexpr size_t LOG_SIZE_MED = 30;  // debugging for slower sensors
     constexpr size_t LOG_SIZE_LARGE = 50;  // larger samples for debugging
 }// unnamed namespace
 
@@ -98,10 +99,16 @@
 
 
 size_t RecentEventLogger::logSizeBySensorType(int sensorType) {
-    return (sensorType == SENSOR_TYPE_STEP_COUNTER ||
-            sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
-            sensorType == SENSOR_TYPE_ACCELEROMETER ||
-            sensorType == SENSOR_TYPE_LIGHT) ? LOG_SIZE_LARGE : LOG_SIZE;
+    if (sensorType == SENSOR_TYPE_STEP_COUNTER ||
+        sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+        sensorType == SENSOR_TYPE_ACCELEROMETER ||
+        sensorType == SENSOR_TYPE_LIGHT) {
+        return LOG_SIZE_LARGE;
+    }
+    if (sensorType == SENSOR_TYPE_PROXIMITY) {
+        return LOG_SIZE_MED;
+    }
+    return LOG_SIZE;
 }
 
 RecentEventLogger::SensorEventLog::SensorEventLog(const sensors_event_t& e) : mEvent(e) {
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 7237bc8..ebc7eb1 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "SensorDevice.h"
+
+#include "android/hardware/sensors/2.0/types.h"
 #include "SensorService.h"
 
 #include <android-base/logging.h>
@@ -29,7 +32,9 @@
 using namespace android::hardware::sensors;
 using namespace android::hardware::sensors::V1_0;
 using namespace android::hardware::sensors::V1_0::implementation;
+using android::hardware::sensors::V2_0::EventQueueFlagBits;
 using android::hardware::hidl_vec;
+using android::hardware::Return;
 using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
 
 namespace android {
@@ -87,22 +92,31 @@
            (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
 }
 
-bool SensorDevice::connectHidlService() {
-    bool connected = connectHidlServiceV2_0();
-    if (!connected) {
-        connected = connectHidlServiceV1_0();
+SensorDevice::~SensorDevice() {
+    if (mEventQueueFlag != nullptr) {
+        hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
+        mEventQueueFlag = nullptr;
     }
-    return connected;
 }
 
-bool SensorDevice::connectHidlServiceV1_0() {
+bool SensorDevice::connectHidlService() {
+    HalConnectionStatus status = connectHidlServiceV2_0();
+    if (status == HalConnectionStatus::DOES_NOT_EXIST) {
+        status = connectHidlServiceV1_0();
+    }
+    return (status == HalConnectionStatus::CONNECTED);
+}
+
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV1_0() {
     // SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
     size_t retry = 10;
+    HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
 
     while (retry-- > 0) {
         sp<V1_0::ISensors> sensors = V1_0::ISensors::getService();
         if (sensors == nullptr) {
             // no sensor hidl service found
+            connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
             break;
         }
 
@@ -113,25 +127,56 @@
         // which will be done since the size is 0.
         if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
             // ok to continue
+            connectionStatus = HalConnectionStatus::CONNECTED;
             break;
         }
 
         // hidl service is restarting, pointer is invalid.
         mSensors = nullptr;
+        connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
         ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
         mRestartWaiter->wait();
     }
-    return (mSensors != nullptr);
+
+    return connectionStatus;
 }
 
-bool SensorDevice::connectHidlServiceV2_0() {
+SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_0() {
+    HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
     sp<V2_0::ISensors> sensors = V2_0::ISensors::getService();
-    if (sensors != nullptr) {
+
+    if (sensors == nullptr) {
+        connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
+    } else {
         mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors);
 
-        // TODO: initialize message queues
+        mEventQueue = std::make_unique<EventMessageQueue>(
+                SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                true /* configureEventFlagWord */);
+
+        mWakeLockQueue = std::make_unique<WakeLockQueue>(
+                SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                true /* configureEventFlagWord */);
+
+        hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+
+        CHECK(mSensors != nullptr && mEventQueue != nullptr &&
+                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);
+
+        status_t status = StatusFromResult(checkReturn(mSensors->initialize(
+                *mEventQueue->getDesc(),
+                *mWakeLockQueue->getDesc(),
+                this)));
+
+        if (status != NO_ERROR) {
+            connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT;
+            ALOGE("Failed to initialize Sensors HAL (%s)", strerror(-status));
+        } else {
+            connectionStatus = HalConnectionStatus::CONNECTED;
+        }
     }
-    return (mSensors != nullptr);
+
+    return connectionStatus;
 }
 
 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
@@ -191,6 +236,19 @@
 }
 
 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
+    ssize_t eventsRead = 0;
+    if (mSensors->supportsMessageQueues()) {
+        eventsRead = pollFmq(buffer, count);
+    } else if (mSensors->supportsPolling()) {
+        eventsRead = pollHal(buffer, count);
+    } else {
+        ALOGE("Must support polling or FMQ");
+        eventsRead = -1;
+    }
+    return eventsRead;
+}
+
+ssize_t SensorDevice::pollHal(sensors_event_t* buffer, size_t count) {
     if (mSensors == nullptr) return NO_INIT;
 
     ssize_t err;
@@ -236,6 +294,79 @@
     return err;
 }
 
+ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
+    if (mSensors == nullptr) {
+        return NO_INIT;
+    }
+
+    ssize_t eventsRead = 0;
+    size_t availableEvents = mEventQueue->availableToRead();
+
+    if (availableEvents == 0) {
+        uint32_t eventFlagState = 0;
+
+        // Wait for events to become available. This is necessary so that the Event FMQ's read() is
+        // able to be called with the correct number of events to read. If the specified number of
+        // events is not available, then read() would return no events, possibly introducing
+        // additional latency in delivering events to applications.
+        mEventQueueFlag->wait(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
+                              &eventFlagState);
+        availableEvents = mEventQueue->availableToRead();
+
+        if (availableEvents == 0) {
+            ALOGW("Event FMQ wake without any events");
+        }
+    }
+
+    size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
+    if (eventsToRead > 0) {
+        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+            for (size_t i = 0; i < eventsToRead; i++) {
+                convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+            }
+            eventsRead = eventsToRead;
+        } else {
+            ALOGW("Failed to read %zu events, currently %zu events available",
+                    eventsToRead, availableEvents);
+        }
+    }
+
+    return eventsRead;
+}
+
+Return<void> SensorDevice::onDynamicSensorsConnected(
+        const hidl_vec<SensorInfo> &dynamicSensorsAdded) {
+    // Allocate a sensor_t structure for each dynamic sensor added and insert
+    // it into the dictionary of connected dynamic sensors keyed by handle.
+    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
+        const SensorInfo &info = dynamicSensorsAdded[i];
+
+        auto it = mConnectedDynamicSensors.find(info.sensorHandle);
+        CHECK(it == mConnectedDynamicSensors.end());
+
+        sensor_t *sensor = new sensor_t();
+        convertToSensor(info, sensor);
+
+        mConnectedDynamicSensors.insert(
+                std::make_pair(sensor->handle, sensor));
+    }
+
+    return Return<void>();
+}
+
+Return<void> SensorDevice::onDynamicSensorsDisconnected(
+        const hidl_vec<int32_t> &dynamicSensorHandlesRemoved) {
+    (void) dynamicSensorHandlesRemoved;
+    // TODO: Currently dynamic sensors do not seem to be removed
+    return Return<void>();
+}
+
+void SensorDevice::writeWakeLockHandled(uint32_t count) {
+    if (mSensors->supportsMessageQueues() && !mWakeLockQueue->write(&count)) {
+        ALOGW("Failed to write wake lock handled");
+    }
+}
+
 void SensorDevice::autoDisable(void *ident, int handle) {
     Mutex::Autolock _l(mLock);
     ssize_t activationIndex = mActivationCount.indexOfKey(handle);
@@ -671,19 +802,9 @@
         const hidl_vec<Event> &src,
         const hidl_vec<SensorInfo> &dynamicSensorsAdded,
         sensors_event_t *dst) {
-    // Allocate a sensor_t structure for each dynamic sensor added and insert
-    // it into the dictionary of connected dynamic sensors keyed by handle.
-    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
-        const SensorInfo &info = dynamicSensorsAdded[i];
 
-        auto it = mConnectedDynamicSensors.find(info.sensorHandle);
-        CHECK(it == mConnectedDynamicSensors.end());
-
-        sensor_t *sensor = new sensor_t;
-        convertToSensor(info, sensor);
-
-        mConnectedDynamicSensors.insert(
-                std::make_pair(sensor->handle, sensor));
+    if (dynamicSensorsAdded.size() > 0) {
+        onDynamicSensorsConnected(dynamicSensorsAdded);
     }
 
     for (size_t i = 0; i < src.size(); ++i) {
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 595a627..282550f 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -21,12 +21,15 @@
 #include "SensorServiceUtils.h"
 #include "SensorsWrapper.h"
 
+#include <fmq/MessageQueue.h>
+#include <sensor/SensorEventQueue.h>
 #include <sensor/Sensor.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/KeyedVector.h>
 #include <utils/Singleton.h>
 #include <utils/String8.h>
+#include <utils/Timers.h>
 
 #include <string>
 #include <unordered_map>
@@ -40,7 +43,9 @@
 
 // ---------------------------------------------------------------------------
 
-class SensorDevice : public Singleton<SensorDevice>, public SensorServiceUtil::Dumpable {
+class SensorDevice : public Singleton<SensorDevice>,
+                     public android::hardware::sensors::V2_0::ISensorsCallback,
+                     public SensorServiceUtil::Dumpable {
 public:
     class HidlTransportErrorLog {
      public:
@@ -68,6 +73,8 @@
         int mCount;   // number of transport errors observed
     };
 
+    ~SensorDevice();
+
     ssize_t getSensorList(sensor_t const** list);
 
     void handleDynamicSensorConnection(int handle, bool connected);
@@ -75,6 +82,7 @@
     int getHalDeviceVersion() const;
 
     ssize_t poll(sensors_event_t* buffer, size_t count);
+    void writeWakeLockHandled(uint32_t count);
 
     status_t activate(void* ident, int handle, int enabled);
     status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
@@ -97,6 +105,12 @@
     status_t injectSensorData(const sensors_event_t *event);
     void notifyConnectionDestroyed(void *ident);
 
+    using Result = ::android::hardware::sensors::V1_0::Result;
+    hardware::Return<void> onDynamicSensorsConnected(
+            const hardware::hidl_vec<hardware::sensors::V1_0::SensorInfo> &dynamicSensorsAdded) override;
+    hardware::Return<void> onDynamicSensorsDisconnected(
+            const hardware::hidl_vec<int32_t> &dynamicSensorHandlesRemoved) override;
+
     // Dumpable
     virtual std::string dump() const;
 private:
@@ -162,8 +176,18 @@
     SortedVector<void *> mDisabledClients;
     SensorDevice();
     bool connectHidlService();
-    bool connectHidlServiceV1_0();
-    bool connectHidlServiceV2_0();
+
+    enum HalConnectionStatus {
+        CONNECTED, // Successfully connected to the HAL
+        DOES_NOT_EXIST, // Could not find the HAL
+        FAILED_TO_CONNECT, // Found the HAL but failed to connect/initialize
+        UNKNOWN,
+    };
+    HalConnectionStatus connectHidlServiceV1_0();
+    HalConnectionStatus connectHidlServiceV2_0();
+
+    ssize_t pollHal(sensors_event_t* buffer, size_t count);
+    ssize_t pollFmq(sensors_event_t* buffer, size_t count);
 
     static void handleHidlDeath(const std::string &detail);
     template<typename T>
@@ -190,6 +214,15 @@
             sensors_event_t *dst);
 
     bool mIsDirectReportSupported;
+
+    typedef hardware::MessageQueue<Event, hardware::kSynchronizedReadWrite> EventMessageQueue;
+    typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
+    std::unique_ptr<EventMessageQueue> mEventQueue;
+    std::unique_ptr<WakeLockQueue> mWakeLockQueue;
+
+    hardware::EventFlag* mEventQueueFlag;
+
+    std::array<Event, SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 3822ee1..7c56e5c 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -651,16 +651,18 @@
         // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
         // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
         // releasing the wakelock.
-        bool bufferHasWakeUpEvent = false;
+        uint32_t wakeEvents = 0;
         for (int i = 0; i < count; i++) {
             if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
-                bufferHasWakeUpEvent = true;
-                break;
+                wakeEvents++;
             }
         }
 
-        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
-            setWakeLockAcquiredLocked(true);
+        if (wakeEvents > 0) {
+            if (!mWakeLockAcquired) {
+                setWakeLockAcquiredLocked(true);
+            }
+            device.writeWakeLockHandled(wakeEvents);
         }
         recordLastValueLocked(mSensorEventBuffer, count);
 
diff --git a/services/sensorservice/SensorsWrapper.h b/services/sensorservice/SensorsWrapper.h
index f3fa164..d1a7234 100644
--- a/services/sensorservice/SensorsWrapper.h
+++ b/services/sensorservice/SensorsWrapper.h
@@ -19,6 +19,7 @@
 
 #include "android/hardware/sensors/1.0/ISensors.h"
 #include "android/hardware/sensors/2.0/ISensors.h"
+#include "android/hardware/sensors/2.0/ISensorsCallback.h"
 
 #include <utils/LightRefBase.h>
 
@@ -33,6 +34,7 @@
 using ::android::hardware::sensors::V1_0::RateLevel;
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SharedMemInfo;
+using ::android::hardware::sensors::V2_0::ISensorsCallback;
 
 /*
  * The ISensorsWrapper interface includes all function from supported Sensors HAL versions. This
@@ -85,10 +87,12 @@
         return Return<void>();
     }
 
-    virtual Return<Result> initializeMessageQueues(const MQDescriptorSync<Event>& eventQueueDesc,
-                                                   const MQDescriptorSync<uint32_t>& wakeLockDesc) {
+    virtual Return<Result> initialize(const MQDescriptorSync<Event>& eventQueueDesc,
+                                      const MQDescriptorSync<uint32_t>& wakeLockDesc,
+                                      const ::android::sp<ISensorsCallback>& callback) {
         (void)eventQueueDesc;
         (void)wakeLockDesc;
+        (void)callback;
         // TODO (b/111070257): Generate an assert-level error since this should never be called
         // directly
         return Result::INVALID_OPERATION;
@@ -177,10 +181,10 @@
         return true;
     }
 
-    Return<Result> initializeMessageQueues(
-            const MQDescriptorSync<Event>& eventQueueDesc,
-            const MQDescriptorSync<uint32_t>& wakeLockDesc) override {
-        return mSensors->initializeMessageQueues(eventQueueDesc, wakeLockDesc);
+    Return<Result> initialize(const MQDescriptorSync<Event>& eventQueueDesc,
+                              const MQDescriptorSync<uint32_t>& wakeLockDesc,
+                              const ::android::sp<ISensorsCallback>& callback) override {
+        return mSensors->initialize(eventQueueDesc, wakeLockDesc, callback);
     }
 };
 
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 744bdba..339f83b 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -4,6 +4,7 @@
         "-DLOG_TAG=\"SurfaceFlinger\"",
         "-Wall",
         "-Werror",
+        "-Wformat",
         "-Wthread-safety",
         "-Wunused",
         "-Wunreachable-code",
@@ -18,6 +19,10 @@
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
     ],
+    include_dirs: [
+        "frameworks/native/vulkan/vkjson",
+        "frameworks/native/vulkan/include",
+    ],
     shared_libs: [
         "android.frameworks.vr.composer@1.0",
         "android.hardware.configstore-utils",
@@ -84,6 +89,18 @@
     ],
 }
 
+cc_defaults {
+    name: "libsurfaceflinger_production_defaults",
+    defaults: ["libsurfaceflinger_defaults"],
+    cflags: [
+        "-fvisibility=hidden",
+        "-fwhole-program-vtables", // requires ThinLTO
+    ],
+    lto: {
+        thin: true,
+    },
+}
+
 cc_library_headers {
     name: "libsurfaceflinger_headers",
     export_include_dirs: ["."],
@@ -121,6 +138,7 @@
         "LayerStats.cpp",
         "LayerVector.cpp",
         "MonitoredProducer.cpp",
+        "NativeWindowSurface.cpp",
         "RenderArea.cpp",
         "Scheduler/DispSync.cpp",
         "Scheduler/DispSyncSource.cpp",
@@ -137,33 +155,23 @@
 }
 
 cc_library_shared {
+    // Please use libsurfaceflinger_defaults to configure how the sources are
+    // built, so the same settings can be used elsewhere.
     name: "libsurfaceflinger",
-    defaults: ["libsurfaceflinger_defaults"],
-    cflags: [
-        "-fvisibility=hidden",
-        "-Werror=format",
-    ],
+    defaults: ["libsurfaceflinger_production_defaults"],
     srcs: [
         ":libsurfaceflinger_sources",
+
+        // Note: SurfaceFlingerFactory is not in the default sources so that it
+        // can be easily replaced.
+        "SurfaceFlingerFactory.cpp",
     ],
     logtags: ["EventLog/EventLogTags.logtags"],
-    include_dirs: [
-        "frameworks/native/vulkan/vkjson",
-        "frameworks/native/vulkan/include",
-    ],
-    cppflags: [
-        "-fwhole-program-vtables", // requires ThinLTO
-    ],
-    lto: {
-        thin: true,
-    },
 }
 
-cc_binary {
-    name: "surfaceflinger",
+cc_defaults {
+    name: "libsurfaceflinger_binary",
     defaults: ["surfaceflinger_defaults"],
-    init_rc: ["surfaceflinger.rc"],
-    srcs: ["main_surfaceflinger.cpp"],
     whole_static_libs: [
         "libsigchain",
     ],
@@ -180,7 +188,6 @@
         "libhidltransport",
         "liblayers_proto",
         "liblog",
-        "libsurfaceflinger",
         "libtimestats_proto",
         "libutils",
     ],
@@ -189,19 +196,19 @@
         "libtrace_proto",
     ],
     ldflags: ["-Wl,--export-dynamic"],
+}
 
-    // TODO(b/71715793): These version-scripts are required due to the use of
-    // whole_static_libs to pull in libsigchain. To work, the files had to be
-    // locally duplicated from their original location
-    // $ANDROID_ROOT/art/sigchainlib/
-    multilib: {
-        lib32: {
-            version_script: "version-script32.txt",
-        },
-        lib64: {
-            version_script: "version-script64.txt",
-        },
-    },
+filegroup {
+    name: "surfaceflinger_binary_sources",
+    srcs: ["main_surfaceflinger.cpp"],
+}
+
+cc_binary {
+    name: "surfaceflinger",
+    defaults: ["libsurfaceflinger_binary"],
+    init_rc: ["surfaceflinger.rc"],
+    srcs: [":surfaceflinger_binary_sources"],
+    shared_libs: ["libsurfaceflinger"],
 }
 
 cc_library_shared {
diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
index 3e9d443..97028a8 100644
--- a/services/surfaceflinger/Barrier.h
+++ b/services/surfaceflinger/Barrier.h
@@ -18,46 +18,40 @@
 #define ANDROID_BARRIER_H
 
 #include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
+#include <condition_variable>
+#include <mutex>
 
 namespace android {
 
 class Barrier
 {
 public:
-    inline Barrier() : state(CLOSED) { }
-    inline ~Barrier() { }
-
     // Release any threads waiting at the Barrier.
     // Provides release semantics: preceding loads and stores will be visible
     // to other threads before they wake up.
     void open() {
-        Mutex::Autolock _l(lock);
-        state = OPENED;
-        cv.broadcast();
+        std::lock_guard<std::mutex> lock(mMutex);
+        mIsOpen = true;
+        mCondition.notify_all();
     }
 
     // Reset the Barrier, so wait() will block until open() has been called.
     void close() {
-        Mutex::Autolock _l(lock);
-        state = CLOSED;
+        std::lock_guard<std::mutex> lock(mMutex);
+        mIsOpen = false;
     }
 
     // Wait until the Barrier is OPEN.
     // Provides acquire semantics: no subsequent loads or stores will occur
     // until wait() returns.
     void wait() const {
-        Mutex::Autolock _l(lock);
-        while (state == CLOSED) {
-            cv.wait(lock);
-        }
+        std::unique_lock<std::mutex> lock(mMutex);
+        mCondition.wait(lock, [this]() NO_THREAD_SAFETY_ANALYSIS { return mIsOpen; });
     }
 private:
-    enum { OPENED, CLOSED };
-    mutable     Mutex       lock;
-    mutable     Condition   cv;
-    volatile    int         state;
+    mutable std::mutex mMutex;
+    mutable std::condition_variable mCondition;
+    int mIsOpen GUARDED_BY(mMutex){false};
 };
 
 }; // namespace android
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 89394cd..642ed2f 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -49,24 +49,16 @@
 
 namespace android {
 
-BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                         uint32_t w, uint32_t h, uint32_t flags)
-      : Layer(flinger, client, name, w, h, flags),
-        mTextureName(mFlinger->getNewTexture()),
-        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
-        mBufferLatched(false),
-        mRefreshPending(false) {
-    ALOGV("Creating Layer %s", name.string());
+BufferLayer::BufferLayer(const LayerCreationArgs& args)
+      : Layer(args), mTextureName(args.flinger->getNewTexture()) {
+    ALOGV("Creating Layer %s", args.name.string());
 
     mTexture.init(renderengine::Texture::TEXTURE_EXTERNAL, mTextureName);
 
-    mPremultipliedAlpha = !(flags & ISurfaceComposerClient::eNonPremultiplied);
+    mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
 
-    mPotentialCursor = flags & ISurfaceComposerClient::eCursorWindow;
-    mProtectedByApp = flags & ISurfaceComposerClient::eProtectedByApp;
-
-    // drawing state & current state are identical
-    mDrawingState = mCurrentState;
+    mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
+    mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
 }
 
 BufferLayer::~BufferLayer() {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 45906ff..92bf132 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -39,6 +39,8 @@
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
+#include <system/window.h> // For NATIVE_WINDOW_SCALING_MODE_FREEZE
+
 #include <stdint.h>
 #include <sys/types.h>
 #include <list>
@@ -47,9 +49,7 @@
 
 class BufferLayer : public Layer {
 public:
-    BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
-                uint32_t h, uint32_t flags);
-
+    explicit BufferLayer(const LayerCreationArgs& args);
     ~BufferLayer() override;
 
     // -----------------------------------------------------------------------
@@ -172,15 +172,15 @@
 
     uint64_t getHeadFrameNumber() const;
 
-    uint32_t mCurrentScalingMode;
+    uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
     // main thread.
-    bool mBufferLatched; // TODO: Use mActiveBuffer?
+    bool mBufferLatched{false}; // TODO: Use mActiveBuffer?
 
     // The texture used to draw the layer in GLES composition mode
     mutable renderengine::Texture mTexture;
 
-    bool mRefreshPending;
+    bool mRefreshPending{false};
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 4839bfb..17706b5 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -21,24 +21,9 @@
 
 namespace android {
 
-BufferQueueLayer::BufferQueueLayer(SurfaceFlinger* flinger, const sp<Client>& client,
-                                   const String8& name, uint32_t w, uint32_t h, uint32_t flags)
-      : BufferLayer(flinger, client, name, w, h, flags),
-        mConsumer(nullptr),
-        mProducer(nullptr),
-        mFormat(PIXEL_FORMAT_NONE),
-        mPreviousFrameNumber(0),
-        mUpdateTexImageFailed(false),
-        mQueueItemLock(),
-        mQueueItemCondition(),
-        mQueueItems(),
-        mLastFrameNumberReceived(0),
-        mAutoRefresh(false),
-        mActiveBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
-        mQueuedFrames(0),
-        mSidebandStreamChanged(false) {
-    mCurrentState.requested_legacy = mCurrentState.active_legacy;
-}
+BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
+
+BufferQueueLayer::~BufferQueueLayer() = default;
 
 // -----------------------------------------------------------------------
 // Interface implementation for Layer
@@ -207,8 +192,9 @@
 }
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
-    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was true
+    bool sidebandStreamChanged = true;
+    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
+        // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
         getBE().compositionInfo.hwc.sidebandStream = mConsumer->getSidebandStream();
         if (getBE().compositionInfo.hwc.sidebandStream != nullptr) {
@@ -259,7 +245,7 @@
             Mutex::Autolock lock(mQueueItemLock);
             mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
+            mQueuedFrames--;
         }
         return BAD_VALUE;
     } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
@@ -270,7 +256,7 @@
         if (queuedBuffer) {
             Mutex::Autolock lock(mQueueItemLock);
             mQueueItems.clear();
-            android_atomic_and(0, &mQueuedFrames);
+            mQueuedFrames = 0;
             mTimeStats.clearLayerRecord(getName().c_str());
         }
 
@@ -294,7 +280,7 @@
         while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
             mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
-            android_atomic_dec(&mQueuedFrames);
+            mQueuedFrames--;
         }
 
         const std::string layerName(getName().c_str());
@@ -306,7 +292,7 @@
 
     // Decrement the queued-frames count.  Signal another event if we
     // have more frames pending.
-    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) {
+    if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
         mFlinger->signalLayerUpdate();
     }
 
@@ -367,7 +353,7 @@
         }
 
         mQueueItems.push_back(item);
-        android_atomic_inc(&mQueuedFrames);
+        mQueuedFrames++;
 
         // Wake up any pending callbacks
         mLastFrameNumberReceived = item.mFrameNumber;
@@ -404,8 +390,9 @@
 }
 
 void BufferQueueLayer::onSidebandStreamChanged() {
-    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
-        // mSidebandStreamChanged was false
+    bool sidebandStreamChanged = false;
+    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, true)) {
+        // mSidebandStreamChanged was changed to true
         mFlinger->signalLayerUpdate();
     }
 }
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 579ed81..051b15d 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -31,8 +31,8 @@
  */
 class BufferQueueLayer : public BufferLayer, public BufferLayerConsumer::ContentsChangedListener {
 public:
-    BufferQueueLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                     uint32_t w, uint32_t h, uint32_t flags);
+    explicit BufferQueueLayer(const LayerCreationArgs&);
+    ~BufferQueueLayer() override;
 
     // -----------------------------------------------------------------------
     // Interface implementation for Layer
@@ -121,24 +121,24 @@
     sp<BufferLayerConsumer> mConsumer;
     sp<IGraphicBufferProducer> mProducer;
 
-    PixelFormat mFormat;
+    PixelFormat mFormat{PIXEL_FORMAT_NONE};
 
     // Only accessed on the main thread.
-    uint64_t mPreviousFrameNumber;
-    bool mUpdateTexImageFailed;
+    uint64_t mPreviousFrameNumber{0};
+    bool mUpdateTexImageFailed{false};
 
     // Local copy of the queued contents of the incoming BufferQueue
     mutable Mutex mQueueItemLock;
     Condition mQueueItemCondition;
     Vector<BufferItem> mQueueItems;
-    std::atomic<uint64_t> mLastFrameNumberReceived;
+    std::atomic<uint64_t> mLastFrameNumberReceived{0};
 
-    bool mAutoRefresh;
-    int mActiveBufferSlot;
+    bool mAutoRefresh{false};
+    int mActiveBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
 
     // thread-safe
-    volatile int32_t mQueuedFrames;
-    volatile int32_t mSidebandStreamChanged; // used like an atomic boolean
+    std::atomic<int32_t> mQueuedFrames{0};
+    std::atomic<bool> mSidebandStreamChanged{false};
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index da9dcfb..9c10868 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -26,18 +26,17 @@
 
 namespace android {
 
-static const std::array<float, 16> IDENTITY_MATRIX{1, 0, 0, 0,
-                                                   0, 1, 0, 0,
-                                                   0, 0, 1, 0,
-                                                   0, 0, 0, 1};
+// clang-format off
+const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{
+        1, 0, 0, 0,
+        0, 1, 0, 0,
+        0, 0, 1, 0,
+        0, 0, 0, 1
+};
+// clang-format on
 
-BufferStateLayer::BufferStateLayer(SurfaceFlinger* flinger, const sp<Client>& client,
-                                   const String8& name, uint32_t w, uint32_t h, uint32_t flags)
-      : BufferLayer(flinger, client, name, w, h, flags),
-        mSidebandStreamChanged(false),
-        mFrameNumber(0) {
-    mTransformMatrix = IDENTITY_MATRIX;
-}
+BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
+BufferStateLayer::~BufferStateLayer() = default;
 
 // -----------------------------------------------------------------------
 // Interface implementation for Layer
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index ac3aad1..b662b96 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -29,8 +29,8 @@
 
 class BufferStateLayer : public BufferLayer {
 public:
-    BufferStateLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                     uint32_t w, uint32_t h, uint32_t flags);
+    explicit BufferStateLayer(const LayerCreationArgs&);
+    ~BufferStateLayer() override;
 
     // -----------------------------------------------------------------------
     // Interface implementation for Layer
@@ -125,13 +125,15 @@
 private:
     void onFirstRef() override;
 
+    static const std::array<float, 16> IDENTITY_MATRIX;
+
     std::unique_ptr<renderengine::Image> mTextureImage;
 
-    std::array<float, 16> mTransformMatrix;
+    std::array<float, 16> mTransformMatrix{IDENTITY_MATRIX};
 
-    std::atomic<bool> mSidebandStreamChanged;
+    std::atomic<bool> mSidebandStreamChanged{false};
 
-    uint32_t mFrameNumber;
+    uint32_t mFrameNumber{0};
 
     // TODO(marissaw): support sticky transform for LEGACY camera mode
 };
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 9bf75e8..b02c16c 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -34,12 +34,9 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                       uint32_t w, uint32_t h, uint32_t flags)
-      : Layer(flinger, client, name, w, h, flags) {
-    // drawing state & current state are identical
-    mDrawingState = mCurrentState;
-}
+ColorLayer::ColorLayer(const LayerCreationArgs& args) : Layer(args) {}
+
+ColorLayer::~ColorLayer() = default;
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) {
@@ -72,9 +69,9 @@
     getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
 
     half4 color = getColor();
-    getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)),
-                                      static_cast<uint8_t>(std::round(255.0f * color.g)),
-                                      static_cast<uint8_t>(std::round(255.0f * color.b)), 255 };
+    getBE().compositionInfo.hwc.color = {static_cast<uint8_t>(std::round(255.0f * color.r)),
+                                         static_cast<uint8_t>(std::round(255.0f * color.g)),
+                                         static_cast<uint8_t>(std::round(255.0f * color.b)), 255};
 
     // Clear out the transform, because it doesn't make sense absent a source buffer
     getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index aa6b049..2c10357 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -25,9 +25,8 @@
 
 class ColorLayer : public Layer {
 public:
-    ColorLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
-               uint32_t h, uint32_t flags);
-    virtual ~ColorLayer() = default;
+    explicit ColorLayer(const LayerCreationArgs&);
+    ~ColorLayer() override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
     virtual void onDraw(const RenderArea& renderArea, const Region& clip,
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index e9f3059..44e843e 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -22,11 +22,9 @@
 
 namespace android {
 
-ContainerLayer::ContainerLayer(SurfaceFlinger* flinger, const sp<Client>& client,
-                               const String8& name, uint32_t w, uint32_t h, uint32_t flags)
-      : Layer(flinger, client, name, w, h, flags) {
-    mDrawingState = mCurrentState;
-}
+ContainerLayer::ContainerLayer(const LayerCreationArgs& args) : Layer(args) {}
+
+ContainerLayer::~ContainerLayer() = default;
 
 void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) {}
 
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 0b4a181..8eddc7f 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -25,9 +25,8 @@
 
 class ContainerLayer : public Layer {
 public:
-    ContainerLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                   uint32_t w, uint32_t h, uint32_t flags);
-    virtual ~ContainerLayer() = default;
+    explicit ContainerLayer(const LayerCreationArgs&);
+    ~ContainerLayer() override;
 
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 4becfab..341dfd5 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -206,54 +206,46 @@
 
 } // anonymous namespace
 
-// clang-format off
-DisplayDevice::DisplayDevice(
-        const sp<SurfaceFlinger>& flinger,
-        DisplayType type,
-        int32_t id,
-        bool isSecure,
-        const wp<IBinder>& displayToken,
-        const sp<ANativeWindow>& nativeWindow,
-        const sp<DisplaySurface>& displaySurface,
-        std::unique_ptr<renderengine::Surface> renderSurface,
-        int displayWidth,
-        int displayHeight,
-        int displayInstallOrientation,
-        bool hasWideColorGamut,
-        const HdrCapabilities& hdrCapabilities,
-        const int32_t supportedPerFrameMetadata,
-        const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
-        int initialPowerMode)
-    : lastCompositionHadVisibleLayers(false),
-      mFlinger(flinger),
-      mType(type),
-      mId(id),
-      mDisplayToken(displayToken),
-      mNativeWindow(nativeWindow),
-      mDisplaySurface(displaySurface),
-      mSurface{std::move(renderSurface)},
-      mDisplayWidth(displayWidth),
-      mDisplayHeight(displayHeight),
-      mDisplayInstallOrientation(displayInstallOrientation),
-      mPageFlipCount(0),
-      mIsSecure(isSecure),
-      mLayerStack(NO_LAYER_STACK),
-      mOrientation(),
-      mViewport(Rect::INVALID_RECT),
-      mFrame(Rect::INVALID_RECT),
-      mPowerMode(initialPowerMode),
-      mActiveConfig(0),
-      mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY),
-      mHasWideColorGamut(hasWideColorGamut),
-      mHasHdr10(false),
-      mHasHLG(false),
-      mHasDolbyVision(false),
-      mSupportedPerFrameMetadata(supportedPerFrameMetadata)
-{
-    // clang-format on
-    populateColorModes(hwcColorModes);
+DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger,
+                                                     const wp<IBinder>& displayToken,
+                                                     DisplayDevice::DisplayType type, int32_t id)
+      : flinger(flinger), displayToken(displayToken), type(type), id(id) {}
 
-    std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes();
+DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs&& args)
+      : lastCompositionHadVisibleLayers(false),
+        mFlinger(args.flinger),
+        mType(args.type),
+        mId(args.id),
+        mDisplayToken(args.displayToken),
+        mNativeWindow(args.nativeWindow),
+        mDisplaySurface(args.displaySurface),
+        mSurface{std::move(args.renderSurface)},
+        mDisplayWidth(args.displayWidth),
+        mDisplayHeight(args.displayHeight),
+        mDisplayInstallOrientation(args.displayInstallOrientation),
+        mPageFlipCount(0),
+        mIsSecure(args.isSecure),
+        mLayerStack(NO_LAYER_STACK),
+        mOrientation(),
+        mViewport(Rect::INVALID_RECT),
+        mFrame(Rect::INVALID_RECT),
+        mPowerMode(args.initialPowerMode),
+        mActiveConfig(0),
+        mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY),
+        mHasWideColorGamut(args.hasWideColorGamut),
+        mHasHdr10(false),
+        mHasHLG(false),
+        mHasDolbyVision(false),
+        mSupportedPerFrameMetadata(args.supportedPerFrameMetadata) {
+    populateColorModes(args.hwcColorModes);
+
+    ALOGE_IF(!mNativeWindow, "No native window was set for display");
+    ALOGE_IF(!mDisplaySurface, "No display surface was set for display");
+    ALOGE_IF(!mSurface, "No render surface was set for display");
+    ALOGE_IF(mDisplayWidth <= 0 || mDisplayHeight <= 0,
+             "Invalid dimensions of %d x %d were set for display", mDisplayWidth, mDisplayHeight);
+
+    std::vector<Hdr> types = args.hdrCapabilities.getSupportedHdrTypes();
     for (Hdr hdrType : types) {
         switch (hdrType) {
             case Hdr::HDR10:
@@ -270,9 +262,9 @@
         }
     }
 
-    float minLuminance = hdrCapabilities.getDesiredMinLuminance();
-    float maxLuminance = hdrCapabilities.getDesiredMaxLuminance();
-    float maxAverageLuminance = hdrCapabilities.getDesiredMaxAverageLuminance();
+    float minLuminance = args.hdrCapabilities.getDesiredMinLuminance();
+    float maxLuminance = args.hdrCapabilities.getDesiredMaxLuminance();
+    float maxAverageLuminance = args.hdrCapabilities.getDesiredMaxAverageLuminance();
 
     minLuminance = minLuminance <= 0.0 ? sDefaultMinLumiance : minLuminance;
     maxLuminance = maxLuminance <= 0.0 ? sDefaultMaxLumiance : maxLuminance;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index ed73671..38482c9 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -43,14 +43,16 @@
 
 namespace android {
 
-struct DisplayInfo;
 class DisplaySurface;
 class Fence;
+class HWComposer;
 class IGraphicBufferProducer;
 class Layer;
 class SurfaceFlinger;
-class HWComposer;
+
 struct CompositionInfo;
+struct DisplayDeviceCreationArgs;
+struct DisplayInfo;
 
 class DisplayDevice : public LightRefBase<DisplayDevice>
 {
@@ -76,25 +78,7 @@
         NO_LAYER_STACK = 0xFFFFFFFF,
     };
 
-    // clang-format off
-    DisplayDevice(
-            const sp<SurfaceFlinger>& flinger,
-            DisplayType type,
-            int32_t id,
-            bool isSecure,
-            const wp<IBinder>& displayToken,
-            const sp<ANativeWindow>& nativeWindow,
-            const sp<DisplaySurface>& displaySurface,
-            std::unique_ptr<renderengine::Surface> renderSurface,
-            int displayWidth,
-            int displayHeight,
-            int displayInstallOrientation,
-            bool hasWideColorGamut,
-            const HdrCapabilities& hdrCapabilities,
-            const int32_t supportedPerFrameMetadata,
-            const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>>& hwcColorModes,
-            int initialPowerMode);
-    // clang-format on
+    explicit DisplayDevice(DisplayDeviceCreationArgs&& args);
 
     ~DisplayDevice();
 
@@ -335,6 +319,31 @@
     static std::atomic<int32_t> sNextSequenceId;
 };
 
+struct DisplayDeviceCreationArgs {
+    // We use a constructor to ensure some of the values are set, without
+    // assuming a default value.
+    DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& displayToken,
+                              DisplayDevice::DisplayType type, int32_t id);
+
+    const sp<SurfaceFlinger> flinger;
+    const wp<IBinder> displayToken;
+    const DisplayDevice::DisplayType type;
+    const int32_t id;
+
+    bool isSecure{false};
+    sp<ANativeWindow> nativeWindow;
+    sp<DisplaySurface> displaySurface;
+    std::unique_ptr<renderengine::Surface> renderSurface;
+    int displayWidth{0};
+    int displayHeight{0};
+    int displayInstallOrientation{DisplayState::eOrientationDefault};
+    bool hasWideColorGamut{false};
+    HdrCapabilities hdrCapabilities;
+    int32_t supportedPerFrameMetadata{0};
+    std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hwcColorModes;
+    int initialPowerMode{HWC_POWER_MODE_NORMAL};
+};
+
 class DisplayRenderArea : public RenderArea {
 public:
     DisplayRenderArea(const sp<const DisplayDevice> device,
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 03b63bd..f9bc1e7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -62,43 +62,24 @@
 
 namespace android {
 
-int32_t Layer::sSequence = 1;
+std::atomic<int32_t> Layer::sSequence{1};
 
-Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
-             uint32_t h, uint32_t flags)
-      : contentDirty(false),
-        sequence(uint32_t(android_atomic_inc(&sSequence))),
-        mFlinger(flinger),
-        mPremultipliedAlpha(true),
-        mName(name),
-        mTransactionFlags(0),
-        mPendingStateMutex(),
-        mPendingStates(),
-        mCurrentTransform(0),
-        mOverrideScalingMode(-1),
-        mCurrentFrameNumber(0),
-        mFrameLatencyNeeded(false),
-        mNeedsFiltering(false),
-        mProtectedByApp(false),
-        mClientRef(client),
-        mPotentialCursor(false),
-        mFreezeGeometryUpdates(false),
-        mCurrentChildren(LayerVector::StateSet::Current),
-        mDrawingChildren(LayerVector::StateSet::Drawing),
-        mBE{this, name.string()} {
-
+Layer::Layer(const LayerCreationArgs& args)
+      : mFlinger(args.flinger),
+        mName(args.name),
+        mClientRef(args.client),
+        mBE{this, args.name.string()} {
     mCurrentCrop.makeInvalid();
 
     uint32_t layerFlags = 0;
-    if (flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
-    if (flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
-    if (flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
+    if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
+    if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
+    if (args.flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
 
-    mName = name;
     mTransactionName = String8("TX - ") + mName;
 
-    mCurrentState.active_legacy.w = w;
-    mCurrentState.active_legacy.h = h;
+    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();
@@ -126,7 +107,7 @@
     mDrawingState = mCurrentState;
 
     CompositorTiming compositorTiming;
-    flinger->getCompositorTiming(&compositorTiming);
+    args.flinger->getCompositorTiming(&compositorTiming);
     mFrameEventHistory.initializeCompositorTiming(compositorTiming);
     mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval);
 }
@@ -1019,11 +1000,11 @@
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    return android_atomic_or(flags, &mTransactionFlags);
+    return mTransactionFlags.fetch_or(flags);
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3845b22..874b551 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -72,14 +72,27 @@
 
 // ---------------------------------------------------------------------------
 
+struct LayerCreationArgs {
+    LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
+                      uint32_t w, uint32_t h, uint32_t flags)
+          : flinger(flinger), client(client), name(name), w(w), h(h), flags(flags) {}
+
+    SurfaceFlinger* flinger;
+    const sp<Client>& client;
+    const String8& name;
+    uint32_t w;
+    uint32_t h;
+    uint32_t flags;
+};
+
 class Layer : public virtual RefBase {
-    static int32_t sSequence;
+    static std::atomic<int32_t> sSequence;
 
 public:
     friend class LayerBE;
     LayerBE& getBE() { return mBE; }
     LayerBE& getBE() const { return mBE; }
-    mutable bool contentDirty;
+    mutable bool contentDirty{false};
     // regions below are in window-manager space
     Region visibleRegion;
     Region coveredRegion;
@@ -89,7 +102,7 @@
     // Layer serial number.  This gives layers an explicit ordering, so we
     // have a stable sort order when their layer stack and Z-order are
     // the same.
-    int32_t sequence;
+    int32_t sequence{sSequence++};
 
     enum { // flags for doTransaction()
         eDontUpdateGeometryState = 0x00000001,
@@ -170,8 +183,7 @@
         sp<NativeHandle> sidebandStream;
     };
 
-    Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
-          uint32_t h, uint32_t flags);
+    explicit Layer(const LayerCreationArgs& args);
     virtual ~Layer();
 
     void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; }
@@ -271,6 +283,7 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
+    uint32_t getTransactionFlags() const { return mTransactionFlags; }
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
 
@@ -687,7 +700,7 @@
     // -----------------------------------------------------------------------
     bool usingRelativeZ(LayerVector::StateSet stateSet);
 
-    bool mPremultipliedAlpha;
+    bool mPremultipliedAlpha{true};
     String8 mName;
     String8 mTransactionName; // A cached version of "TX - " + mName for systraces
 
@@ -696,7 +709,7 @@
     // these are protected by an external lock
     State mCurrentState;
     State mDrawingState;
-    volatile int32_t mTransactionFlags;
+    std::atomic<uint32_t> mTransactionFlags{0};
 
     // Accessed from main thread and binder threads
     Mutex mPendingStateMutex;
@@ -718,18 +731,18 @@
     sp<GraphicBuffer> mActiveBuffer;
     ui::Dataspace mCurrentDataSpace = ui::Dataspace::UNKNOWN;
     Rect mCurrentCrop;
-    uint32_t mCurrentTransform;
+    uint32_t mCurrentTransform{0};
     // We encode unset as -1.
-    int32_t mOverrideScalingMode;
-    std::atomic<uint64_t> mCurrentFrameNumber;
-    bool mFrameLatencyNeeded;
+    int32_t mOverrideScalingMode{-1};
+    std::atomic<uint64_t> mCurrentFrameNumber{0};
+    bool mFrameLatencyNeeded{false};
     // Whether filtering is needed b/c of the drawingstate
-    bool mNeedsFiltering;
+    bool mNeedsFiltering{false};
 
-    bool mPendingRemoval = false;
+    bool mPendingRemoval{false};
 
     // page-flip thread (currently main thread)
-    bool mProtectedByApp; // application requires protected path to external sink
+    bool mProtectedByApp{false}; // application requires protected path to external sink
 
     // protected by mLock
     mutable Mutex mLock;
@@ -737,14 +750,14 @@
     const wp<Client> mClientRef;
 
     // This layer can be a cursor on some displays.
-    bool mPotentialCursor;
+    bool mPotentialCursor{false};
 
-    bool mFreezeGeometryUpdates;
+    bool mFreezeGeometryUpdates{false};
 
     // Child list about to be committed/used for editing.
-    LayerVector mCurrentChildren;
+    LayerVector mCurrentChildren{LayerVector::StateSet::Current};
     // Child list used for rendering.
-    LayerVector mDrawingChildren;
+    LayerVector mDrawingChildren{LayerVector::StateSet::Drawing};
 
     wp<Layer> mCurrentParent;
     wp<Layer> mDrawingParent;
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index 04ab121..9c2d312 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -57,7 +57,7 @@
 }
 
 void LayerStats::traverseLayerTreeStatsLocked(
-        const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+        const std::vector<LayerProtoParser::Layer*>& layerTree,
         const LayerProtoParser::LayerGlobal& layerGlobal,
         std::vector<std::string>* const outLayerShapeVec) {
     for (const auto& layer : layerTree) {
@@ -82,7 +82,7 @@
         base::StringAppendF(&key, ",%s",
                             destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
                                             layerGlobal.resolution[1], false));
-        base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str());
+        base::StringAppendF(&key, ",%s", scaleRatioWH(layer).c_str());
         base::StringAppendF(&key, ",%s", alpha(static_cast<float>(layer->color.a)));
 
         outLayerShapeVec->push_back(key);
@@ -98,7 +98,7 @@
     std::vector<std::string> layerShapeVec;
 
     std::lock_guard<std::mutex> lock(mMutex);
-    traverseLayerTreeStatsLocked(layerTree, layerGlobal, &layerShapeVec);
+    traverseLayerTreeStatsLocked(layerTree.topLevelLayers, layerGlobal, &layerShapeVec);
 
     std::string layerShapeKey =
             base::StringPrintf("%d,%s,%s,%s", static_cast<int32_t>(layerShapeVec.size()),
diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h
index 7a190fd..944073b 100644
--- a/services/surfaceflinger/LayerStats.h
+++ b/services/surfaceflinger/LayerStats.h
@@ -38,7 +38,7 @@
 private:
     // Traverse layer tree to get all visible layers' stats
     void traverseLayerTreeStatsLocked(
-            const std::vector<std::unique_ptr<LayerProtoParser::Layer>>& layerTree,
+            const std::vector<LayerProtoParser::Layer*>& layerTree,
             const LayerProtoParser::LayerGlobal& layerGlobal,
             std::vector<std::string>* const outLayerShapeVec);
     // Convert layer's top-left position into 8x8 percentage of the display
diff --git a/services/surfaceflinger/NativeWindowSurface.cpp b/services/surfaceflinger/NativeWindowSurface.cpp
new file mode 100644
index 0000000..3fff928
--- /dev/null
+++ b/services/surfaceflinger/NativeWindowSurface.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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 "NativeWindowSurface.h"
+
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/Surface.h>
+
+namespace android::surfaceflinger {
+
+NativeWindowSurface::~NativeWindowSurface() = default;
+
+namespace impl {
+
+std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
+        const sp<IGraphicBufferProducer>& producer) {
+    class NativeWindowSurface final : public surfaceflinger::NativeWindowSurface {
+    public:
+        explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer)
+              : mSurface(new Surface(producer, /* controlledByApp */ false)) {}
+
+        ~NativeWindowSurface() override = default;
+
+        sp<ANativeWindow> getNativeWindow() const override { return mSurface; }
+
+        void preallocateBuffers() override { mSurface->allocateBuffers(); }
+
+    private:
+        sp<Surface> mSurface;
+    };
+
+    return std::make_unique<NativeWindowSurface>(producer);
+}
+
+} // namespace impl
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/NativeWindowSurface.h b/services/surfaceflinger/NativeWindowSurface.h
new file mode 100644
index 0000000..f34a45a
--- /dev/null
+++ b/services/surfaceflinger/NativeWindowSurface.h
@@ -0,0 +1,50 @@
+/*
+ * 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>
+
+#include <utils/StrongPointer.h>
+
+struct ANativeWindow;
+
+namespace android {
+
+class IGraphicBufferProducer;
+
+namespace surfaceflinger {
+
+// A thin interface to abstract creating instances of Surface (gui/Surface.h) to
+// use as a NativeWindow.
+class NativeWindowSurface {
+public:
+    virtual ~NativeWindowSurface();
+
+    // Gets the NativeWindow to use for the surface.
+    virtual sp<ANativeWindow> getNativeWindow() const = 0;
+
+    // Indicates that the surface should allocate its buffers now.
+    virtual void preallocateBuffers() = 0;
+};
+
+namespace impl {
+
+std::unique_ptr<NativeWindowSurface> createNativeWindowSurface(const sp<IGraphicBufferProducer>&);
+
+} // namespace impl
+} // namespace surfaceflinger
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fa9cc79..9410cdb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -74,6 +74,7 @@
 #include "Layer.h"
 #include "LayerVector.h"
 #include "MonitoredProducer.h"
+#include "NativeWindowSurface.h"
 #include "SurfaceFlinger.h"
 
 #include "DisplayHardware/ComposerHal.h"
@@ -222,32 +223,6 @@
     }
 }
 
-NativeWindowSurface::~NativeWindowSurface() = default;
-
-namespace impl {
-
-class NativeWindowSurface final : public android::NativeWindowSurface {
-public:
-    static std::unique_ptr<android::NativeWindowSurface> create(
-            const sp<IGraphicBufferProducer>& producer) {
-        return std::make_unique<NativeWindowSurface>(producer);
-    }
-
-    explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer)
-          : surface(new Surface(producer, false)) {}
-
-    ~NativeWindowSurface() override = default;
-
-private:
-    sp<ANativeWindow> getNativeWindow() const override { return surface; }
-
-    void preallocateBuffers() override { surface->allocateBuffers(); }
-
-    sp<Surface> surface;
-};
-
-} // namespace impl
-
 SurfaceFlingerBE::SurfaceFlingerBE()
       : mHwcServiceName(getHwcServiceName()),
         mRenderEngine(nullptr),
@@ -259,12 +234,10 @@
 
 SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag)
       : BnSurfaceComposer(),
-        mTransactionFlags(0),
         mTransactionPending(false),
         mAnimTransactionPending(false),
         mLayersRemoved(false),
         mLayersAdded(false),
-        mRepaintEverything(0),
         mBootTime(systemTime()),
         mDisplayTokens(),
         mVisibleRegionsDirty(false),
@@ -286,7 +259,7 @@
         mVrFlingerRequestsDisplay(false),
         mMainThreadId(std::this_thread::get_id()),
         mCreateBufferQueue(&BufferQueue::createBufferQueue),
-        mCreateNativeWindowSurface(&impl::NativeWindowSurface::create) {}
+        mCreateNativeWindowSurface(&surfaceflinger::impl::createNativeWindowSurface) {}
 
 SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
     ALOGI("SurfaceFlinger is starting");
@@ -1468,7 +1441,7 @@
 
     resyncToHardwareVsync(false);
 
-    android_atomic_or(1, &mRepaintEverything);
+    mRepaintEverything = true;
     setTransactionFlags(eDisplayTransactionNeeded);
 }
 
@@ -1527,7 +1500,7 @@
 
     mRefreshPending = false;
 
-    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+    const bool repaintEverything = mRepaintEverything.exchange(false);
     preComposition();
     rebuildLayerStacks();
     calculateWorkingSet();
@@ -2454,31 +2427,34 @@
 sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
         const wp<IBinder>& displayToken, int32_t displayId, const DisplayDeviceState& state,
         const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
-    bool hasWideColorGamut = false;
-    std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;
-    HdrCapabilities hdrCapabilities;
-    int32_t supportedPerFrameMetadata = 0;
+    DisplayDeviceCreationArgs creationArgs(this, displayToken, state.type, displayId);
+    creationArgs.isSecure = state.isSecure;
+    creationArgs.displaySurface = dispSurface;
+    creationArgs.hasWideColorGamut = false;
+    creationArgs.supportedPerFrameMetadata = 0;
 
     if (useColorManagement && displayId >= 0) {
         std::vector<ColorMode> modes = getHwComposer().getColorModes(displayId);
         for (ColorMode colorMode : modes) {
             if (isWideColorMode(colorMode)) {
-                hasWideColorGamut = true;
+                creationArgs.hasWideColorGamut = true;
             }
 
             std::vector<RenderIntent> renderIntents =
                     getHwComposer().getRenderIntents(displayId, colorMode);
-            hwcColorModes.emplace(colorMode, renderIntents);
+            creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
         }
     }
 
     if (displayId >= 0) {
-        getHwComposer().getHdrCapabilities(displayId, &hdrCapabilities);
-        supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(displayId);
+        getHwComposer().getHdrCapabilities(displayId, &creationArgs.hdrCapabilities);
+        creationArgs.supportedPerFrameMetadata =
+                getHwComposer().getSupportedPerFrameMetadata(displayId);
     }
 
     auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
     auto nativeWindow = nativeWindowSurface->getNativeWindow();
+    creationArgs.nativeWindow = nativeWindow;
 
     /*
      * Create our display's surface
@@ -2487,8 +2463,9 @@
     renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);
     renderSurface->setAsync(state.isVirtual());
     renderSurface->setNativeWindow(nativeWindow.get());
-    const int displayWidth = renderSurface->getWidth();
-    const int displayHeight = renderSurface->getHeight();
+    creationArgs.displayWidth = renderSurface->getWidth();
+    creationArgs.displayHeight = renderSurface->getHeight();
+    creationArgs.renderSurface = std::move(renderSurface);
 
     // Make sure that composition can never be stalled by a virtual display
     // consumer that isn't processing buffers fast enough. We have to do this
@@ -2501,18 +2478,14 @@
         nativeWindow->setSwapInterval(nativeWindow.get(), 0);
     }
 
-    const int displayInstallOrientation = state.type == DisplayDevice::DISPLAY_PRIMARY ?
-        primaryDisplayOrientation : DisplayState::eOrientationDefault;
+    creationArgs.displayInstallOrientation = state.type == DisplayDevice::DISPLAY_PRIMARY
+            ? primaryDisplayOrientation
+            : DisplayState::eOrientationDefault;
 
     // virtual displays are always considered enabled
-    auto initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
+    creationArgs.initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
 
-    sp<DisplayDevice> display =
-            new DisplayDevice(this, state.type, displayId, state.isSecure, displayToken,
-                              nativeWindow, dispSurface, std::move(renderSurface), displayWidth,
-                              displayHeight, displayInstallOrientation, hasWideColorGamut,
-                              hdrCapabilities, supportedPerFrameMetadata, hwcColorModes,
-                              initialPowerMode);
+    sp<DisplayDevice> display = new DisplayDevice(std::move(creationArgs));
 
     if (maxFrameBufferAcquiredBuffers >= 3) {
         nativeWindowSurface->preallocateBuffers();
@@ -2520,7 +2493,7 @@
 
     ColorMode defaultColorMode = ColorMode::NATIVE;
     Dataspace defaultDataSpace = Dataspace::UNKNOWN;
-    if (hasWideColorGamut) {
+    if (display->hasWideColorGamut()) {
         defaultColorMode = ColorMode::SRGB;
         defaultDataSpace = Dataspace::SRGB;
     }
@@ -3355,11 +3328,11 @@
 }
 
 uint32_t SurfaceFlinger::peekTransactionFlags() {
-    return android_atomic_release_load(&mTransactionFlags);
+    return mTransactionFlags;
 }
 
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
@@ -3368,7 +3341,7 @@
 
 uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags,
         VSyncModulator::TransactionStart transactionStart) {
-    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
+    uint32_t old = mTransactionFlags.fetch_or(flags);
     mVsyncModulator.setTransactionStart(transactionStart);
     if ((old & flags)==0) { // wake the server up
         signalTransaction();
@@ -3875,7 +3848,8 @@
         break;
     }
 
-    sp<BufferQueueLayer> layer = new BufferQueueLayer(this, client, name, w, h, flags);
+    sp<BufferQueueLayer> layer =
+            new BufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags));
     status_t err = layer->setDefaultBufferProperties(w, h, format);
     if (err == NO_ERROR) {
         *handle = layer->getHandle();
@@ -3890,7 +3864,8 @@
 status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, const String8& name,
                                                 uint32_t w, uint32_t h, uint32_t flags,
                                                 sp<IBinder>* handle, sp<Layer>* outLayer) {
-    sp<BufferStateLayer> layer = new BufferStateLayer(this, client, name, w, h, flags);
+    sp<BufferStateLayer> layer =
+            new BufferStateLayer(LayerCreationArgs(this, client, name, w, h, flags));
     *handle = layer->getHandle();
     *outLayer = layer;
 
@@ -3901,7 +3876,7 @@
         const String8& name, uint32_t w, uint32_t h, uint32_t flags,
         sp<IBinder>* handle, sp<Layer>* outLayer)
 {
-    *outLayer = new ColorLayer(this, client, name, w, h, flags);
+    *outLayer = new ColorLayer(LayerCreationArgs(this, client, name, w, h, flags));
     *handle = (*outLayer)->getHandle();
     return NO_ERROR;
 }
@@ -3910,7 +3885,7 @@
         const String8& name, uint32_t w, uint32_t h, uint32_t flags,
         sp<IBinder>* handle, sp<Layer>* outLayer)
 {
-    *outLayer = new ContainerLayer(this, client, name, w, h, flags);
+    *outLayer = new ContainerLayer(LayerCreationArgs(this, client, name, w, h, flags));
     *handle = (*outLayer)->getHandle();
     return NO_ERROR;
 }
@@ -4620,10 +4595,12 @@
                         mGraphicBufferProducerList.size(), mMaxGraphicBufferProducerListSize);
     colorizer.reset(result);
 
-    LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
-    auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
-    result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
-    result.append("\n");
+    {
+        LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
+        auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
+        result.append(LayerProtoParser::layerTreeToString(layerTree).c_str());
+        result.append("\n");
+    }
 
     result.append("\nFrame-Composition information:\n");
     dumpFrameCompositionInfo(result);
@@ -4661,7 +4638,7 @@
     }
     result.appendFormat("  transaction-flags         : %08x\n"
                         "  gpu_to_cpu_unsupported    : %d\n",
-                        mTransactionFlags, !mGpuToCpuSupported);
+                        mTransactionFlags.load(), !mGpuToCpuSupported);
 
     if (display) {
         const auto activeConfig = getHwComposer().getActiveConfig(display->getId());
@@ -5178,7 +5155,7 @@
 }
 
 void SurfaceFlinger::repaintEverything() {
-    android_atomic_or(1, &mRepaintEverything);
+    mRepaintEverything = true;
     signalTransaction();
 }
 
@@ -5288,9 +5265,9 @@
                 drawLayers();
             } else {
                 Rect bounds = getBounds();
-                screenshotParentLayer =
-                        new ContainerLayer(mFlinger, nullptr, String8("Screenshot Parent"),
-                                           bounds.getWidth(), bounds.getHeight(), 0);
+                screenshotParentLayer = new ContainerLayer(
+                        LayerCreationArgs(mFlinger, nullptr, String8("Screenshot Parent"),
+                                          bounds.getWidth(), bounds.getHeight(), 0));
 
                 ReparentForDrawing reparent(mLayer, screenshotParentLayer);
                 drawLayers();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 01d18d9..b77bf48 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -117,6 +117,10 @@
 class VrFlinger;
 } // namespace dvr
 
+namespace surfaceflinger {
+class NativeWindowSurface;
+} // namespace surfaceflinger
+
 // ---------------------------------------------------------------------------
 
 enum {
@@ -133,18 +137,6 @@
     ENHANCED = 2,
 };
 
-// A thin interface to abstract creating instances of Surface (gui/Surface.h) to
-// use as a NativeWindow.
-class NativeWindowSurface {
-public:
-    virtual ~NativeWindowSurface();
-
-    // Gets the NativeWindow to use for the surface.
-    virtual sp<ANativeWindow> getNativeWindow() const = 0;
-
-    // Indicates that the surface should allocate its buffers now.
-    virtual void preallocateBuffers() = 0;
-};
 
 class SurfaceFlingerBE
 {
@@ -793,7 +785,7 @@
     // access must be protected by mStateLock
     mutable Mutex mStateLock;
     State mCurrentState{LayerVector::StateSet::Current};
-    volatile int32_t mTransactionFlags;
+    std::atomic<int32_t> mTransactionFlags{0};
     Condition mTransactionCV;
     bool mTransactionPending;
     bool mAnimTransactionPending;
@@ -812,8 +804,7 @@
     bool mLayersRemoved;
     bool mLayersAdded;
 
-    // access must be protected by mInvalidateLock
-    volatile int32_t mRepaintEverything;
+    std::atomic<bool> mRepaintEverything{false};
 
     // helper methods
     void configureHwcCommonData(const CompositionInfo& compositionInfo) const;
@@ -939,7 +930,8 @@
     CreateBufferQueueFunction mCreateBufferQueue;
 
     using CreateNativeWindowSurfaceFunction =
-            std::function<std::unique_ptr<NativeWindowSurface>(const sp<IGraphicBufferProducer>&)>;
+            std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
+                    const sp<IGraphicBufferProducer>&)>;
     CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
 
     SurfaceFlingerBE mBE;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.cpp b/services/surfaceflinger/SurfaceFlingerFactory.cpp
new file mode 100644
index 0000000..b37d6f0
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlingerFactory.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 "SurfaceFlingerFactory.h"
+#include "SurfaceFlinger.h"
+
+namespace android::surfaceflinger {
+
+sp<SurfaceFlinger> createSurfaceFlinger() {
+    return new SurfaceFlinger();
+}
+
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
new file mode 100644
index 0000000..65eb797
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <cutils/compiler.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class SurfaceFlinger;
+
+namespace surfaceflinger {
+
+ANDROID_API sp<SurfaceFlinger> createSurfaceFlinger();
+
+} // namespace surfaceflinger
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 0b4c6fc..57bda5a 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -96,8 +96,9 @@
         const sp<const Layer>& layer)
 {
     Transaction* transaction(increment->mutable_transaction());
-    transaction->set_synchronous(layer->mTransactionFlags & BnSurfaceComposer::eSynchronous);
-    transaction->set_animation(layer->mTransactionFlags & BnSurfaceComposer::eAnimation);
+    const uint32_t layerFlags = layer->getTransactionFlags();
+    transaction->set_synchronous(layerFlags & BnSurfaceComposer::eSynchronous);
+    transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
     addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 370b3b8..67dcd06 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -27,32 +27,36 @@
 namespace android {
 
 void SurfaceTracing::enable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (mEnabled) {
         return;
     }
-    ATRACE_CALL();
     mEnabled = true;
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
-    mTrace.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                            LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    mTrace = std::make_unique<LayersTraceFileProto>();
+    mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                             LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
 }
 
 status_t SurfaceTracing::disable() {
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
+
     if (!mEnabled) {
         return NO_ERROR;
     }
-    ATRACE_CALL();
-    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     mEnabled = false;
     status_t err(writeProtoFileLocked());
     ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
     ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
-    mTrace.Clear();
+    mTrace.reset();
     return err;
 }
 
 bool SurfaceTracing::isEnabled() const {
+    std::lock_guard<std::mutex> protoGuard(mTraceMutex);
     return mEnabled;
 }
 
@@ -61,29 +65,29 @@
     if (!mEnabled) {
         return;
     }
-    LayersTraceProto* entry = mTrace.add_entry();
+    LayersTraceProto* entry = mTrace->add_entry();
     entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry->set_where(where);
     entry->mutable_layers()->Swap(&layers);
 
     constexpr int maxBufferedEntryCount = 3600;
-    if (mTrace.entry_size() >= maxBufferedEntryCount) {
+    if (mTrace->entry_size() >= maxBufferedEntryCount) {
         // TODO: flush buffered entries without disabling tracing
         ALOGE("too many buffered frames; force disable tracing");
         mEnabled = false;
         writeProtoFileLocked();
-        mTrace.Clear();
+        mTrace.reset();
     }
 }
 
 status_t SurfaceTracing::writeProtoFileLocked() {
     ATRACE_CALL();
 
-    if (!mTrace.IsInitialized()) {
+    if (!mTrace->IsInitialized()) {
         return NOT_ENOUGH_DATA;
     }
     std::string output;
-    if (!mTrace.SerializeToString(&output)) {
+    if (!mTrace->SerializeToString(&output)) {
         return PERMISSION_DENIED;
     }
     if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
@@ -97,7 +101,7 @@
     std::lock_guard<std::mutex> protoGuard(mTraceMutex);
 
     result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
-    result.appendFormat("  number of entries: %d\n", mTrace.entry_size());
+    result.appendFormat("  number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 27e2c9e..fd8cb82 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -20,6 +20,7 @@
 #include <utils/Errors.h>
 #include <utils/String8.h>
 
+#include <memory>
 #include <mutex>
 
 using namespace android::surfaceflinger;
@@ -46,7 +47,7 @@
     bool mEnabled = false;
     std::string mOutputFileName = DEFAULT_FILENAME;
     mutable std::mutex mTraceMutex;
-    LayersTraceFileProto mTrace;
+    std::unique_ptr<LayersTraceFileProto> mTrace;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index bf12df6..1d7fb67 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -37,11 +37,6 @@
     return lhs->id < rhs->id;
 }
 
-bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs,
-                   const std::unique_ptr<LayerProtoParser::Layer>& rhs) {
-    return sortLayers(lhs.get(), rhs.get());
-}
-
 const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo(
         const LayersProto& layersProto) {
     LayerGlobal layerGlobal;
@@ -52,77 +47,80 @@
     return layerGlobal;
 }
 
-std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree(
-        const LayersProto& layersProto) {
-    std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto);
-    std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers;
+LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(const LayersProto& layersProto) {
+    LayerTree layerTree;
+    layerTree.allLayers = generateLayerList(layersProto);
 
-    for (std::pair<int32_t, Layer*> kv : layerMap) {
-        if (kv.second->parent == nullptr) {
-            // Make unique_ptr for top level layers since they are not children. This ensures there
-            // will only be one unique_ptr made for each layer.
-            layers.push_back(std::unique_ptr<Layer>(kv.second));
+    // find and sort the top-level layers
+    for (Layer& layer : layerTree.allLayers) {
+        if (layer.parent == nullptr) {
+            layerTree.topLevelLayers.push_back(&layer);
         }
     }
+    std::sort(layerTree.topLevelLayers.begin(), layerTree.topLevelLayers.end(), sortLayers);
 
-    std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs);
-    return layers;
+    return layerTree;
 }
 
-std::unordered_map<int32_t, LayerProtoParser::Layer*> LayerProtoParser::generateMap(
+std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList(
         const LayersProto& layersProto) {
+    std::vector<Layer> layerList;
     std::unordered_map<int32_t, Layer*> layerMap;
 
+    // build the layer list and the layer map
+    layerList.reserve(layersProto.layers_size());
+    layerMap.reserve(layersProto.layers_size());
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        layerMap[layerProto.id()] = generateLayer(layerProto);
+        layerList.emplace_back(generateLayer(layersProto.layers(i)));
+        // this works because layerList never changes capacity
+        layerMap[layerList.back().id] = &layerList.back();
     }
 
+    // fix up children and relatives
     for (int i = 0; i < layersProto.layers_size(); i++) {
-        const LayerProto& layerProto = layersProto.layers(i);
-        updateChildrenAndRelative(layerProto, layerMap);
+        updateChildrenAndRelative(layersProto.layers(i), layerMap);
     }
 
-    return layerMap;
+    return layerList;
 }
 
-LayerProtoParser::Layer* LayerProtoParser::generateLayer(const LayerProto& layerProto) {
-    Layer* layer = new Layer();
-    layer->id = layerProto.id();
-    layer->name = layerProto.name();
-    layer->type = layerProto.type();
-    layer->transparentRegion = generateRegion(layerProto.transparent_region());
-    layer->visibleRegion = generateRegion(layerProto.visible_region());
-    layer->damageRegion = generateRegion(layerProto.damage_region());
-    layer->layerStack = layerProto.layer_stack();
-    layer->z = layerProto.z();
-    layer->position = {layerProto.position().x(), layerProto.position().y()};
-    layer->requestedPosition = {layerProto.requested_position().x(),
+LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerProto) {
+    Layer layer;
+    layer.id = layerProto.id();
+    layer.name = layerProto.name();
+    layer.type = layerProto.type();
+    layer.transparentRegion = generateRegion(layerProto.transparent_region());
+    layer.visibleRegion = generateRegion(layerProto.visible_region());
+    layer.damageRegion = generateRegion(layerProto.damage_region());
+    layer.layerStack = layerProto.layer_stack();
+    layer.z = layerProto.z();
+    layer.position = {layerProto.position().x(), layerProto.position().y()};
+    layer.requestedPosition = {layerProto.requested_position().x(),
                                 layerProto.requested_position().y()};
-    layer->size = {layerProto.size().w(), layerProto.size().h()};
-    layer->crop = generateRect(layerProto.crop());
-    layer->isOpaque = layerProto.is_opaque();
-    layer->invalidate = layerProto.invalidate();
-    layer->dataspace = layerProto.dataspace();
-    layer->pixelFormat = layerProto.pixel_format();
-    layer->color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
+    layer.size = {layerProto.size().w(), layerProto.size().h()};
+    layer.crop = generateRect(layerProto.crop());
+    layer.isOpaque = layerProto.is_opaque();
+    layer.invalidate = layerProto.invalidate();
+    layer.dataspace = layerProto.dataspace();
+    layer.pixelFormat = layerProto.pixel_format();
+    layer.color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
                     layerProto.color().a()};
-    layer->requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
+    layer.requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
                              layerProto.requested_color().b(), layerProto.requested_color().a()};
-    layer->flags = layerProto.flags();
-    layer->transform = generateTransform(layerProto.transform());
-    layer->requestedTransform = generateTransform(layerProto.requested_transform());
-    layer->activeBuffer = generateActiveBuffer(layerProto.active_buffer());
-    layer->bufferTransform = generateTransform(layerProto.buffer_transform());
-    layer->queuedFrames = layerProto.queued_frames();
-    layer->refreshPending = layerProto.refresh_pending();
-    layer->hwcFrame = generateRect(layerProto.hwc_frame());
-    layer->hwcCrop = generateFloatRect(layerProto.hwc_crop());
-    layer->hwcTransform = layerProto.hwc_transform();
-    layer->windowType = layerProto.window_type();
-    layer->appId = layerProto.app_id();
-    layer->hwcCompositionType = layerProto.hwc_composition_type();
-    layer->isProtected = layerProto.is_protected();
+    layer.flags = layerProto.flags();
+    layer.transform = generateTransform(layerProto.transform());
+    layer.requestedTransform = generateTransform(layerProto.requested_transform());
+    layer.activeBuffer = generateActiveBuffer(layerProto.active_buffer());
+    layer.bufferTransform = generateTransform(layerProto.buffer_transform());
+    layer.queuedFrames = layerProto.queued_frames();
+    layer.refreshPending = layerProto.refresh_pending();
+    layer.hwcFrame = generateRect(layerProto.hwc_frame());
+    layer.hwcCrop = generateFloatRect(layerProto.hwc_crop());
+    layer.hwcTransform = layerProto.hwc_transform();
+    layer.windowType = layerProto.window_type();
+    layer.appId = layerProto.app_id();
+    layer.hwcCompositionType = layerProto.hwc_composition_type();
+    layer.isProtected = layerProto.is_protected();
 
     return layer;
 }
@@ -186,9 +184,7 @@
 
     for (int i = 0; i < layerProto.children_size(); i++) {
         if (layerMap.count(layerProto.children(i)) > 0) {
-            // Only make unique_ptrs for children since they are guaranteed to be unique, only one
-            // parent per child. This ensures there will only be one unique_ptr made for each layer.
-            currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)]));
+            currLayer->children.push_back(layerMap[layerProto.children(i)]);
         }
     }
 
@@ -211,29 +207,28 @@
     }
 }
 
-std::string LayerProtoParser::layersToString(
-        std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) {
+std::string LayerProtoParser::layerTreeToString(const LayerTree& layerTree) {
     std::string result;
-    for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) {
+    for (const LayerProtoParser::Layer* layer : layerTree.topLevelLayers) {
         if (layer->zOrderRelativeOf != nullptr) {
             continue;
         }
-        result.append(layerToString(layer.get()).c_str());
+        result.append(layerToString(layer));
     }
 
     return result;
 }
 
-std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) {
+std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
     std::string result;
 
     std::vector<Layer*> traverse(layer->relatives);
-    for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) {
+    for (LayerProtoParser::Layer* child : layer->children) {
         if (child->zOrderRelativeOf != nullptr) {
             continue;
         }
 
-        traverse.push_back(child.get());
+        traverse.push_back(child);
     }
 
     std::sort(traverse.begin(), traverse.end(), sortLayers);
@@ -244,13 +239,13 @@
         if (relative->z >= 0) {
             break;
         }
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
-    result.append(layer->to_string().c_str());
+    result.append(layer->to_string());
     result.append("\n");
     for (; i < traverse.size(); i++) {
         auto& relative = traverse[i];
-        result.append(layerToString(relative).c_str());
+        result.append(layerToString(relative));
     }
 
     return result;
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index b1610cf..6b3b497 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -80,7 +80,7 @@
     public:
         int32_t id;
         std::string name;
-        std::vector<std::unique_ptr<Layer>> children;
+        std::vector<Layer*> children;
         std::vector<Layer*> relatives;
         std::string type;
         LayerProtoParser::Region transparentRegion;
@@ -126,13 +126,22 @@
         int32_t globalTransform;
     };
 
+    class LayerTree {
+    public:
+        // all layers in LayersProto and in the original order
+        std::vector<Layer> allLayers;
+
+        // pointers to top-level layers in allLayers
+        std::vector<Layer*> topLevelLayers;
+    };
+
     static const LayerGlobal generateLayerGlobalInfo(const LayersProto& layersProto);
-    static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto);
-    static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers);
+    static LayerTree generateLayerTree(const LayersProto& layersProto);
+    static std::string layerTreeToString(const LayerTree& layerTree);
 
 private:
-    static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto);
-    static LayerProtoParser::Layer* generateLayer(const LayerProto& layerProto);
+    static std::vector<Layer> generateLayerList(const LayersProto& layersProto);
+    static LayerProtoParser::Layer generateLayer(const LayerProto& layerProto);
     static LayerProtoParser::Region generateRegion(const RegionProto& regionProto);
     static LayerProtoParser::Rect generateRect(const RectProto& rectProto);
     static LayerProtoParser::FloatRect generateFloatRect(const FloatRectProto& rectProto);
@@ -142,7 +151,7 @@
     static void updateChildrenAndRelative(const LayerProto& layerProto,
                                           std::unordered_map<int32_t, Layer*>& layerMap);
 
-    static std::string layerToString(LayerProtoParser::Layer* layer);
+    static std::string layerToString(const LayerProtoParser::Layer* layer);
 };
 
 } // namespace surfaceflinger
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index b1ff522..9c2edca 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -21,16 +21,16 @@
 #include <android/frameworks/displayservice/1.0/IDisplayService.h>
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <cutils/sched_policy.h>
-#include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <configstore/Utils.h>
+#include <cutils/sched_policy.h>
 #include <displayservice/DisplayService.h>
 #include <hidl/LegacySupport.h>
-#include <configstore/Utils.h>
 #include "GpuService.h"
 #include "SurfaceFlinger.h"
+#include "SurfaceFlingerFactory.h"
 
 using namespace android;
 
@@ -85,7 +85,7 @@
     ps->startThreadPool();
 
     // instantiate surfaceflinger
-    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
+    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
 
     setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
 
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 4577153..3e1be8e 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -101,10 +101,7 @@
     for (int i = 0; i < 100000; i++) {
         surfaceflinger::LayersProto layersProto = generateLayerProto();
         auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
-        // Allow some layerTrees to just fall out of scope (instead of std::move)
-        if (i % 2) {
-            surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree));
-        }
+        surfaceflinger::LayerProtoParser::layerTreeToString(layerTree);
     }
     system(cmd.c_str());
 }
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index d52f0d8..52e64d8 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -774,9 +774,10 @@
 
     static FlingerLayerType createLayer(CompositionTest* test) {
         FlingerLayerType layer = Base::template createLayerWithFactory<ColorLayer>(test, [test]() {
-            return new ColorLayer(test->mFlinger.mFlinger.get(), sp<Client>(),
-                                  String8("test-layer"), LayerProperties::WIDTH,
-                                  LayerProperties::HEIGHT, LayerProperties::LAYER_FLAGS);
+            return new ColorLayer(LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(),
+                                                    String8("test-layer"), LayerProperties::WIDTH,
+                                                    LayerProperties::HEIGHT,
+                                                    LayerProperties::LAYER_FLAGS));
         });
         return layer;
     }
@@ -811,10 +812,11 @@
 
         FlingerLayerType layer =
                 Base::template createLayerWithFactory<BufferQueueLayer>(test, [test]() {
-                    return new BufferQueueLayer(test->mFlinger.mFlinger.get(), sp<Client>(),
-                                                String8("test-layer"), LayerProperties::WIDTH,
-                                                LayerProperties::HEIGHT,
-                                                LayerProperties::LAYER_FLAGS);
+                    return new BufferQueueLayer(
+                            LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(),
+                                              String8("test-layer"), LayerProperties::WIDTH,
+                                              LayerProperties::HEIGHT,
+                                              LayerProperties::LAYER_FLAGS));
                 });
 
         LayerProperties::setupLayerState(test, layer);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index cc46043..b474e42 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -125,7 +125,7 @@
     // These mocks are created only when expected to be created via a factory.
     sp<mock::GraphicBufferConsumer> mConsumer;
     sp<mock::GraphicBufferProducer> mProducer;
-    mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
+    surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
     sp<mock::NativeWindow> mNativeWindow;
     renderengine::mock::Surface* mRenderSurface = nullptr;
 };
@@ -195,11 +195,12 @@
     // This setup is only expected once per test.
     ASSERT_TRUE(mNativeWindowSurface == nullptr);
 
-    mNativeWindowSurface = new mock::NativeWindowSurface();
+    mNativeWindowSurface = new surfaceflinger::mock::NativeWindowSurface();
     mNativeWindow = new mock::NativeWindow();
 
-    mFlinger.setCreateNativeWindowSurface(
-            [this](auto) { return std::unique_ptr<NativeWindowSurface>(mNativeWindowSurface); });
+    mFlinger.setCreateNativeWindowSurface([this](auto) {
+        return std::unique_ptr<surfaceflinger::NativeWindowSurface>(mNativeWindowSurface);
+    });
 }
 
 bool DisplayTransactionTest::hasHwcDisplay(hwc2_display_t displayId) {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index f367275..2046439 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -192,7 +192,7 @@
     public:
         FakePowerAdvisor() = default;
         ~FakePowerAdvisor() override = default;
-        void setExpensiveRenderingExpected(hwc2_display_t, bool) override { }
+        void setExpensiveRenderingExpected(hwc2_display_t, bool) override {}
     };
 
     struct HWC2Display : public HWC2::Display {
@@ -315,7 +315,8 @@
     public:
         FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, DisplayDevice::DisplayType type,
                                   int32_t displayId)
-              : mFlinger(flinger), mType(type), mDisplayId(displayId) {}
+              : mFlinger(flinger),
+                mCreationArgs(flinger.mFlinger.get(), mDisplayToken, type, displayId) {}
 
         sp<IBinder> token() const { return mDisplayToken; }
 
@@ -338,54 +339,49 @@
         auto& mutableDisplayDevice() { return mFlinger.mutableDisplays()[mDisplayToken]; }
 
         auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
-            mNativeWindow = nativeWindow;
+            mCreationArgs.nativeWindow = nativeWindow;
             return *this;
         }
 
         auto& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
-            mDisplaySurface = displaySurface;
+            mCreationArgs.displaySurface = displaySurface;
             return *this;
         }
 
         auto& setRenderSurface(std::unique_ptr<renderengine::Surface> renderSurface) {
-            mRenderSurface = std::move(renderSurface);
+            mCreationArgs.renderSurface = std::move(renderSurface);
             return *this;
         }
 
         auto& setSecure(bool secure) {
-            mSecure = secure;
+            mCreationArgs.isSecure = secure;
             return *this;
         }
 
         auto& setDisplaySize(int width, int height) {
-            mWidth = width;
-            mHeight = height;
+            mCreationArgs.displayWidth = width;
+            mCreationArgs.displayHeight = height;
             return *this;
         }
 
         auto& setPowerMode(int mode) {
-            mPowerMode = mode;
+            mCreationArgs.initialPowerMode = mode;
             return *this;
         }
 
         sp<DisplayDevice> inject() {
-            std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents;
-            sp<DisplayDevice> device =
-                    new DisplayDevice(mFlinger.mFlinger.get(), mType, mDisplayId, mSecure,
-                                      mDisplayToken, mNativeWindow, mDisplaySurface,
-                                      std::move(mRenderSurface), mWidth, mHeight,
-                                      DisplayState::eOrientationDefault, false, HdrCapabilities(),
-                                      0, hdrAndRenderIntents, mPowerMode);
-            mFlinger.mutableDisplays().emplace(mDisplayToken, device);
-
             DisplayDeviceState state;
-            state.type = mType;
-            state.isSecure = mSecure;
+            state.type = mCreationArgs.type;
+            state.isSecure = mCreationArgs.isSecure;
+
+            sp<DisplayDevice> device = new DisplayDevice(std::move(mCreationArgs));
+            mFlinger.mutableDisplays().emplace(mDisplayToken, device);
             mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
             mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
 
-            if (mType >= DisplayDevice::DISPLAY_PRIMARY && mType < DisplayDevice::DISPLAY_VIRTUAL) {
-                mFlinger.mutableDisplayTokens()[mType] = mDisplayToken;
+            if (state.type >= DisplayDevice::DISPLAY_PRIMARY &&
+                state.type < DisplayDevice::DISPLAY_VIRTUAL) {
+                mFlinger.mutableDisplayTokens()[state.type] = mDisplayToken;
             }
 
             return device;
@@ -394,15 +390,7 @@
     private:
         TestableSurfaceFlinger& mFlinger;
         sp<BBinder> mDisplayToken = new BBinder();
-        DisplayDevice::DisplayType mType;
-        const int32_t mDisplayId;
-        sp<ANativeWindow> mNativeWindow;
-        sp<DisplaySurface> mDisplaySurface;
-        std::unique_ptr<renderengine::Surface> mRenderSurface;
-        bool mSecure = false;
-        int mWidth = 0;
-        int mHeight = 0;
-        int mPowerMode = HWC_POWER_MODE_NORMAL;
+        DisplayDeviceCreationArgs mCreationArgs;
     };
 
     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);
diff --git a/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
index 25ff39b..9cc6d38 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
@@ -1,6 +1,6 @@
 /*
- * 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.
  * You may obtain a copy of the License at
@@ -16,12 +16,10 @@
 
 #include "mock/MockNativeWindowSurface.h"
 
-namespace android {
-namespace mock {
+namespace android::surfaceflinger::mock {
 
 // Explicit default instantiation is recommended.
 NativeWindowSurface::NativeWindowSurface() = default;
 NativeWindowSurface::~NativeWindowSurface() = default;
 
-} // namespace mock
-} // namespace android
+} // namespace android::surfaceflinger::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h
index 88d1a9f..7bc1151 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h
@@ -20,19 +20,17 @@
 
 #include <system/window.h> // for ANativeWindow
 
-#include "SurfaceFlinger.h" // for base NativeWindowSurface
+#include "NativeWindowSurface.h"
 
-namespace android {
-namespace mock {
+namespace android::surfaceflinger::mock {
 
-class NativeWindowSurface : public android::NativeWindowSurface {
+class NativeWindowSurface : public surfaceflinger::NativeWindowSurface {
 public:
     NativeWindowSurface();
-    ~NativeWindowSurface();
+    ~NativeWindowSurface() override;
 
     MOCK_CONST_METHOD0(getNativeWindow, sp<ANativeWindow>());
     MOCK_METHOD0(preallocateBuffers, void());
 };
 
-} // namespace mock
-} // namespace android
+} // namespace android::surfaceflinger::mock
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
index 499a8f6..04b9511 100644
--- a/services/vr/bufferhubd/Android.bp
+++ b/services/vr/bufferhubd/Android.bp
@@ -12,46 +12,65 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-sourceFiles = [
-    "buffer_channel.cpp",
-    "buffer_hub.cpp",
-    "buffer_node.cpp",
-    "bufferhubd.cpp",
-    "consumer_channel.cpp",
-    "producer_channel.cpp",
-    "consumer_queue_channel.cpp",
-    "producer_queue_channel.cpp",
-]
-
-headerLibraries = ["libdvr_headers"]
-
-staticLibraries = [
-    "libperformance",
-    "libbufferhub",
-]
-
 sharedLibraries = [
     "libbase",
     "libbinder",
     "libcutils",
-    "liblog",
-    "libsync",
-    "libutils",
     "libgui",
-    "libui",
+    "liblog",
     "libpdx_default_transport",
+    "libsync",
+    "libui",
+    "libutils",
 ]
 
+cc_library_static {
+    name: "libbufferhubd",
+    srcs: [
+        "binder/android/dvr/IBufferHub.aidl",
+        "buffer_channel.cpp",
+        "buffer_hub.cpp",
+        "buffer_hub_binder.cpp",
+        "buffer_node.cpp",
+        "consumer_channel.cpp",
+        "consumer_queue_channel.cpp",
+        "producer_channel.cpp",
+        "producer_queue_channel.cpp",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"libbufferhubd\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    export_include_dirs: ["include"],
+    header_libs: ["libdvr_headers"],
+    shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+    ],
+    aidl: {
+        local_include_dirs: ["binder"],
+        include_dirs: ["frameworks/native/aidl/binder"],
+        export_aidl_headers: true,
+    },
+}
+
 cc_binary {
-    srcs: sourceFiles,
+    srcs: ["bufferhubd.cpp"],
     cflags: [
         "-DLOG_TAG=\"bufferhubd\"",
         "-DTRACE=0",
         "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
     ],
-    header_libs: headerLibraries,
-    static_libs: staticLibraries,
+    header_libs: ["libdvr_headers"],
     shared_libs: sharedLibraries,
+    static_libs: [
+        "libbufferhub",
+        "libbufferhubd",
+        "libperformance",
+    ],
     name: "bufferhubd",
     init_rc: ["bufferhubd.rc"],
 }
+
+subdirs = ["tests"]
\ No newline at end of file
diff --git a/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
new file mode 100644
index 0000000..6a86adc
--- /dev/null
+++ b/services/vr/bufferhubd/binder/android/dvr/IBufferHub.aidl
@@ -0,0 +1,5 @@
+package android.dvr;
+
+/** {@hide} */
+interface IBufferHub {
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_channel.cpp b/services/vr/bufferhubd/buffer_channel.cpp
index 2150d62..6d22dee 100644
--- a/services/vr/bufferhubd/buffer_channel.cpp
+++ b/services/vr/bufferhubd/buffer_channel.cpp
@@ -1,5 +1,5 @@
-#include "buffer_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index c0ee31b..15391da 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -1,9 +1,5 @@
-#include "buffer_hub.h"
-
 #include <inttypes.h>
-#include <log/log.h>
 #include <poll.h>
-#include <utils/Trace.h>
 
 #include <iomanip>
 #include <memory>
@@ -11,12 +7,15 @@
 #include <string>
 #include <thread>
 
+#include <log/log.h>
 #include <pdx/default_transport/service_endpoint.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
-#include "producer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::Channel;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/buffer_hub_binder.cpp b/services/vr/bufferhubd/buffer_hub_binder.cpp
new file mode 100644
index 0000000..def15f1
--- /dev/null
+++ b/services/vr/bufferhubd/buffer_hub_binder.cpp
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+#include <log/log.h>
+#include <private/dvr/buffer_hub_binder.h>
+
+namespace android {
+namespace dvr {
+
+status_t BufferHubBinderService::start() {
+  ProcessState::self()->startThreadPool();
+  IPCThreadState::self()->disableBackgroundScheduling(true);
+  status_t result = BinderService<BufferHubBinderService>::publish();
+  if (result != OK) {
+    ALOGE("Publishing bufferhubd failed with error %d", result);
+    return result;
+  }
+
+  return result;
+}
+
+status_t BufferHubBinderService::dump(int fd, const Vector<String16> & /* args */) {
+  // TODO(b/115435506): not implemented yet
+  FILE *out = fdopen(dup(fd), "w");
+
+  fprintf(out, "BufferHubBinderService::dump(): Not Implemented.\n");
+
+  fclose(out);
+  return NO_ERROR;
+}
+
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.cpp b/services/vr/bufferhubd/buffer_node.cpp
index de22bba..5a04d0c 100644
--- a/services/vr/bufferhubd/buffer_node.cpp
+++ b/services/vr/bufferhubd/buffer_node.cpp
@@ -1,6 +1,5 @@
-#include "buffer_node.h"
-
 #include <private/dvr/buffer_hub_defs.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/bufferhubd.cpp b/services/vr/bufferhubd/bufferhubd.cpp
index b27f218..0ca7edc 100644
--- a/services/vr/bufferhubd/bufferhubd.cpp
+++ b/services/vr/bufferhubd/bufferhubd.cpp
@@ -1,13 +1,12 @@
 #include <sched.h>
+#include <sys/resource.h>
 #include <unistd.h>
 
-#include <log/log.h>
-#include <sys/resource.h>
-
 #include <dvr/performance_client_api.h>
+#include <log/log.h>
 #include <pdx/service_dispatcher.h>
-
-#include "buffer_hub.h"
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_hub_binder.h>
 
 int main(int, char**) {
   int ret = -1;
@@ -34,11 +33,14 @@
   else
     ALOGI("New nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
 
+  CHECK_ERROR(android::dvr::BufferHubBinderService::start() != android::OK,
+              error, "Failed to create bufferhub binder service\n");
+
   dispatcher = android::pdx::ServiceDispatcher::Create();
   CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher\n");
 
   service = android::dvr::BufferHubService::Create();
-  CHECK_ERROR(!service, error, "Failed to create buffer hub service\n");
+  CHECK_ERROR(!service, error, "Failed to create bufferhubd service\n");
   dispatcher->AddService(service);
 
   ret = dvrSetSchedulerClass(0, "graphics");
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index a6d2dbb..623c9d6 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -1,12 +1,10 @@
-#include "consumer_channel.h"
-
-#include <log/log.h>
-#include <utils/Trace.h>
-
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "producer_channel.h"
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::Channel;
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index 4d43001..74b549d 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -1,8 +1,6 @@
-#include "consumer_queue_channel.h"
-
 #include <pdx/channel_handle.h>
-
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::RemoteChannelHandle;
diff --git a/services/vr/bufferhubd/buffer_channel.h b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
similarity index 96%
rename from services/vr/bufferhubd/buffer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_channel.h
index ac99a73..bcc93a1 100644
--- a/services/vr/bufferhubd/buffer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
@@ -1,11 +1,10 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_BUFFER_CHANNEL_H_
 
-#include "buffer_hub.h"
-#include "buffer_node.h"
-
 #include <pdx/channel_handle.h>
 #include <pdx/file_handle.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_hub.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_hub.h
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
new file mode 100644
index 0000000..c0281fd
--- /dev/null
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
@@ -0,0 +1,23 @@
+#ifndef ANDROID_DVR_BUFFER_HUB_BINDER_H
+#define ANDROID_DVR_BUFFER_HUB_BINDER_H
+
+#include <binder/BinderService.h>
+
+#include "android/dvr/BnBufferHub.h"
+
+namespace android {
+namespace dvr {
+
+class BufferHubBinderService : public BinderService<BufferHubBinderService>, public BnBufferHub {
+ public:
+  static status_t start();
+  static const char* getServiceName() { return "bufferhubd"; }
+  // Dump bufferhub related information to given fd (usually stdout)
+  // usage: adb shell dumpsys bufferhubd
+  virtual status_t dump(int fd, const Vector<String16> &args) override;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif // ANDROID_DVR_BUFFER_HUB_BINDER_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/buffer_node.h b/services/vr/bufferhubd/include/private/dvr/buffer_node.h
similarity index 100%
rename from services/vr/bufferhubd/buffer_node.h
rename to services/vr/bufferhubd/include/private/dvr/buffer_node.h
diff --git a/services/vr/bufferhubd/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
similarity index 97%
rename from services/vr/bufferhubd/consumer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_channel.h
index 55cf969..0d70409 100644
--- a/services/vr/bufferhubd/consumer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/consumer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
similarity index 93%
rename from services/vr/bufferhubd/consumer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
index 8437c4c..d98dbbc 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
@@ -1,14 +1,12 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
-#include <private/dvr/bufferhub_rpc.h>
-
 #include <queue>
 
-#include "consumer_channel.h"
-#include "producer_queue_channel.h"
+#include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_channel.h
index 10a4ce7..242198f 100644
--- a/services/vr/bufferhubd/producer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
@@ -1,8 +1,6 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <functional>
 #include <memory>
 #include <vector>
@@ -11,6 +9,7 @@
 #include <pdx/file_handle.h>
 #include <pdx/rpc/buffer_wrapper.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 #include <private/dvr/ion_buffer.h>
 
 namespace android {
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
similarity index 98%
rename from services/vr/bufferhubd/producer_queue_channel.h
rename to services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
index e4fa243..c4003da 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
@@ -1,10 +1,9 @@
 #ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 #define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
 
-#include "buffer_hub.h"
-
 #include <pdx/status.h>
 #include <private/dvr/bufferhub_rpc.h>
+#include <private/dvr/buffer_hub.h>
 
 namespace android {
 namespace dvr {
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 19d48f2..057d4f4 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -1,19 +1,18 @@
-#include "producer_channel.h"
-
-#include <log/log.h>
-#include <sync/sync.h>
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #include <sys/poll.h>
-#include <utils/Trace.h>
 
 #include <algorithm>
 #include <atomic>
 #include <thread>
 
+#include <log/log.h>
 #include <private/dvr/bufferhub_rpc.h>
-#include "buffer_channel.h"
-#include "consumer_channel.h"
+#include <private/dvr/buffer_channel.h>
+#include <private/dvr/consumer_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
 
 using android::pdx::BorrowedHandle;
 using android::pdx::ErrorStatus;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 88f5508..6b5027c 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -1,9 +1,8 @@
-#include "producer_queue_channel.h"
-
 #include <inttypes.h>
 
-#include "consumer_queue_channel.h"
-#include "producer_channel.h"
+#include <private/dvr/consumer_queue_channel.h>
+#include <private/dvr/producer_channel.h>
+#include <private/dvr/producer_queue_channel.h>
 
 using android::pdx::ErrorStatus;
 using android::pdx::Message;
diff --git a/services/vr/bufferhubd/tests/Android.bp b/services/vr/bufferhubd/tests/Android.bp
new file mode 100644
index 0000000..4d1d43f
--- /dev/null
+++ b/services/vr/bufferhubd/tests/Android.bp
@@ -0,0 +1,16 @@
+cc_test {
+    name: "buffer_hub_binder_service-test",
+    srcs: ["buffer_hub_binder_service-test.cpp"],
+    cflags: [
+        "-DLOG_TAG=\"buffer_hub_binder_service-test\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+    ],
+    static_libs: ["libbufferhubd"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+}
\ No newline at end of file
diff --git a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
new file mode 100644
index 0000000..e3f2825
--- /dev/null
+++ b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
@@ -0,0 +1,22 @@
+#include <private/dvr/buffer_hub_binder.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class BufferHubBinderServiceTest : public ::testing::Test {
+  // Add setup and teardown if necessary
+};
+
+TEST_F(BufferHubBinderServiceTest, TestInitialize) {
+  // Test if start binder server returns OK
+  EXPECT_EQ(BufferHubBinderService::start(), OK);
+}
+
+}  // namespace
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 4c2d223..a607a5d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1165,27 +1165,28 @@
         result = EnumeratePhysicalDevices(instance, &device_count, nullptr);
         if (result < 0)
             return result;
+
         if (!pPhysicalDeviceGroupProperties) {
             *pPhysicalDeviceGroupCount = device_count;
             return result;
         }
 
-        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
         if (!device_count) {
             *pPhysicalDeviceGroupCount = 0;
             return result;
         }
+        device_count = std::min(device_count, *pPhysicalDeviceGroupCount);
+        if (!device_count)
+            return VK_INCOMPLETE;
 
         android::Vector<VkPhysicalDevice> devices;
         devices.resize(device_count);
-
+        *pPhysicalDeviceGroupCount = device_count;
         result = EnumeratePhysicalDevices(instance, &device_count,
                                           devices.editArray());
         if (result < 0)
             return result;
 
-        devices.resize(device_count);
-        *pPhysicalDeviceGroupCount = device_count;
         for (uint32_t i = 0; i < device_count; ++i) {
             pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
             pPhysicalDeviceGroupProperties[i].physicalDevices[0] = devices[i];
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 915de45..8601373 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -569,6 +569,7 @@
     switch (native_format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_RGBA_FP16:
             format_supported = true;
             break;
         default:
@@ -695,6 +696,10 @@
          VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
         {VK_FORMAT_R8G8B8A8_SRGB,
          VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
+        {VK_FORMAT_R16G16B16A16_SFLOAT,
+         VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT},
+        {VK_FORMAT_R16G16B16A16_SFLOAT,
+         VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT},
     };
     const uint32_t kNumWideColorFormats =
         sizeof(kWideColorFormats) / sizeof(kWideColorFormats[0]);