Merge "Support GraphicBuffer::flatten and GraphicBuffer::unflatten with BufferHub"
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index 37ff442..347856d 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -61,7 +61,6 @@
     // Default mode.
     const int BUGREPORT_MODE_DEFAULT = 6;
 
-    // TODO(b/111441001): Should the args be for the consuming application rather than triggering?
     /*
      * Starts a bugreport in the background.
      *
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 738c20f..1fbd2b3 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1583,6 +1583,9 @@
 
     RunDumpsys("DUMPSYS", {"connectivity"}, CommandOptions::WithTimeout(90).Build(),
                SEC_TO_MSEC(10));
+    RunDumpsys("DUMPSYS", {"connmetrics"}, CommandOptions::WithTimeout(90).Build(),
+               SEC_TO_MSEC(10));
+    RunDumpsys("DUMPSYS", {"netd"}, CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
     RunDumpsys("DUMPSYS", {"carrier_config"}, CommandOptions::WithTimeout(90).Build(),
                SEC_TO_MSEC(10));
     RunDumpsys("DUMPSYS", {"wifi"}, CommandOptions::WithTimeout(90).Build(),
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index b60bbc0..d66066e 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -146,9 +146,11 @@
     ],
     shared_libs: [
         "libbase",
+        "libbinder",
         "liblog",
         "libprotobuf-cpp-full",
         "libselinux",
+        "libutils",
         "libziparchive",
     ],
     static_libs: [
@@ -157,6 +159,7 @@
         "lib_apex_manifest_proto",
         "libavb",
         "libdm",
+        "libvold_binder",
     ],
 }
 
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 2efcf11..92fac66 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1648,7 +1648,8 @@
 
     ATRACE_BEGIN("obb");
     for (const auto& packageName : packageNames) {
-        auto obbCodePath = create_data_media_obb_path(uuid_, packageName.c_str());
+        auto obbCodePath = create_data_media_package_path(uuid_, userId,
+                "obb", packageName.c_str());
         calculate_tree_size(obbCodePath, &extStats.codeSize);
     }
     ATRACE_END();
@@ -1982,7 +1983,8 @@
         ATRACE_END();
 
         ATRACE_BEGIN("obb");
-        auto obbPath = create_data_media_obb_path(uuid_, "");
+        auto obbPath = StringPrintf("%s/Android/obb",
+                create_data_media_path(uuid_, userId).c_str());
         calculate_tree_size(obbPath, &obbSize);
         ATRACE_END();
     }
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 72571cf..20142aa 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -58,6 +58,7 @@
 using android::base::EndsWith;
 using android::base::GetBoolProperty;
 using android::base::GetProperty;
+using android::base::ReadFdToString;
 using android::base::ReadFully;
 using android::base::StringPrintf;
 using android::base::WriteFully;
@@ -319,6 +320,7 @@
                bool background_job_compile,
                int profile_fd,
                const char* class_loader_context,
+               const std::string& class_loader_context_fds,
                int target_sdk_version,
                bool enable_hidden_api_checks,
                bool generate_compact_dex,
@@ -423,9 +425,14 @@
             target_sdk_version_arg = StringPrintf("-Xtarget-sdk-version:%d", target_sdk_version);
         }
         std::string class_loader_context_arg;
+        std::string class_loader_context_fds_arg;
         if (class_loader_context != nullptr) {
             class_loader_context_arg = StringPrintf("--class-loader-context=%s",
                                                     class_loader_context);
+            if (!class_loader_context_fds.empty()) {
+                class_loader_context_fds_arg = StringPrintf("--class-loader-context-fds=%s",
+                                                            class_loader_context_fds.c_str());
+            }
         }
 
         if (swap_fd >= 0) {
@@ -518,6 +525,7 @@
         AddArg(profile_arg);
         AddArg(base_dir);
         AddArg(class_loader_context_arg);
+        AddArg(class_loader_context_fds_arg);
         if (generate_minidebug_info) {
             AddArg(kMinidebugDex2oatFlag);
         }
@@ -1514,14 +1522,15 @@
 class RunDexoptAnalyzer : public ExecVHelper {
  public:
     RunDexoptAnalyzer(const std::string& dex_file,
-                    int vdex_fd,
-                    int oat_fd,
-                    int zip_fd,
-                    const std::string& instruction_set,
-                    const std::string& compiler_filter,
-                    bool profile_was_updated,
-                    bool downgrade,
-                    const char* class_loader_context) {
+                      int vdex_fd,
+                      int oat_fd,
+                      int zip_fd,
+                      const std::string& instruction_set,
+                      const std::string& compiler_filter,
+                      bool profile_was_updated,
+                      bool downgrade,
+                      const char* class_loader_context,
+                      const std::string& class_loader_context_fds) {
         CHECK_GE(zip_fd, 0);
 
         // We always run the analyzer in the background job.
@@ -1540,6 +1549,10 @@
         if (class_loader_context != nullptr) {
             class_loader_context_arg += class_loader_context;
         }
+        std::string class_loader_context_fds_arg = "--class-loader-context-fds=";
+        if (!class_loader_context_fds.empty()) {
+            class_loader_context_fds_arg += class_loader_context_fds;
+        }
 
         // program name, dex file, isa, filter
         AddArg(dex_file_arg);
@@ -1560,10 +1573,27 @@
         }
         if (class_loader_context != nullptr) {
             AddArg(class_loader_context_arg.c_str());
+            if (!class_loader_context_fds.empty()) {
+                AddArg(class_loader_context_fds_arg.c_str());
+            }
         }
 
         PrepareArgs(dexoptanalyzer_bin);
     }
+
+    // Dexoptanalyzer mode which flattens the given class loader context and
+    // prints a list of its dex files in that flattened order.
+    RunDexoptAnalyzer(const char* class_loader_context) {
+        CHECK(class_loader_context != nullptr);
+
+        // We always run the analyzer in the background job.
+        const char* dexoptanalyzer_bin = select_execution_binary(
+             kDexoptanalyzerPath, kDexoptanalyzerDebugPath, /*background_job_compile=*/ true);
+
+        AddArg("--flatten-class-loader-context");
+        AddArg(std::string("--class-loader-context=") + class_loader_context);
+        PrepareArgs(dexoptanalyzer_bin);
+    }
 };
 
 // Prepares the oat dir for the secondary dex files.
@@ -1743,6 +1773,95 @@
     return true;
 }
 
+static bool get_class_loader_context_dex_paths(const char* class_loader_context, int uid,
+        /* out */ std::vector<std::string>* context_dex_paths) {
+    if (class_loader_context == nullptr) {
+      return true;
+    }
+
+    LOG(DEBUG) << "Getting dex paths for context " << class_loader_context;
+
+    // Pipe to get the hash result back from our child process.
+    unique_fd pipe_read, pipe_write;
+    if (!Pipe(&pipe_read, &pipe_write)) {
+        PLOG(ERROR) << "Failed to create pipe";
+        return false;
+    }
+
+    pid_t pid = fork();
+    if (pid == 0) {
+        // child -- drop privileges before continuing.
+        drop_capabilities(uid);
+
+        // Route stdout to `pipe_write`
+        while ((dup2(pipe_write, STDOUT_FILENO) == -1) && (errno == EINTR)) {}
+        pipe_write.reset();
+        pipe_read.reset();
+
+        RunDexoptAnalyzer run_dexopt_analyzer(class_loader_context);
+        run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec);
+    }
+
+    /* parent */
+    pipe_write.reset();
+
+    std::string str_dex_paths;
+    if (!ReadFdToString(pipe_read, &str_dex_paths)) {
+        PLOG(ERROR) << "Failed to read from pipe";
+        return false;
+    }
+    pipe_read.reset();
+
+    int return_code = wait_child(pid);
+    if (!WIFEXITED(return_code)) {
+        PLOG(ERROR) << "Error waiting for child dexoptanalyzer process";
+        return false;
+    }
+
+    constexpr int kFlattenClassLoaderContextSuccess = 50;
+    return_code = WEXITSTATUS(return_code);
+    if (return_code != kFlattenClassLoaderContextSuccess) {
+        LOG(ERROR) << "Dexoptanalyzer could not flatten class loader context, code=" << return_code;
+        return false;
+    }
+
+    if (!str_dex_paths.empty()) {
+        *context_dex_paths = android::base::Split(str_dex_paths, ":");
+    }
+    return true;
+}
+
+static int open_dex_paths(const std::vector<std::string>& dex_paths,
+        /* out */ std::vector<unique_fd>* zip_fds, /* out */ std::string* error_msg) {
+    for (const std::string& dex_path : dex_paths) {
+        zip_fds->emplace_back(open(dex_path.c_str(), O_RDONLY));
+        if (zip_fds->back().get() < 0) {
+            *error_msg = StringPrintf(
+                    "installd cannot open '%s' for input during dexopt", dex_path.c_str());
+            if (errno == ENOENT) {
+                return kSecondaryDexDexoptAnalyzerSkippedNoFile;
+            } else {
+                return kSecondaryDexDexoptAnalyzerSkippedOpenZip;
+            }
+        }
+    }
+    return 0;
+}
+
+static std::string join_fds(const std::vector<unique_fd>& fds) {
+    std::stringstream ss;
+    bool is_first = true;
+    for (const unique_fd& fd : fds) {
+        if (is_first) {
+            is_first = false;
+        } else {
+            ss << ":";
+        }
+        ss << fd.get();
+    }
+    return ss.str();
+}
+
 // Processes the dex_path as a secondary dex files and return true if the path dex file should
 // be compiled. Returns false for errors (logged) or true if the secondary dex path was process
 // successfully.
@@ -1754,7 +1873,7 @@
         int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
         const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out,
         std::string* oat_dir_out, bool downgrade, const char* class_loader_context,
-        /* out */ std::string* error_msg) {
+        const std::vector<std::string>& context_dex_paths, /* out */ std::string* error_msg) {
     LOG(DEBUG) << "Processing secondary dex path " << dex_path;
     int storage_flag;
     if (!validate_dexopt_storage_flags(dexopt_flags, &storage_flag, error_msg)) {
@@ -1794,6 +1913,13 @@
             }
         }
 
+        // Open class loader context dex files.
+        std::vector<unique_fd> context_zip_fds;
+        int open_dex_paths_rc = open_dex_paths(context_dex_paths, &context_zip_fds, error_msg);
+        if (open_dex_paths_rc != 0) {
+            _exit(open_dex_paths_rc);
+        }
+
         // Prepare the oat directories.
         if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set)) {
             _exit(kSecondaryDexDexoptAnalyzerSkippedPrepareDir);
@@ -1825,7 +1951,8 @@
                                               instruction_set,
                                               compiler_filter, profile_was_updated,
                                               downgrade,
-                                              class_loader_context);
+                                              class_loader_context,
+                                              join_fds(context_zip_fds));
         run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec);
     }
 
@@ -1913,10 +2040,16 @@
 
     // Check if we're dealing with a secondary dex file and if we need to compile it.
     std::string oat_dir_str;
+    std::vector<std::string> context_dex_paths;
     if (is_secondary_dex) {
+        if (!get_class_loader_context_dex_paths(class_loader_context, uid, &context_dex_paths)) {
+            *error_msg = "Failed acquiring context dex paths";
+            return -1;  // We had an error, logged in the process method.
+        }
+
         if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
                 instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str,
-                downgrade, class_loader_context, error_msg)) {
+                downgrade, class_loader_context, context_dex_paths, error_msg)) {
             oat_dir = oat_dir_str.c_str();
             if (dexopt_needed == NO_DEXOPT_NEEDED) {
                 return 0;  // Nothing to do, report success.
@@ -1928,7 +2061,7 @@
             return -1;  // We had an error, logged in the process method.
         }
     } else {
-        // Currently these flags are only use for secondary dex files.
+        // Currently these flags are only used for secondary dex files.
         // Verify that they are not set for primary apks.
         CHECK((dexopt_flags & DEXOPT_STORAGE_CE) == 0);
         CHECK((dexopt_flags & DEXOPT_STORAGE_DE) == 0);
@@ -1942,6 +2075,13 @@
         return -1;
     }
 
+    // Open class loader context dex files.
+    std::vector<unique_fd> context_input_fds;
+    if (open_dex_paths(context_dex_paths, &context_input_fds, error_msg) != 0) {
+        LOG(ERROR) << *error_msg;
+        return -1;
+    }
+
     // Create the output OAT file.
     char out_oat_path[PKG_PATH_MAX];
     Dex2oatFileWrapper out_oat_fd = open_oat_out_file(dex_path, oat_dir, is_public, uid,
@@ -2010,6 +2150,7 @@
                       background_job_compile,
                       reference_profile_fd.get(),
                       class_loader_context,
+                      join_fds(context_input_fds),
                       target_sdk_version,
                       enable_hidden_api_checks,
                       generate_compact_dex,
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 0fdc9d6..2e2cc18 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -25,6 +25,7 @@
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
+#include <libdm/dm.h>
 #include <selinux/android.h>
 
 #include <apexd.h>
@@ -77,6 +78,37 @@
     }
 }
 
+static void TryExtraMount(const char* name, const char* slot, const char* target) {
+    std::string partition_name = StringPrintf("%s%s", name, slot);
+
+    // See whether update_engine mounted a logical partition.
+    {
+        auto& dm = dm::DeviceMapper::Instance();
+        if (dm.GetState(partition_name) != dm::DmDeviceState::INVALID) {
+            std::string path;
+            if (dm.GetDmDevicePathByName(partition_name, &path)) {
+                int mount_result = mount(path.c_str(),
+                                         target,
+                                         "ext4",
+                                         MS_RDONLY,
+                                         /* data */ nullptr);
+                if (mount_result == 0) {
+                    return;
+                }
+            }
+        }
+    }
+
+    // Fall back and attempt a direct mount.
+    std::string block_device = StringPrintf("/dev/block/by-name/%s", partition_name.c_str());
+    int mount_result = mount(block_device.c_str(),
+                             target,
+                             "ext4",
+                             MS_RDONLY,
+                             /* data */ nullptr);
+    UNUSED(mount_result);
+}
+
 // Entry for otapreopt_chroot. Expected parameters are:
 //   [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
 // The file descriptor denoted by status-fd will be closed. The rest of the parameters will
@@ -137,29 +169,11 @@
         LOG(ERROR) << "Target slot suffix not legal: " << arg[2];
         exit(207);
     }
-    {
-      std::string vendor_partition = StringPrintf("/dev/block/by-name/vendor%s",
-                                                  arg[2]);
-      int vendor_result = mount(vendor_partition.c_str(),
-                                "/postinstall/vendor",
-                                "ext4",
-                                MS_RDONLY,
-                                /* data */ nullptr);
-      UNUSED(vendor_result);
-    }
+    TryExtraMount("vendor", arg[2], "/postinstall/vendor");
 
     // Try to mount the product partition. update_engine doesn't do this for us, but we
     // want it for product APKs. Same notes as vendor above.
-    {
-      std::string product_partition = StringPrintf("/dev/block/by-name/product%s",
-                                                   arg[2]);
-      int product_result = mount(product_partition.c_str(),
-                                 "/postinstall/product",
-                                 "ext4",
-                                 MS_RDONLY,
-                                 /* data */ nullptr);
-      UNUSED(product_result);
-    }
+    TryExtraMount("product", arg[2], "/postinstall/product");
 
     // Setup APEX mount point and its security context.
     static constexpr const char* kPostinstallApexDir = "/postinstall/apex";
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 71b710b..36d5a60 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -327,16 +327,21 @@
 
     void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
             bool should_binder_call_succeed, bool should_dex_be_compiled = true,
-            /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1) {
+            /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1,
+            const char* class_loader_context = nullptr) {
         if (uid == -1) {
             uid = kTestAppUid;
         }
+        if (class_loader_context == nullptr) {
+            class_loader_context = "&";
+        }
         std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
         int32_t dexopt_needed = 0;  // does not matter;
         std::unique_ptr<std::string> out_path = nullptr;  // does not matter
         int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
         std::string compiler_filter = "speed-profile";
-        std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
+        std::unique_ptr<std::string> class_loader_context_ptr(
+                new std::string(class_loader_context));
         std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
         bool downgrade = false;
         int32_t target_sdk_version = 0;  // default
@@ -555,12 +560,26 @@
         /*binder_ok*/ true, /*compile_ok*/ true);
 }
 
+TEST_F(DexoptTest, DexoptSecondaryCeWithContext) {
+    LOG(INFO) << "DexoptSecondaryCeWithContext";
+    std::string class_loader_context = "PCL[" + secondary_dex_ce_ + "]";
+    CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
+        /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
+}
+
 TEST_F(DexoptTest, DexoptSecondaryDe) {
     LOG(INFO) << "DexoptSecondaryDe";
     CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
         /*binder_ok*/ true, /*compile_ok*/ true);
 }
 
+TEST_F(DexoptTest, DexoptSecondaryDeWithContext) {
+    LOG(INFO) << "DexoptSecondaryDeWithContext";
+    std::string class_loader_context = "PCL[" + secondary_dex_de_ + "]";
+    CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
+        /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
+}
+
 TEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
     LOG(INFO) << "DexoptSecondaryDoesNotExist";
     // If the file validates but does not exist we do not treat it as an error.
@@ -576,7 +595,7 @@
     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
         /*binder_ok*/ false,  /*compile_ok*/ false, &status);
     EXPECT_STREQ(status.toString8().c_str(),
-                 "Status(-8): '-1: Dexoptanalyzer path validation failed'");
+                 "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
 }
 
 TEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
@@ -585,7 +604,7 @@
     CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
         /*binder_ok*/ false,  /*compile_ok*/ false, &status);
     EXPECT_STREQ(status.toString8().c_str(),
-                 "Status(-8): '-1: Dexoptanalyzer path validation failed'");
+                 "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
 }
 
 TEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
@@ -593,7 +612,8 @@
     binder::Status status;
     CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
         /*binder_ok*/ false,  /*compile_ok*/ false, &status, kSystemUid);
-    EXPECT_STREQ(status.toString8().c_str(), "Status(-8): '-1: Dexoptanalyzer open zip failed'");
+    EXPECT_STREQ(status.toString8().c_str(),
+                 "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer open zip failed'");
 }
 
 TEST_F(DexoptTest, DexoptPrimaryPublic) {
@@ -615,7 +635,7 @@
                           DEX2OAT_FROM_SCRATCH,
                           &status);
     EXPECT_STREQ(status.toString8().c_str(),
-                 "Status(-8): \'256: Dex2oat invocation for "
+                 "Status(-8, EX_SERVICE_SPECIFIC): \'256: Dex2oat invocation for "
                  "/data/app/com.installd.test.dexopt/base.jar failed: unspecified dex2oat error'");
 }
 
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index da097db..4eb1df0 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -244,10 +244,6 @@
     return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
 }
 
-std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name) {
-    return StringPrintf("%s/media/obb/%s", create_data_path(volume_uuid).c_str(), package_name);
-}
-
 std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
         const char* data_type, const char* package_name) {
     return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(),
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index 955d524..6a42026 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -75,7 +75,6 @@
         userid_t user, int32_t snapshot_id, const char* package_name);
 
 std::string create_data_media_path(const char* volume_uuid, userid_t userid);
-std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name);
 std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
         const char* data_type, const char* package_name);
 
diff --git a/cmds/servicemanager/binder.h b/cmds/servicemanager/binder.h
index 70be3b4..a9ccc74 100644
--- a/cmds/servicemanager/binder.h
+++ b/cmds/servicemanager/binder.h
@@ -4,10 +4,9 @@
 #ifndef _BINDER_H_
 #define _BINDER_H_
 
+#include <linux/android/binder.h>
 #include <sys/ioctl.h>
 
-#include "binder_kernel.h"
-
 struct binder_state;
 
 struct binder_io
diff --git a/cmds/servicemanager/binder_kernel.h b/cmds/servicemanager/binder_kernel.h
deleted file mode 100644
index 19fd773..0000000
--- a/cmds/servicemanager/binder_kernel.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BINDER_KERNEL_H
-#define ANDROID_BINDER_KERNEL_H
-
-#include <linux/android/binder.h>
-
-/**
- * This file exists because the uapi kernel headers in bionic are built
- * from upstream kernel headers only, and not all of the hwbinder kernel changes
- * have made it upstream yet. Therefore, the modifications to the
- * binder header are added locally in this file.
- */
-
-enum {
-        FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
-};
-
-#define BINDER_SET_CONTEXT_MGR_EXT      _IOW('b', 13, struct flat_binder_object)
-
-struct binder_transaction_data_secctx {
-        struct binder_transaction_data transaction_data;
-        binder_uintptr_t secctx;
-};
-
-enum {
-        BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
-                              struct binder_transaction_data_secctx),
-};
-
-
-#endif // ANDROID_BINDER_KERNEL_H
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
index 5c1cab6..ad7791e 100644
--- a/data/etc/car_core_hardware.xml
+++ b/data/etc/car_core_hardware.xml
@@ -46,12 +46,6 @@
     <feature name="android.software.cant_save_state" />
     <feature name="android.software.secure_lock_screen" />
 
-    <!-- Feature to specify if the device supports adding device admins. -->
-    <feature name="android.software.device_admin" />
-
-    <!-- Feature to specify if the device support managed users. -->
-    <feature name="android.software.managed_users" />
-
     <!-- devices with GPS must include android.hardware.location.gps.xml -->
     <!-- devices with an autofocus camera and/or flash must include either
          android.hardware.camera.autofocus.xml or
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index cd12fcd..4365a3c 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -22,7 +22,6 @@
 
 #include <binder/IInterface.h>
 
-#include <utils/Vector.h>
 #include <input/InputWindow.h>
 #include <input/ISetInputWindowsListener.h>
 
@@ -36,7 +35,7 @@
 public:
     DECLARE_META_INTERFACE(InputFlinger)
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles,
+    virtual void setInputWindows(const std::vector<InputWindowInfo>& inputHandles,
             const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0;
     virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
     virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 48ac88d..b6efc82 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -19,6 +19,7 @@
 
 #include <input/Input.h>
 #include <input/KeyCharacterMap.h>
+#include <vector>
 
 namespace android {
 
@@ -121,7 +122,7 @@
     inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; }
     inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; }
 
-    inline const Vector<MotionRange>& getMotionRanges() const {
+    inline const std::vector<MotionRange>& getMotionRanges() const {
         return mMotionRanges;
     }
 
@@ -139,7 +140,7 @@
     bool mHasVibrator;
     bool mHasButtonUnderPad;
 
-    Vector<MotionRange> mMotionRanges;
+    std::vector<MotionRange> mMotionRanges;
 };
 
 /* Types of input device configuration files. */
diff --git a/include/input/KeyLayoutMap.h b/include/input/KeyLayoutMap.h
index 73815fe..26f3501 100644
--- a/include/input/KeyLayoutMap.h
+++ b/include/input/KeyLayoutMap.h
@@ -66,7 +66,7 @@
 
     status_t mapKey(int32_t scanCode, int32_t usageCode,
             int32_t* outKeyCode, uint32_t* outFlags) const;
-    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+    status_t findScanCodesForKey(int32_t keyCode, std::vector<int32_t>* outScanCodes) const;
     status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const;
     status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const;
 
diff --git a/include/input/VirtualKeyMap.h b/include/input/VirtualKeyMap.h
index 4f7cfb6..6e8e2c9 100644
--- a/include/input/VirtualKeyMap.h
+++ b/include/input/VirtualKeyMap.h
@@ -24,6 +24,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/Tokenizer.h>
 #include <utils/Unicode.h>
+#include <vector>
 
 namespace android {
 
@@ -51,7 +52,7 @@
 
     static std::unique_ptr<VirtualKeyMap> load(const std::string& filename);
 
-    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
+    inline const std::vector<VirtualKeyDefinition>& getVirtualKeys() const {
         return mVirtualKeys;
     }
 
@@ -70,7 +71,7 @@
         bool parseNextIntField(int32_t* outValue);
     };
 
-    Vector<VirtualKeyDefinition> mVirtualKeys;
+    std::vector<VirtualKeyDefinition> mVirtualKeys;
 
     VirtualKeyMap();
 };
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index a3f8755..8b33a56 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -63,6 +63,26 @@
     return ret;
 }
 
+std::string Status::exceptionToString(int32_t exceptionCode) {
+    switch (exceptionCode) {
+        #define EXCEPTION_TO_CASE(EXCEPTION) case EXCEPTION: return #EXCEPTION;
+        EXCEPTION_TO_CASE(EX_NONE)
+        EXCEPTION_TO_CASE(EX_SECURITY)
+        EXCEPTION_TO_CASE(EX_BAD_PARCELABLE)
+        EXCEPTION_TO_CASE(EX_ILLEGAL_ARGUMENT)
+        EXCEPTION_TO_CASE(EX_NULL_POINTER)
+        EXCEPTION_TO_CASE(EX_ILLEGAL_STATE)
+        EXCEPTION_TO_CASE(EX_NETWORK_MAIN_THREAD)
+        EXCEPTION_TO_CASE(EX_UNSUPPORTED_OPERATION)
+        EXCEPTION_TO_CASE(EX_SERVICE_SPECIFIC)
+        EXCEPTION_TO_CASE(EX_PARCELABLE)
+        EXCEPTION_TO_CASE(EX_HAS_REPLY_HEADER)
+        EXCEPTION_TO_CASE(EX_TRANSACTION_FAILED)
+        #undef EXCEPTION_TO_CASE
+        default: return std::to_string(exceptionCode);
+    }
+}
+
 Status::Status(int32_t exceptionCode, int32_t errorCode)
     : mException(exceptionCode),
       mErrorCode(errorCode) {}
@@ -184,7 +204,7 @@
     if (mException == EX_NONE) {
         ret.append("No error");
     } else {
-        ret.appendFormat("Status(%d): '", mException);
+        ret.appendFormat("Status(%d, %s): '", mException, exceptionToString(mException).c_str());
         if (mException == EX_SERVICE_SPECIFIC ||
             mException == EX_TRANSACTION_FAILED) {
             ret.appendFormat("%d: ", mErrorCode);
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 1674516..aa44285 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -143,6 +143,9 @@
      * dies.  The @a cookie is optional.  If non-NULL, you can
      * supply a NULL @a recipient, and the recipient previously
      * added with that cookie will be unlinked.
+     *
+     * If the binder is dead, this will return DEAD_OBJECT. Deleting
+     * the object will also unlink all death recipients.
      */
     // NOLINTNEXTLINE(google-default-arguments)
     virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index afdfe4f..e5219a5 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -20,6 +20,8 @@
 #include <string>
 #include <vector>
 
+#include <linux/android/binder.h>
+
 #include <android-base/unique_fd.h>
 #include <cutils/native_handle.h>
 #include <utils/Errors.h>
@@ -28,7 +30,6 @@
 #include <utils/Vector.h>
 #include <utils/Flattenable.h>
 
-#include <binder/binder_kernel.h>
 #include <binder/IInterface.h>
 #include <binder/Parcelable.h>
 #include <binder/Map.h>
diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h
index c3738f8..7d889b6 100644
--- a/libs/binder/include/binder/Status.h
+++ b/libs/binder/include/binder/Status.h
@@ -22,6 +22,7 @@
 
 #include <binder/Parcel.h>
 #include <utils/String8.h>
+#include <string>
 
 namespace android {
 namespace binder {
@@ -97,6 +98,8 @@
 
     static Status fromStatusT(status_t status);
 
+    static std::string exceptionToString(status_t exceptionCode);
+
     Status() = default;
     ~Status() = default;
 
diff --git a/libs/binder/include/binder/binder_kernel.h b/libs/binder/include/binder/binder_kernel.h
deleted file mode 100644
index c7f6b4b..0000000
--- a/libs/binder/include/binder/binder_kernel.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BINDER_KERNEL_H
-#define ANDROID_BINDER_KERNEL_H
-
-#include <linux/android/binder.h>
-
-/**
- * This file exists because the uapi kernel headers in bionic are built
- * from upstream kernel headers only, and not all of the hwbinder kernel changes
- * have made it upstream yet. Therefore, the modifications to the
- * binder header are added locally in this file.
- */
-
-enum {
-        FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
-};
-
-#define BINDER_SET_CONTEXT_MGR_EXT      _IOW('b', 13, struct flat_binder_object)
-
-struct binder_transaction_data_secctx {
-        struct binder_transaction_data transaction_data;
-        binder_uintptr_t secctx;
-};
-
-enum {
-        BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
-                              struct binder_transaction_data_secctx),
-};
-
-#endif // ANDROID_BINDER_KERNEL_H
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index bdbc0d3..bd6886d 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -269,6 +269,18 @@
     CHECK(who == mWho);
 
     mOnDied(mCookie);
+
+    sp<AIBinder_DeathRecipient> recipient = mParentRecipient.promote();
+    sp<IBinder> strongWho = who.promote();
+
+    // otherwise this will be cleaned up later with pruneDeadTransferEntriesLocked
+    if (recipient != nullptr && strongWho != nullptr) {
+        status_t result = recipient->unlinkToDeath(strongWho, mCookie);
+        if (result != ::android::DEAD_OBJECT) {
+            LOG(WARNING) << "Unlinking to dead binder resulted in: " << result;
+        }
+    }
+
     mWho = nullptr;
 }
 
@@ -277,24 +289,34 @@
     CHECK(onDied != nullptr);
 }
 
-binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* cookie) {
+void AIBinder_DeathRecipient::pruneDeadTransferEntriesLocked() {
+    mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
+                                          [](const sp<TransferDeathRecipient>& tdr) {
+                                              return tdr->getWho() == nullptr;
+                                          }),
+                           mDeathRecipients.end());
+}
+
+binder_status_t AIBinder_DeathRecipient::linkToDeath(sp<IBinder> binder, void* cookie) {
     CHECK(binder != nullptr);
 
     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
 
     sp<TransferDeathRecipient> recipient =
-            new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied);
+            new TransferDeathRecipient(binder, cookie, this, mOnDied);
 
-    status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/);
+    status_t status = binder->linkToDeath(recipient, cookie, 0 /*flags*/);
     if (status != STATUS_OK) {
         return PruneStatusT(status);
     }
 
     mDeathRecipients.push_back(recipient);
+
+    pruneDeadTransferEntriesLocked();
     return STATUS_OK;
 }
 
-binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) {
+binder_status_t AIBinder_DeathRecipient::unlinkToDeath(sp<IBinder> binder, void* cookie) {
     CHECK(binder != nullptr);
 
     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
@@ -302,10 +324,10 @@
     for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) {
         sp<TransferDeathRecipient> recipient = *it;
 
-        if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) {
+        if (recipient->getCookie() == cookie && recipient->getWho() == binder) {
             mDeathRecipients.erase(it.base() - 1);
 
-            status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/);
+            status_t status = binder->unlinkToDeath(recipient, cookie, 0 /*flags*/);
             if (status != ::android::OK) {
                 LOG(ERROR) << __func__
                            << ": removed reference to death recipient but unlink failed.";
@@ -390,7 +412,7 @@
     }
 
     // returns binder_status_t
-    return recipient->linkToDeath(binder, cookie);
+    return recipient->linkToDeath(binder->getBinder(), cookie);
 }
 
 binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
@@ -401,7 +423,7 @@
     }
 
     // returns binder_status_t
-    return recipient->unlinkToDeath(binder, cookie);
+    return recipient->unlinkToDeath(binder->getBinder(), cookie);
 }
 
 uid_t AIBinder_getCallingUid() {
@@ -555,9 +577,15 @@
         LOG(ERROR) << __func__ << ": requires non-null onBinderDied parameter.";
         return nullptr;
     }
-    return new AIBinder_DeathRecipient(onBinderDied);
+    auto ret = new AIBinder_DeathRecipient(onBinderDied);
+    ret->incStrong(nullptr);
+    return ret;
 }
 
 void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) {
-    delete recipient;
+    if (recipient == nullptr) {
+        return;
+    }
+
+    recipient->decStrong(nullptr);
 }
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index 202d6d2..5cb68c2 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -128,13 +128,14 @@
 //
 // When the AIBinder_DeathRecipient is dropped, so are the actual underlying death recipients. When
 // the IBinder dies, only a wp to it is kept.
-struct AIBinder_DeathRecipient {
+struct AIBinder_DeathRecipient : ::android::RefBase {
     // One of these is created for every linkToDeath. This is to be able to recover data when a
     // binderDied receipt only gives us information about the IBinder.
     struct TransferDeathRecipient : ::android::IBinder::DeathRecipient {
         TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie,
+                               const ::android::wp<AIBinder_DeathRecipient>& parentRecipient,
                                const AIBinder_DeathRecipient_onBinderDied onDied)
-            : mWho(who), mCookie(cookie), mOnDied(onDied) {}
+            : mWho(who), mCookie(cookie), mParentRecipient(parentRecipient), mOnDied(onDied) {}
 
         void binderDied(const ::android::wp<::android::IBinder>& who) override;
 
@@ -144,14 +145,24 @@
        private:
         ::android::wp<::android::IBinder> mWho;
         void* mCookie;
+
+        ::android::wp<AIBinder_DeathRecipient> mParentRecipient;
+
+        // This is kept separately from AIBinder_DeathRecipient in case the death recipient is
+        // deleted while the death notification is fired
         const AIBinder_DeathRecipient_onBinderDied mOnDied;
     };
 
     explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
-    binder_status_t linkToDeath(AIBinder* binder, void* cookie);
-    binder_status_t unlinkToDeath(AIBinder* binder, void* cookie);
+    binder_status_t linkToDeath(::android::sp<::android::IBinder>, void* cookie);
+    binder_status_t unlinkToDeath(::android::sp<::android::IBinder> binder, void* cookie);
 
    private:
+    // When the user of this API deletes a Bp object but not the death recipient, the
+    // TransferDeathRecipient object can't be cleaned up. This is called whenever a new
+    // TransferDeathRecipient is linked, and it ensures that mDeathRecipients can't grow unbounded.
+    void pruneDeadTransferEntriesLocked();
+
     std::mutex mDeathRecipientsMutex;
     std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients;
     AIBinder_DeathRecipient_onBinderDied mOnDied;
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index bddc10d..80d1254 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -301,6 +301,11 @@
  * may return a binder transaction failure and in case the death recipient cannot be found, it
  * returns STATUS_NAME_NOT_FOUND.
  *
+ * This only ever needs to be called when the AIBinder_DeathRecipient remains for use with other
+ * AIBinder objects. If the death recipient is deleted, all binders will automatically be unlinked.
+ * If the binder dies, it will automatically unlink. If the binder is deleted, it will be
+ * automatically unlinked.
+ *
  * \param binder the binder object to remove a previously linked death recipient from.
  * \param recipient the callback to remove.
  * \param cookie the cookie used to link to death.
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
index bff601e..8467734 100644
--- a/libs/binder/ndk/test/main_client.cpp
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -86,12 +86,15 @@
     // the binder driver should return this if the service dies during the transaction
     EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
 
+    foo = nullptr;
+    AIBinder_decStrong(binder);
+    binder = nullptr;
+
     std::unique_lock<std::mutex> lock(deathMutex);
     EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
     EXPECT_TRUE(deathRecieved);
 
     AIBinder_DeathRecipient_delete(recipient);
-    AIBinder_decStrong(binder);
 }
 
 TEST(NdkBinder, RetrieveNonNdkService) {
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 8b663bc..4c2e653 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -31,44 +31,7 @@
         "-Werror",
     ],
     cppflags: [
-        "-Weverything",
-
-        // The static constructors and destructors in this library have not been noted to
-        // introduce significant overheads
-        "-Wno-exit-time-destructors",
-        "-Wno-global-constructors",
-
-        // We only care about compiling as C++14
-        "-Wno-c++98-compat-pedantic",
-
-        // We don't need to enumerate every case in a switch as long as a default case
-        // is present
-        "-Wno-switch-enum",
-
-        // Allow calling variadic macros without a __VA_ARGS__ list
-        "-Wno-gnu-zero-variadic-macro-arguments",
-
-        // Don't warn about struct padding
-        "-Wno-padded",
-
-        // We are aware of the risks inherent in comparing floats for equality
-        "-Wno-float-equal",
-
-        // Pure abstract classes trigger this warning
-        "-Wno-weak-vtables",
-
-        // Allow four-character integer literals
-        "-Wno-four-char-constants",
-
-        // Allow documentation warnings
-        "-Wno-documentation",
-
-        // Allow implicit instantiation for templated class function
-        "-Wno-undefined-func-template",
-
-        // Allow explicitly marking struct as packed even when unnecessary
-        "-Wno-packed",
-
+        "-Wextra",
         "-DDEBUG_ONLY_CODE=0",
     ],
 
@@ -121,30 +84,38 @@
         "view/Surface.cpp",
         "bufferqueue/1.0/B2HProducerListener.cpp",
         "bufferqueue/1.0/H2BGraphicBufferProducer.cpp",
+        "bufferqueue/1.0/H2BProducerListener.cpp",
+        "bufferqueue/2.0/B2HGraphicBufferProducer.cpp",
+        "bufferqueue/2.0/B2HProducerListener.cpp",
+        "bufferqueue/2.0/H2BGraphicBufferProducer.cpp",
+        "bufferqueue/2.0/H2BProducerListener.cpp",
+        "bufferqueue/2.0/types.cpp",
     ],
 
     shared_libs: [
         "android.frameworks.bufferhub@1.0",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
+        "android.hidl.token@1.0-utils",
         "libbase",
-        "libsync",
         "libbinder",
-        "libhwbinder",
         "libbufferhub",
         "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
-        "libpdx_default_transport",
         "libcutils",
         "libEGL",
         "libGLESv2",
-        "libui",
-        "libutils",
-        "libnativewindow",
-        "liblog",
-        "libinput",
         "libhidlbase",
         "libhidltransport",
-        "android.hidl.token@1.0-utils",
-        "android.hardware.graphics.bufferqueue@1.0",
+        "libhwbinder",
+        "libinput",
+        "liblog",
+        "libnativewindow",
+        "libpdx_default_transport",
+        "libsync",
+        "libui",
+        "libutils",
         "libvndksupport",
     ],
 
@@ -163,16 +134,16 @@
                 "android.frameworks.bufferhub@1.0",
                 "libbufferhub",
                 "libbufferhubqueue",
-                "libpdx_default_transport",
                 "libinput",
+                "libpdx_default_transport",
             ],
         },
     },
 
     header_libs: [
         "libdvr_headers",
-        "libnativebase_headers",
         "libgui_headers",
+        "libnativebase_headers",
         "libpdx_headers",
     ],
 
@@ -181,9 +152,11 @@
         "libEGL",
         "libnativewindow",
         "libui",
-        "android.hidl.token@1.0-utils",
         "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.1",
+        "android.hardware.graphics.common@1.2",
+        "android.hidl.token@1.0-utils",
     ],
 
     export_header_lib_headers: [
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 8907de4..9dde15d 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -30,16 +30,21 @@
 #ifndef NO_BUFFERHUB
 #include <gui/BufferHubProducer.h>
 #endif
+
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
 #include <gui/BufferQueueDefs.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/IProducerListener.h>
 
-#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-
 namespace android {
 // ----------------------------------------------------------------------------
 
-using ::android::hardware::graphics::bufferqueue::V1_0::utils::
+using H2BGraphicBufferProducerV1_0 =
+        ::android::hardware::graphics::bufferqueue::V1_0::utils::
+        H2BGraphicBufferProducer;
+using H2BGraphicBufferProducerV2_0 =
+        ::android::hardware::graphics::bufferqueue::V2_0::utils::
         H2BGraphicBufferProducer;
 
 enum {
@@ -534,7 +539,9 @@
 BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
 
 class HpGraphicBufferProducer : public HpInterface<
-        BpGraphicBufferProducer, H2BGraphicBufferProducer> {
+        BpGraphicBufferProducer,
+        H2BGraphicBufferProducerV1_0,
+        H2BGraphicBufferProducerV2_0> {
 public:
     explicit HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {}
 
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 62abfa8..936063a 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -15,7 +15,8 @@
  */
 
 #include <binder/Parcel.h>
-
+#include <gui/bufferqueue/1.0/H2BProducerListener.h>
+#include <gui/bufferqueue/2.0/H2BProducerListener.h>
 #include <gui/IProducerListener.h>
 
 namespace android {
@@ -61,7 +62,24 @@
 // translation unit (see clang warning -Wweak-vtables)
 BpProducerListener::~BpProducerListener() {}
 
-IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener")
+class HpProducerListener : public HpInterface<
+        BpProducerListener,
+        hardware::graphics::bufferqueue::V1_0::utils::H2BProducerListener,
+        hardware::graphics::bufferqueue::V2_0::utils::H2BProducerListener> {
+public:
+    explicit HpProducerListener(const sp<IBinder>& base) : PBase{base} {}
+
+    virtual void onBufferReleased() override {
+        mBase->onBufferReleased();
+    }
+
+    virtual bool needsReleaseNotify() override {
+        return mBase->needsReleaseNotify();
+    }
+};
+
+IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener,
+        "android.gui.IProducerListener")
 
 status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
         Parcel* reply, uint32_t flags) {
diff --git a/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp
new file mode 100644
index 0000000..2712f42
--- /dev/null
+++ b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "H2BProducerListener@1.0"
+
+#include <android-base/logging.h>
+
+#include <gui/bufferqueue/1.0/H2BProducerListener.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+
+H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base)
+      : CBase{base} {
+}
+
+void H2BProducerListener::onBufferReleased() {
+    if (!mBase->onBufferReleased().isOk()) {
+        LOG(ERROR) << "onBufferReleased: transaction failed.";
+    }
+}
+
+bool H2BProducerListener::needsReleaseNotify() {
+    Return<bool> transResult = mBase->needsReleaseNotify();
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "needsReleaseNotify: transaction failed.";
+        return false;
+    }
+    return static_cast<bool>(transResult);
+}
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
new file mode 100644
index 0000000..e039593
--- /dev/null
+++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "H2BGraphicBufferProducer@2.0"
+
+#include <android-base/logging.h>
+
+#include <android/hardware/graphics/bufferqueue/2.0/types.h>
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <gui/bufferqueue/2.0/H2BProducerListener.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <vndk/hardware_buffer.h>
+
+namespace android {
+
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// B2HGraphicBufferProducer
+// ========================
+
+B2HGraphicBufferProducer::B2HGraphicBufferProducer(
+        sp<BGraphicBufferProducer> const& base)
+      : mBase{base} {
+}
+
+Return<HStatus> B2HGraphicBufferProducer::setMaxDequeuedBufferCount(
+        int32_t maxDequeuedBuffers) {
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->setMaxDequeuedBufferCount(
+                static_cast<int>(maxDequeuedBuffers)),
+            &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<void> B2HGraphicBufferProducer::requestBuffer(
+        int32_t slot,
+        requestBuffer_cb _hidl_cb) {
+    sp<GraphicBuffer> bBuffer;
+    HStatus hStatus{};
+    HardwareBuffer hBuffer{};
+    uint32_t hGenerationNumber{};
+    bool converted =
+            b2h(mBase->requestBuffer(
+                    static_cast<int>(slot), &bBuffer),
+                &hStatus) &&
+            b2h(bBuffer, &hBuffer, &hGenerationNumber);
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             hBuffer, hGenerationNumber);
+    return {};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::setAsyncMode(bool async) {
+    HStatus hStatus{};
+    bool converted = b2h(mBase->setAsyncMode(async), &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<void> B2HGraphicBufferProducer::dequeueBuffer(
+        DequeueBufferInput const& input,
+        dequeueBuffer_cb _hidl_cb) {
+    int bSlot{};
+    sp<BFence> bFence;
+    HStatus hStatus{};
+    DequeueBufferOutput hOutput{};
+    HFenceWrapper hFenceWrapper;
+    bool converted =
+            b2h(mBase->dequeueBuffer(
+                    &bSlot,
+                    &bFence,
+                    input.width,
+                    input.height,
+                    static_cast<PixelFormat>(input.format),
+                    input.usage,
+                    &hOutput.bufferAge,
+                    nullptr /* outTimestamps */),
+                &hStatus,
+                &hOutput.bufferNeedsReallocation,
+                &hOutput.releaseAllBuffers) &&
+            b2h(bFence, &hFenceWrapper);
+    hOutput.fence = hFenceWrapper.getHandle();
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             static_cast<int32_t>(bSlot),
+             hOutput);
+    return {};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::detachBuffer(int32_t slot) {
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->detachBuffer(static_cast<int>(slot)), &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<void> B2HGraphicBufferProducer::detachNextBuffer(
+        detachNextBuffer_cb _hidl_cb) {
+    sp<GraphicBuffer> bBuffer;
+    sp<BFence> bFence;
+    HStatus hStatus{};
+    HardwareBuffer hBuffer{};
+    HFenceWrapper hFenceWrapper;
+    bool converted =
+            b2h(mBase->detachNextBuffer(&bBuffer, &bFence), &hStatus) &&
+            b2h(bBuffer, &hBuffer) &&
+            b2h(bFence, &hFenceWrapper);
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             hBuffer,
+             hFenceWrapper.getHandle());
+    return {};
+}
+
+Return<void> B2HGraphicBufferProducer::attachBuffer(
+        HardwareBuffer const& hBuffer,
+        uint32_t generationNumber,
+        attachBuffer_cb _hidl_cb) {
+    sp<GraphicBuffer> bBuffer;
+    if (!h2b(hBuffer, &bBuffer) || !bBuffer) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR,
+                 static_cast<int32_t>(SlotIndex::INVALID),
+                 false);
+        return {};
+    }
+    bBuffer->setGenerationNumber(generationNumber);
+
+    int bSlot{};
+    HStatus hStatus{};
+    bool releaseAllBuffers{};
+    bool converted = b2h(
+            mBase->attachBuffer(&bSlot, bBuffer), &hStatus,
+            nullptr /* bufferNeedsReallocation */,
+            &releaseAllBuffers);
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             static_cast<int32_t>(bSlot),
+             releaseAllBuffers);
+    return {};
+}
+
+Return<void> B2HGraphicBufferProducer::queueBuffer(
+        int32_t slot,
+        QueueBufferInput const& hInput,
+        queueBuffer_cb _hidl_cb) {
+    using HOutput = QueueBufferOutput;
+    using BInput = BGraphicBufferProducer::QueueBufferInput;
+    using BOutput = BGraphicBufferProducer::QueueBufferOutput;
+
+    BInput bInput{
+            hInput.timestamp,
+            hInput.isAutoTimestamp,
+            static_cast<android_dataspace>(hInput.dataSpace),
+            {}, /* crop */
+            0 /* scalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE */,
+            static_cast<uint32_t>(hInput.transform),
+            {}, /* fence */
+            static_cast<uint32_t>(hInput.stickyTransform),
+            false /* getFrameTimestamps */};
+
+    // Convert crop.
+    if (!h2b(hInput.crop, &bInput.crop)) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        return {};
+    }
+
+    // Convert surfaceDamage.
+    if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        return {};
+    }
+
+    // Convert fence.
+    if (!h2b(hInput.fence, &bInput.fence)) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        return {};
+    }
+
+    BOutput bOutput{};
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
+            &hStatus);
+
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             HOutput{bOutput.width,
+                     bOutput.height,
+                     static_cast<int32_t>(bOutput.transformHint),
+                     bOutput.numPendingBuffers,
+                     bOutput.nextFrameNumber,
+                     bOutput.bufferReplaced});
+    return {};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::cancelBuffer(
+        int32_t slot,
+        hidl_handle const& fence) {
+    sp<BFence> bFence;
+    if (!h2b(fence.getNativeHandle(), &bFence)) {
+        return {HStatus::UNKNOWN_ERROR};
+    }
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->cancelBuffer(static_cast<int>(slot), bFence),
+            &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<void> B2HGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) {
+    int value{};
+    int result = mBase->query(static_cast<int>(what), &value);
+    _hidl_cb(static_cast<int32_t>(result), static_cast<int32_t>(value));
+    return {};
+}
+
+Return<void> B2HGraphicBufferProducer::connect(
+        sp<HProducerListener> const& hListener,
+        HConnectionType hConnectionType,
+        bool producerControlledByApp,
+        connect_cb _hidl_cb) {
+    using BOutput = BGraphicBufferProducer::QueueBufferOutput;
+    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
+    sp<BProducerListener> bListener = new H2BProducerListener(hListener);
+    if (!bListener) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        return {};
+    }
+    int bConnectionType;
+    if (!h2b(hConnectionType, &bConnectionType)) {
+        _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{});
+        return {};
+    }
+    BOutput bOutput{};
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->connect(bListener,
+                           bConnectionType,
+                           producerControlledByApp,
+                           &bOutput),
+            &hStatus);
+    _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
+             HOutput{bOutput.width,
+                     bOutput.height,
+                     static_cast<int32_t>(bOutput.transformHint),
+                     bOutput.numPendingBuffers,
+                     bOutput.nextFrameNumber,
+                     bOutput.bufferReplaced});
+    return {};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::disconnect(
+        HConnectionType hConnectionType) {
+    int bConnectionType;
+    if (!h2b(hConnectionType, &bConnectionType)) {
+        return {HStatus::UNKNOWN_ERROR};
+    }
+    HStatus hStatus{};
+    bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::allocateBuffers(
+        uint32_t width, uint32_t height,
+        uint32_t format, uint64_t usage) {
+    mBase->allocateBuffers(
+            width, height, static_cast<PixelFormat>(format), usage);
+    return {HStatus::OK};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) {
+    HStatus hStatus{};
+    bool converted = b2h(mBase->allowAllocation(allow), &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber(
+        uint32_t generationNumber) {
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->setGenerationNumber(generationNumber),
+            &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout(
+        int64_t timeoutNs) {
+    HStatus hStatus{};
+    bool converted = b2h(
+            mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)),
+            &hStatus);
+    return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
+}
+
+Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() {
+    uint64_t outId{};
+    HStatus hStatus{};
+    bool converted = b2h(mBase->getUniqueId(&outId), &hStatus);
+    return {converted ? outId : 0};
+}
+
+Return<void> B2HGraphicBufferProducer::getConsumerName(
+        getConsumerName_cb _hidl_cb) {
+    _hidl_cb(hidl_string{mBase->getConsumerName().c_str()});
+    return {};
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp
new file mode 100644
index 0000000..c4c96eb
--- /dev/null
+++ b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gui/bufferqueue/2.0/B2HProducerListener.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// B2HProducerListener
+B2HProducerListener::B2HProducerListener(sp<BProducerListener> const& base)
+      : mBase{base},
+        mNeedsReleaseNotify{base ? base->needsReleaseNotify() : false} {
+}
+
+Return<void> B2HProducerListener::onBuffersReleased(uint32_t count) {
+    if (mNeedsReleaseNotify) {
+        for (; count > 0; --count) {
+            mBase->onBufferReleased();
+        }
+    }
+    return {};
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
new file mode 100644
index 0000000..1023ef1
--- /dev/null
+++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp
@@ -0,0 +1,514 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "H2BGraphicBufferProducer@2.0"
+
+#include <android-base/logging.h>
+
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <gui/bufferqueue/2.0/B2HProducerListener.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <vndk/hardware_buffer.h>
+
+namespace android {
+
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// H2BGraphicBufferProducer
+// ========================
+
+status_t H2BGraphicBufferProducer::requestBuffer(int slot,
+                                                 sp<GraphicBuffer>* bBuffer) {
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->requestBuffer(slot,
+            [&converted, &bStatus, bBuffer](
+                    HStatus hStatus,
+                    HardwareBuffer const& hBuffer,
+                    uint32_t generationNumber) {
+                converted =
+                        h2b(hStatus, &bStatus) &&
+                        h2b(hBuffer, bBuffer);
+                if (*bBuffer) {
+                    (*bBuffer)->setGenerationNumber(generationNumber);
+                }
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "requestBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "requestBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
+        int maxDequeuedBuffers) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->setMaxDequeuedBufferCount(
+            static_cast<int32_t>(maxDequeuedBuffers));
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "setMaxDequeuedBufferCount: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "setMaxDequeuedBufferCount: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->setAsyncMode(async);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "setAsyncMode: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "setAsyncMode: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::dequeueBuffer(
+        int* slot, sp<BFence>* fence,
+        uint32_t w, uint32_t h,
+        PixelFormat format, uint64_t usage,
+        uint64_t* outBufferAge, FrameEventHistoryDelta* /* outTimestamps */) {
+
+    using HInput = HGraphicBufferProducer::DequeueBufferInput;
+    HInput input{w, h, static_cast<uint32_t>(format), usage};
+
+    using HOutput = HGraphicBufferProducer::DequeueBufferOutput;
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->dequeueBuffer(input,
+            [&converted, &bStatus, slot, fence, outBufferAge] (
+                    HStatus hStatus, int32_t hSlot, HOutput const& hOutput) {
+                converted = h2b(hStatus, &bStatus);
+                if (!converted || bStatus != OK) {
+                    return;
+                }
+                *slot = hSlot;
+                *outBufferAge = hOutput.bufferAge;
+                bStatus =
+                        (hOutput.bufferNeedsReallocation ?
+                        BUFFER_NEEDS_REALLOCATION : 0) |
+                        (hOutput.releaseAllBuffers ?
+                        RELEASE_ALL_BUFFERS : 0);
+                converted = h2b(hOutput.fence, fence);
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "dequeueBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "dequeueBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->detachBuffer(
+            static_cast<int32_t>(slot));
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "detachBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "detachBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::detachNextBuffer(
+        sp<GraphicBuffer>* outBuffer, sp<BFence>* outFence) {
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->detachNextBuffer(
+            [&converted, &bStatus, outBuffer, outFence] (
+                    HStatus hStatus,
+                    HardwareBuffer const& hBuffer,
+                    hidl_handle const& hFence) {
+                converted = h2b(hStatus, &bStatus) &&
+                    h2b(hBuffer, outBuffer) &&
+                    h2b(hFence, outFence);
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "detachNextBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "detachNextBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::attachBuffer(
+        int* outSlot, sp<GraphicBuffer> const& buffer) {
+    HardwareBuffer hBuffer{};
+    uint32_t hGenerationNumber{};
+    if (!b2h(buffer, &hBuffer, &hGenerationNumber)) {
+        LOG(ERROR) << "attachBuffer: invalid input buffer.";
+        return BAD_VALUE;
+    }
+
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->attachBuffer(hBuffer, hGenerationNumber,
+            [&converted, &bStatus, outSlot](
+                    HStatus hStatus, int32_t hSlot, bool releaseAllBuffers) {
+                converted = h2b(hStatus, &bStatus);
+                *outSlot = static_cast<int>(hSlot);
+                if (converted && releaseAllBuffers && bStatus == OK) {
+                    bStatus = IGraphicBufferProducer::RELEASE_ALL_BUFFERS;
+                }
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "attachBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "attachBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::queueBuffer(
+        int slot,
+        QueueBufferInput const& input,
+        QueueBufferOutput* output) {
+    HRect hCrop{};
+    (void)b2h(input.crop, &hCrop);
+
+    using HInput = HGraphicBufferProducer::QueueBufferInput;
+    HInput hInput{
+            input.timestamp,
+            static_cast<bool>(input.isAutoTimestamp),
+            static_cast<int32_t>(input.dataSpace),
+            {}, // crop
+            static_cast<int32_t>(input.transform),
+            static_cast<int32_t>(input.stickyTransform),
+            {}, // fence
+            {}  // surfaceDamage
+            };
+
+    // Convert crop.
+    if (!b2h(input.crop, &hInput.crop)) {
+        LOG(ERROR) << "queueBuffer: corrupted input crop rectangle.";
+        return UNKNOWN_ERROR;
+    }
+
+    // Convert surfaceDamage.
+    size_t numRects;
+    Rect const* rectArray = input.surfaceDamage.getArray(&numRects);
+    hInput.surfaceDamage.resize(numRects);
+    for (size_t i = 0; i < numRects; ++i) {
+        if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) {
+            LOG(ERROR) << "queueBuffer: corrupted input surface damage.";
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    // Convert fence.
+    HFenceWrapper hFenceWrapper;
+    if (!b2h(input.fence, &hFenceWrapper)) {
+        LOG(ERROR) << "queueBuffer: corrupted input fence.";
+        return UNKNOWN_ERROR;
+    }
+    hInput.fence = hFenceWrapper.getHandle();
+
+    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->queueBuffer(
+            static_cast<int32_t>(slot),
+            hInput,
+            [&converted, &bStatus, output](
+                    HStatus hStatus,
+                    HOutput const& hOutput) {
+                converted = h2b(hStatus, &bStatus);
+                output->width = hOutput.width;
+                output->height = hOutput.height;
+                output->transformHint =
+                        static_cast<uint32_t>(hOutput.transformHint);
+                output->numPendingBuffers = hOutput.numPendingBuffers;
+                output->nextFrameNumber = hOutput.nextFrameNumber;
+                output->bufferReplaced = hOutput.bufferReplaced;
+            });
+
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "queueBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "queueBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::cancelBuffer(int slot, sp<BFence> const& fence) {
+    HFenceWrapper hFenceWrapper;
+    if (!b2h(fence, &hFenceWrapper)) {
+        LOG(ERROR) << "cancelBuffer: corrupted input fence.";
+        return UNKNOWN_ERROR;
+    }
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->cancelBuffer(
+            static_cast<int32_t>(slot),
+            hFenceWrapper.getHandle());
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "cancelBuffer: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "cancelBuffer: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+int H2BGraphicBufferProducer::query(int what, int* value) {
+    int result{};
+    Return<void> transResult = mBase->query(
+            static_cast<int32_t>(what),
+            [&result, value](int32_t r, int32_t v) {
+                result = static_cast<int>(r);
+                *value = static_cast<int>(v);
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "query: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    return result;
+}
+
+status_t H2BGraphicBufferProducer::connect(
+        sp<IProducerListener> const& listener, int api,
+        bool producerControlledByApp, QueueBufferOutput* output) {
+    HConnectionType hConnectionType;
+    if (!b2h(api, &hConnectionType)) {
+        LOG(ERROR) << "connect: corrupted input connection type.";
+        return UNKNOWN_ERROR;
+    }
+    sp<HProducerListener> hListener = nullptr;
+    if (listener && listener->needsReleaseNotify()) {
+        hListener = new B2HProducerListener(listener);
+        if (!hListener) {
+            LOG(ERROR) << "connect: failed to wrap listener.";
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    using HOutput = HGraphicBufferProducer::QueueBufferOutput;
+    bool converted{};
+    status_t bStatus{};
+    Return<void> transResult = mBase->connect(
+            hListener,
+            hConnectionType,
+            producerControlledByApp,
+            [&converted, &bStatus, output](
+                    HStatus hStatus,
+                    HOutput hOutput) {
+                converted = h2b(hStatus, &bStatus);
+                output->width = hOutput.width;
+                output->height = hOutput.height;
+                output->transformHint =
+                        static_cast<uint32_t>(hOutput.transformHint);
+                output->numPendingBuffers = hOutput.numPendingBuffers;
+                output->nextFrameNumber = hOutput.nextFrameNumber;
+                output->bufferReplaced = hOutput.bufferReplaced;
+            });
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "connect: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!converted) {
+        LOG(ERROR) << "connect: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+
+}
+
+status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
+    HConnectionType hConnectionType;
+    if (mode == DisconnectMode::AllLocal) {
+        hConnectionType = HConnectionType::CURRENTLY_CONNECTED;
+    } else if (!b2h(api, &hConnectionType)) {
+        LOG(ERROR) << "connect: corrupted input connection type.";
+        return UNKNOWN_ERROR;
+    }
+
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->disconnect(hConnectionType);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "disconnect: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "disconnect: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::setSidebandStream(
+        sp<NativeHandle> const& stream) {
+    if (stream) {
+        LOG(INFO) << "setSidebandStream: not supported.";
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+void H2BGraphicBufferProducer::allocateBuffers(
+        uint32_t width, uint32_t height,
+        PixelFormat format, uint64_t usage) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->allocateBuffers(
+            width, height, static_cast<uint32_t>(format), usage);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "allocateBuffer: transaction failed.";
+        return;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "allocateBuffer: corrupted transaction.";
+        return;
+    }
+}
+
+status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->allowAllocation(allow);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "allowAllocation: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "allowAllocation: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::setGenerationNumber(
+        uint32_t generationNumber) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->setGenerationNumber(generationNumber);
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "setGenerationNumber: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "setGenerationNumber: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+String8 H2BGraphicBufferProducer::getConsumerName() const {
+    String8 bName;
+    Return<void> transResult = mBase->getConsumerName(
+            [&bName](hidl_string const& name) {
+                bName = name.c_str();
+            });
+    return bName;
+}
+
+status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
+    if (sharedBufferMode) {
+        LOG(INFO) << "setSharedBufferMode: not supported.";
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
+    if (autoRefresh) {
+        LOG(INFO) << "setAutoRefresh: not supported.";
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
+    status_t bStatus{};
+    Return<HStatus> transResult = mBase->setDequeueTimeout(
+            static_cast<int64_t>(timeout));
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "setDequeueTimeout: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
+        LOG(ERROR) << "setDequeueTimeout: corrupted transaction.";
+        return FAILED_TRANSACTION;
+    }
+    return bStatus;
+}
+
+status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
+        sp<GraphicBuffer>*,
+        sp<BFence>*,
+        float[16]) {
+    LOG(INFO) << "getLastQueuedBuffer: not supported.";
+    return INVALID_OPERATION;
+}
+
+void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) {
+    LOG(INFO) << "getFrameTimestamps: not supported.";
+}
+
+status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
+    Return<uint64_t> transResult = mBase->getUniqueId();
+    if (!transResult.isOk()) {
+        LOG(ERROR) << "getUniqueId: transaction failed.";
+        return FAILED_TRANSACTION;
+    }
+    *outId = static_cast<uint64_t>(transResult);
+    return OK;
+}
+
+status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t*) const {
+    LOG(INFO) << "getConsumerUsage: not supported.";
+    return INVALID_OPERATION;
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp
new file mode 100644
index 0000000..b81a357
--- /dev/null
+++ b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "H2BProducerListener@2.0"
+
+#include <android-base/logging.h>
+
+#include <gui/bufferqueue/2.0/H2BProducerListener.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+
+H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base)
+      : CBase{base} {
+}
+
+void H2BProducerListener::onBufferReleased() {
+    if (mBase) {
+        Return<void> transResult = mBase->onBuffersReleased(1);
+        if (!transResult.isOk()) {
+            LOG(ERROR) << "onBuffersReleased: transaction failed.";
+        }
+    }
+}
+
+bool H2BProducerListener::needsReleaseNotify() {
+    return static_cast<bool>(mBase);
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/libs/gui/bufferqueue/2.0/types.cpp b/libs/gui/bufferqueue/2.0/types.cpp
new file mode 100644
index 0000000..a110517
--- /dev/null
+++ b/libs/gui/bufferqueue/2.0/types.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/native_handle.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <system/window.h>
+#include <vndk/hardware_buffer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// Status
+// ======
+
+bool b2h(status_t from, HStatus* to,
+         bool* bufferNeedsReallocation, bool* releaseAllBuffers) {
+    switch (from) {
+    case OK:
+        *to = HStatus::OK; break;
+    case NO_MEMORY:
+        *to = HStatus::NO_MEMORY; break;
+    case NO_INIT:
+        *to = HStatus::NO_INIT; break;
+    case BAD_VALUE:
+        *to = HStatus::BAD_VALUE; break;
+    case DEAD_OBJECT:
+        *to = HStatus::DEAD_OBJECT; break;
+    case INVALID_OPERATION:
+        *to = HStatus::INVALID_OPERATION; break;
+    case TIMED_OUT:
+        *to = HStatus::TIMED_OUT; break;
+    case WOULD_BLOCK:
+        *to = HStatus::WOULD_BLOCK; break;
+    case UNKNOWN_ERROR:
+        *to = HStatus::UNKNOWN_ERROR; break;
+    default:
+        using BGBP = ::android::IGraphicBufferProducer;
+        status_t mask =
+                (bufferNeedsReallocation ? BGBP::BUFFER_NEEDS_REALLOCATION : 0)
+                | (releaseAllBuffers ? BGBP::RELEASE_ALL_BUFFERS : 0);
+        if (from & ~mask) {
+            *to = static_cast<HStatus>(from);
+        } else {
+            *to = HStatus::OK;
+            if (bufferNeedsReallocation) {
+                *bufferNeedsReallocation = from & BGBP::BUFFER_NEEDS_REALLOCATION;
+            }
+            if (releaseAllBuffers) {
+                *releaseAllBuffers = from & BGBP::RELEASE_ALL_BUFFERS;
+            }
+        }
+    }
+    return true;
+}
+
+bool h2b(HStatus from, status_t* to) {
+    switch (from) {
+    case HStatus::OK:
+        *to = OK; break;
+    case HStatus::NO_MEMORY:
+        *to = NO_MEMORY; break;
+    case HStatus::NO_INIT:
+        *to = NO_INIT; break;
+    case HStatus::BAD_VALUE:
+        *to = BAD_VALUE; break;
+    case HStatus::DEAD_OBJECT:
+        *to = DEAD_OBJECT; break;
+    case HStatus::INVALID_OPERATION:
+        *to = INVALID_OPERATION; break;
+    case HStatus::TIMED_OUT:
+        *to = TIMED_OUT; break;
+    case HStatus::WOULD_BLOCK:
+        *to = WOULD_BLOCK; break;
+    case HStatus::UNKNOWN_ERROR:
+        *to = UNKNOWN_ERROR; break;
+    default:
+        *to = static_cast<status_t>(from);
+    }
+    return true;
+}
+
+// Fence
+// =====
+
+HFenceWrapper::HFenceWrapper(native_handle_t* h) : mHandle{h} {
+}
+
+HFenceWrapper::~HFenceWrapper() {
+    native_handle_delete(mHandle);
+}
+
+HFenceWrapper& HFenceWrapper::set(native_handle_t* h) {
+    native_handle_delete(mHandle);
+    mHandle = h;
+    return *this;
+}
+
+HFenceWrapper& HFenceWrapper::operator=(native_handle_t* h) {
+    return set(h);
+}
+
+hidl_handle HFenceWrapper::getHandle() const {
+    return hidl_handle{mHandle};
+}
+
+HFenceWrapper::operator hidl_handle() const {
+    return getHandle();
+}
+
+bool b2h(sp<BFence> const& from, HFenceWrapper* to) {
+    if (!from) {
+        to->set(nullptr);
+        return true;
+    }
+    int fenceFd = from->get();
+    if (fenceFd == -1) {
+        to->set(nullptr);
+        return true;
+    }
+    native_handle_t* nh = native_handle_create(1, 0);
+    if (!nh) {
+        return false;
+    }
+    nh->data[0] = fenceFd;
+    to->set(nh);
+    return true;
+}
+
+bool h2b(native_handle_t const* from, sp<BFence>* to) {
+    if (!from || from->numFds == 0) {
+        *to = new ::android::Fence();
+        return true;
+    }
+    if (from->numFds != 1 || from->numInts != 0) {
+        return false;
+    }
+    *to = new BFence(dup(from->data[0]));
+    return true;
+}
+
+// ConnectionType
+// ==============
+
+bool b2h(int from, HConnectionType* to) {
+    *to = static_cast<HConnectionType>(from);
+    switch (from) {
+    case BufferQueueCore::CURRENTLY_CONNECTED_API:
+        *to = HConnectionType::CURRENTLY_CONNECTED; break;
+    case NATIVE_WINDOW_API_EGL:
+        *to = HConnectionType::EGL; break;
+    case NATIVE_WINDOW_API_CPU:
+        *to = HConnectionType::CPU; break;
+    case NATIVE_WINDOW_API_MEDIA:
+        *to = HConnectionType::MEDIA; break;
+    case NATIVE_WINDOW_API_CAMERA:
+        *to = HConnectionType::CAMERA; break;
+    }
+    return true;
+}
+
+bool h2b(HConnectionType from, int* to) {
+    *to = static_cast<int>(from);
+    switch (from) {
+    case HConnectionType::CURRENTLY_CONNECTED:
+        *to = BufferQueueCore::CURRENTLY_CONNECTED_API; break;
+    case HConnectionType::EGL:
+        *to = NATIVE_WINDOW_API_EGL; break;
+    case HConnectionType::CPU:
+        *to = NATIVE_WINDOW_API_CPU; break;
+    case HConnectionType::MEDIA:
+        *to = NATIVE_WINDOW_API_MEDIA; break;
+    case HConnectionType::CAMERA:
+        *to = NATIVE_WINDOW_API_CAMERA; break;
+    }
+    return true;
+}
+
+// Rect
+// ====
+
+bool b2h(BRect const& from, HRect* to) {
+    BRect* dst = reinterpret_cast<BRect*>(to->data());
+    dst->left = from.left;
+    dst->top = from.top;
+    dst->right = from.right;
+    dst->bottom = from.bottom;
+    return true;
+}
+
+bool h2b(HRect const& from, BRect* to) {
+    BRect const* src = reinterpret_cast<BRect const*>(from.data());
+    to->left = src->left;
+    to->top = src->top;
+    to->right = src->right;
+    to->bottom = src->bottom;
+    return true;
+}
+
+// Region
+// ======
+
+bool b2h(BRegion const& from, HRegion* to) {
+    size_t numRects;
+    BRect const* rectArray = from.getArray(&numRects);
+    to->resize(numRects);
+    for (size_t i = 0; i < numRects; ++i) {
+        if (!b2h(rectArray[i], &(*to)[i])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool h2b(HRegion const& from, BRegion* to) {
+    if (from.size() > 0) {
+        BRect bRect;
+        if (!h2b(from[0], &bRect)) {
+            return false;
+        }
+        to->set(bRect);
+        for (size_t i = 1; i < from.size(); ++i) {
+            if (!h2b(from[i], &bRect)) {
+                return false;
+            }
+            to->addRectUnchecked(
+                    static_cast<int>(bRect.left),
+                    static_cast<int>(bRect.top),
+                    static_cast<int>(bRect.right),
+                    static_cast<int>(bRect.bottom));
+        }
+    } else {
+        to->clear();
+    }
+    return true;
+}
+
+// GraphicBuffer
+// =============
+
+// The handle is not cloned. Its lifetime is tied to the original GraphicBuffer.
+bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to,
+         uint32_t* toGenerationNumber) {
+    if (!from) {
+        return false;
+    }
+    AHardwareBuffer* hwBuffer = from->toAHardwareBuffer();
+    to->nativeHandle.setTo(
+          const_cast<native_handle_t*>(
+              AHardwareBuffer_getNativeHandle(hwBuffer)),
+          false);
+    AHardwareBuffer_describe(
+            hwBuffer,
+            reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data()));
+    if (toGenerationNumber) {
+        *toGenerationNumber = from->getGenerationNumber();
+    }
+    return true;
+}
+
+// The handle is cloned.
+bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to) {
+    AHardwareBuffer_Desc const* desc =
+            reinterpret_cast<AHardwareBuffer_Desc const*>(
+            from.description.data());
+    native_handle_t const* handle = from.nativeHandle;
+    AHardwareBuffer* hwBuffer;
+    if (AHardwareBuffer_createFromHandle(
+            desc, handle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE,
+            &hwBuffer) != OK) {
+        return false;
+    }
+    *to = GraphicBuffer::fromAHardwareBuffer(hwBuffer);
+    return true;
+}
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 8ff8d81..2f538ad 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -35,6 +35,7 @@
 
 #include <hidl/HybridInterface.h>
 #include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -42,8 +43,6 @@
 class IProducerListener;
 class NativeHandle;
 class Surface;
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
-        HGraphicBufferProducer;
 
 /*
  * This class defines the Binder IPC interface for the producer side of
@@ -62,7 +61,16 @@
 class IGraphicBufferProducer : public IInterface
 {
 public:
-    DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer)
+    using HGraphicBufferProducerV1_0 =
+            ::android::hardware::graphics::bufferqueue::V1_0::
+            IGraphicBufferProducer;
+    using HGraphicBufferProducerV2_0 =
+            ::android::hardware::graphics::bufferqueue::V2_0::
+            IGraphicBufferProducer;
+
+    DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer,
+                                  HGraphicBufferProducerV1_0,
+                                  HGraphicBufferProducerV2_0)
 
     enum {
         // A flag returned by dequeueBuffer when the client needs to call
@@ -366,7 +374,6 @@
         const HdrMetadata& getHdrMetadata() const { return hdrMetadata; }
         void setHdrMetadata(const HdrMetadata& metadata) { hdrMetadata = metadata; }
 
-    private:
         int64_t timestamp{0};
         int isAutoTimestamp{0};
         android_dataspace dataSpace{HAL_DATASPACE_UNKNOWN};
diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h
index e808bd3..a13d8e4 100644
--- a/libs/gui/include/gui/IProducerListener.h
+++ b/libs/gui/include/gui/IProducerListener.h
@@ -17,8 +17,10 @@
 #ifndef ANDROID_GUI_IPRODUCERLISTENER_H
 #define ANDROID_GUI_IPRODUCERLISTENER_H
 
+#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
+#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>
 #include <binder/IInterface.h>
-
+#include <hidl/HybridInterface.h>
 #include <utils/RefBase.h>
 
 namespace android {
@@ -47,7 +49,14 @@
 class IProducerListener : public ProducerListener, public IInterface
 {
 public:
-    DECLARE_META_INTERFACE(ProducerListener)
+    using HProducerListener1 =
+            ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener;
+    using HProducerListener2 =
+            ::android::hardware::graphics::bufferqueue::V2_0::IProducerListener;
+    DECLARE_HYBRID_META_INTERFACE(
+            ProducerListener,
+            HProducerListener1,
+            HProducerListener2)
 };
 
 class BnProducerListener : public BnInterface<IProducerListener>
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 3dffa8f..8f54fee 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -194,8 +194,7 @@
      * of the buffer. The caller should pick the data space and pixel format
      * that it can consume.
      *
-     * At the moment, sourceCrop is ignored and is always set to the visible
-     * region (projected display viewport) of the screen.
+     * sourceCrop is the crop on the logical display.
      *
      * reqWidth and reqHeight specifies the size of the buffer.  When either
      * of them is 0, they are set to the size of the logical display viewport.
diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h
new file mode 100644
index 0000000..211fdd5
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H
+
+#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
+#include <gui/IProducerListener.h>
+#include <hidl/HybridInterface.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V1_0 {
+namespace utils {
+
+using HProducerListener = ::android::hardware::graphics::bufferqueue::V1_0::
+        IProducerListener;
+
+using BProducerListener = ::android::IProducerListener;
+
+class H2BProducerListener
+      : public H2BConverter<HProducerListener, BnProducerListener> {
+public:
+    H2BProducerListener(sp<HProducerListener> const& base);
+    virtual void onBufferReleased() override;
+    virtual bool needsReleaseNotify() override;
+};
+
+}  // namespace utils
+}  // namespace V1_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H
+
diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h
new file mode 100644
index 0000000..1c58167
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <hidl/HidlSupport.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+using HGraphicBufferProducer =
+        ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer;
+using BGraphicBufferProducer =
+        ::android::
+        IGraphicBufferProducer;
+using HProducerListener =
+        ::android::hardware::graphics::bufferqueue::V2_0::
+        IProducerListener;
+
+using ::android::hardware::Return;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+using ::android::hardware::graphics::common::V1_2::HardwareBuffer;
+
+class B2HGraphicBufferProducer : public HGraphicBufferProducer {
+public:
+    B2HGraphicBufferProducer(sp<BGraphicBufferProducer> const& base);
+
+    virtual Return<HStatus> setMaxDequeuedBufferCount(
+            int32_t maxDequeuedBuffers) override;
+
+    virtual Return<void> requestBuffer(
+            int32_t slot,
+            requestBuffer_cb _hidl_cb) override;
+
+    virtual Return<HStatus> setAsyncMode(bool async) override;
+
+    virtual Return<void> dequeueBuffer(
+            DequeueBufferInput const& input,
+            dequeueBuffer_cb _hidl_cb) override;
+
+    virtual Return<HStatus> detachBuffer(int32_t slot) override;
+
+    virtual Return<void> detachNextBuffer(
+            detachNextBuffer_cb _hidl_cb) override;
+
+    virtual Return<void> attachBuffer(
+            HardwareBuffer const& buffer,
+            uint32_t generationNumber,
+            attachBuffer_cb _hidl_cb) override;
+
+    virtual Return<void> queueBuffer(
+            int32_t slot,
+            QueueBufferInput const& input,
+            queueBuffer_cb _hidl_cb) override;
+
+    virtual Return<HStatus> cancelBuffer(
+            int32_t slot,
+            hidl_handle const& fence) override;
+
+    virtual Return<void> query(int32_t what, query_cb _hidl_cb) override;
+
+    virtual Return<void> connect(
+            sp<HProducerListener> const& listener,
+            HConnectionType api,
+            bool producerControlledByApp,
+            connect_cb _hidl_cb) override;
+
+    virtual Return<HStatus> disconnect(HConnectionType api) override;
+
+    virtual Return<HStatus> allocateBuffers(
+            uint32_t width, uint32_t height,
+            uint32_t format, uint64_t usage) override;
+
+    virtual Return<HStatus> allowAllocation(bool allow) override;
+
+    virtual Return<HStatus> setGenerationNumber(uint32_t generationNumber) override;
+
+    virtual Return<HStatus> setDequeueTimeout(int64_t timeoutNs) override;
+
+    virtual Return<uint64_t> getUniqueId() override;
+
+    virtual Return<void> getConsumerName(getConsumerName_cb _hidl_cb) override;
+
+protected:
+    sp<BGraphicBufferProducer> mBase;
+};
+
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H
diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h
new file mode 100644
index 0000000..b48a473
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <binder/IBinder.h>
+#include <gui/IProducerListener.h>
+#include <hidl/Status.h>
+
+#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+using ::android::hardware::Return;
+
+using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0::
+        IProducerListener;
+
+using BProducerListener = ::android::IProducerListener;
+
+struct B2HProducerListener : public HProducerListener {
+    explicit B2HProducerListener(sp<BProducerListener> const& base);
+    Return<void> onBuffersReleased(uint32_t count) override;
+protected:
+    sp<BProducerListener> mBase;
+    bool mNeedsReleaseNotify;
+};
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H
+
diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h
new file mode 100644
index 0000000..7dd1617
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H
+
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
+#include <hidl/HybridInterface.h>
+#include <ui/Fence.h>
+
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+using ::android::BnGraphicBufferProducer;
+using ::android::IProducerListener;
+using Fence = ::android::Fence;
+
+using HGraphicBufferProducer =
+        ::android::hardware::graphics::bufferqueue::V2_0::
+        IGraphicBufferProducer;
+using HProducerListener =
+        ::android::hardware::graphics::bufferqueue::V2_0::
+        IProducerListener;
+using BGraphicBufferProducer =
+        ::android::IGraphicBufferProducer;
+
+struct H2BGraphicBufferProducer
+      : public ::android::H2BConverter<HGraphicBufferProducer,
+                                       BnGraphicBufferProducer> {
+    explicit H2BGraphicBufferProducer(
+            sp<HGraphicBufferProducer> const& base) : CBase(base) {}
+
+    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
+    virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override;
+    virtual status_t setAsyncMode(bool async) override;
+    virtual status_t dequeueBuffer(
+            int* slot, sp<Fence>* fence,
+            uint32_t width, uint32_t height,
+            PixelFormat format, uint64_t usage,
+            uint64_t* outBufferAge,
+            FrameEventHistoryDelta* outTimestamps) override;
+    virtual status_t detachBuffer(int slot) override;
+    virtual status_t detachNextBuffer(
+            sp<GraphicBuffer>* outBuffer,
+            sp<Fence>* outFence) override;
+    virtual status_t attachBuffer(
+            int* outSlot,
+            sp<GraphicBuffer> const& buffer) override;
+    virtual status_t queueBuffer(
+            int slot,
+            QueueBufferInput const& input,
+            QueueBufferOutput* output) override;
+    virtual status_t cancelBuffer(int slot, sp<Fence> const& fence) override;
+    virtual int query(int what, int* value) override;
+    virtual status_t connect(
+            sp<IProducerListener> const& listener,
+            int api,
+            bool producerControlledByApp,
+            QueueBufferOutput* output) override;
+    virtual status_t disconnect(
+            int api,
+            DisconnectMode mode = DisconnectMode::Api) override;
+    virtual status_t setSidebandStream(sp<NativeHandle> const& stream) override;
+    virtual void allocateBuffers(
+            uint32_t width, uint32_t height,
+            PixelFormat format, uint64_t usage) override;
+    virtual status_t allowAllocation(bool allow) override;
+    virtual status_t setGenerationNumber(uint32_t generationNumber) override;
+    virtual String8 getConsumerName() const override;
+    virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
+    virtual status_t setAutoRefresh(bool autoRefresh) override;
+    virtual status_t setDequeueTimeout(nsecs_t timeout) override;
+    virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
+          sp<Fence>* outFence, float outTransformMatrix[16]) override;
+    virtual void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
+    virtual status_t getUniqueId(uint64_t* outId) const override;
+    virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+};
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H
diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h
new file mode 100644
index 0000000..898920b
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H
+
+#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>
+#include <gui/IProducerListener.h>
+#include <hidl/HybridInterface.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0::
+        IProducerListener;
+
+using BProducerListener = ::android::IProducerListener;
+
+class H2BProducerListener
+      : public H2BConverter<HProducerListener, BnProducerListener> {
+public:
+    H2BProducerListener(sp<HProducerListener> const& base);
+    virtual void onBufferReleased() override;
+    virtual bool needsReleaseNotify() override;
+};
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H
+
diff --git a/libs/gui/include/gui/bufferqueue/2.0/types.h b/libs/gui/include/gui/bufferqueue/2.0/types.h
new file mode 100644
index 0000000..62176ce
--- /dev/null
+++ b/libs/gui/include/gui/bufferqueue/2.0/types.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H
+
+#include <android/hardware/graphics/bufferqueue/2.0/types.h>
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <hidl/HidlSupport.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V2_0 {
+namespace utils {
+
+// Status
+// ======
+
+using HStatus = ::android::hardware::graphics::bufferqueue::V2_0::
+        Status;
+
+// A status_t value may have flags encoded. These flags are decoded into boolean
+// values if their corresponding output pointers are not null.
+bool b2h(status_t from, HStatus* to,
+         bool* bufferNeedsReallocation = nullptr,
+         bool* releaseAllBuffers = nullptr);
+// Simple 1-to-1 mapping. If BUFFER_NEEDS_REALLOCATION or RELEASE_ALL_BUFFERS
+// needs to be added, it must be done manually afterwards.
+bool h2b(HStatus from, status_t* to);
+
+// Fence
+// =====
+
+using BFence = ::android::Fence;
+// This class manages the lifetime of a copied handle. Its destructor calls
+// native_handle_delete() but not native_handle_close().
+struct HFenceWrapper {
+    HFenceWrapper() = default;
+    // Sets mHandle to a new value.
+    HFenceWrapper(native_handle_t* h);
+    // Deletes mHandle without closing.
+    ~HFenceWrapper();
+    // Deletes mHandle without closing, then sets mHandle to a new value.
+    HFenceWrapper& set(native_handle_t* h);
+    HFenceWrapper& operator=(native_handle_t* h);
+    // Returns a non-owning hidl_handle pointing to mHandle.
+    hidl_handle getHandle() const;
+    operator hidl_handle() const;
+protected:
+    native_handle_t* mHandle{nullptr};
+};
+
+// Does not clone the fd---only copy the fd. The returned HFenceWrapper should
+// not outlive the input Fence object.
+bool b2h(sp<BFence> const& from, HFenceWrapper* to);
+// Clones the fd and puts it in a new Fence object.
+bool h2b(native_handle_t const* from, sp<BFence>* to);
+
+// ConnectionType
+// ==============
+
+using HConnectionType = ::android::hardware::graphics::bufferqueue::V2_0::
+        ConnectionType;
+
+bool b2h(int from, HConnectionType* to);
+bool h2b(HConnectionType from, int* to);
+
+// Rect
+// ====
+
+using BRect = ::android::Rect;
+using HRect = ::android::hardware::graphics::common::V1_2::Rect;
+
+bool b2h(BRect const& from, HRect* to);
+bool h2b(HRect const& from, BRect* to);
+
+// Region
+// ======
+
+using BRegion = ::android::Region;
+using HRegion = ::android::hardware::hidl_vec<HRect>;
+
+bool b2h(BRegion const& from, HRegion* to);
+bool h2b(HRegion const& from, BRegion* to);
+
+// GraphicBuffer
+// =============
+
+using HardwareBuffer = ::android::hardware::graphics::common::V1_2::
+        HardwareBuffer;
+using HardwareBufferDescription = ::android::hardware::graphics::common::V1_2::
+        HardwareBufferDescription;
+
+// Does not clone the handle. The returned HardwareBuffer should not outlive the
+// input GraphicBuffer. Note that HardwareBuffer does not carry the generation
+// number, so this function needs another output argument.
+bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to,
+         uint32_t* toGenerationNumber = nullptr);
+// Clones the handle and creates a new GraphicBuffer from the cloned handle.
+// Note that the generation number of the GraphicBuffer has to be set manually
+// afterwards because HardwareBuffer does not have such information.
+bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to);
+
+}  // namespace utils
+}  // namespace V2_0
+}  // namespace bufferqueue
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H
+
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index 4ce5a10..d6a73bf 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -30,7 +30,7 @@
     explicit BpInputFlinger(const sp<IBinder>& impl) :
             BpInterface<IInputFlinger>(impl) { }
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& inputInfo,
+    virtual void setInputWindows(const std::vector<InputWindowInfo>& inputInfo,
             const sp<ISetInputWindowsListener>& setInputWindowsListener) {
         Parcel data, reply;
         data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
@@ -81,10 +81,9 @@
         if (count > data.dataSize()) {
             return BAD_VALUE;
         }
-        Vector<InputWindowInfo> handles;
-        handles.setCapacity(count);
+        std::vector<InputWindowInfo> handles;
         for (size_t i = 0; i < count; i++) {
-            handles.add(InputWindowInfo(data));
+            handles.push_back(InputWindowInfo::read(data));
         }
         const sp<ISetInputWindowsListener> setInputWindowsListener =
                 ISetInputWindowsListener::asInterface(data.readStrongBinder());
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index dab6eac..4db9e06 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -186,7 +186,7 @@
         int32_t axis, uint32_t source) const {
     size_t numRanges = mMotionRanges.size();
     for (size_t i = 0; i < numRanges; i++) {
-        const MotionRange& range = mMotionRanges.itemAt(i);
+        const MotionRange& range = mMotionRanges[i];
         if (range.axis == axis && range.source == source) {
             return &range;
         }
@@ -201,11 +201,11 @@
 void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
         float flat, float fuzz, float resolution) {
     MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
-    mMotionRanges.add(range);
+    mMotionRanges.push_back(range);
 }
 
 void InputDeviceInfo::addMotionRange(const MotionRange& range) {
-    mMotionRanges.add(range);
+    mMotionRanges.push_back(range);
 }
 
 } // namespace android
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 88cb0db..efca68d 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -120,11 +120,12 @@
     return nullptr;
 }
 
-status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
+status_t KeyLayoutMap::findScanCodesForKey(
+        int32_t keyCode, std::vector<int32_t>* outScanCodes) const {
     const size_t N = mKeysByScanCode.size();
     for (size_t i=0; i<N; i++) {
         if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
-            outScanCodes->add(mKeysByScanCode.keyAt(i));
+            outScanCodes->push_back(mKeysByScanCode.keyAt(i));
         }
     }
     return NO_ERROR;
diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp
index 624f152..865366b 100644
--- a/libs/input/VirtualKeyMap.cpp
+++ b/libs/input/VirtualKeyMap.cpp
@@ -112,7 +112,7 @@
                         "width=%d, height=%d",
                         defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
 #endif
-                mMap->mVirtualKeys.push(defn);
+                mMap->mVirtualKeys.push_back(defn);
             } while (consumeFieldDelimiterAndSkipWhitespace());
 
             if (!mTokenizer->isEol()) {
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 994e953..bf80481 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -93,8 +93,57 @@
     outDesc->rfu1 = 0;
 }
 
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
+        int32_t fence, const ARect* rect, void** outVirtualAddress,
+        int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {
+    if (!buffer) return BAD_VALUE;
+
+    if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+                  AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
+        ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+                "AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
+        return BAD_VALUE;
+    }
+
+    usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+    GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+
+    //Mapper implementations before 3.0 will not return bytes per pixel or
+    //bytes per stride information.
+    if (gbuffer->getBufferMapperVersion() == GraphicBufferMapper::Version::GRALLOC_2) {
+        ALOGE("Mapper versions before 3.0 cannot retrieve bytes per pixel and bytes per stride info");
+        return INVALID_OPERATION;
+    }
+
+    if (gbuffer->getLayerCount() > 1) {
+        ALOGE("Buffer with multiple layers passed to AHardwareBuffer_lock; "
+                "only buffers with one layer are allowed");
+        return INVALID_OPERATION;
+    }
+
+    Rect bounds;
+    if (!rect) {
+        bounds.set(Rect(gbuffer->getWidth(), gbuffer->getHeight()));
+    } else {
+        bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+    }
+    int result = gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, outBytesPerPixel, outBytesPerStride);
+
+    // if hardware returns -1 for bytes per pixel or bytes per stride, we fail
+    // and unlock the buffer
+    if (*outBytesPerPixel == -1 || *outBytesPerStride == -1) {
+        gbuffer->unlock();
+        return INVALID_OPERATION;
+    }
+
+    return result;
+}
+
 int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, void** outVirtualAddress) {
+                         int32_t fence, const ARect* rect, void** outVirtualAddress) {
+    int32_t bytesPerPixel;
+    int32_t bytesPerStride;
+
     if (!buffer) return BAD_VALUE;
 
     if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
@@ -119,7 +168,7 @@
     } else {
         bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
     }
-    return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
+    return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, &bytesPerPixel, &bytesPerStride);
 }
 
 int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
@@ -636,11 +685,11 @@
 }
 
 const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
-    return reinterpret_cast<const GraphicBuffer*>(buffer);
+    return GraphicBuffer::fromAHardwareBuffer(buffer);
 }
 
 GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) {
-    return reinterpret_cast<GraphicBuffer*>(buffer);
+    return GraphicBuffer::fromAHardwareBuffer(buffer);
 }
 
 const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) {
@@ -652,7 +701,7 @@
 }
 
 AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) {
-    return reinterpret_cast<AHardwareBuffer*>(buffer);
+    return buffer->toAHardwareBuffer();
 }
 
 } // namespace android
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index d847884..27ab482 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -24,7 +24,7 @@
 cc_library_headers {
     name: "libnativewindow_headers",
     export_include_dirs: ["include"],
-    vendor_available: false,
+    vendor_available: true,
 }
 
 ndk_library {
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 02c7c1b..da959e3 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -506,6 +506,18 @@
  */
 int AHardwareBuffer_isSupported(const AHardwareBuffer_Desc* desc) __INTRODUCED_IN(29);
 
+/**
+ * Lock an AHardwareBuffer for direct CPU access.
+ *
+ * This function is the same as the above lock function, but passes back
+ * additional information about the bytes per pixel and the bytes per stride
+ * of the locked buffer.  If the bytes per pixel or bytes per stride are unknown
+ * or variable, or if the underlying mapper implementation does not support returning
+ * additional information, then this call will fail with INVALID_OPERATION
+ */
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
+        int32_t fence, const ARect* rect, void** outVirtualAddress,
+        int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29);
 #endif // __ANDROID_API__ >= 29
 
 __END_DECLS
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index a796e97..23a05f3 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -7,6 +7,7 @@
     AHardwareBuffer_getNativeHandle; # vndk
     AHardwareBuffer_isSupported; # introduced=29
     AHardwareBuffer_lock;
+    AHardwareBuffer_lockAndGetInfo; # introduced=29
     AHardwareBuffer_recvHandleFromUnixSocket;
     AHardwareBuffer_release;
     AHardwareBuffer_sendHandleToUnixSocket;
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 4ca1781..755418e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -124,7 +124,6 @@
             exclude_header_libs: [
                 "libbufferhub_headers",
                 "libdvr_headers",
-                "libnativewindow_headers",
             ],
             exclude_shared_libs: [
                 "android.frameworks.bufferhub@1.0",
@@ -152,6 +151,7 @@
     export_header_lib_headers: [
         "libbase_headers",
         "libnativebase_headers",
+        "libnativewindow_headers",
         "libhardware_headers",
         "libui_headers",
     ],
@@ -167,6 +167,12 @@
             override_export_include_dirs: ["include_vndk"],
         },
     },
+    header_libs: [
+        "libnativewindow_headers",
+    ],
+    export_header_lib_headers: [
+        "libnativewindow_headers",
+    ],
 }
 
 subdirs = [
diff --git a/libs/ui/ColorSpace.cpp b/libs/ui/ColorSpace.cpp
index 5b4bf23..7a14af1 100644
--- a/libs/ui/ColorSpace.cpp
+++ b/libs/ui/ColorSpace.cpp
@@ -351,13 +351,12 @@
     };
 }
 
-std::unique_ptr<float3> ColorSpace::createLUT(uint32_t size,
-        const ColorSpace& src, const ColorSpace& dst) {
-
+std::unique_ptr<float3[]> ColorSpace::createLUT(uint32_t size, const ColorSpace& src,
+                                                const ColorSpace& dst) {
     size = clamp(size, 2u, 256u);
     float m = 1.0f / float(size - 1);
 
-    std::unique_ptr<float3> lut(new float3[size * size * size]);
+    std::unique_ptr<float3[]> lut(new float3[size * size * size]);
     float3* data = lut.get();
 
     ColorSpaceConnector connector(src, dst);
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index ed7ccb0b..4ce891e 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -110,7 +110,7 @@
     }
 
     struct sync_file_info* finfo = sync_file_info(mFenceFd);
-    if (finfo == NULL) {
+    if (finfo == nullptr) {
         ALOGE("sync_file_info returned NULL for fd %d", mFenceFd.get());
         return SIGNAL_TIME_INVALID;
     }
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index ca9f3ee..e1c325e 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -49,6 +49,22 @@
     return static_cast<GraphicBuffer *>(anwb);
 }
 
+GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) {
+    return reinterpret_cast<GraphicBuffer*>(buffer);
+}
+
+GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) {
+    return reinterpret_cast<GraphicBuffer const*>(buffer);
+}
+
+AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() {
+    return reinterpret_cast<AHardwareBuffer*>(this);
+}
+
+AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const {
+    return reinterpret_cast<AHardwareBuffer const*>(this);
+}
+
 GraphicBuffer::GraphicBuffer()
     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
@@ -60,7 +76,7 @@
     usage_deprecated = 0;
     usage  = 0;
     layerCount = 0;
-    handle = NULL;
+    handle = nullptr;
 }
 
 // deprecated
@@ -127,7 +143,7 @@
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
     }
-    handle = NULL;
+    handle = nullptr;
 }
 
 status_t GraphicBuffer::initCheck() const {
@@ -162,7 +178,7 @@
     if (handle) {
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
-        handle = 0;
+        handle = nullptr;
     }
     return initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, "[Reallocation]");
 }
@@ -456,7 +472,7 @@
         width = height = stride = format = usage_deprecated = 0;
         layerCount = 0;
         usage = 0;
-        handle = NULL;
+        handle = nullptr;
         ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts);
         return BAD_VALUE;
     }
@@ -490,7 +506,7 @@
             width = height = stride = format = usage_deprecated = 0;
             layerCount = 0;
             usage = 0;
-            handle = NULL;
+            handle = nullptr;
             ALOGE("unflatten: native_handle_create failed");
             return NO_MEMORY;
         }
@@ -501,7 +517,7 @@
         width = height = stride = format = usage_deprecated = 0;
         layerCount = 0;
         usage = 0;
-        handle = NULL;
+        handle = nullptr;
     }
 
     mId = static_cast<uint64_t>(buf[7]) << 32;
@@ -511,7 +527,7 @@
 
     mOwner = ownHandle;
 
-    if (handle != 0) {
+    if (handle != nullptr) {
         buffer_handle_t importedHandle;
         status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height),
                 uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle);
@@ -519,7 +535,7 @@
             width = height = stride = format = usage_deprecated = 0;
             layerCount = 0;
             usage = 0;
-            handle = NULL;
+            handle = nullptr;
             ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err);
             return err;
         }
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 06981c3..25b7247 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -53,6 +53,9 @@
     mMapper = std::make_unique<const Gralloc3Mapper>();
     if (!mMapper->isLoaded()) {
         mMapper = std::make_unique<const Gralloc2Mapper>();
+        mMapperVersion = Version::GRALLOC_2;
+    } else {
+        mMapperVersion = Version::GRALLOC_3;
     }
 
     if (!mMapper->isLoaded()) {
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 3bd3748..224dc2c 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -820,7 +820,7 @@
     }
 
     if (numRects > (UINT32_MAX / sizeof(Rect))) {
-        android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, NULL, 0);
+        android_errorWriteWithInfoLog(0x534e4554, "29983260", -1, nullptr, 0);
         return NO_MEMORY;
     }
 
diff --git a/libs/ui/include/ui/ColorSpace.h b/libs/ui/include/ui/ColorSpace.h
index 8ccf6d3..241ec10 100644
--- a/libs/ui/include/ui/ColorSpace.h
+++ b/libs/ui/include/ui/ColorSpace.h
@@ -250,8 +250,8 @@
     // axis is thus already flipped
     // The source color space must define its values in the domain [0..1]
     // The generated LUT transforms from gamma space to gamma space
-    static std::unique_ptr<float3> createLUT(uint32_t size,
-            const ColorSpace& src, const ColorSpace& dst);
+    static std::unique_ptr<float3[]> createLUT(uint32_t size, const ColorSpace& src,
+                                               const ColorSpace& dst);
 
 private:
     static constexpr mat3 computeXYZMatrix(
diff --git a/libs/ui/include/ui/Fence.h b/libs/ui/include/ui/Fence.h
index ec67fa9..6efecd3 100644
--- a/libs/ui/include/ui/Fence.h
+++ b/libs/ui/include/ui/Fence.h
@@ -99,6 +99,12 @@
     // be returned and errno will indicate the problem.
     int dup() const;
 
+    // Return the underlying file descriptor without giving up ownership. The
+    // returned file descriptor is only valid for as long as the owning Fence
+    // object lives. (If the situation is unclear, dup() is always a safer
+    // option.)
+    int get() const { return mFenceFd.get(); }
+
     // getSignalTime returns the system monotonic clock time at which the
     // fence transitioned to the signaled state.  If the fence is not signaled
     // then SIGNAL_TIME_PENDING is returned.  If the fence is invalid or if an
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index 23337a4..cb4ee2a 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -22,7 +22,9 @@
 
 #include <string>
 
+#include <android/hardware_buffer.h>
 #include <ui/ANativeObjectBase.h>
+#include <ui/GraphicBufferMapper.h>
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
 #include <utils/Flattenable.h>
@@ -78,6 +80,10 @@
 
     static sp<GraphicBuffer> from(ANativeWindowBuffer *);
 
+    static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*);
+    static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*);
+    AHardwareBuffer* toAHardwareBuffer();
+    AHardwareBuffer const* toAHardwareBuffer() const;
 
     // Create a GraphicBuffer to be unflatten'ed into or be reallocated.
     GraphicBuffer();
@@ -209,6 +215,10 @@
     status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
     status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
 
+    GraphicBufferMapper::Version getBufferMapperVersion() const {
+        return mBufferMapper.getMapperVersion();
+    }
+
 #ifndef LIBUI_IN_VNDK
     // Returns whether this GraphicBuffer is backed by BufferHubBuffer.
     bool isBufferHubBuffer() const;
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 77c99cc..2461454 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -41,6 +41,10 @@
 class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
 {
 public:
+    enum Version {
+        GRALLOC_2,
+        GRALLOC_3,
+    };
     static void preloadHal();
     static inline GraphicBufferMapper& get() { return getInstance(); }
 
@@ -85,12 +89,16 @@
         return reinterpret_cast<const GrallocMapper&>(*mMapper);
     }
 
+    Version getMapperVersion() const { return mMapperVersion; }
+
 private:
     friend class Singleton<GraphicBufferMapper>;
 
     GraphicBufferMapper();
 
     std::unique_ptr<const GrallocMapper> mMapper;
+
+    Version mMapperVersion;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/ui/tools/lutgen.cpp b/libs/ui/tools/lutgen.cpp
index 97b0822..85a1ceb 100644
--- a/libs/ui/tools/lutgen.cpp
+++ b/libs/ui/tools/lutgen.cpp
@@ -85,11 +85,11 @@
 static int handleCommandLineArgments(int argc, char* argv[]) {
     static constexpr const char* OPTSTR = "h:d:s:t:";
     static const struct option OPTIONS[] = {
-            { "help",       no_argument,       0, 'h' },
-            { "dimension",  required_argument, 0, 'd' },
-            { "source",     required_argument, 0, 's' },
-            { "target",     required_argument, 0, 't' },
-            { 0, 0, 0, 0 }  // termination of the option list
+            { "help",       no_argument,       nullptr, 'h' },
+            { "dimension",  required_argument, nullptr, 'd' },
+            { "source",     required_argument, nullptr, 's' },
+            { "target",     required_argument, nullptr, 't' },
+            { nullptr, 0, nullptr, 0 }  // termination of the option list
     };
 
     int opt;
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index c100db7..54fa89f 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -314,6 +314,24 @@
             }
         }
 
+        if (cnx->minor == 5) {
+            // full list in egl_entries.in
+            if (!cnx->egl.eglCreateImage ||
+                !cnx->egl.eglDestroyImage ||
+                !cnx->egl.eglGetPlatformDisplay ||
+                !cnx->egl.eglCreatePlatformWindowSurface ||
+                !cnx->egl.eglCreatePlatformPixmapSurface ||
+                !cnx->egl.eglCreateSync ||
+                !cnx->egl.eglDestroySync ||
+                !cnx->egl.eglClientWaitSync ||
+                !cnx->egl.eglGetSyncAttrib ||
+                !cnx->egl.eglWaitSync) {
+                ALOGE("Driver indicates EGL 1.5 support, but does not have "
+                      "a critical API");
+                cnx->minor = 4;
+            }
+        }
+
         // the query strings are per-display
         mVendorString = sVendorString;
         mVersionString.clear();
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 4da1473..0544ec1 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -415,14 +415,14 @@
 
     Device* device = getDeviceLocked(deviceId);
     if (device && device->hasValidFd() && device->keyMap.haveKeyLayout()) {
-        Vector<int32_t> scanCodes;
+        std::vector<int32_t> scanCodes;
         device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
         if (scanCodes.size() != 0) {
             uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
             memset(keyState, 0, sizeof(keyState));
             if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
                 for (size_t i = 0; i < scanCodes.size(); i++) {
-                    int32_t sc = scanCodes.itemAt(i);
+                    int32_t sc = scanCodes[i];
                     if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) {
                         return AKEY_STATE_DOWN;
                     }
@@ -478,7 +478,7 @@
 
     Device* device = getDeviceLocked(deviceId);
     if (device && device->keyMap.haveKeyLayout()) {
-        Vector<int32_t> scanCodes;
+        std::vector<int32_t> scanCodes;
         for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
             scanCodes.clear();
 
@@ -609,13 +609,15 @@
 }
 
 void EventHub::getVirtualKeyDefinitions(int32_t deviceId,
-        Vector<VirtualKeyDefinition>& outVirtualKeys) const {
+        std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
     outVirtualKeys.clear();
 
     AutoMutex _l(mLock);
     Device* device = getDeviceLocked(deviceId);
     if (device && device->virtualKeyMap) {
-        outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys());
+        const std::vector<VirtualKeyDefinition> virtualKeys =
+                device->virtualKeyMap->getVirtualKeys();
+        outVirtualKeys.insert(outVirtualKeys.end(), virtualKeys.begin(), virtualKeys.end());
     }
 }
 
@@ -1680,11 +1682,11 @@
         return false;
     }
 
-    Vector<int32_t> scanCodes;
+    std::vector<int32_t> scanCodes;
     device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
     const size_t N = scanCodes.size();
     for (size_t i=0; i<N && i<=KEY_MAX; i++) {
-        int32_t sc = scanCodes.itemAt(i);
+        int32_t sc = scanCodes[i];
         if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
             return true;
         }
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 44f7b37..63a20ef 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -228,7 +228,7 @@
     virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
 
     virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
+            std::vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
 
     virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
     virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0;
@@ -304,7 +304,7 @@
     virtual void setLedState(int32_t deviceId, int32_t led, bool on);
 
     virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const;
+            std::vector<VirtualKeyDefinition>& outVirtualKeys) const;
 
     virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
     virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map);
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index bcb1ec5..1317620 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -524,10 +524,8 @@
 sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
         int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) {
     // Traverse windows from front to back to find touched window.
-    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
-    size_t numWindows = windowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
+    const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
+    for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
         const InputWindowInfo* windowInfo = windowHandle->getInfo();
         if (windowInfo->displayId == displayId) {
             int32_t flags = windowInfo->layoutParamsFlags;
@@ -859,7 +857,7 @@
     }
 
     // Identify targets.
-    Vector<InputTarget> inputTargets;
+    std::vector<InputTarget> inputTargets;
     int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
             entry, inputTargets, nextWakeupTime);
     if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
@@ -910,7 +908,7 @@
     bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
 
     // Identify targets.
-    Vector<InputTarget> inputTargets;
+    std::vector<InputTarget> inputTargets;
 
     bool conflictingPointerActions = false;
     int32_t injectionResult;
@@ -946,11 +944,11 @@
         ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId);
         if (stateIndex >= 0) {
             const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex);
-            if (!state.portalWindows.isEmpty()) {
+            if (!state.portalWindows.empty()) {
                 // The event has gone through these portal windows, so we add monitoring targets of
                 // the corresponding displays as well.
                 for (size_t i = 0; i < state.portalWindows.size(); i++) {
-                    const InputWindowInfo* windowInfo = state.portalWindows.itemAt(i)->getInfo();
+                    const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
                     addMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
                             -windowInfo->frameLeft, -windowInfo->frameTop);
                 }
@@ -1004,7 +1002,7 @@
 }
 
 void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
-        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
+        EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) {
 #if DEBUG_DISPATCH_CYCLE
     ALOGD("dispatchEventToCurrentInputTargets");
 #endif
@@ -1013,9 +1011,7 @@
 
     pokeUserActivityLocked(eventEntry);
 
-    for (size_t i = 0; i < inputTargets.size(); i++) {
-        const InputTarget& inputTarget = inputTargets.itemAt(i);
-
+    for (const InputTarget& inputTarget : inputTargets) {
         ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
         if (connectionIndex >= 0) {
             sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
@@ -1181,7 +1177,7 @@
 }
 
 int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
-        const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
+        const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
     int32_t injectionResult;
     std::string reason;
 
@@ -1244,7 +1240,7 @@
 }
 
 int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
-        const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
+        const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
         bool* outConflictingPointerActions) {
     enum InjectionPermission {
         INJECTION_PERMISSION_UNKNOWN,
@@ -1460,8 +1456,7 @@
     // is at least one touched foreground window.
     {
         bool haveForegroundWindow = false;
-        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+        for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
             if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
                 haveForegroundWindow = true;
                 if (! checkInjectionPermission(touchedWindow.windowHandle,
@@ -1491,8 +1486,7 @@
         sp<InputWindowHandle> foregroundWindowHandle =
                 mTempTouchState.getFirstForegroundWindowHandle();
         const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
-        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+        for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
             if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
                 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
                 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
@@ -1504,8 +1498,7 @@
     }
 
     // Ensure all touched foreground windows are ready for new input.
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+    for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
         if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
             // Check whether the window is ready for more input.
             std::string reason = checkWindowReadyForMoreInputLocked(currentTime,
@@ -1528,10 +1521,9 @@
         sp<InputWindowHandle> foregroundWindowHandle =
                 mTempTouchState.getFirstForegroundWindowHandle();
         if (foregroundWindowHandle->getInfo()->hasWallpaper) {
-            const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
-            size_t numWindows = windowHandles.size();
-            for (size_t i = 0; i < numWindows; i++) {
-                sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
+            const std::vector<sp<InputWindowHandle>> windowHandles =
+                    getWindowHandlesLocked(displayId);
+            for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
                 const InputWindowInfo* info = windowHandle->getInfo();
                 if (info->displayId == displayId
                         && windowHandle->getInfo()->layoutParamsType
@@ -1549,8 +1541,7 @@
     // Success!  Output targets.
     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
 
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
+    for (const TouchedWindow& touchedWindow : mTempTouchState.windows) {
         addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
                 touchedWindow.pointerIds, inputTargets);
     }
@@ -1613,11 +1604,11 @@
                     uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
 
                     for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
-                        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
+                        TouchedWindow& touchedWindow = mTempTouchState.windows[i];
                         if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
                             touchedWindow.pointerIds.clearBit(pointerId);
                             if (touchedWindow.pointerIds.isEmpty()) {
-                                mTempTouchState.windows.removeAt(i);
+                                mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i);
                                 continue;
                             }
                         }
@@ -1664,17 +1655,15 @@
 }
 
 void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
-        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
+        int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) {
     sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
     if (inputChannel == nullptr) {
         ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
         return;
     }
 
-    inputTargets.push();
-
     const InputWindowInfo* windowInfo = windowHandle->getInfo();
-    InputTarget& target = inputTargets.editTop();
+    InputTarget target;
     target.inputChannel = inputChannel;
     target.flags = targetFlags;
     target.xOffset = - windowInfo->frameLeft;
@@ -1683,26 +1672,26 @@
     target.windowXScale = windowInfo->windowXScale;
     target.windowYScale = windowInfo->windowYScale;
     target.pointerIds = pointerIds;
+    inputTargets.push_back(target);
 }
 
-void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets,
+void InputDispatcher::addMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
         int32_t displayId, float xOffset, float yOffset) {
-    std::unordered_map<int32_t, Vector<sp<InputChannel>>>::const_iterator it =
+    std::unordered_map<int32_t, std::vector<sp<InputChannel>>>::const_iterator it =
             mMonitoringChannelsByDisplay.find(displayId);
 
     if (it != mMonitoringChannelsByDisplay.end()) {
-        const Vector<sp<InputChannel>>& monitoringChannels = it->second;
+        const std::vector<sp<InputChannel>>& monitoringChannels = it->second;
         const size_t numChannels = monitoringChannels.size();
         for (size_t i = 0; i < numChannels; i++) {
-            inputTargets.push();
-
-            InputTarget& target = inputTargets.editTop();
+            InputTarget target;
             target.inputChannel = monitoringChannels[i];
             target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
             target.xOffset = xOffset;
             target.yOffset = yOffset;
             target.pointerIds.clear();
             target.globalScaleFactor = 1.0f;
+            inputTargets.push_back(target);
         }
     } else {
         // If there is no monitor channel registered or all monitor channel unregistered,
@@ -1735,10 +1724,8 @@
 bool InputDispatcher::isWindowObscuredAtPointLocked(
         const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
     int32_t displayId = windowHandle->getInfo()->displayId;
-    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
-    size_t numWindows = windowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
+    const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
+    for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
         if (otherHandle == windowHandle) {
             break;
         }
@@ -1756,11 +1743,9 @@
 
 bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
     int32_t displayId = windowHandle->getInfo()->displayId;
-    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
+    const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
     const InputWindowInfo* windowInfo = windowHandle->getInfo();
-    size_t numWindows = windowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i);
+    for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
         if (otherHandle == windowHandle) {
             break;
         }
@@ -2333,7 +2318,7 @@
 void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked (
         const CancelationOptions& options) {
     for (auto& it : mMonitoringChannelsByDisplay) {
-        const Vector<sp<InputChannel>>& monitoringChannels = it.second;
+        const std::vector<sp<InputChannel>>& monitoringChannels = it.second;
         const size_t numChannels = monitoringChannels.size();
         for (size_t i = 0; i < numChannels; i++) {
             synthesizeCancelationEventsForInputChannelLocked(monitoringChannels[i], options);
@@ -2358,11 +2343,11 @@
 
     nsecs_t currentTime = now();
 
-    Vector<EventEntry*> cancelationEvents;
+    std::vector<EventEntry*> cancelationEvents;
     connection->inputState.synthesizeCancelationEvents(currentTime,
             cancelationEvents, options);
 
-    if (!cancelationEvents.isEmpty()) {
+    if (!cancelationEvents.empty()) {
 #if DEBUG_OUTBOUND_EVENT_DETAILS
         ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
                 "with reality: %s, mode=%d.",
@@ -2370,7 +2355,7 @@
                 options.reason, options.mode);
 #endif
         for (size_t i = 0; i < cancelationEvents.size(); i++) {
-            EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
+            EventEntry* cancelationEventEntry = cancelationEvents[i];
             switch (cancelationEventEntry->type) {
             case EventEntry::TYPE_KEY:
                 logOutboundKeyDetails("cancel - ",
@@ -3011,24 +2996,23 @@
     }
 }
 
-Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t displayId) const {
-    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>>::const_iterator it =
+std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(
+        int32_t displayId) const {
+    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>::const_iterator it =
             mWindowHandlesByDisplay.find(displayId);
     if(it != mWindowHandlesByDisplay.end()) {
         return it->second;
     }
 
     // Return an empty one if nothing found.
-    return Vector<sp<InputWindowHandle>>();
+    return std::vector<sp<InputWindowHandle>>();
 }
 
 sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
         const sp<IBinder>& windowHandleToken) const {
     for (auto& it : mWindowHandlesByDisplay) {
-        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
-        size_t numWindows = windowHandles.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
+        const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
+        for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
             if (windowHandle->getToken() == windowHandleToken) {
                 return windowHandle;
             }
@@ -3039,11 +3023,9 @@
 
 bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
     for (auto& it : mWindowHandlesByDisplay) {
-        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
-        size_t numWindows = windowHandles.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            if (windowHandles.itemAt(i)->getToken()
-                    == windowHandle->getToken()) {
+        const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
+        for (const sp<InputWindowHandle>& handle : windowHandles) {
+            if (handle->getToken() == windowHandle->getToken()) {
                 if (windowHandle->getInfo()->displayId != it.first) {
                     ALOGE("Found window %s in display %" PRId32
                             ", but it should belong to display %" PRId32,
@@ -3072,7 +3054,7 @@
  * For focused handle, check if need to change and send a cancel event to previous one.
  * For removed handle, check if need to send a cancel event if already in touch.
  */
-void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles,
+void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
         int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
 #if DEBUG_FOCUS
     ALOGD("setInputWindows displayId=%" PRId32, displayId);
@@ -3081,28 +3063,27 @@
         std::scoped_lock _l(mLock);
 
         // Copy old handles for release if they are no longer present.
-        const Vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+        const std::vector<sp<InputWindowHandle>> oldWindowHandles =
+                getWindowHandlesLocked(displayId);
 
         sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
         bool foundHoveredWindow = false;
 
-        if (inputWindowHandles.isEmpty()) {
+        if (inputWindowHandles.empty()) {
             // Remove all handles on a display if there are no windows left.
             mWindowHandlesByDisplay.erase(displayId);
         } else {
             // Since we compare the pointer of input window handles across window updates, we need
             // to make sure the handle object for the same window stays unchanged across updates.
-            const Vector<sp<InputWindowHandle>>& oldHandles = mWindowHandlesByDisplay[displayId];
+            const std::vector<sp<InputWindowHandle>>& oldHandles =
+                    mWindowHandlesByDisplay[displayId];
             std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
-            for (size_t i = 0; i < oldHandles.size(); i++) {
-                const sp<InputWindowHandle>& handle = oldHandles.itemAt(i);
+            for (const sp<InputWindowHandle>& handle : oldHandles) {
                 oldHandlesByTokens[handle->getToken()] = handle;
             }
 
-            const size_t numWindows = inputWindowHandles.size();
-            Vector<sp<InputWindowHandle>> newHandles;
-            for (size_t i = 0; i < numWindows; i++) {
-                const sp<InputWindowHandle>& handle = inputWindowHandles.itemAt(i);
+            std::vector<sp<InputWindowHandle>> newHandles;
+            for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
                 if (!handle->updateInfo() || (getInputChannelLocked(handle->getToken()) == nullptr
                         && handle->getInfo()->portalToDisplayId == ADISPLAY_ID_NONE)) {
                     ALOGE("Window handle %s has no registered input channel",
@@ -3127,8 +3108,7 @@
                 }
             }
 
-            for (size_t i = 0; i < newHandles.size(); i++) {
-                const sp<InputWindowHandle>& windowHandle = newHandles.itemAt(i);
+            for (const sp<InputWindowHandle>& windowHandle : newHandles) {
                 // Set newFocusedWindowHandle to the top most focused window instead of the last one
                 if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
                         && windowHandle->getInfo()->visible) {
@@ -3184,7 +3164,7 @@
         if (stateIndex >= 0) {
             TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
             for (size_t i = 0; i < state.windows.size(); ) {
-                TouchedWindow& touchedWindow = state.windows.editItemAt(i);
+                TouchedWindow& touchedWindow = state.windows[i];
                 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
 #if DEBUG_FOCUS
                     ALOGD("Touched window was removed: %s in display %" PRId32,
@@ -3198,7 +3178,7 @@
                         synthesizeCancelationEventsForInputChannelLocked(
                                 touchedInputChannel, options);
                     }
-                    state.windows.removeAt(i);
+                    state.windows.erase(state.windows.begin() + i);
                 } else {
                   ++i;
                 }
@@ -3209,9 +3189,7 @@
         // This ensures that unused input channels are released promptly.
         // Otherwise, they might stick around until the window handle is destroyed
         // which might not happen until the next GC.
-        size_t numWindows = oldWindowHandles.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
+        for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
             if (!hasWindowHandleLocked(oldWindowHandle)) {
 #if DEBUG_FOCUS
                 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
@@ -3415,7 +3393,7 @@
                     int32_t oldTargetFlags = touchedWindow.targetFlags;
                     BitSet32 pointerIds = touchedWindow.pointerIds;
 
-                    state.windows.removeAt(i);
+                    state.windows.erase(state.windows.begin() + i);
 
                     int32_t newTargetFlags = oldTargetFlags
                             & (InputTarget::FLAG_FOREGROUND
@@ -3531,7 +3509,7 @@
             dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
                     state.displayId, toString(state.down), toString(state.split),
                     state.deviceId, state.source);
-            if (!state.windows.isEmpty()) {
+            if (!state.windows.empty()) {
                 dump += INDENT3 "Windows:\n";
                 for (size_t i = 0; i < state.windows.size(); i++) {
                     const TouchedWindow& touchedWindow = state.windows[i];
@@ -3543,10 +3521,10 @@
             } else {
                 dump += INDENT3 "Windows: <none>\n";
             }
-            if (!state.portalWindows.isEmpty()) {
+            if (!state.portalWindows.empty()) {
                 dump += INDENT3 "Portal windows:\n";
                 for (size_t i = 0; i < state.portalWindows.size(); i++) {
-                    const sp<InputWindowHandle> portalWindowHandle = state.portalWindows.itemAt(i);
+                    const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
                     dump += StringPrintf(INDENT4 "%zu: name='%s'\n",
                             i, portalWindowHandle->getName().c_str());
                 }
@@ -3558,12 +3536,12 @@
 
     if (!mWindowHandlesByDisplay.empty()) {
        for (auto& it : mWindowHandlesByDisplay) {
-            const Vector<sp<InputWindowHandle>> windowHandles = it.second;
+            const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
             dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
-            if (!windowHandles.isEmpty()) {
+            if (!windowHandles.empty()) {
                 dump += INDENT2 "Windows:\n";
                 for (size_t i = 0; i < windowHandles.size(); i++) {
-                    const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
+                    const sp<InputWindowHandle>& windowHandle = windowHandles[i];
                     const InputWindowInfo* windowInfo = windowHandle->getInfo();
 
                     dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, "
@@ -3600,7 +3578,7 @@
 
     if (!mMonitoringChannelsByDisplay.empty()) {
        for (auto& it : mMonitoringChannelsByDisplay) {
-            const Vector<sp<InputChannel>>& monitoringChannels = it.second;
+            const std::vector<sp<InputChannel>>& monitoringChannels = it.second;
             dump += StringPrintf(INDENT "MonitoringChannels in display %" PRId32 ":\n", it.first);
             const size_t numChannels = monitoringChannels.size();
             for (size_t i = 0; i < numChannels; i++) {
@@ -3754,9 +3732,9 @@
 
         // Store monitor channel by displayId.
         if (monitor) {
-            Vector<sp<InputChannel>>& monitoringChannels =
+            std::vector<sp<InputChannel>>& monitoringChannels =
                     mMonitoringChannelsByDisplay[displayId];
-            monitoringChannels.push(inputChannel);
+            monitoringChannels.push_back(inputChannel);
         }
 
         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
@@ -3817,11 +3795,11 @@
 void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
     for (auto it = mMonitoringChannelsByDisplay.begin();
             it != mMonitoringChannelsByDisplay.end(); ) {
-        Vector<sp<InputChannel>>& monitoringChannels = it->second;
+        std::vector<sp<InputChannel>>& monitoringChannels = it->second;
         const size_t numChannels = monitoringChannels.size();
         for (size_t i = 0; i < numChannels; i++) {
              if (monitoringChannels[i] == inputChannel) {
-                 monitoringChannels.removeAt(i);
+                 monitoringChannels.erase(monitoringChannels.begin() + i);
                  break;
              }
         }
@@ -4495,13 +4473,12 @@
 }
 
 bool InputDispatcher::InputState::isNeutral() const {
-    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
+    return mKeyMementos.empty() && mMotionMementos.empty();
 }
 
 bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
         int32_t displayId) const {
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
+    for (const MotionMemento& memento : mMotionMementos) {
         if (memento.deviceId == deviceId
                 && memento.source == source
                 && memento.displayId == displayId
@@ -4527,7 +4504,7 @@
         }
         ssize_t index = findKeyMemento(entry);
         if (index >= 0) {
-            mKeyMementos.removeAt(index);
+            mKeyMementos.erase(mKeyMementos.begin() + index);
             return true;
         }
         /* FIXME: We can't just drop the key up event because that prevents creating
@@ -4552,7 +4529,7 @@
     case AKEY_EVENT_ACTION_DOWN: {
         ssize_t index = findKeyMemento(entry);
         if (index >= 0) {
-            mKeyMementos.removeAt(index);
+            mKeyMementos.erase(mKeyMementos.begin() + index);
         }
         addKeyMemento(entry, flags);
         return true;
@@ -4571,7 +4548,7 @@
     case AMOTION_EVENT_ACTION_CANCEL: {
         ssize_t index = findMotionMemento(entry, false /*hovering*/);
         if (index >= 0) {
-            mMotionMementos.removeAt(index);
+            mMotionMementos.erase(mMotionMementos.begin() + index);
             return true;
         }
 #if DEBUG_OUTBOUND_EVENT_DETAILS
@@ -4585,7 +4562,7 @@
     case AMOTION_EVENT_ACTION_DOWN: {
         ssize_t index = findMotionMemento(entry, false /*hovering*/);
         if (index >= 0) {
-            mMotionMementos.removeAt(index);
+            mMotionMementos.erase(mMotionMementos.begin() + index);
         }
         addMotionMemento(entry, flags, false /*hovering*/);
         return true;
@@ -4610,9 +4587,9 @@
             // anything generating fallback events (e.g. DPad keys for joystick movements).
             if (index >= 0) {
                 if (entry->pointerCoords[0].isEmpty()) {
-                    mMotionMementos.removeAt(index);
+                    mMotionMementos.erase(mMotionMementos.begin() + index);
                 } else {
-                    MotionMemento& memento = mMotionMementos.editItemAt(index);
+                    MotionMemento& memento = mMotionMementos[index];
                     memento.setPointers(entry);
                 }
             } else if (!entry->pointerCoords[0].isEmpty()) {
@@ -4623,7 +4600,7 @@
             return true;
         }
         if (index >= 0) {
-            MotionMemento& memento = mMotionMementos.editItemAt(index);
+            MotionMemento& memento = mMotionMementos[index];
             memento.setPointers(entry);
             return true;
         }
@@ -4638,7 +4615,7 @@
     case AMOTION_EVENT_ACTION_HOVER_EXIT: {
         ssize_t index = findMotionMemento(entry, true /*hovering*/);
         if (index >= 0) {
-            mMotionMementos.removeAt(index);
+            mMotionMementos.erase(mMotionMementos.begin() + index);
             return true;
         }
 #if DEBUG_OUTBOUND_EVENT_DETAILS
@@ -4653,7 +4630,7 @@
     case AMOTION_EVENT_ACTION_HOVER_MOVE: {
         ssize_t index = findMotionMemento(entry, true /*hovering*/);
         if (index >= 0) {
-            mMotionMementos.removeAt(index);
+            mMotionMementos.erase(mMotionMementos.begin() + index);
         }
         addMotionMemento(entry, flags, true /*hovering*/);
         return true;
@@ -4666,7 +4643,7 @@
 
 ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
     for (size_t i = 0; i < mKeyMementos.size(); i++) {
-        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        const KeyMemento& memento = mKeyMementos[i];
         if (memento.deviceId == entry->deviceId
                 && memento.source == entry->source
                 && memento.displayId == entry->displayId
@@ -4681,7 +4658,7 @@
 ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
         bool hovering) const {
     for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        const MotionMemento& memento = mMotionMementos[i];
         if (memento.deviceId == entry->deviceId
                 && memento.source == entry->source
                 && memento.displayId == entry->displayId
@@ -4693,8 +4670,7 @@
 }
 
 void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
-    mKeyMementos.push();
-    KeyMemento& memento = mKeyMementos.editTop();
+    KeyMemento memento;
     memento.deviceId = entry->deviceId;
     memento.source = entry->source;
     memento.displayId = entry->displayId;
@@ -4704,12 +4680,12 @@
     memento.flags = flags;
     memento.downTime = entry->downTime;
     memento.policyFlags = entry->policyFlags;
+    mKeyMementos.push_back(memento);
 }
 
 void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
         int32_t flags, bool hovering) {
-    mMotionMementos.push();
-    MotionMemento& memento = mMotionMementos.editTop();
+    MotionMemento memento;
     memento.deviceId = entry->deviceId;
     memento.source = entry->source;
     memento.displayId = entry->displayId;
@@ -4720,6 +4696,7 @@
     memento.setPointers(entry);
     memento.hovering = hovering;
     memento.policyFlags = entry->policyFlags;
+    mMotionMementos.push_back(memento);
 }
 
 void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
@@ -4731,23 +4708,21 @@
 }
 
 void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
-        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
-    for (size_t i = 0; i < mKeyMementos.size(); i++) {
-        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        std::vector<EventEntry*>& outEvents, const CancelationOptions& options) {
+    for (KeyMemento& memento : mKeyMementos) {
         if (shouldCancelKey(memento, options)) {
-            outEvents.push(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
+            outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
                     memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
                     AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
                     memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
         }
     }
 
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
+    for (const MotionMemento& memento : mMotionMementos) {
         if (shouldCancelMotion(memento, options)) {
             const int32_t action = memento.hovering ?
                     AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
-            outEvents.push(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
+            outEvents.push_back(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
                     memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
                     action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/,
                     MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
@@ -4766,19 +4741,19 @@
 
 void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
     for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        const MotionMemento& memento = mMotionMementos[i];
         if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
             for (size_t j = 0; j < other.mMotionMementos.size(); ) {
-                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
+                const MotionMemento& otherMemento = other.mMotionMementos[j];
                 if (memento.deviceId == otherMemento.deviceId
                         && memento.source == otherMemento.source
                         && memento.displayId == otherMemento.displayId) {
-                    other.mMotionMementos.removeAt(j);
+                    other.mMotionMementos.erase(other.mMotionMementos.begin() + j);
                 } else {
                     j += 1;
                 }
             }
-            other.mMotionMementos.push(memento);
+            other.mMotionMementos.push_back(memento);
         }
     }
 }
@@ -4940,7 +4915,7 @@
     }
 
     for (size_t i = 0; i < windows.size(); i++) {
-        TouchedWindow& touchedWindow = windows.editItemAt(i);
+        TouchedWindow& touchedWindow = windows[i];
         if (touchedWindow.windowHandle == windowHandle) {
             touchedWindow.targetFlags |= targetFlags;
             if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
@@ -4951,19 +4926,17 @@
         }
     }
 
-    windows.push();
-
-    TouchedWindow& touchedWindow = windows.editTop();
+    TouchedWindow touchedWindow;
     touchedWindow.windowHandle = windowHandle;
     touchedWindow.targetFlags = targetFlags;
     touchedWindow.pointerIds = pointerIds;
+    windows.push_back(touchedWindow);
 }
 
 void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
     size_t numWindows = portalWindows.size();
     for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> portalWindowHandle = portalWindows.itemAt(i);
-        if (portalWindowHandle == windowHandle) {
+        if (portalWindows[i] == windowHandle) {
             return;
         }
     }
@@ -4972,8 +4945,8 @@
 
 void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
     for (size_t i = 0; i < windows.size(); i++) {
-        if (windows.itemAt(i).windowHandle == windowHandle) {
-            windows.removeAt(i);
+        if (windows[i].windowHandle == windowHandle) {
+            windows.erase(windows.begin() + i);
             return;
         }
     }
@@ -4981,8 +4954,8 @@
 
 void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) {
     for (size_t i = 0; i < windows.size(); i++) {
-        if (windows.itemAt(i).windowHandle->getToken() == token) {
-            windows.removeAt(i);
+        if (windows[i].windowHandle->getToken() == token) {
+            windows.erase(windows.begin() + i);
             return;
         }
     }
@@ -4990,21 +4963,21 @@
 
 void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
     for (size_t i = 0 ; i < windows.size(); ) {
-        TouchedWindow& window = windows.editItemAt(i);
+        TouchedWindow& window = windows[i];
         if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
                 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
             window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
             window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
             i += 1;
         } else {
-            windows.removeAt(i);
+            windows.erase(windows.begin() + i);
         }
     }
 }
 
 sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
     for (size_t i = 0; i < windows.size(); i++) {
-        const TouchedWindow& window = windows.itemAt(i);
+        const TouchedWindow& window = windows[i];
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
             return window.windowHandle;
         }
@@ -5015,8 +4988,7 @@
 bool InputDispatcher::TouchState::isSlippery() const {
     // Must have exactly one foreground window.
     bool haveSlipperyForegroundWindow = false;
-    for (size_t i = 0; i < windows.size(); i++) {
-        const TouchedWindow& window = windows.itemAt(i);
+    for (const TouchedWindow& window : windows) {
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
             if (haveSlipperyForegroundWindow
                     || !(window.windowHandle->getInfo()->layoutParamsFlags
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 24ae32f..4d2c216 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -23,8 +23,6 @@
 #include <input/InputTransport.h>
 #include <input/InputWindow.h>
 #include <input/ISetInputWindowsListener.h>
-#include <utils/KeyedVector.h>
-#include <utils/Vector.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
 #include <utils/RefBase.h>
@@ -315,7 +313,7 @@
      *
      * This method may be called on any thread (usually by the input manager).
      */
-    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
+    virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles,
             int32_t displayId,
             const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
 
@@ -407,7 +405,7 @@
             int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
             uint32_t policyFlags);
 
-    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
+    virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles,
             int32_t displayId,
             const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr);
     virtual void setFocusedApplication(int32_t displayId,
@@ -762,7 +760,7 @@
 
         // Synthesizes cancelation events for the current state and resets the tracked state.
         void synthesizeCancelationEvents(nsecs_t currentTime,
-                Vector<EventEntry*>& outEvents, const CancelationOptions& options);
+                std::vector<EventEntry*>& outEvents, const CancelationOptions& options);
 
         // Clears the current state.
         void clear();
@@ -815,8 +813,8 @@
             void setPointers(const MotionEntry* entry);
         };
 
-        Vector<KeyMemento> mKeyMementos;
-        Vector<MotionMemento> mMotionMementos;
+        std::vector<KeyMemento> mKeyMementos;
+        std::vector<MotionMemento> mMotionMementos;
         KeyedVector<int32_t, int32_t> mFallbackKeys;
 
         ssize_t findKeyMemento(const KeyEntry* entry) const;
@@ -941,7 +939,7 @@
     ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
 
     // Input channels that will receive a copy of all input events sent to the provided display.
-    std::unordered_map<int32_t, Vector<sp<InputChannel>>> mMonitoringChannelsByDisplay
+    std::unordered_map<int32_t, std::vector<sp<InputChannel>>> mMonitoringChannelsByDisplay
             GUARDED_BY(mLock);
 
     // Event injection and synchronization.
@@ -998,10 +996,11 @@
     bool mDispatchFrozen GUARDED_BY(mLock);
     bool mInputFilterEnabled GUARDED_BY(mLock);
 
-    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
+    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
             GUARDED_BY(mLock);
     // Get window handles by display, return an empty vector if not found.
-    Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const REQUIRES(mLock);
+    std::vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const
+            REQUIRES(mLock);
     sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const
             REQUIRES(mLock);
     sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const REQUIRES(mLock);
@@ -1023,12 +1022,12 @@
         int32_t deviceId; // id of the device that is currently down, others are rejected
         uint32_t source;  // source of the device that is current down, others are rejected
         int32_t displayId; // id to the display that currently has a touch, others are rejected
-        Vector<TouchedWindow> windows;
+        std::vector<TouchedWindow> windows;
 
         // This collects the portal windows that the touch has gone through. Each portal window
         // targets a display (embedded display for most cases). With this info, we can add the
         // monitoring channels of the displays touched.
-        Vector<sp<InputWindowHandle>> portalWindows;
+        std::vector<sp<InputWindowHandle>> portalWindows;
 
         TouchState();
         ~TouchState();
@@ -1069,7 +1068,7 @@
             nsecs_t currentTime, MotionEntry* entry,
             DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
     void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
-            const Vector<InputTarget>& inputTargets) REQUIRES(mLock);
+            const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
 
     void logOutboundKeyDetails(const char* prefix, const KeyEntry* entry);
     void logOutboundMotionDetails(const char* prefix, const MotionEntry* entry);
@@ -1105,15 +1104,15 @@
 
     int32_t getTargetDisplayId(const EventEntry* entry);
     int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
-            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) REQUIRES(mLock);
+            std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) REQUIRES(mLock);
     int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
-            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
+            std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
             bool* outConflictingPointerActions) REQUIRES(mLock);
 
     void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
-            int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets)
+            int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets)
             REQUIRES(mLock);
-    void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets, int32_t displayId,
+    void addMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
             float xOffset = 0, float yOffset = 0) REQUIRES(mLock);
 
     void pokeUserActivityLocked(const EventEntry* eventEntry) REQUIRES(mLock);
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index a403f31..423b69c 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -229,23 +229,23 @@
 
 void QueuedInputListener::notifyConfigurationChanged(
         const NotifyConfigurationChangedArgs* args) {
-    mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
+    mArgsQueue.push_back(new NotifyConfigurationChangedArgs(*args));
 }
 
 void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
-    mArgsQueue.push(new NotifyKeyArgs(*args));
+    mArgsQueue.push_back(new NotifyKeyArgs(*args));
 }
 
 void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
-    mArgsQueue.push(new NotifyMotionArgs(*args));
+    mArgsQueue.push_back(new NotifyMotionArgs(*args));
 }
 
 void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
-    mArgsQueue.push(new NotifySwitchArgs(*args));
+    mArgsQueue.push_back(new NotifySwitchArgs(*args));
 }
 
 void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
-    mArgsQueue.push(new NotifyDeviceResetArgs(*args));
+    mArgsQueue.push_back(new NotifyDeviceResetArgs(*args));
 }
 
 void QueuedInputListener::flush() {
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index b0157a1..3996cca 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -103,14 +103,14 @@
     }
 };
 
-void InputManager::setInputWindows(const Vector<InputWindowInfo>& infos,
+void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos,
         const sp<ISetInputWindowsListener>& setInputWindowsListener) {
-    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> handlesPerDisplay;
+    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay;
 
-    Vector<sp<InputWindowHandle>> handles;
+    std::vector<sp<InputWindowHandle>> handles;
     for (const auto& info : infos) {
-        handlesPerDisplay.emplace(info.displayId, Vector<sp<InputWindowHandle>>());
-        handlesPerDisplay[info.displayId].add(new BinderWindowHandle(info));
+        handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
+        handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
     }
     for (auto const& i : handlesPerDisplay) {
         mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index ff9a080..e568df5 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -94,7 +94,7 @@
     virtual sp<InputClassifierInterface> getClassifier();
     virtual sp<InputDispatcherInterface> getDispatcher();
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& handles,
+    virtual void setInputWindows(const std::vector<InputWindowInfo>& handles,
             const sp<ISetInputWindowsListener>& setInputWindowsListener);
     virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 21ba029..a45b8a5 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -287,7 +287,7 @@
     int32_t oldGeneration;
     int32_t timeoutMillis;
     bool inputDevicesChanged = false;
-    Vector<InputDeviceInfo> inputDevices;
+    std::vector<InputDeviceInfo> inputDevices;
     { // acquire lock
         AutoMutex _l(mLock);
 
@@ -590,12 +590,13 @@
     refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
 }
 
-void InputReader::getExternalStylusDevicesLocked(Vector<InputDeviceInfo>& outDevices) {
+void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) {
     for (size_t i = 0; i < mDevices.size(); i++) {
         InputDevice* device = mDevices.valueAt(i);
         if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
-            outDevices.push();
-            device->getDeviceInfo(&outDevices.editTop());
+            InputDeviceInfo info;
+            device->getDeviceInfo(&info);
+            outDevices.push_back(info);
         }
     }
 }
@@ -643,20 +644,21 @@
     return ++mGeneration;
 }
 
-void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
+void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
     AutoMutex _l(mLock);
     getInputDevicesLocked(outInputDevices);
 }
 
-void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
+void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
     outInputDevices.clear();
 
     size_t numDevices = mDevices.size();
     for (size_t i = 0; i < numDevices; i++) {
         InputDevice* device = mDevices.valueAt(i);
         if (!device->isIgnored()) {
-            outInputDevices.push();
-            device->getDeviceInfo(&outInputDevices.editTop());
+            InputDeviceInfo info;
+            device->getDeviceInfo(&info);
+            outInputDevices.push_back(info);
         }
     }
 }
@@ -951,7 +953,7 @@
     return mReader->bumpGenerationLocked();
 }
 
-void InputReader::ContextImpl::getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) {
+void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
     // lock is already held by whatever called refreshConfigurationLocked
     mReader->getExternalStylusDevicesLocked(outDevices);
 }
@@ -1031,11 +1033,11 @@
     dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
     dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
 
-    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
-    if (!ranges.isEmpty()) {
+    const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+    if (!ranges.empty()) {
         dump += INDENT2 "Motion Ranges:\n";
         for (size_t i = 0; i < ranges.size(); i++) {
-            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
+            const InputDeviceInfo::MotionRange& range = ranges[i];
             const char* label = getAxisLabel(range.axis);
             char name[32];
             if (label) {
@@ -1059,7 +1061,7 @@
 }
 
 void InputDevice::addMapper(InputMapper* mapper) {
-    mMappers.add(mapper);
+    mMappers.push_back(mapper);
 }
 
 void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
@@ -1110,9 +1112,7 @@
             }
         }
 
-        size_t numMappers = mMappers.size();
-        for (size_t i = 0; i < numMappers; i++) {
-            InputMapper* mapper = mMappers[i];
+        for (InputMapper* mapper : mMappers) {
             mapper->configure(when, config, changes);
             mSources |= mapper->getSources();
         }
@@ -1120,9 +1120,7 @@
 }
 
 void InputDevice::reset(nsecs_t when) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->reset(when);
     }
 
@@ -1137,7 +1135,6 @@
     // have side-effects that must be interleaved.  For example, joystick movement events and
     // gamepad button presses are handled by different mappers but they should be dispatched
     // in the order received.
-    size_t numMappers = mMappers.size();
     for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
 #if DEBUG_RAW_EVENTS
         ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
@@ -1161,8 +1158,7 @@
             mDropUntilNextSync = true;
             reset(rawEvent->when);
         } else {
-            for (size_t i = 0; i < numMappers; i++) {
-                InputMapper* mapper = mMappers[i];
+            for (InputMapper* mapper : mMappers) {
                 mapper->process(rawEvent);
             }
         }
@@ -1171,17 +1167,13 @@
 }
 
 void InputDevice::timeoutExpired(nsecs_t when) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->timeoutExpired(when);
     }
 }
 
 void InputDevice::updateExternalStylusState(const StylusState& state) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->updateExternalStylusState(state);
     }
 }
@@ -1189,9 +1181,7 @@
 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
     outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
             mIsExternal, mHasMic);
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->populateDeviceInfo(outDeviceInfo);
     }
 }
@@ -1210,9 +1200,7 @@
 
 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
     int32_t result = AKEY_STATE_UNKNOWN;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
             // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
             // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
@@ -1230,9 +1218,7 @@
 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
         const int32_t* keyCodes, uint8_t* outFlags) {
     bool result = false;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
             result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
         }
@@ -1242,50 +1228,39 @@
 
 void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
         int32_t token) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->vibrate(pattern, patternSize, repeat, token);
     }
 }
 
 void InputDevice::cancelVibrate(int32_t token) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->cancelVibrate(token);
     }
 }
 
 void InputDevice::cancelTouch(nsecs_t when) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->cancelTouch(when);
     }
 }
 
 int32_t InputDevice::getMetaState() {
     int32_t result = 0;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         result |= mapper->getMetaState();
     }
     return result;
 }
 
 void InputDevice::updateMetaState(int32_t keyCode) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        mMappers[i]->updateMetaState(keyCode);
+    for (InputMapper* mapper : mMappers) {
+        mapper->updateMetaState(keyCode);
     }
 }
 
 void InputDevice::fadePointer() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         mapper->fadePointer();
     }
 }
@@ -1300,9 +1275,7 @@
 }
 
 std::optional<int32_t> InputDevice::getAssociatedDisplay() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
+    for (InputMapper* mapper : mMappers) {
         std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplay();
         if (associatedDisplayId) {
             return associatedDisplayId;
@@ -2405,7 +2378,7 @@
         ssize_t keyDownIndex = findKeyDown(scanCode);
         if (keyDownIndex >= 0) {
             // key repeat, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+            keyCode = mKeyDowns[keyDownIndex].keyCode;
         } else {
             // key down
             if ((policyFlags & POLICY_FLAG_VIRTUAL)
@@ -2417,10 +2390,10 @@
                 mDevice->cancelTouch(when);
             }
 
-            mKeyDowns.push();
-            KeyDown& keyDown = mKeyDowns.editTop();
+            KeyDown keyDown;
             keyDown.keyCode = keyCode;
             keyDown.scanCode = scanCode;
+            mKeyDowns.push_back(keyDown);
         }
 
         mDownTime = when;
@@ -2429,8 +2402,8 @@
         ssize_t keyDownIndex = findKeyDown(scanCode);
         if (keyDownIndex >= 0) {
             // key up, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
-            mKeyDowns.removeAt(size_t(keyDownIndex));
+            keyCode = mKeyDowns[keyDownIndex].keyCode;
+            mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex);
         } else {
             // key was not actually down
             ALOGI("Dropping key up from device %s because the key was not down.  "
@@ -3316,9 +3289,9 @@
 }
 
 void TouchInputMapper::resolveExternalStylusPresence() {
-    Vector<InputDeviceInfo> devices;
+    std::vector<InputDeviceInfo> devices;
     mContext->getExternalStylusDevices(devices);
-    mExternalStylusConnected = !devices.isEmpty();
+    mExternalStylusConnected = !devices.empty();
 
     if (!mExternalStylusConnected) {
         resetExternalStylus();
@@ -3967,7 +3940,7 @@
 }
 
 void TouchInputMapper::configureVirtualKeys() {
-    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
+    std::vector<VirtualKeyDefinition> virtualKeyDefinitions;
     getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
 
     mVirtualKeys.clear();
@@ -3976,19 +3949,13 @@
         return;
     }
 
-    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
-
     int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
     int32_t touchScreenTop = mRawPointerAxes.y.minValue;
     int32_t touchScreenWidth = mRawPointerAxes.getRawWidth();
     int32_t touchScreenHeight = mRawPointerAxes.getRawHeight();
 
-    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
-        const VirtualKeyDefinition& virtualKeyDefinition =
-                virtualKeyDefinitions[i];
-
-        mVirtualKeys.add();
-        VirtualKey& virtualKey = mVirtualKeys.editTop();
+    for (const VirtualKeyDefinition& virtualKeyDefinition : virtualKeyDefinitions) {
+        VirtualKey virtualKey;
 
         virtualKey.scanCode = virtualKeyDefinition.scanCode;
         int32_t keyCode;
@@ -3998,8 +3965,7 @@
                                   &keyCode, &dummyKeyMetaState, &flags)) {
             ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
                     virtualKey.scanCode);
-            mVirtualKeys.pop(); // drop the key
-            continue;
+            continue; // drop the key
         }
 
         virtualKey.keyCode = keyCode;
@@ -4017,15 +3983,16 @@
                 * touchScreenHeight / mSurfaceHeight + touchScreenTop;
         virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
                 * touchScreenHeight / mSurfaceHeight + touchScreenTop;
+        mVirtualKeys.push_back(virtualKey);
     }
 }
 
 void TouchInputMapper::dumpVirtualKeys(std::string& dump) {
-    if (!mVirtualKeys.isEmpty()) {
+    if (!mVirtualKeys.empty()) {
         dump += INDENT3 "Virtual Keys:\n";
 
         for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
+            const VirtualKey& virtualKey = mVirtualKeys[i];
             dump += StringPrintf(INDENT4 "%zu: scanCode=%d, keyCode=%d, "
                     "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
                     i, virtualKey.scanCode, virtualKey.keyCode,
@@ -4347,7 +4314,8 @@
     nsecs_t timeSinceLastReport = now - mStatistics.lastReportTime;
     if (timeSinceLastReport > STATISTICS_REPORT_FREQUENCY) {
         android::util::stats_write(android::util::TOUCH_EVENT_REPORTED,
-                mStatistics.min, mStatistics.max, mStatistics.mean(), mStatistics.stdev());
+                mStatistics.min, mStatistics.max,
+                mStatistics.mean(), mStatistics.stdev(), mStatistics.count);
         mStatistics.reset(now);
     }
 }
@@ -4364,12 +4332,13 @@
 }
 
 void TouchInputMapper::sync(nsecs_t when) {
-    const RawState* last = mRawStatesPending.isEmpty() ?
-            &mCurrentRawState : &mRawStatesPending.top();
+    const RawState* last = mRawStatesPending.empty() ?
+            &mCurrentRawState : &mRawStatesPending.back();
 
     // Push a new state.
-    mRawStatesPending.push();
-    RawState* next = &mRawStatesPending.editTop();
+    mRawStatesPending.emplace_back();
+
+    RawState* next = &mRawStatesPending.back();
     next->clear();
     next->when = when;
 
@@ -4436,7 +4405,7 @@
         cookAndDispatch(mCurrentRawState.when);
     }
     if (count != 0) {
-        mRawStatesPending.removeItemsAt(0, count);
+        mRawStatesPending.erase(mRawStatesPending.begin(), mRawStatesPending.begin() + count);
     }
 
     if (mExternalStylusDataPending) {
@@ -6623,12 +6592,9 @@
             && scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
 }
 
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
-        int32_t x, int32_t y) {
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
 
+    for (const VirtualKey& virtualKey: mVirtualKeys) {
 #if DEBUG_VIRTUAL_KEYS
         ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
                 "left=%d, top=%d, right=%d, bottom=%d",
@@ -6838,9 +6804,7 @@
         return AKEY_STATE_VIRTUAL;
     }
 
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
+    for (const VirtualKey& virtualKey : mVirtualKeys) {
         if (virtualKey.keyCode == keyCode) {
             return AKEY_STATE_UP;
         }
@@ -6854,9 +6818,7 @@
         return AKEY_STATE_VIRTUAL;
     }
 
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
+    for (const VirtualKey& virtualKey : mVirtualKeys) {
         if (virtualKey.scanCode == scanCode) {
             return AKEY_STATE_UP;
         }
@@ -6867,10 +6829,7 @@
 
 bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
         const int32_t* keyCodes, uint8_t* outFlags) {
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
-
+    for (const VirtualKey& virtualKey : mVirtualKeys) {
         for (size_t i = 0; i < numCodes; i++) {
             if (virtualKey.keyCode == keyCodes[i]) {
                 outFlags[i] = 1;
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index fed55ac..9777779 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -90,7 +90,7 @@
     virtual void requestTimeoutAtTime(nsecs_t when) = 0;
     virtual int32_t bumpGeneration() = 0;
 
-    virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) = 0;
+    virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) = 0;
     virtual void dispatchExternalStylusState(const StylusState& outState) = 0;
 
     virtual InputReaderPolicyInterface* getPolicy() = 0;
@@ -124,7 +124,7 @@
 
     virtual void loopOnce();
 
-    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices);
+    virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices);
 
     virtual bool isInputDeviceEnabled(int32_t deviceId);
 
@@ -166,7 +166,7 @@
         virtual void fadePointer();
         virtual void requestTimeoutAtTime(nsecs_t when);
         virtual int32_t bumpGeneration();
-        virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices);
+        virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices);
         virtual void dispatchExternalStylusState(const StylusState& outState);
         virtual InputReaderPolicyInterface* getPolicy();
         virtual InputListenerInterface* getListener();
@@ -211,7 +211,7 @@
     int32_t getGlobalMetaStateLocked();
 
     void notifyExternalStylusPresenceChanged();
-    void getExternalStylusDevicesLocked(Vector<InputDeviceInfo>& outDevices);
+    void getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices);
     void dispatchExternalStylusState(const StylusState& state);
 
     void fadePointerLocked();
@@ -219,7 +219,7 @@
     int32_t mGeneration;
     int32_t bumpGenerationLocked();
 
-    void getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices);
+    void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices);
 
     nsecs_t mDisableVirtualKeysTimeout;
     void disableVirtualKeysUntilLocked(nsecs_t time);
@@ -266,7 +266,7 @@
     inline void setMic(bool hasMic) { mHasMic = hasMic; }
     inline bool hasMic() const { return mHasMic; }
 
-    inline bool isIgnored() { return mMappers.isEmpty(); }
+    inline bool isIgnored() { return mMappers.empty(); }
 
     bool isEnabled();
     void setEnabled(bool enabled, nsecs_t when);
@@ -331,7 +331,7 @@
     std::string mAlias;
     uint32_t mClasses;
 
-    Vector<InputMapper*> mMappers;
+    std::vector<InputMapper*> mMappers;
 
     uint32_t mSources;
     bool mIsExternal;
@@ -877,7 +877,7 @@
     uint32_t mSource;
     int32_t mKeyboardType;
 
-    Vector<KeyDown> mKeyDowns; // keys that are down
+    std::vector<KeyDown> mKeyDowns; // keys that are down
     int32_t mMetaState;
     nsecs_t mDownTime; // time of most recent key down
 
@@ -1235,7 +1235,7 @@
         }
     };
 
-    Vector<RawState> mRawStatesPending;
+    std::vector<RawState> mRawStatesPending;
     RawState mCurrentRawState;
     CookedState mCurrentCookedState;
     RawState mLastRawState;
@@ -1262,7 +1262,7 @@
     // The pointer controller, or null if the device is not a pointer.
     sp<PointerControllerInterface> mPointerController;
 
-    Vector<VirtualKey> mVirtualKeys;
+    std::vector<VirtualKey> mVirtualKeys;
 
     virtual void configureParameters();
     virtual void dumpParameters(std::string& dump);
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index a00b5fb..d8b352c 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -40,7 +40,8 @@
     InputFlinger() ANDROID_API;
 
     virtual status_t dump(int fd, const Vector<String16>& args);
-    void setInputWindows(const Vector<InputWindowInfo>&, const sp<ISetInputWindowsListener>&) {}
+    void setInputWindows(const std::vector<InputWindowInfo>&,
+            const sp<ISetInputWindowsListener>&) {}
     void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}
     void registerInputChannel(const sp<InputChannel>&) {}
     void unregisterInputChannel(const sp<InputChannel>&) {}
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index cd8caf7..b51dcb6 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -221,7 +221,7 @@
 
 private:
     sp<InputListenerInterface> mInnerListener;
-    Vector<NotifyArgs*> mArgsQueue;
+    std::vector<NotifyArgs*> mArgsQueue;
 };
 
 } // namespace android
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index fe1d4d0..8ad5dd0 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -74,7 +74,7 @@
      *
      * This method may be called on any thread (usually by the input manager).
      */
-    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0;
+    virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) = 0;
 
     /* Query current input state. */
     virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
@@ -333,7 +333,7 @@
     /* Notifies the input reader policy that some input devices have changed
      * and provides information about all current input devices.
      */
-    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
+    virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) = 0;
 
     /* Gets the keyboard layout for a particular input device. */
     virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 3b6fe52..d63ff8c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -571,8 +571,8 @@
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
             ADISPLAY_ID_DEFAULT);
 
-    Vector<sp<InputWindowHandle>> inputWindowHandles;
-    inputWindowHandles.add(window);
+    std::vector<sp<InputWindowHandle>> inputWindowHandles;
+    inputWindowHandles.push_back(window);
 
     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
@@ -591,9 +591,9 @@
     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
             ADISPLAY_ID_DEFAULT);
 
-    Vector<sp<InputWindowHandle>> inputWindowHandles;
-    inputWindowHandles.add(windowTop);
-    inputWindowHandles.add(windowSecond);
+    std::vector<sp<InputWindowHandle>> inputWindowHandles;
+    inputWindowHandles.push_back(windowTop);
+    inputWindowHandles.push_back(windowSecond);
 
     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
@@ -617,9 +617,9 @@
 
     // Expect one focus window exist in display.
     windowSecond->setFocus();
-    Vector<sp<InputWindowHandle>> inputWindowHandles;
-    inputWindowHandles.add(windowTop);
-    inputWindowHandles.add(windowSecond);
+    std::vector<sp<InputWindowHandle>> inputWindowHandles;
+    inputWindowHandles.push_back(windowTop);
+    inputWindowHandles.push_back(windowSecond);
 
     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -643,9 +643,9 @@
     // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
     windowTop->setFocus();
     windowSecond->setFocus();
-    Vector<sp<InputWindowHandle>> inputWindowHandles;
-    inputWindowHandles.add(windowTop);
-    inputWindowHandles.add(windowSecond);
+    std::vector<sp<InputWindowHandle>> inputWindowHandles;
+    inputWindowHandles.push_back(windowTop);
+    inputWindowHandles.push_back(windowSecond);
 
     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -669,9 +669,9 @@
 
     windowTop->setFocus();
     windowSecond->setFocus();
-    Vector<sp<InputWindowHandle>> inputWindowHandles;
-    inputWindowHandles.add(windowTop);
-    inputWindowHandles.add(windowSecond);
+    std::vector<sp<InputWindowHandle>> inputWindowHandles;
+    inputWindowHandles.push_back(windowTop);
+    inputWindowHandles.push_back(windowSecond);
     // Release channel for window is no longer valid.
     windowTop->releaseChannel();
     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
@@ -695,8 +695,8 @@
         application1 = new FakeApplicationHandle();
         windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
                 ADISPLAY_ID_DEFAULT);
-        Vector<sp<InputWindowHandle>> inputWindowHandles;
-        inputWindowHandles.push(windowInPrimary);
+        std::vector<sp<InputWindowHandle>> inputWindowHandles;
+        inputWindowHandles.push_back(windowInPrimary);
         // Set focus window for primary display, but focused display would be second one.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
         windowInPrimary->setFocus();
@@ -706,8 +706,8 @@
         windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
                 SECOND_DISPLAY_ID);
         // Set focus to second display window.
-        Vector<sp<InputWindowHandle>> inputWindowHandles_Second;
-        inputWindowHandles_Second.push(windowInSecondary);
+        std::vector<sp<InputWindowHandle>> inputWindowHandles_Second;
+        inputWindowHandles_Second.push_back(windowInSecondary);
         // Set focus display to second one.
         mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
         // Set focus window for second display.
@@ -762,7 +762,7 @@
     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
 
     // Remove secondary display.
-    Vector<sp<InputWindowHandle>> noWindows;
+    std::vector<sp<InputWindowHandle>> noWindows;
     mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID);
 
     // Expect old focus should receive a cancel event.
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 80a55f1..d353028 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -158,7 +158,7 @@
 class FakeInputReaderPolicy : public InputReaderPolicyInterface {
     InputReaderConfiguration mConfig;
     KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
-    Vector<InputDeviceInfo> mInputDevices;
+    std::vector<InputDeviceInfo> mInputDevices;
     std::vector<DisplayViewport> mViewports;
     TouchAffineTransformation transform;
 
@@ -226,7 +226,7 @@
         return &mConfig;
     }
 
-    const Vector<InputDeviceInfo>& getInputDevices() const {
+    const std::vector<InputDeviceInfo>& getInputDevices() const {
         return mInputDevices;
     }
 
@@ -280,7 +280,7 @@
         return mPointerControllers.valueFor(deviceId);
     }
 
-    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
+    virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
         mInputDevices = inputDevices;
     }
 
@@ -314,7 +314,7 @@
         KeyedVector<int32_t, KeyInfo> keysByScanCode;
         KeyedVector<int32_t, KeyInfo> keysByUsageCode;
         KeyedVector<int32_t, bool> leds;
-        Vector<VirtualKeyDefinition> virtualKeys;
+        std::vector<VirtualKeyDefinition> virtualKeys;
         bool enabled;
 
         status_t enable() {
@@ -482,7 +482,7 @@
 
     void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
         Device* device = getDevice(deviceId);
-        device->virtualKeys.push(definition);
+        device->virtualKeys.push_back(definition);
     }
 
     void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
@@ -728,12 +728,12 @@
     }
 
     virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const {
+            std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
         outVirtualKeys.clear();
 
         Device* device = getDevice(deviceId);
         if (device) {
-            outVirtualKeys.appendVector(device->virtualKeys);
+            outVirtualKeys = device->virtualKeys;
         }
     }
 
@@ -842,7 +842,7 @@
         return ++mGeneration;
     }
 
-    virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) {
+    virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) {
 
     }
 
@@ -865,7 +865,7 @@
     KeyedVector<int32_t, int32_t> mKeyCodeStates;
     KeyedVector<int32_t, int32_t> mScanCodeStates;
     KeyedVector<int32_t, int32_t> mSwitchStates;
-    Vector<int32_t> mSupportedKeyCodes;
+    std::vector<int32_t> mSupportedKeyCodes;
     RawEvent mLastEvent;
 
     bool mConfigureWasCalled;
@@ -925,7 +925,7 @@
     }
 
     void addSupportedKeyCode(int32_t keyCode) {
-        mSupportedKeyCodes.add(keyCode);
+        mSupportedKeyCodes.push_back(keyCode);
     }
 
 private:
@@ -1309,7 +1309,7 @@
             0, nullptr)); // no classes so device will be ignored
 
 
-    Vector<InputDeviceInfo> inputDevices;
+    std::vector<InputDeviceInfo> inputDevices;
     mReader->getInputDevices(inputDevices);
 
     ASSERT_EQ(1U, inputDevices.size());
@@ -4436,7 +4436,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
     ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
 
-    // airbrush
+    // air-brush
     processKey(mapper, BTN_TOOL_PENCIL, 0);
     processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
     processSync(mapper);
@@ -5943,7 +5943,7 @@
     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
     ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
 
-    // airbrush
+    // air-brush
     processKey(mapper, BTN_TOOL_PENCIL, 0);
     processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
     processSync(mapper);
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index cc78ece..f2d4c51 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -323,7 +323,8 @@
                                        mCurrentTextureBuffer == nullptr
                                                ? nullptr
                                                : mCurrentTextureBuffer->graphicBuffer(),
-                                       mCurrentCrop, mCurrentTransform, mFilteringEnabled);
+                                       getCurrentCropLocked(), mCurrentTransform,
+                                       mFilteringEnabled);
 }
 
 nsecs_t BufferLayerConsumer::getTimestamp() {
@@ -380,6 +381,10 @@
 
 Rect BufferLayerConsumer::getCurrentCrop() const {
     Mutex::Autolock lock(mMutex);
+    return getCurrentCropLocked();
+}
+
+Rect BufferLayerConsumer::getCurrentCropLocked() const {
     return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
             ? GLConsumer::scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight)
             : mCurrentCrop;
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 32ccfbb..f4ca846 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -253,6 +253,9 @@
     // access the current texture buffer.
     status_t doFenceWaitLocked() const;
 
+    // getCurrentCropLocked returns the cropping rectangle of the current buffer.
+    Rect getCurrentCropLocked() const;
+
     // The default consumer usage flags that BufferLayerConsumer always sets on its
     // BufferQueue instance; these will be OR:d with any additional flags passed
     // from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 1ca0b02..5efa4e0 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -139,7 +139,6 @@
 
 bool BufferStateLayer::setTransform(uint32_t transform) {
     if (mCurrentState.transform == transform) return false;
-    mCurrentState.sequence++;
     mCurrentState.transform = transform;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -170,7 +169,6 @@
     }
 
     if (mCurrentState.crop == c) return false;
-    mCurrentState.sequence++;
     mCurrentState.crop = c;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -242,7 +240,6 @@
 
 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
     if (mCurrentState.hdrMetadata == hdrMetadata) return false;
-    mCurrentState.sequence++;
     mCurrentState.hdrMetadata = hdrMetadata;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -250,7 +247,6 @@
 }
 
 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
-    mCurrentState.sequence++;
     mCurrentState.surfaceDamageRegion = surfaceDamage;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -259,7 +255,6 @@
 
 bool BufferStateLayer::setApi(int32_t api) {
     if (mCurrentState.api == api) return false;
-    mCurrentState.sequence++;
     mCurrentState.api = api;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -268,7 +263,6 @@
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
     if (mCurrentState.sidebandStream == sidebandStream) return false;
-    mCurrentState.sequence++;
     mCurrentState.sidebandStream = sidebandStream;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -551,6 +545,8 @@
     mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
     mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
 
+    mCurrentStateModified = false;
+
     return NO_ERROR;
 }
 
@@ -600,7 +596,6 @@
               s.buffer->handle, to_string(error).c_str(), static_cast<int32_t>(error));
     }
 
-    mCurrentStateModified = false;
     mFrameNumber++;
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 512a0b4..898d37e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1788,9 +1788,13 @@
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+    return getRoundedCornerStateInternal(mSourceBounds);
+}
+
+Layer::RoundedCornerState Layer::getRoundedCornerStateInternal(const FloatRect bounds) const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        RoundedCornerState parentState = p->getRoundedCornerState();
+        RoundedCornerState parentState = p->getRoundedCornerStateInternal(bounds);
         if (parentState.radius > 0) {
             ui::Transform t = getActiveTransform(getDrawingState());
             t = t.inverse();
@@ -1804,7 +1808,9 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(getBounds(), radius) : RoundedCornerState();
+    return radius > 0
+            ? RoundedCornerState(bounds.intersect(getCrop(getDrawingState()).toFloatRect()), radius)
+            : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -1839,7 +1845,8 @@
     setTransactionFlags(eTransactionNeeded);
 }
 
-void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
+void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet,
+                         uint32_t traceFlags) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
     const State& state = useDrawing ? mDrawingState : mCurrentState;
@@ -1847,114 +1854,129 @@
     ui::Transform requestedTransform = state.active_legacy.transform;
     ui::Transform transform = getTransform();
 
-    layerInfo->set_id(sequence);
-    layerInfo->set_name(getName().c_str());
-    layerInfo->set_type(String8(getTypeId()));
+    if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
+        layerInfo->set_id(sequence);
+        layerInfo->set_name(getName().c_str());
+        layerInfo->set_type(String8(getTypeId()));
 
-    for (const auto& child : children) {
-        layerInfo->add_children(child->sequence);
-    }
-
-    for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
-        sp<Layer> strongRelative = weakRelative.promote();
-        if (strongRelative != nullptr) {
-            layerInfo->add_relatives(strongRelative->sequence);
+        for (const auto& child : children) {
+            layerInfo->add_children(child->sequence);
         }
-    }
 
-    LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
-                                   [&]() { return layerInfo->mutable_transparent_region(); });
-    LayerProtoHelper::writeToProto(visibleRegion,
-                                   [&]() { return layerInfo->mutable_visible_region(); });
-    LayerProtoHelper::writeToProto(surfaceDamageRegion,
-                                   [&]() { return layerInfo->mutable_damage_region(); });
-
-    layerInfo->set_layer_stack(getLayerStack());
-    layerInfo->set_z(state.z);
-
-    LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
-                                           [&]() { return layerInfo->mutable_position(); });
-
-    LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(), [&]() {
-        return layerInfo->mutable_requested_position();
-    });
-
-    LayerProtoHelper::writeSizeToProto(state.active_legacy.w, state.active_legacy.h,
-                                       [&]() { return layerInfo->mutable_size(); });
-
-    LayerProtoHelper::writeToProto(state.crop_legacy, [&]() { return layerInfo->mutable_crop(); });
-    layerInfo->set_corner_radius(getRoundedCornerState().radius);
-
-    layerInfo->set_is_opaque(isOpaque(state));
-    layerInfo->set_invalidate(contentDirty);
-
-    // XXX (b/79210409) mCurrentDataSpace is not protected
-    layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
-
-    layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
-    LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
-    LayerProtoHelper::writeToProto(state.color,
-                                   [&]() { return layerInfo->mutable_requested_color(); });
-    layerInfo->set_flags(state.flags);
-
-    LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
-    LayerProtoHelper::writeToProto(requestedTransform, layerInfo->mutable_requested_transform());
-
-    auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
-    if (parent != nullptr) {
-        layerInfo->set_parent(parent->sequence);
-    } else {
-        layerInfo->set_parent(-1);
-    }
-
-    auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
-    if (zOrderRelativeOf != nullptr) {
-        layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
-    } else {
-        layerInfo->set_z_order_relative_of(-1);
-    }
-
-    auto buffer = mActiveBuffer;
-    if (buffer != nullptr) {
-        LayerProtoHelper::writeToProto(buffer,
-                                       [&]() { return layerInfo->mutable_active_buffer(); });
-        LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform),
-                                       layerInfo->mutable_buffer_transform());
-    }
-
-    layerInfo->set_queued_frames(getQueuedFrameCount());
-    layerInfo->set_refresh_pending(isBufferLatched());
-    layerInfo->set_curr_frame(mCurrentFrameNumber);
-    layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
-
-    for (const auto& pendingState : mPendingStates) {
-        auto barrierLayer = pendingState.barrierLayer_legacy.promote();
-        if (barrierLayer != nullptr) {
-            BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
-            barrierLayerProto->set_id(barrierLayer->sequence);
-            barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy);
+        for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
+            sp<Layer> strongRelative = weakRelative.promote();
+            if (strongRelative != nullptr) {
+                layerInfo->add_relatives(strongRelative->sequence);
+            }
         }
+
+        LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
+                                       [&]() { return layerInfo->mutable_transparent_region(); });
+        LayerProtoHelper::writeToProto(visibleRegion,
+                                       [&]() { return layerInfo->mutable_visible_region(); });
+        LayerProtoHelper::writeToProto(surfaceDamageRegion,
+                                       [&]() { return layerInfo->mutable_damage_region(); });
+
+        layerInfo->set_layer_stack(getLayerStack());
+        layerInfo->set_z(state.z);
+
+        LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
+                                               [&]() { return layerInfo->mutable_position(); });
+
+        LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(),
+                                               [&]() {
+                                                   return layerInfo->mutable_requested_position();
+                                               });
+
+        LayerProtoHelper::writeSizeToProto(state.active_legacy.w, state.active_legacy.h,
+                                           [&]() { return layerInfo->mutable_size(); });
+
+        LayerProtoHelper::writeToProto(state.crop_legacy,
+                                       [&]() { return layerInfo->mutable_crop(); });
+        layerInfo->set_corner_radius(getRoundedCornerState().radius);
+
+        layerInfo->set_is_opaque(isOpaque(state));
+        layerInfo->set_invalidate(contentDirty);
+
+        // XXX (b/79210409) mCurrentDataSpace is not protected
+        layerInfo->set_dataspace(
+                dataspaceDetails(static_cast<android_dataspace>(mCurrentDataSpace)));
+
+        layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
+        LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
+        LayerProtoHelper::writeToProto(state.color,
+                                       [&]() { return layerInfo->mutable_requested_color(); });
+        layerInfo->set_flags(state.flags);
+
+        LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
+        LayerProtoHelper::writeToProto(requestedTransform,
+                                       layerInfo->mutable_requested_transform());
+
+        auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
+        if (parent != nullptr) {
+            layerInfo->set_parent(parent->sequence);
+        } else {
+            layerInfo->set_parent(-1);
+        }
+
+        auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
+        if (zOrderRelativeOf != nullptr) {
+            layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
+        } else {
+            layerInfo->set_z_order_relative_of(-1);
+        }
+
+        auto buffer = mActiveBuffer;
+        if (buffer != nullptr) {
+            LayerProtoHelper::writeToProto(buffer,
+                                           [&]() { return layerInfo->mutable_active_buffer(); });
+            LayerProtoHelper::writeToProto(ui::Transform(mCurrentTransform),
+                                           layerInfo->mutable_buffer_transform());
+        }
+
+        layerInfo->set_queued_frames(getQueuedFrameCount());
+        layerInfo->set_refresh_pending(isBufferLatched());
+        layerInfo->set_curr_frame(mCurrentFrameNumber);
+        layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
+
+        for (const auto& pendingState : mPendingStates) {
+            auto barrierLayer = pendingState.barrierLayer_legacy.promote();
+            if (barrierLayer != nullptr) {
+                BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
+                barrierLayerProto->set_id(barrierLayer->sequence);
+                barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy);
+            }
+        }
+        LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
     }
 
-    auto protoMap = layerInfo->mutable_metadata();
-    for (const auto& entry : state.metadata.mMap) {
-        (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
+    if (traceFlags & SurfaceTracing::TRACE_INPUT) {
+        LayerProtoHelper::writeToProto(state.inputInfo, state.touchableRegionCrop,
+                                       [&]() { return layerInfo->mutable_input_window_info(); });
     }
-    LayerProtoHelper::writeToProto(mEffectiveTransform, layerInfo->mutable_effective_transform());
-    LayerProtoHelper::writeToProto(mSourceBounds,
-                                   [&]() { return layerInfo->mutable_source_bounds(); });
-    LayerProtoHelper::writeToProto(mScreenBounds,
-                                   [&]() { return layerInfo->mutable_screen_bounds(); });
-    LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
+
+    if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
+        auto protoMap = layerInfo->mutable_metadata();
+        for (const auto& entry : state.metadata.mMap) {
+            (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
+        }
+        LayerProtoHelper::writeToProto(mEffectiveTransform,
+                                       layerInfo->mutable_effective_transform());
+        LayerProtoHelper::writeToProto(mSourceBounds,
+                                       [&]() { return layerInfo->mutable_source_bounds(); });
+        LayerProtoHelper::writeToProto(mScreenBounds,
+                                       [&]() { return layerInfo->mutable_screen_bounds(); });
+    }
 }
 
-void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice) {
+void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice,
+                         uint32_t traceFlags) {
     auto outputLayer = findOutputLayerForDisplay(displayDevice);
     if (!outputLayer) {
         return;
     }
 
-    writeToProto(layerInfo, LayerVector::StateSet::Drawing);
+    writeToProto(layerInfo, LayerVector::StateSet::Drawing, traceFlags);
 
     const auto& compositionState = outputLayer->getState();
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 89063da..83ff3b6 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -433,10 +433,11 @@
 
     bool isRemovedFromCurrentState() const;
 
-    void writeToProto(LayerProto* layerInfo,
-                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
+    void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet,
+                      uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
 
-    void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice);
+    void writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice,
+                      uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
 
     virtual Geometry getActiveGeometry(const Layer::State& s) const { return s.active_legacy; }
     virtual uint32_t getActiveWidth(const Layer::State& s) const { return s.active_legacy.w; }
@@ -907,6 +908,8 @@
      */
     Rect getCroppedBufferSize(const Layer::State& s) const;
 
+    RoundedCornerState getRoundedCornerStateInternal(const FloatRect bounds) const;
+
     // Cached properties computed from drawing state
     // Effective transform taking into account parent transforms and any parent scaling.
     ui::Transform mEffectiveTransform;
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index c25c418..c94e439 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -119,5 +119,41 @@
     }
 }
 
+void LayerProtoHelper::writeToProto(
+        const InputWindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
+        std::function<InputWindowInfoProto*()> getInputWindowInfoProto) {
+    if (inputInfo.token == nullptr) {
+        return;
+    }
+
+    InputWindowInfoProto* proto = getInputWindowInfoProto();
+    proto->set_layout_params_flags(inputInfo.layoutParamsFlags);
+    proto->set_layout_params_type(inputInfo.layoutParamsType);
+
+    LayerProtoHelper::writeToProto({inputInfo.frameLeft, inputInfo.frameTop, inputInfo.frameRight,
+                                    inputInfo.frameBottom},
+                                   [&]() { return proto->mutable_frame(); });
+    LayerProtoHelper::writeToProto(inputInfo.touchableRegion,
+                                   [&]() { return proto->mutable_touchable_region(); });
+
+    proto->set_surface_inset(inputInfo.surfaceInset);
+    proto->set_visible(inputInfo.visible);
+    proto->set_can_receive_keys(inputInfo.canReceiveKeys);
+    proto->set_has_focus(inputInfo.hasFocus);
+    proto->set_has_wallpaper(inputInfo.hasWallpaper);
+
+    proto->set_global_scale_factor(inputInfo.globalScaleFactor);
+    proto->set_window_x_scale(inputInfo.windowXScale);
+    proto->set_window_y_scale(inputInfo.windowYScale);
+    proto->set_replace_touchable_region_with_crop(inputInfo.replaceTouchableRegionWithCrop);
+    auto cropLayer = touchableRegionBounds.promote();
+    if (cropLayer != nullptr) {
+        proto->set_crop_layer_id(cropLayer->sequence);
+        LayerProtoHelper::writeToProto(cropLayer->getScreenBounds(
+                                               false /* reduceTransparentRegion */),
+                                       [&]() { return proto->mutable_touchable_region_crop(); });
+    }
+}
+
 } // namespace surfaceflinger
 } // namespace android
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index dca9a5e..1754a3f 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -16,6 +16,8 @@
 
 #include <layerproto/LayerProtoHeader.h>
 
+#include <Layer.h>
+#include <input/InputWindow.h>
 #include <math/vec4.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
@@ -38,6 +40,9 @@
     static void writeToProto(const ui::Transform& transform, TransformProto* transformProto);
     static void writeToProto(const sp<GraphicBuffer>& buffer,
                              std::function<ActiveBufferProto*()> getActiveBufferProto);
+    static void writeToProto(const InputWindowInfo& inputInfo,
+                             const wp<Layer>& touchableRegionBounds,
+                             std::function<InputWindowInfoProto*()> getInputWindowInfoProto);
 };
 
 } // namespace surfaceflinger
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index 5296da9..6599f9e 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -789,31 +789,6 @@
     StringAppendF(&result, "current monotonic time: %" PRId64 "\n", now);
 }
 
-// TODO(b/113612090): Figure out how much of this is still relevant.
-// We need to determine the time when a buffer acquired now will be
-// displayed.  This can be calculated:
-//   time when previous buffer's actual-present fence was signaled
-//    + current display refresh rate * HWC latency
-//    + a little extra padding
-//
-// Buffer producers are expected to set their desired presentation time
-// based on choreographer time stamps, which (coming from vsync events)
-// will be slightly later then the actual-present timing.  If we get a
-// desired-present time that is unintentionally a hair after the next
-// vsync, we'll hold the frame when we really want to display it.  We
-// need to take the offset between actual-present and reported-vsync
-// into account.
-//
-// If the system is configured without a DispSync phase offset for the app,
-// we also want to throw in a bit of padding to avoid edge cases where we
-// just barely miss.  We want to do it here, not in every app.  A major
-// source of trouble is the app's use of the display's ideal refresh time
-// (via Display.getRefreshRate()), which could be off of the actual refresh
-// by a few percent, with the error multiplied by the number of frames
-// between now and when the buffer should be displayed.
-//
-// If the refresh reported to the app has a phase offset, we shouldn't need
-// to tweak anything here.
 nsecs_t DispSync::expectedPresentTime() {
     // The HWC doesn't currently have a way to report additional latency.
     // Assume that whatever we submit now will appear right after the flip.
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index d5e3349..67e6de9 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -135,7 +135,7 @@
 public:
     using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
 
-    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
+    // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete.
     EventThread(VSyncSource*, InterceptVSyncsCallback, const char* threadName);
     EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback, const char* threadName);
     ~EventThread();
@@ -169,7 +169,7 @@
 
     using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
 
-    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
+    // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete.
     EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
                 InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
 
@@ -186,10 +186,7 @@
     // Implements VSyncSource::Callback
     void onVSyncEvent(nsecs_t timestamp) override;
 
-    // Acquires mutex and requests next vsync.
-    void requestNextVsyncInternal(const sp<EventThreadConnection>& connection) EXCLUDES(mMutex);
-
-    // TODO(b/113612090): Once the Scheduler is complete this pointer will become obsolete.
+    // TODO(b/128863962): Once the Scheduler is complete this pointer will become obsolete.
     VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
     std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
 
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 56a00c0..245a8ac 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -85,7 +85,7 @@
     virtual ~MessageQueue();
 
     virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
-    // TODO(akrulec): Remove this function once everything is migrated to Scheduler.
+    // TODO(b/128863962): Remove this function once everything is migrated to Scheduler.
     virtual void setEventThread(EventThread* events, ResyncCallback resyncCallback) = 0;
     virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
     virtual void waitMessage() = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 08a728a..f6251b8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1245,7 +1245,7 @@
         auto resyncCallback =
                 mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
 
-        // TODO(akrulec): Part of the Injector should be refactored, so that it
+        // TODO(b/128863962): Part of the Injector should be refactored, so that it
         // can be passed to Scheduler.
         if (enable) {
             ALOGV("VSync Injections enabled");
@@ -2906,13 +2906,13 @@
 }
 
 void SurfaceFlinger::updateInputWindowInfo() {
-    Vector<InputWindowInfo> inputHandles;
+    std::vector<InputWindowInfo> inputHandles;
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
         if (layer->hasInput()) {
             // When calculating the screen bounds we ignore the transparent region since it may
             // result in an unwanted offset.
-            inputHandles.add(layer->fillInputInfo());
+            inputHandles.push_back(layer->fillInputInfo());
         }
     });
 
@@ -3514,7 +3514,7 @@
                 break;
             }
             applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
-                                  desiredPresentTime, postTime, privileged);
+                                  desiredPresentTime, postTime, privileged, /*isMainThread*/ true);
             transactionQueue.pop();
         }
 
@@ -3601,7 +3601,7 @@
                                            const Vector<DisplayState>& displays, uint32_t flags,
                                            const InputWindowCommands& inputWindowCommands,
                                            const int64_t desiredPresentTime, const int64_t postTime,
-                                           bool privileged) {
+                                           bool privileged, bool isMainThread) {
     uint32_t transactionFlags = 0;
 
     if (flags & eAnimation) {
@@ -3665,7 +3665,12 @@
         }
 
         mPendingSyncInputWindows = mPendingInputWindowCommands.syncInputWindows;
-        while (mTransactionPending || mPendingSyncInputWindows) {
+
+        // applyTransactionState can be called by either the main SF thread or by
+        // another process through setTransactionState.  While a given process may wish
+        // to wait on synchronous transactions, the main SF thread should never
+        // be blocked.  Therefore, we only wait if isMainThread is false.
+        while (!isMainThread && (mTransactionPending || mPendingSyncInputWindows)) {
             status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
             if (CC_UNLIKELY(err != NO_ERROR)) {
                 // just in case something goes wrong in SF, return to the
@@ -4639,13 +4644,14 @@
     result.append("\n");
 }
 
-LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const {
+LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet,
+                                          uint32_t traceFlags) const {
     LayersProto layersProto;
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const State& state = useDrawing ? mDrawingState : mCurrentState;
     state.traverseInZOrder([&](Layer* layer) {
         LayerProto* layerProto = layersProto.add_layers();
-        layer->writeToProto(layerProto, stateSet);
+        layer->writeToProto(layerProto, stateSet, traceFlags);
     });
 
     return layersProto;
@@ -4988,9 +4994,9 @@
         code == IBinder::SYSPROPS_TRANSACTION) {
         return OK;
     }
-    // Numbers from 1000 to 1032 are currently use for backdoors. The code
+    // Numbers from 1000 to 1033 are currently used for backdoors. The code
     // in onTransact verifies that the user is root, and has access to use SF.
-    if (code >= 1000 && code <= 1032) {
+    if (code >= 1000 && code <= 1033) {
         ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
         return OK;
     }
@@ -5298,6 +5304,14 @@
                 mDebugEnableProtectedContent = n;
                 return NO_ERROR;
             }
+            // Set trace flags
+            case 1033: {
+                n = data.readUint32();
+                ALOGD("Updating trace flags to 0x%x", n);
+                mTracing.setTraceFlags(n);
+                reply->writeInt32(NO_ERROR);
+                return NO_ERROR;
+            }
         }
     }
     return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 0d39cb5..3bf7c21 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -578,7 +578,7 @@
                                const Vector<DisplayState>& displays, uint32_t flags,
                                const InputWindowCommands& inputWindowCommands,
                                const int64_t desiredPresentTime, const int64_t postTime,
-                               bool privileged) REQUIRES(mStateLock);
+                               bool privileged, bool isMainThread = false) REQUIRES(mStateLock);
     bool flushTransactionQueues();
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t peekTransactionFlags();
@@ -895,7 +895,8 @@
     void dumpBufferingStats(std::string& result) const;
     void dumpDisplayIdentificationData(std::string& result) const;
     void dumpWideColorInfo(std::string& result) const;
-    LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const;
+    LayersProto dumpProtoInfo(LayerVector::StateSet stateSet,
+                              uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
     void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
     LayersProto dumpVisibleLayersProtoInfo(const sp<DisplayDevice>& display) const;
 
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index db78f1d..c4ab066 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -28,46 +28,56 @@
 
 namespace android {
 
-void SurfaceTracing::mainLoop() {
-    bool enabled = true;
-    // Upon activation, logs the first frame
-    traceLayers("tracing.enable");
-    do {
-        std::unique_lock<std::mutex> sfLock(mFlinger.mDrawingStateLock);
-        mConditionalVariable.wait(sfLock);
-        LayersTraceProto entry = traceLayersLocked(mWhere);
-        sfLock.unlock();
-        {
-            std::scoped_lock bufferLock(mTraceLock);
-            mBuffer.emplace(std::move(entry));
-            if (mWriteToFile) {
-                writeProtoFileLocked();
-                mWriteToFile = false;
-            }
+SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
+      : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
 
-            enabled = mEnabled;
-        }
-    } while (enabled);
+void SurfaceTracing::mainLoop() {
+    addFirstEntry();
+    bool enabled = true;
+    while (enabled) {
+        LayersTraceProto entry = traceWhenNotified();
+        enabled = addTraceToBuffer(entry);
+    }
 }
 
-void SurfaceTracing::traceLayers(const char* where) {
-    std::unique_lock<std::mutex> sfLock(mFlinger.mDrawingStateLock);
-    LayersTraceProto entry = traceLayersLocked(where);
-    sfLock.unlock();
-    std::scoped_lock bufferLock(mTraceLock);
+void SurfaceTracing::addFirstEntry() {
+    LayersTraceProto entry;
+    {
+        std::scoped_lock lock(mSfLock);
+        entry = traceLayersLocked("tracing.enable");
+    }
+    addTraceToBuffer(entry);
+}
+
+LayersTraceProto SurfaceTracing::traceWhenNotified() {
+    std::unique_lock<std::mutex> lock(mSfLock);
+    mCanStartTrace.wait(lock);
+    android::base::ScopedLockAssertion assumeLock(mSfLock);
+    LayersTraceProto entry = traceLayersLocked(mWhere);
+    lock.unlock();
+    return entry;
+}
+
+bool SurfaceTracing::addTraceToBuffer(LayersTraceProto& entry) {
+    std::scoped_lock lock(mTraceLock);
     mBuffer.emplace(std::move(entry));
+    if (mWriteToFile) {
+        writeProtoFileLocked();
+        mWriteToFile = false;
+    }
+    return mEnabled;
 }
 
 void SurfaceTracing::notify(const char* where) {
-    std::lock_guard<std::mutex> sfLock(mFlinger.mDrawingStateLock);
+    std::scoped_lock lock(mSfLock);
     mWhere = where;
-    mConditionalVariable.notify_one();
+    mCanStartTrace.notify_one();
 }
 
 void SurfaceTracing::writeToFileAsync() {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
+    std::scoped_lock lock(mTraceLock);
     mWriteToFile = true;
-    mConditionalVariable.notify_one();
+    mCanStartTrace.notify_one();
 }
 
 void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
@@ -102,12 +112,11 @@
 }
 
 void SurfaceTracing::enable() {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
+    std::scoped_lock lock(mTraceLock);
 
     if (mEnabled) {
         return;
     }
-
     mBuffer.reset(mBufferSize);
     mEnabled = true;
     mThread = std::thread(&SurfaceTracing::mainLoop, this);
@@ -119,7 +128,7 @@
 }
 
 bool SurfaceTracing::disable() {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
+    std::scoped_lock lock(mTraceLock);
 
     if (!mEnabled) {
         return false;
@@ -127,28 +136,33 @@
 
     mEnabled = false;
     mWriteToFile = true;
-    mConditionalVariable.notify_all();
+    mCanStartTrace.notify_all();
     return true;
 }
 
 bool SurfaceTracing::isEnabled() const {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
+    std::scoped_lock lock(mTraceLock);
     return mEnabled;
 }
 
 void SurfaceTracing::setBufferSize(size_t bufferSizeInByte) {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
+    std::scoped_lock lock(mTraceLock);
     mBufferSize = bufferSizeInByte;
     mBuffer.setSize(bufferSizeInByte);
 }
 
+void SurfaceTracing::setTraceFlags(uint32_t flags) {
+    std::scoped_lock lock(mSfLock);
+    mTraceFlags = flags;
+}
+
 LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
     ATRACE_CALL();
 
     LayersTraceProto entry;
     entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry.set_where(where);
-    LayersProto layers(mFlinger.dumpProtoInfo(LayerVector::StateSet::Drawing));
+    LayersProto layers(mFlinger.dumpProtoInfo(LayerVector::StateSet::Drawing, mTraceFlags));
     entry.mutable_layers()->Swap(&layers);
 
     return entry;
@@ -179,8 +193,7 @@
 }
 
 void SurfaceTracing::dump(std::string& result) const {
-    std::lock_guard<std::mutex> bufferLock(mTraceLock);
-
+    std::scoped_lock lock(mTraceLock);
     base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
     base::StringAppendF(&result, "  number of entries: %zu (%.2fMB / %.2fMB)\n",
                         mBuffer.frameCount(), float(mBuffer.used()) / float(1_MB),
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 9484480..4be2ee9 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -41,7 +41,7 @@
  */
 class SurfaceTracing {
 public:
-    SurfaceTracing(SurfaceFlinger& flinger) : mFlinger(flinger) {}
+    SurfaceTracing(SurfaceFlinger& flinger);
     void enable();
     bool disable();
     status_t writeToFile();
@@ -52,6 +52,14 @@
     void writeToFileAsync();
     void dump(std::string& result) const;
 
+    enum : uint32_t {
+        TRACE_CRITICAL = 1 << 0,
+        TRACE_INPUT = 1 << 1,
+        TRACE_EXTRA = 1 << 2,
+        TRACE_ALL = 0xffffffff
+    };
+    void setTraceFlags(uint32_t flags);
+
 private:
     static constexpr auto kDefaultBufferCapInByte = 100_MB;
     static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
@@ -74,18 +82,24 @@
     };
 
     void mainLoop();
-    void traceLayers(const char* where);
-    LayersTraceProto traceLayersLocked(const char* where);
+    void addFirstEntry();
+    LayersTraceProto traceWhenNotified();
+    LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
+
+    // Returns true if trace is enabled.
+    bool addTraceToBuffer(LayersTraceProto& entry);
     void writeProtoFileLocked() REQUIRES(mTraceLock);
 
     const SurfaceFlinger& mFlinger;
-
-    const char* mWhere = "";
     status_t mLastErr = NO_ERROR;
     std::thread mThread;
-    std::condition_variable mConditionalVariable;
-    mutable std::mutex mTraceLock;
+    std::condition_variable mCanStartTrace;
 
+    std::mutex& mSfLock;
+    uint32_t mTraceFlags GUARDED_BY(mSfLock) = TRACE_ALL;
+    const char* mWhere GUARDED_BY(mSfLock) = "";
+
+    mutable std::mutex mTraceLock;
     LayersTraceBuffer mBuffer GUARDED_BY(mTraceLock);
     size_t mBufferSize GUARDED_BY(mTraceLock) = kDefaultBufferCapInByte;
     bool mEnabled GUARDED_BY(mTraceLock) = false;
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index fd4695e..b097505 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -96,6 +96,8 @@
   FloatRectProto source_bounds = 44;
   FloatRectProto bounds = 45;
   FloatRectProto screen_bounds = 46;
+
+  InputWindowInfoProto input_window_info = 47;
 }
 
 message PositionProto {
@@ -155,3 +157,24 @@
   // frame number the barrier is waiting on.
   uint64 frame_number = 2;
 }
+
+message InputWindowInfoProto {
+    uint32 layout_params_flags = 1;
+    uint32 layout_params_type = 2;
+    RectProto frame = 3;
+    RegionProto touchable_region = 4;
+
+    uint32 surface_inset = 5;
+    bool visible = 6;
+    bool can_receive_keys = 7;
+    bool has_focus = 8;
+    bool has_wallpaper = 9;
+
+    float global_scale_factor = 10;
+    float window_x_scale = 11;
+    float window_y_scale = 12;
+
+    uint32 crop_layer_id = 13;
+    bool replace_touchable_region_with_crop = 14;
+    RectProto touchable_region_crop = 15;
+}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 4342dc9..b7e55f4 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -27,6 +27,7 @@
 
 using namespace std::chrono_literals;
 using testing::_;
+using testing::AtLeast;
 
 namespace android {
 namespace scheduler {
@@ -75,7 +76,7 @@
     init(configs);
 
     // There is one default config, so the refresh rates should have one item.
-    ASSERT_EQ(1, mRefreshRateStats->getTotalTimes().size());
+    EXPECT_EQ(1, mRefreshRateStats->getTotalTimes().size());
 }
 
 TEST_F(RefreshRateStatsTest, oneConfigTest) {
@@ -88,13 +89,14 @@
 
     init(configs);
 
-    EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(4);
-    EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(2);
+    EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
+    EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
 
     std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(2, times.size());
-    ASSERT_EQ(0, times["ScreenOff"]);
-    ASSERT_EQ(0, times["90fps"]);
+    EXPECT_EQ(2, times.size());
+    EXPECT_NE(0u, times.count("ScreenOff"));
+    EXPECT_EQ(1u, times.count("90fps"));
+    EXPECT_EQ(0, times["90fps"]);
     // Setting up tests on mobile harness can be flaky with time passing, so testing for
     // exact time changes can result in flaxy numbers. To avoid that remember old
     // numbers to make sure the correct values are increasing in the next test.
@@ -104,31 +106,31 @@
     // Screen is off by default.
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(0, times["90fps"]);
-    screenOff = times["ScreenOff"];
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(0, times["90fps"]);
 
     mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+    screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(screenOff, times["ScreenOff"]);
-    ASSERT_LT(ninety, times["90fps"]);
-    ninety = times["90fps"];
+    EXPECT_EQ(screenOff, times["ScreenOff"]);
+    EXPECT_LT(ninety, times["90fps"]);
 
     mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
+    ninety = mRefreshRateStats->getTotalTimes()["90fps"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    screenOff = times["ScreenOff"];
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
 
     mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+    screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
     // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
     // does not update refresh rates that come from the config.
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
 }
 
 TEST_F(RefreshRateStatsTest, twoConfigsTest) {
@@ -145,15 +147,17 @@
 
     init(configs);
 
-    EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(6);
-    EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(4);
-    EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(4);
+    EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
+    EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
+    EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
 
     std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(3, times.size());
-    ASSERT_EQ(0, times["ScreenOff"]);
-    ASSERT_EQ(0, times["60fps"]);
-    ASSERT_EQ(0, times["90fps"]);
+    EXPECT_EQ(3, times.size());
+    EXPECT_NE(0u, times.count("ScreenOff"));
+    EXPECT_EQ(1u, times.count("60fps"));
+    EXPECT_EQ(0, times["60fps"]);
+    EXPECT_EQ(1u, times.count("90fps"));
+    EXPECT_EQ(0, times["90fps"]);
     // Setting up tests on mobile harness can be flaky with time passing, so testing for
     // exact time changes can result in flaxy numbers. To avoid that remember old
     // numbers to make sure the correct values are increasing in the next test.
@@ -164,61 +168,61 @@
     // Screen is off by default.
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(sixty, times["60fps"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    screenOff = times["ScreenOff"];
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(sixty, times["60fps"]);
+    EXPECT_EQ(ninety, times["90fps"]);
 
     mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+    screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(sixty, times["60fps"]);
-    ASSERT_LT(ninety, times["90fps"]);
-    ninety = times["90fps"];
+    EXPECT_EQ(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(sixty, times["60fps"]);
+    EXPECT_LT(ninety, times["90fps"]);
 
     // When power mode is normal, time for configs updates.
     mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+    ninety = mRefreshRateStats->getTotalTimes()["90fps"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    ASSERT_LT(sixty, times["60fps"]);
-    sixty = times["60fps"];
+    EXPECT_EQ(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
+    EXPECT_LT(sixty, times["60fps"]);
 
     mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+    sixty = mRefreshRateStats->getTotalTimes()["60fps"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(screenOff, times["ScreenOff"]);
-    ASSERT_LT(ninety, times["90fps"]);
-    ASSERT_EQ(sixty, times["60fps"]);
-    ninety = times["90fps"];
+    EXPECT_EQ(screenOff, times["ScreenOff"]);
+    EXPECT_LT(ninety, times["90fps"]);
+    EXPECT_EQ(sixty, times["60fps"]);
 
     mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+    ninety = mRefreshRateStats->getTotalTimes()["90fps"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_EQ(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    ASSERT_LT(sixty, times["60fps"]);
-    sixty = times["60fps"];
+    EXPECT_EQ(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
+    EXPECT_LT(sixty, times["60fps"]);
 
     // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
     // does not update refresh rates that come from the config.
     mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
     mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+    sixty = mRefreshRateStats->getTotalTimes()["60fps"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    ASSERT_EQ(sixty, times["60fps"]);
-    screenOff = times["ScreenOff"];
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
+    EXPECT_EQ(sixty, times["60fps"]);
 
     mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+    screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
     std::this_thread::sleep_for(std::chrono::milliseconds(2));
     times = mRefreshRateStats->getTotalTimes();
-    ASSERT_LT(screenOff, times["ScreenOff"]);
-    ASSERT_EQ(ninety, times["90fps"]);
-    ASSERT_EQ(sixty, times["60fps"]);
+    EXPECT_LT(screenOff, times["ScreenOff"]);
+    EXPECT_EQ(ninety, times["90fps"]);
+    EXPECT_EQ(sixty, times["60fps"]);
 }
 } // namespace
 } // namespace scheduler