Merge changes Iee2984f7,I18a3fd8a

* changes:
  Fix logic error in atrace when detecting available categories.
  Add several more tracepoints to the memory category in atrace
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 2d780f5..73360a3 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,17 @@
+[Builtin Hooks]
+clang_format = true
+
+[Builtin Hooks Options]
+# Only turn on clang-format check for the following subfolders.
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+               libs/binder/ndk/
+               libs/graphicsenv/
+               libs/gui/
+               libs/ui/
+               libs/vr/
+               services/surfaceflinger/
+               services/vr/
+
 [Hook Scripts]
 owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
 installd_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/installd/"
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 0ee6c3a..849eb44 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -108,7 +108,8 @@
         bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_REMOTE &&
         bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WEAR &&
         bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_TELEPHONY &&
-        bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WIFI) {
+        bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WIFI &&
+        bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_DEFAULT) {
         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
                          StringPrintf("Invalid bugreport mode: %d", bugreport_mode));
     }
@@ -137,6 +138,7 @@
     dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str());
     dprintf(fd, "version: %s\n", ds_.version_.c_str());
     dprintf(fd, "bugreport_dir: %s\n", ds_.bugreport_dir_.c_str());
+    dprintf(fd, "bugreport_internal_dir_: %s\n", ds_.bugreport_internal_dir_.c_str());
     dprintf(fd, "screenshot_path: %s\n", ds_.screenshot_path_.c_str());
     dprintf(fd, "log_path: %s\n", ds_.log_path_.c_str());
     dprintf(fd, "tmp_path: %s\n", ds_.tmp_path_.c_str());
diff --git a/cmds/dumpstate/README.md b/cmds/dumpstate/README.md
index d5b2953..6ac17d8 100644
--- a/cmds/dumpstate/README.md
+++ b/cmds/dumpstate/README.md
@@ -26,6 +26,18 @@
 mmm -j frameworks/native/cmds/dumpstate && adb push ${OUT}/system/bin/dumpstate system/bin && adb shell am bug-report
 ```
 
+Make sure that the device is remounted before running the above command.
+* If you're working with `userdebug` variant, you may need to run the following to remount your device:
+
+  ```
+  adb root && adb remount -R && adb wait-for-device && adb root && adb remount
+  ```
+* If you're working with `eng` variant, you may need to run the following to remount your device:
+
+  ```
+  adb root && adb remount
+  ```
+
 ## To build, deploy, and run unit tests
 
 First create `/data/nativetest64`:
@@ -37,13 +49,13 @@
 Then run:
 
 ```
-mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest/dumpstate_test/dumpstate_test
+mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest64/dumpstate_test/dumpstate_test
 ```
 
 And to run just one test (for example, `DumpstateTest.RunCommandNoArgs`):
 
 ```
-mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest/dumpstate_test/dumpstate_test --gtest_filter=DumpstateTest.RunCommandNoArgs
+mmm -j frameworks/native/cmds/dumpstate/ && adb push ${OUT}/data/nativetest64/dumpstate_test* /data/nativetest64 && adb shell /data/nativetest64/dumpstate_test/dumpstate_test --gtest_filter=DumpstateTest.RunCommandNoArgs
 ```
 
 ## To take quick bugreports
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index 9e59f58..617eab3 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -40,7 +40,7 @@
                                 boolean getSectionDetails);
 
     // These modes encapsulate a set of run time options for generating bugreports.
-    // A zipped bugreport; default mode.
+    // Takes a bugreport without user interference.
     const int BUGREPORT_MODE_FULL = 0;
 
     // Interactive bugreport, i.e. triggered by the user.
@@ -58,6 +58,9 @@
     // Bugreport limited to only wifi info.
     const int BUGREPORT_MODE_WIFI = 5;
 
+    // Default mode.
+    const int BUGREPORT_MODE_DEFAULT = 6;
+
     /*
      * Starts a bugreport in the background.
      */
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 026c260..59a0047 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -82,6 +82,7 @@
 using android::TIMED_OUT;
 using android::UNKNOWN_ERROR;
 using android::Vector;
+using android::base::StringPrintf;
 using android::os::dumpstate::CommandOptions;
 using android::os::dumpstate::DumpFileToFd;
 using android::os::dumpstate::DumpstateSectionReporter;
@@ -121,6 +122,69 @@
 
 // TODO: temporary variables and functions used during C++ refactoring
 static Dumpstate& ds = Dumpstate::GetInstance();
+
+namespace android {
+namespace os {
+namespace {
+
+static int Open(std::string path, int flags, mode_t mode = 0) {
+    int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
+    if (fd == -1) {
+        MYLOGE("open(%s, %s)\n", path.c_str(), strerror(errno));
+    }
+    return fd;
+}
+
+static int OpenForWrite(std::string path) {
+    return Open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+                S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+}
+
+static int OpenForRead(std::string path) {
+    return Open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
+}
+
+bool CopyFile(int in_fd, int out_fd) {
+    char buf[4096];
+    ssize_t byte_count;
+    while ((byte_count = TEMP_FAILURE_RETRY(read(in_fd, buf, sizeof(buf)))) > 0) {
+        if (!android::base::WriteFully(out_fd, buf, byte_count)) {
+            return false;
+        }
+    }
+    return (byte_count != -1);
+}
+
+static bool CopyFileToFd(const std::string& input_file, int out_fd) {
+    MYLOGD("Going to copy bugreport file (%s) to %d\n", ds.path_.c_str(), out_fd);
+
+    // Obtain a handle to the source file.
+    android::base::unique_fd in_fd(OpenForRead(input_file));
+    if (out_fd != -1 && in_fd.get() != -1) {
+        if (CopyFile(in_fd.get(), out_fd)) {
+            return true;
+        }
+        MYLOGE("Failed to copy zip file: %s\n", strerror(errno));
+    }
+    return false;
+}
+
+static bool CopyFileToFile(const std::string& input_file, const std::string& output_file) {
+    if (input_file == output_file) {
+        MYLOGD("Skipping copying bugreport file since the destination is the same (%s)\n",
+               output_file.c_str());
+        return false;
+    }
+
+    MYLOGD("Going to copy bugreport file (%s) to %s\n", input_file.c_str(), output_file.c_str());
+    android::base::unique_fd out_fd(OpenForWrite(output_file));
+    return CopyFileToFd(input_file, out_fd.get());
+}
+
+}  // namespace
+}  // namespace os
+}  // namespace android
+
 static int RunCommand(const std::string& title, const std::vector<std::string>& fullCommand,
                       const CommandOptions& options = CommandOptions::DEFAULT) {
     return ds.RunCommand(title, fullCommand, options);
@@ -137,8 +201,6 @@
 // Relative directory (inside the zip) for all files copied as-is into the bugreport.
 static const std::string ZIP_ROOT_DIR = "FS";
 
-// Must be hardcoded because dumpstate HAL implementation need SELinux access to it
-static const std::string kDumpstateBoardPath = "/bugreports/";
 static const std::string kProtoPath = "proto/";
 static const std::string kProtoExt = ".proto";
 static const std::string kDumpstateBoardFiles[] = {
@@ -1145,7 +1207,7 @@
                                 return !isalnum(c) &&
                                     std::string("@-_:.").find(c) == std::string::npos;
                             }, '_');
-            const std::string path = kDumpstateBoardPath + "lshal_debug_" + cleanName;
+            const std::string path = ds.bugreport_internal_dir_ + "/lshal_debug_" + cleanName;
 
             {
                 auto fd = android::base::unique_fd(
@@ -1523,7 +1585,8 @@
     std::vector<std::string> paths;
     std::vector<android::base::ScopeGuard<std::function<void()>>> remover;
     for (int i = 0; i < NUM_OF_DUMPS; i++) {
-        paths.emplace_back(kDumpstateBoardPath + kDumpstateBoardFiles[i]);
+        paths.emplace_back(StringPrintf("%s/%s", ds.bugreport_internal_dir_.c_str(),
+                                        kDumpstateBoardFiles[i].c_str()));
         remover.emplace_back(android::base::make_scope_guard(std::bind(
             [](std::string path) {
                 if (remove(path.c_str()) != 0 && errno != ENOENT) {
@@ -1681,7 +1744,8 @@
         MYLOGE("Failed to add dumpstate log to .zip file\n");
         return false;
     }
-    // ... and re-opens it for further logging.
+    // TODO: Should truncate the existing file.
+    // ... and re-open it for further logging.
     redirect_to_existing_file(stderr, const_cast<char*>(ds.log_path_.c_str()));
     fprintf(stderr, "\n");
 
@@ -1764,17 +1828,30 @@
     // clang-format on
 }
 
+static void MaybeResolveSymlink(std::string* path) {
+    std::string resolved_path;
+    if (android::base::Readlink(*path, &resolved_path)) {
+        *path = resolved_path;
+    }
+}
+
 /*
  * Prepares state like filename, screenshot path, etc in Dumpstate. Also initializes ZipWriter
  * if we are writing zip files and adds the version file.
  */
 static void PrepareToWriteToFile() {
-    ds.bugreport_dir_ = dirname(ds.options_->use_outfile.c_str());
+    MaybeResolveSymlink(&ds.bugreport_internal_dir_);
+
+    std::string base_name_part1 = "bugreport";
+    if (!ds.options_->use_outfile.empty()) {
+        ds.bugreport_dir_ = dirname(ds.options_->use_outfile.c_str());
+        base_name_part1 = basename(ds.options_->use_outfile.c_str());
+    }
+
     std::string build_id = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
     std::string device_name = android::base::GetProperty("ro.product.name", "UNKNOWN_DEVICE");
     ds.base_name_ =
-        android::base::StringPrintf("%s-%s-%s", basename(ds.options_->use_outfile.c_str()),
-                                    device_name.c_str(), build_id.c_str());
+        StringPrintf("%s-%s-%s", base_name_part1.c_str(), device_name.c_str(), build_id.c_str());
     if (ds.options_->do_add_date) {
         char date[80];
         strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
@@ -1795,15 +1872,18 @@
     ds.tmp_path_ = ds.GetPath(".tmp");
     ds.log_path_ = ds.GetPath("-dumpstate_log-" + std::to_string(ds.pid_) + ".txt");
 
+    std::string destination = ds.options_->fd != -1 ? StringPrintf("[fd:%d]", ds.options_->fd)
+                                                    : ds.bugreport_dir_.c_str();
     MYLOGD(
         "Bugreport dir: %s\n"
+        "Internal Bugreport dir: %s\n"
         "Base name: %s\n"
         "Suffix: %s\n"
         "Log path: %s\n"
         "Temporary path: %s\n"
         "Screenshot path: %s\n",
-        ds.bugreport_dir_.c_str(), ds.base_name_.c_str(), ds.name_.c_str(), ds.log_path_.c_str(),
-        ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
+        destination.c_str(), ds.bugreport_internal_dir_.c_str(), ds.base_name_.c_str(),
+        ds.name_.c_str(), ds.log_path_.c_str(), ds.tmp_path_.c_str(), ds.screenshot_path_.c_str());
 
     if (ds.options_->do_zip_file) {
         ds.path_ = ds.GetPath(".zip");
@@ -1858,6 +1938,30 @@
             do_text_file = true;
         } else {
             do_text_file = false;
+            // If the user has changed the suffix, we need to change the zip file name.
+            std::string new_path = ds.GetPath(".zip");
+            if (ds.path_ != new_path) {
+                MYLOGD("Renaming zip file from %s to %s\n", ds.path_.c_str(), new_path.c_str());
+                if (rename(ds.path_.c_str(), new_path.c_str())) {
+                    MYLOGE("rename(%s, %s): %s\n", ds.path_.c_str(), new_path.c_str(),
+                           strerror(errno));
+                } else {
+                    ds.path_ = new_path;
+                }
+            }
+            // The zip file lives in an internal directory. Copy it over to output.
+            bool copy_succeeded = false;
+            if (ds.options_->fd != -1) {
+                copy_succeeded = android::os::CopyFileToFd(ds.path_, ds.options_->fd);
+            } else {
+                ds.final_path_ = ds.GetPath(ds.bugreport_dir_, ".zip");
+                copy_succeeded = android::os::CopyFileToFile(ds.path_, ds.final_path_);
+            }
+            if (copy_succeeded) {
+                if (remove(ds.path_.c_str())) {
+                    MYLOGE("remove(%s): %s", ds.path_.c_str(), strerror(errno));
+                }
+            }
         }
     }
     if (do_text_file) {
@@ -1882,8 +1986,9 @@
 
 /* Broadcasts that we are done with the bugreport */
 static void SendBugreportFinishedBroadcast() {
-    if (!ds.path_.empty()) {
-        MYLOGI("Final bugreport path: %s\n", ds.path_.c_str());
+    // TODO(b/111441001): use callback instead of broadcast.
+    if (!ds.final_path_.empty()) {
+        MYLOGI("Final bugreport path: %s\n", ds.final_path_.c_str());
         // clang-format off
 
         std::vector<std::string> am_args = {
@@ -1891,7 +1996,7 @@
              "--ei", "android.intent.extra.ID", std::to_string(ds.id_),
              "--ei", "android.intent.extra.PID", std::to_string(ds.pid_),
              "--ei", "android.intent.extra.MAX", std::to_string(ds.progress_->GetMax()),
-             "--es", "android.intent.extra.BUGREPORT", ds.path_,
+             "--es", "android.intent.extra.BUGREPORT", ds.final_path_,
              "--es", "android.intent.extra.DUMPSTATE_LOG", ds.log_path_
         };
         // clang-format on
@@ -1913,7 +2018,7 @@
         if (ds.options_->is_remote_mode) {
             am_args.push_back("--es");
             am_args.push_back("android.intent.extra.REMOTE_BUGREPORT_HASH");
-            am_args.push_back(SHA256_file_hash(ds.path_));
+            am_args.push_back(SHA256_file_hash(ds.final_path_));
             SendBroadcast("com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED", am_args);
         } else {
             SendBroadcast("com.android.internal.intent.action.BUGREPORT_FINISHED", am_args);
@@ -1937,10 +2042,13 @@
             return "BUGREPORT_TELEPHONY";
         case Dumpstate::BugreportMode::BUGREPORT_WIFI:
             return "BUGREPORT_WIFI";
+        case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+            return "BUGREPORT_DEFAULT";
     }
 }
 
 static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options) {
+    options->extra_options = ModeToString(mode);
     switch (mode) {
         case Dumpstate::BugreportMode::BUGREPORT_FULL:
             options->do_broadcast = true;
@@ -1977,12 +2085,14 @@
             options->do_fb = true;
             options->do_broadcast = true;
             break;
+        case Dumpstate::BugreportMode::BUGREPORT_DEFAULT:
+            break;
     }
 }
 
 static Dumpstate::BugreportMode getBugreportModeFromProperty() {
-    // If the system property is not set, it's assumed to be a full bugreport.
-    Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_FULL;
+    // If the system property is not set, it's assumed to be a default bugreport.
+    Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_DEFAULT;
 
     std::string extra_options = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
     if (!extra_options.empty()) {
@@ -1990,6 +2100,8 @@
         // Currently, it contains the type of the requested bugreport.
         if (extra_options == "bugreportplus") {
             mode = Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE;
+        } else if (extra_options == "bugreportfull") {
+            mode = Dumpstate::BugreportMode::BUGREPORT_FULL;
         } else if (extra_options == "bugreportremote") {
             mode = Dumpstate::BugreportMode::BUGREPORT_REMOTE;
         } else if (extra_options == "bugreportwear") {
@@ -2043,6 +2155,7 @@
     MYLOGI("telephony_only: %d\n", options.telephony_only);
     MYLOGI("wifi_only: %d\n", options.wifi_only);
     MYLOGI("do_progress_updates: %d\n", options.do_progress_updates);
+    MYLOGI("fd: %d\n", options.fd);
     MYLOGI("use_outfile: %s\n", options.use_outfile.c_str());
     MYLOGI("extra_options: %s\n", options.extra_options.c_str());
     MYLOGI("args: %s\n", options.args.c_str());
@@ -2108,8 +2221,13 @@
 }
 
 bool Dumpstate::DumpOptions::ValidateOptions() const {
-    if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast)
-            && use_outfile.empty()) {
+    if (fd != -1 && !do_zip_file) {
+        return false;
+    }
+
+    bool has_out_file_options = !use_outfile.empty() || fd != -1;
+    if ((do_zip_file || do_add_date || do_progress_updates || do_broadcast) &&
+        !has_out_file_options) {
         return false;
     }
 
@@ -2131,10 +2249,31 @@
     options_ = std::move(options);
 }
 
+/*
+ * Dumps relevant information to a bugreport based on the given options.
+ *
+ * The bugreport can be dumped to a file or streamed to a socket.
+ *
+ * How dumping to file works:
+ * stdout is redirected to a temporary file. This will later become the main bugreport entry.
+ * stderr is redirected a log file.
+ *
+ * The temporary bugreport is then populated via printfs, dumping contents of files and
+ * output of commands to stdout.
+ *
+ * If zipping, the temporary bugreport file is added to the zip archive. Else it's renamed to final
+ * text file.
+ *
+ * If zipping, a bunch of other files and dumps also get added to the zip archive. The log file also
+ * gets added to the archive.
+ *
+ * Bugreports are first generated in a local directory and later copied to the caller's fd or
+ * directory.
+ */
 Dumpstate::RunStatus Dumpstate::Run() {
+    LogDumpOptions(*options_);
     if (!options_->ValidateOptions()) {
         MYLOGE("Invalid options specified\n");
-        LogDumpOptions(*options_);
         return RunStatus::INVALID_INPUT;
     }
     /* set as high priority, and protect from OOM killer */
@@ -2174,9 +2313,9 @@
 
     // TODO: temporarily set progress until it's part of the Dumpstate constructor
     std::string stats_path =
-        is_redirecting ? android::base::StringPrintf("%s/dumpstate-stats.txt",
-                                                     dirname(options_->use_outfile.c_str()))
-                       : "";
+        is_redirecting
+            ? android::base::StringPrintf("%s/dumpstate-stats.txt", bugreport_internal_dir_.c_str())
+            : "";
     progress_.reset(new Progress(stats_path));
 
     /* gets the sequential id */
@@ -2272,13 +2411,18 @@
     int dup_stdout_fd;
     int dup_stderr_fd;
     if (is_redirecting) {
+        // Redirect stderr to log_path_ for debugging.
         TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
         redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()));
         if (chown(log_path_.c_str(), AID_SHELL, AID_SHELL)) {
             MYLOGE("Unable to change ownership of dumpstate log file %s: %s\n", log_path_.c_str(),
                    strerror(errno));
         }
+
+        // Redirect stdout to tmp_path_. This is the main bugreport entry and will be
+        // moved into zip file later, if zipping.
         TEMP_FAILURE_RETRY(dup_stdout_fd = dup(fileno(stdout)));
+        // TODO: why not write to a file instead of stdout to overcome this problem?
         /* TODO: rather than generating a text file now and zipping it later,
            it would be more efficient to redirect stdout to the zip entry
            directly, but the libziparchive doesn't support that option yet. */
@@ -2353,7 +2497,7 @@
     return RunStatus::OK;
 }
 
-/* Main entry point for dumpstate. */
+/* Main entry point for dumpstate binary. */
 int run_main(int argc, char* argv[]) {
     std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
     Dumpstate::RunStatus status = options->Initialize(argc, argv);
@@ -2365,7 +2509,7 @@
     switch (status) {
         case Dumpstate::RunStatus::OK:
             return 0;
-            break;
+            // TODO(b/111441001): Exit directly in the following cases.
         case Dumpstate::RunStatus::HELP:
             ShowUsageAndExit(0 /* exit code */);
             break;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 35cbdb1..ee952d9 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -142,7 +142,7 @@
     float growth_factor_;
     int32_t n_runs_;
     int32_t average_max_;
-    const std::string& path_;
+    std::string path_;
 };
 
 /*
@@ -164,6 +164,11 @@
 static std::string VERSION_DEFAULT = "default";
 
 /*
+ * Directory used by Dumpstate binary to keep its local files.
+ */
+static const std::string DUMPSTATE_DIRECTORY = "/bugreports";
+
+/*
  * Structure that contains the information of an open dump file.
  */
 struct DumpData {
@@ -196,7 +201,8 @@
         BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE,
         BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR,
         BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY,
-        BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI
+        BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI,
+        BUGREPORT_DEFAULT = android::os::IDumpstate::BUGREPORT_MODE_DEFAULT
     };
 
     static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
@@ -300,7 +306,11 @@
      */
     bool FinishZipFile();
 
-    /* Gets the path of a bugreport file with the given suffix. */
+    /* Constructs a full path inside directory with file name formatted using the given suffix. */
+    std::string GetPath(const std::string& directory, const std::string& suffix) const;
+
+    /* Constructs a full path inside bugreport_internal_dir_ with file name formatted using the
+     * given suffix. */
     std::string GetPath(const std::string& suffix) const;
 
     /* Returns true if the current version supports priority dump feature. */
@@ -314,7 +324,6 @@
     /* Sets runtime options. */
     void SetOptions(std::unique_ptr<DumpOptions> options);
 
-    // TODO: add other options from DumpState.
     /*
      * Structure to hold options that determine the behavior of dumpstate.
      */
@@ -333,6 +342,10 @@
         bool wifi_only = false;
         // Whether progress updates should be published.
         bool do_progress_updates = false;
+        // File descriptor to output zip file. -1 indicates not set. Takes precedence over
+        // use_outfile.
+        int fd = -1;
+        // Partial path to output file.
         std::string use_outfile;
         // TODO: rename to MODE.
         // Extra options passed as system property.
@@ -381,12 +394,6 @@
     // Bugreport format version;
     std::string version_ = VERSION_CURRENT;
 
-    // Full path of the directory where the bugreport files will be written.
-    std::string bugreport_dir_;
-
-    // Full path of the temporary file containing the screenshot (when requested).
-    std::string screenshot_path_;
-
     time_t now_;
 
     // Base name (without suffix or extensions) of the bugreport files, typically
@@ -397,15 +404,30 @@
     // `-d`), but it could be changed by the user..
     std::string name_;
 
-    // Full path of the temporary file containing the bugreport.
+    std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY;
+
+    // Full path of the temporary file containing the bugreport, inside bugreport_internal_dir_.
+    // At the very end this file is pulled into the zip file.
     std::string tmp_path_;
 
-    // Full path of the file containing the dumpstate logs.
+    // Full path of the file containing the dumpstate logs, inside bugreport_internal_dir_.
+    // This is useful for debugging.
     std::string log_path_;
 
-    // Pointer to the actual path, be it zip or text.
+    // Full path of the bugreport file, be it zip or text, inside bugreport_internal_dir_.
     std::string path_;
 
+    // TODO: If temporary this should be removed at the end.
+    // Full path of the temporary file containing the screenshot (when requested).
+    std::string screenshot_path_;
+
+    // TODO(b/111441001): remove when obsolete.
+    // Full path of the final zip file inside the caller-specified directory, if available.
+    std::string final_path_;
+
+    // The caller-specified directory, if available.
+    std::string bugreport_dir_;
+
     // Pointer to the zipped file.
     std::unique_ptr<FILE, int (*)(FILE*)> zip_file{nullptr, fclose};
 
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 9ca894d..fcf9371 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -36,6 +36,7 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <cutils/properties.h>
 
 namespace android {
 namespace os {
@@ -148,7 +149,10 @@
     virtual void SetUp() {
         options_ = Dumpstate::DumpOptions();
     }
-
+    void TearDown() {
+        // Reset the property
+        property_set("dumpstate.options", "");
+    }
     Dumpstate::DumpOptions options_;
 };
 
@@ -163,7 +167,6 @@
 
     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
 
-    // These correspond to bugreport_mode = full, because that's the default.
     EXPECT_FALSE(options_.do_add_date);
     EXPECT_FALSE(options_.do_zip_file);
     EXPECT_EQ("", options_.use_outfile);
@@ -171,10 +174,295 @@
     EXPECT_FALSE(options_.use_control_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_TRUE(options_.do_fb);
+    EXPECT_FALSE(options_.do_fb);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.do_broadcast);
+}
+
+TEST_F(DumpOptionsTest, InitializeAdbBugreport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstatez"),
+        const_cast<char*>("-S"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.use_control_socket);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_fb);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.do_broadcast);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeAdbShellBugreport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("dumpstate"),
+        const_cast<char*>("-s"),
+    };
+    // clang-format on
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.use_socket);
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_EQ("", options_.use_outfile);
+    EXPECT_FALSE(options_.do_add_date);
+    EXPECT_FALSE(options_.do_zip_file);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_fb);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.do_broadcast);
+}
+
+TEST_F(DumpOptionsTest, InitializeFullBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+    property_set("dumpstate.options", "bugreportfull");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_fb);
+    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.do_start_service);
+}
+
+TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "bugreportplus");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.do_progress_updates);
+    EXPECT_TRUE(options_.do_start_service);
+    EXPECT_FALSE(options_.do_fb);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "bugreportremote");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.do_vibrate);
+    EXPECT_FALSE(options_.do_fb);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeWearBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "bugreportwear");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_fb);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.do_progress_updates);
+    EXPECT_TRUE(options_.do_start_service);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "bugreporttelephony");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_fb);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.telephony_only);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "bugreportwifi");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_fb);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.wifi_only);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+}
+
+TEST_F(DumpOptionsTest, InitializeDefaultBugReport) {
+    // default: commandline options are not overridden
+    // clang-format off
+    char* argv[] = {
+        const_cast<char*>("bugreport"),
+        const_cast<char*>("-d"),
+        const_cast<char*>("-p"),
+        const_cast<char*>("-B"),
+        const_cast<char*>("-z"),
+        const_cast<char*>("-o abc"),
+    };
+    // clang-format on
+
+    property_set("dumpstate.options", "");
+
+    Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
+
+    EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+    EXPECT_TRUE(options_.do_add_date);
+    EXPECT_TRUE(options_.do_fb);
+    EXPECT_TRUE(options_.do_zip_file);
+    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_EQ(" abc", std::string(options_.use_outfile));
+
+    // Other options retain default values
+    EXPECT_TRUE(options_.do_vibrate);
+    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.show_header_only);
+    EXPECT_FALSE(options_.do_progress_updates);
+    EXPECT_FALSE(options_.is_remote_mode);
+    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.wifi_only);
 }
 
 TEST_F(DumpOptionsTest, InitializePartial1) {
@@ -203,10 +491,10 @@
     // Other options retain default values
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_TRUE(options_.do_fb);
+    EXPECT_FALSE(options_.do_fb);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_TRUE(options_.do_broadcast);
+    EXPECT_FALSE(options_.do_broadcast);
 }
 
 TEST_F(DumpOptionsTest, InitializePartial2) {
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 6cbb691..d97ffbf 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -229,7 +229,11 @@
 }
 
 std::string Dumpstate::GetPath(const std::string& suffix) const {
-    return android::base::StringPrintf("%s/%s-%s%s", bugreport_dir_.c_str(), base_name_.c_str(),
+    return GetPath(bugreport_internal_dir_, suffix);
+}
+
+std::string Dumpstate::GetPath(const std::string& directory, const std::string& suffix) const {
+    return android::base::StringPrintf("%s/%s-%s%s", directory.c_str(), base_name_.c_str(),
                                        name_.c_str(), suffix.c_str());
 }
 
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 5412d4d..8fbea8a 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -389,7 +389,7 @@
         auto time_left_ms = [end]() {
             auto now = std::chrono::steady_clock::now();
             auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
-            return std::max(diff.count(), 0ll);
+            return std::max(diff.count(), 0LL);
         };
 
         int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index aad9939..25e5247 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -313,9 +313,14 @@
         bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
                                 vold_decrypt == "1";
 
-        const std::string resolve_startup_string_arg  =
+        const std::string resolve_startup_string_arg =
                 MapPropertyToArg("dalvik.vm.dex2oat-resolve-startup-strings",
                                  "--resolve-startup-const-strings=%s");
+
+        const std::string image_block_size_arg =
+                MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size",
+                                 "--max-image-block-size=%s");
+
         const bool generate_debug_info = GetBoolProperty("debug.generate-debug-info", false);
 
         std::string image_format_arg;
@@ -430,6 +435,7 @@
         AddRuntimeArg(dex2oat_Xmx_arg);
 
         AddArg(resolve_startup_string_arg);
+        AddArg(image_block_size_arg);
         AddArg(dex2oat_compiler_filter_arg);
         AddArg(dex2oat_threads_arg);
         AddArg(dex2oat_swap_fd);
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index a6d7a78..c706d91 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -376,23 +376,23 @@
     }
 
     mServicesTable.setDescription(
-            "All binderized services (registered services through hwservicemanager)");
+            "| All binderized services (registered with hwservicemanager)");
     mPassthroughRefTable.setDescription(
-            "All interfaces that getService() has ever return as a passthrough interface;\n"
-            "PIDs / processes shown below might be inaccurate because the process\n"
-            "might have relinquished the interface or might have died.\n"
-            "The Server / Server CMD column can be ignored.\n"
-            "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
-            "the library and successfully fetched the passthrough implementation.");
+            "| All interfaces that getService() has ever returned as a passthrough interface;\n"
+            "| PIDs / processes shown below might be inaccurate because the process\n"
+            "| might have relinquished the interface or might have died.\n"
+            "| The Server / Server CMD column can be ignored.\n"
+            "| The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
+            "| the library and successfully fetched the passthrough implementation.");
     mImplementationsTable.setDescription(
-            "All available passthrough implementations (all -impl.so files).\n"
-            "These may return subclasses through their respective HIDL_FETCH_I* functions.");
+            "| All available passthrough implementations (all -impl.so files).\n"
+            "| These may return subclasses through their respective HIDL_FETCH_I* functions.");
     mManifestHalsTable.setDescription(
-            "All HALs that are in VINTF manifest.");
+            "| All HALs that are in VINTF manifest.");
     mLazyHalsTable.setDescription(
-            "All HALs that are declared in VINTF manifest:\n"
-            "   - as hwbinder HALs but are not registered to hwservicemanager, and\n"
-            "   - as hwbinder/passthrough HALs with no implementation.");
+            "| All HALs that are declared in VINTF manifest:\n"
+            "|    - as hwbinder HALs but are not registered to hwservicemanager, and\n"
+            "|    - as hwbinder/passthrough HALs with no implementation.");
 }
 
 bool ListCommand::addEntryWithInstance(const TableEntry& entry,
@@ -972,10 +972,10 @@
         thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
         return OK;
     }, "print VINTF info. This column contains a comma-separated list of:\n"
-       "    - DM: device manifest\n"
-       "    - DC: device compatibility matrix\n"
-       "    - FM: framework manifest\n"
-       "    - FC: framework compatibility matrix"});
+       "    - DM: if the HAL is in the device manifest\n"
+       "    - DC: if the HAL is in the device compatibility matrix\n"
+       "    - FM: if the HAL is in the framework manifest\n"
+       "    - FC: if the HAL is in the framework compatibility matrix"});
     mOptions.push_back({'S', "service-status", no_argument, v++, [](ListCommand* thiz, const char*) {
         thiz->mSelectedColumns.push_back(TableColumnType::SERVICE_STATUS);
         return OK;
@@ -1054,7 +1054,7 @@
         return OK;
     }, "comma-separated list of one or more sections.\nThe output is restricted to the selected "
        "section(s). Valid options\nare: (b|binderized), (c|passthrough_clients), (l|"
-       "passthrough_libs), and (v|vintf).\nDefault is `bcl`."});
+       "passthrough_libs), (v|vintf), and (z|lazy).\nDefault is `bcl`."});
 }
 
 // Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
@@ -1150,7 +1150,7 @@
     }
 
     if (mSelectedColumns.empty()) {
-        mSelectedColumns = {TableColumnType::RELEASED,
+        mSelectedColumns = {TableColumnType::VINTF, TableColumnType::RELEASED,
                             TableColumnType::INTERFACE_NAME, TableColumnType::THREADS,
                             TableColumnType::SERVER_PID, TableColumnType::CLIENT_PIDS};
     }
@@ -1210,7 +1210,7 @@
     err() << "list:" << std::endl
           << "    lshal" << std::endl
           << "    lshal list" << std::endl
-          << "        List all hals with default ordering and columns (`lshal list -liepc`)" << std::endl
+          << "        List all hals with default ordering and columns (`lshal list -Vliepc`)" << std::endl
           << "    lshal list [-h|--help]" << std::endl
           << "        -h, --help: Print help message for list (`lshal help list`)" << std::endl
           << "    lshal [list] [OPTIONS...]" << std::endl;
diff --git a/cmds/rss_hwm_reset/Android.bp b/cmds/rss_hwm_reset/Android.bp
new file mode 100644
index 0000000..15f10ef
--- /dev/null
+++ b/cmds/rss_hwm_reset/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://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.
+
+cc_binary {
+    name: "rss_hwm_reset",
+
+    srcs: [
+        "rss_hwm_reset.cc",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+
+    init_rc: ["rss_hwm_reset.rc"],
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.cc b/cmds/rss_hwm_reset/rss_hwm_reset.cc
new file mode 100644
index 0000000..1626e7e
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://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.
+ */
+
+ /*
+  * rss_hwm_reset clears the RSS high-water mark counters for all currently
+  * running processes. It writes "5" to /proc/PID/clear_refs for every PID.
+  *
+  * It runs in its own process becuase dac_override capability is required
+  * in order to write to other processes' clear_refs.
+  *
+  * It is invoked from a system service by flipping sys.rss_hwm_reset.on
+  * property to "1".
+  */
+
+#define LOG_TAG "rss_hwm_reset"
+
+#include <dirent.h>
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+
+namespace {
+// Resets RSS HWM counter for the selected process by writing 5 to
+// /proc/PID/clear_refs.
+void reset_rss_hwm(const char* pid) {
+    std::string clear_refs_path =
+            ::android::base::StringPrintf("/proc/%s/clear_refs", pid);
+    ::android::base::WriteStringToFile("5", clear_refs_path);
+}
+}
+
+// Clears RSS HWM counters for all currently running processes.
+int main(int /* argc */, char** /* argv[] */) {
+    DIR* dirp = opendir("/proc");
+    if (dirp == nullptr) {
+        ALOGE("unable to read /proc");
+        return 1;
+    }
+    struct dirent* entry;
+    while ((entry = readdir(dirp)) != nullptr) {
+        // Skip entries that are not directories.
+        if (entry->d_type != DT_DIR) continue;
+        // Skip entries that do not contain only numbers.
+        const char* pid = entry->d_name;
+        while (*pid) {
+            if (*pid < '0' || *pid > '9') break;
+            pid++;
+        }
+        if (*pid != 0) continue;
+
+        pid = entry->d_name;
+        reset_rss_hwm(pid);
+    }
+    closedir(dirp);
+    return 0;
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.rc b/cmds/rss_hwm_reset/rss_hwm_reset.rc
new file mode 100644
index 0000000..fbbc820
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.rc
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://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.
+
+service rss_hwm_reset /system/bin/rss_hwm_reset
+    class late_start
+    disabled
+    oneshot
+    user nobody
+    group nobody readproc
+    writepid /dev/cpuset/system-background/tasks
+    capabilities DAC_OVERRIDE
+
+on property:sys.rss_hwm_reset.on=1
+    start rss_hwm_reset
+    setprop sys.rss_hwm_reset.on 0
diff --git a/headers/media_plugin/media/cas/DescramblerAPI.h b/headers/media_plugin/media/cas/DescramblerAPI.h
index 033c8ce..c57f606 100644
--- a/headers/media_plugin/media/cas/DescramblerAPI.h
+++ b/headers/media_plugin/media/cas/DescramblerAPI.h
@@ -72,12 +72,12 @@
     // associated MediaCas session is used to load decryption keys
     // into the crypto/cas plugin.  The keys are then referenced by key-id
     // in the 'key' parameter to the decrypt() method.
-    // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if
+    // Should return NO_ERROR on success, ERROR_CAS_SESSION_NOT_OPENED if
     // the session is not opened and a code from MediaErrors.h otherwise.
     virtual status_t setMediaCasSession(const CasSessionId& sessionId) = 0;
 
     // If the error returned falls into the range
-    // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be
+    // ERROR_CAS_VENDOR_MIN..ERROR_CAS_VENDOR_MAX, errorDetailMsg should be
     // filled in with an appropriate string.
     // At the java level these special errors will then trigger a
     // MediaCodec.CryptoException that gives clients access to both
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 4d24680..ed9531e 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -110,6 +110,47 @@
 
 #endif /* __ANDROID_API__ >= 23 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated
+ * with Domain Name |dname| on the given |network|.
+ * The typical value for |ns_class| is ns_c_in, while |type| can be any
+ * record type (for instance, ns_t_aaaa or ns_t_txt).
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nquery(net_handle_t network,
+        const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29);
+
+/**
+ * Issue the query |msg| on the given |network|.
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nsend(net_handle_t network,
+        const unsigned char *msg, int msglen) __INTRODUCED_IN(29);
+
+/**
+ * Read a result for the query associated with the |fd| descriptor.
+ *
+ * Returns:
+ *     < 0: negative POSIX error code (see errno.h for possible values). |rcode| is not set.
+ *     >= 0: length of |answer|. |rcode| is the resolver return code (e.g., ns_r_nxdomain)
+ */
+int android_res_nresult(int fd,
+        int *rcode, unsigned char *answer, int anslen) __INTRODUCED_IN(29);
+
+/**
+ * Attempts to cancel the in-progress query associated with the |nsend_fd|
+ * descriptor.
+ */
+void android_res_cancel(int nsend_fd) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif  // ANDROID_MULTINETWORK_H
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 07d5c4b..b2db945 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -467,7 +467,6 @@
 
 status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
 {
-    const sp<ProcessState> proc(ProcessState::self());
     status_t err;
     const uint8_t *data = parcel->mData;
     const binder_size_t *objects = parcel->mObjects;
@@ -520,6 +519,7 @@
     err = NO_ERROR;
 
     if (numObjects > 0) {
+        const sp<ProcessState> proc(ProcessState::self());
         // grow objects
         if (mObjectsCapacity < mObjectsSize + numObjects) {
             size_t newSize = ((mObjectsSize + numObjects)*3)/2;
@@ -2543,8 +2543,11 @@
 
 void Parcel::releaseObjects()
 {
-    const sp<ProcessState> proc(ProcessState::self());
     size_t i = mObjectsSize;
+    if (i == 0) {
+        return;
+    }
+    sp<ProcessState> proc(ProcessState::self());
     uint8_t* const data = mData;
     binder_size_t* const objects = mObjects;
     while (i > 0) {
@@ -2557,8 +2560,11 @@
 
 void Parcel::acquireObjects()
 {
-    const sp<ProcessState> proc(ProcessState::self());
     size_t i = mObjectsSize;
+    if (i == 0) {
+        return;
+    }
+    const sp<ProcessState> proc(ProcessState::self());
     uint8_t* const data = mData;
     binder_size_t* const objects = mObjects;
     while (i > 0) {
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 14ce4cb..1b69dfd 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -23,6 +23,8 @@
         "include_apex",
     ],
 
+    cflags: ["-Wall", "-Wextra", "-Werror"],
+
     srcs: [
         "ibinder.cpp",
         "ibinder_jni.cpp",
@@ -39,9 +41,11 @@
         "libutils",
     ],
 
-    cpp_std: "c++17",
-
     version_script: "libbinder_ndk.map.txt",
+    stubs: {
+        symbol_file: "libbinder_ndk.map.txt",
+        versions: ["29"],
+    },
 }
 
 ndk_headers {
@@ -52,10 +56,12 @@
         "include_ndk/android/*.h",
     ],
     license: "NOTICE",
+    draft: true,
 }
 
 ndk_library {
     name: "libbinder_ndk",
     symbol_file: "libbinder_ndk.map.txt",
     first_version: "29",
+    draft: true,
 }
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index c6fcaa4..ff1860e 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -163,9 +163,7 @@
     ScopedAResource& operator=(ScopedAResource&&) = delete;
 
     // move-constructing is okay
-    ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) {
-      other.mT = DEFAULT;
-    }
+    ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) { other.mT = DEFAULT; }
 
    private:
     T mT;
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 3594349..2258210 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -54,6 +54,31 @@
 void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29);
 
 /**
+ * Sets the position within the parcel.
+ *
+ * \param parcel The parcel of which to set the position.
+ * \param position Position of the parcel to set. This must be a value returned by
+ * AParcel_getDataPosition. Positions are constant for a given parcel between processes.
+ *
+ * \return STATUS_OK on success. If position is negative, then STATUS_BAD_VALUE will be returned.
+ */
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position)
+        __INTRODUCED_IN(29);
+
+/**
+ * Gets the current position within the parcel.
+ *
+ * \param parcel The parcel of which to get the position.
+ *
+ * \return The size of the parcel. This will always be greater than 0. The values returned by this
+ * function before and after calling various reads and writes are not defined. Only the delta
+ * between two positions between a specific sequence of calls is defined. For instance, if position
+ * is X, writeBool is called, and then position is Y, readBool can be called from position X will
+ * return the same value, and then position will be Y.
+ */
+int32_t AParcel_getDataPosition(const AParcel* parcel) __INTRODUCED_IN(29);
+
+/**
  * This is called to allocate a buffer for a C-style string (null-terminated). The returned buffer
  * should be at least length bytes. This includes space for a null terminator. For a string, length
  * will always be strictly less than or equal to the maximum size that can be held in a size_t and
@@ -124,7 +149,49 @@
  * not required to be null-terminated. If the object at index is null, then this should be null.
  */
 typedef const char* (*AParcel_stringArrayElementGetter)(const void* arrayData, size_t index,
-                                                        size_t* outLength);
+                                                        int32_t* outLength);
+
+/**
+ * This is called to allocate an array of size 'length'. If length is -1, then a 'null' array (or
+ * equivalent) should be created.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param arrayData some external representation of an array
+ * \param length the length to allocate this array to
+ *
+ * \return true if allocation succeeded. If length is -1, a true return here means that a 'null'
+ * value (or equivalent) was successfully stored.
+ */
+typedef bool (*AParcel_parcelableArrayAllocator)(void* arrayData, int32_t length);
+
+/**
+ * This is called to parcel the underlying data from an arrayData object at index.
+ *
+ * See also AParcel_writeParcelableArray
+ *
+ * \param parcel parcel to write the parcelable to
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be retrieved.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_writeParcelableElement)(AParcel* parcel, const void* arrayData,
+                                                          size_t index);
+
+/**
+ * This is called to set an underlying value in an arrayData object at index.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param parcel parcel to read the parcelable from
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be set.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_readParcelableElement)(const AParcel* parcel, void* arrayData,
+                                                         size_t index);
 
 // @START-PRIMITIVE-VECTOR-GETTERS
 /**
@@ -472,6 +539,40 @@
                                         AParcel_stringArrayElementAllocator elementAllocator)
         __INTRODUCED_IN(29);
 
+/**
+ * Writes an array of parcelables (user-defined types) to the next location in a non-null parcel.
+ *
+ * \param parcel the parcel to write to.
+ * \param arrayData an array of size 'length' (or null if length is -1, may be null if length is 0).
+ * \param length the length of arrayData or -1 if this represents a null array.
+ * \param elementWriter function to be called for every array index to write the user-defined type
+ * at that location.
+ *
+ * \return STATUS_OK on successful write.
+ */
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+                                             AParcel_writeParcelableElement elementWriter)
+        __INTRODUCED_IN(29);
+
+/**
+ * Reads an array of parcelables (user-defined types) from the next location in a non-null parcel.
+ *
+ * First, allocator will be called with the length of the array. If the allocation succeeds and the
+ * length is greater than zero, elementReader will be called for every index to read the
+ * corresponding parcelable.
+ *
+ * \param parcel the parcel to read from.
+ * \param arrayData some external representation of an array.
+ * \param allocator the callback that will be called to allocate the array.
+ * \param elementReader the callback that will be called to fill out individual elements.
+ *
+ * \return STATUS_OK on successful read.
+ */
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+                                            AParcel_parcelableArrayAllocator allocator,
+                                            AParcel_readParcelableElement elementReader)
+        __INTRODUCED_IN(29);
+
 // @START-PRIMITIVE-READ-WRITE
 /**
  * Writes int32_t value to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index f99c3a9..f3bc31b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -43,7 +43,7 @@
     if (length < 0) return false;
 
     std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
-    if (length > vec->max_size()) return false;
+    if (static_cast<size_t>(length) > vec->max_size()) return false;
 
     vec->resize(length);
     *outBuffer = vec->data();
@@ -65,7 +65,7 @@
 
     *vec = std::optional<std::vector<T>>(std::vector<T>{});
 
-    if (length > (*vec)->max_size()) return false;
+    if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
     (*vec)->resize(length);
 
     *outBuffer = (*vec)->data();
@@ -88,7 +88,7 @@
     if (length < 0) return false;
 
     std::vector<T>* vec = static_cast<std::vector<T>*>(vectorData);
-    if (length > vec->max_size()) return false;
+    if (static_cast<size_t>(length) > vec->max_size()) return false;
 
     vec->resize(length);
     return true;
@@ -116,7 +116,7 @@
 
     *vec = std::optional<std::vector<T>>(std::vector<T>{});
 
-    if (length > (*vec)->max_size()) return false;
+    if (static_cast<size_t>(length) > (*vec)->max_size()) return false;
     (*vec)->resize(length);
 
     return true;
@@ -299,7 +299,7 @@
  * index.
  */
 static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index,
-                                                               size_t* outLength) {
+                                                               int32_t* outLength) {
     const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData);
     const std::string& element = vec->at(index);
 
@@ -327,7 +327,7 @@
  */
 static inline const char* AParcel_nullableStdVectorStringElementGetter(const void* vectorData,
                                                                        size_t index,
-                                                                       size_t* outLength) {
+                                                                       int32_t* outLength) {
     const std::optional<std::vector<std::optional<std::string>>>* vec =
             static_cast<const std::optional<std::vector<std::optional<std::string>>>*>(vectorData);
     const std::optional<std::string>& element = vec->value().at(index);
@@ -420,6 +420,46 @@
             AParcel_nullableStdVectorStringElementAllocator);
 }
 
+/**
+ * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_writeStdVectorParcelableElement(AParcel* parcel, const void* vectorData,
+                                                        size_t index) {
+    const std::vector<P>* vector = static_cast<const std::vector<P>*>(vectorData);
+    return vector->at(index).writeToParcel(parcel);
+}
+
+/**
+ * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_readStdVectorParcelableElement(const AParcel* parcel, void* vectorData,
+                                                       size_t index) {
+    std::vector<P>* vector = static_cast<std::vector<P>*>(vectorData);
+    return vector->at(index).readFromParcel(parcel);
+}
+
+/**
+ * Convenience API for writing a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<P>& vec) {
+    const void* vectorData = static_cast<const void*>(&vec);
+    return AParcel_writeParcelableArray(parcel, vectorData, vec.size(),
+                                        AParcel_writeStdVectorParcelableElement<P>);
+}
+
+/**
+ * Convenience API for reading a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<P>* vec) {
+    void* vectorData = static_cast<void*>(vec);
+    return AParcel_readParcelableArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<P>,
+                                       AParcel_readStdVectorParcelableElement<P>);
+}
+
 // @START
 /**
  * Writes a vector of int32_t to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 41df90b..ee7132f 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -25,6 +25,7 @@
     AIBinder_Weak_new;
     AIBinder_Weak_promote;
     AParcel_delete;
+    AParcel_getDataPosition;
     AParcel_readBool;
     AParcel_readBoolArray;
     AParcel_readByte;
@@ -39,6 +40,7 @@
     AParcel_readInt32Array;
     AParcel_readInt64;
     AParcel_readInt64Array;
+    AParcel_readParcelableArray;
     AParcel_readParcelFileDescriptor;
     AParcel_readStatusHeader;
     AParcel_readString;
@@ -48,6 +50,7 @@
     AParcel_readUint32Array;
     AParcel_readUint64;
     AParcel_readUint64Array;
+    AParcel_setDataPosition;
     AParcel_writeBool;
     AParcel_writeBoolArray;
     AParcel_writeByte;
@@ -62,6 +65,7 @@
     AParcel_writeInt32Array;
     AParcel_writeInt64;
     AParcel_writeInt64Array;
+    AParcel_writeParcelableArray;
     AParcel_writeParcelFileDescriptor;
     AParcel_writeStatusHeader;
     AParcel_writeString;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 3c32100..ae2276e 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -173,7 +173,7 @@
 
     Parcel* rawParcel = parcel->get();
 
-    for (size_t i = 0; i < length; i++) {
+    for (int32_t i = 0; i < length; i++) {
         status = (rawParcel->*write)(getter(arrayData, i));
 
         if (status != STATUS_OK) return PruneStatusT(status);
@@ -197,7 +197,7 @@
 
     if (length <= 0) return STATUS_OK;
 
-    for (size_t i = 0; i < length; i++) {
+    for (int32_t i = 0; i < length; i++) {
         T readTarget;
         status = (rawParcel->*read)(&readTarget);
         if (status != STATUS_OK) return PruneStatusT(status);
@@ -212,6 +212,19 @@
     delete parcel;
 }
 
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
+    if (position < 0) {
+        return STATUS_BAD_VALUE;
+    }
+
+    parcel->get()->setDataPosition(position);
+    return STATUS_OK;
+}
+
+int32_t AParcel_getDataPosition(const AParcel* parcel) {
+    return parcel->get()->dataPosition();
+}
+
 binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
     sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
     return parcel->get()->writeStrongBinder(writeBinder);
@@ -363,12 +376,12 @@
     if (status != STATUS_OK) return status;
     if (length <= 0) return STATUS_OK;
 
-    for (size_t i = 0; i < length; i++) {
-        size_t length = 0;
-        const char* str = getter(arrayData, i, &length);
-        if (str == nullptr && length != -1) return STATUS_BAD_VALUE;
+    for (int32_t i = 0; i < length; i++) {
+        int32_t elementLength = 0;
+        const char* str = getter(arrayData, i, &elementLength);
+        if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
 
-        binder_status_t status = AParcel_writeString(parcel, str, length);
+        binder_status_t status = AParcel_writeString(parcel, str, elementLength);
         if (status != STATUS_OK) return status;
     }
 
@@ -379,7 +392,7 @@
 // allocator.
 struct StringArrayElementAllocationAdapter {
     void* arrayData;  // stringData from the NDK
-    size_t index;     // index into the string array
+    int32_t index;    // index into the string array
     AParcel_stringArrayElementAllocator elementAllocator;
 
     static bool Allocator(void* stringData, int32_t length, char** buffer) {
@@ -420,6 +433,45 @@
     return STATUS_OK;
 }
 
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+                                             AParcel_writeParcelableElement elementWriter) {
+    // we have no clue if arrayData represents a null object or not, we can only infer from length
+    bool arrayIsNull = length < 0;
+    binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
+    if (status != STATUS_OK) return status;
+    if (length <= 0) return STATUS_OK;
+
+    for (int32_t i = 0; i < length; i++) {
+        binder_status_t status = elementWriter(parcel, arrayData, i);
+        if (status != STATUS_OK) return status;
+    }
+
+    return STATUS_OK;
+}
+
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+                                            AParcel_parcelableArrayAllocator allocator,
+                                            AParcel_readParcelableElement elementReader) {
+    const Parcel* rawParcel = parcel->get();
+
+    int32_t length;
+    status_t status = rawParcel->readInt32(&length);
+
+    if (status != STATUS_OK) return PruneStatusT(status);
+    if (length < -1) return STATUS_BAD_VALUE;
+
+    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
+
+    if (length == -1) return STATUS_OK;  // null array
+
+    for (int32_t i = 0; i < length; i++) {
+        binder_status_t status = elementReader(parcel, arrayData, i);
+        if (status != STATUS_OK) return status;
+    }
+
+    return STATUS_OK;
+}
+
 // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
 // libbinder and this library.
 // @START
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index 67481cf..b29b6e7 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -22,7 +22,6 @@
     strip: {
         none: true,
     },
-    cpp_std: "c++17",
     cflags: [
         "-O0",
         "-g",
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 73c2eba..2dd86ba 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -1295,7 +1295,7 @@
         }
         IPCThreadState::self()->flushCommands(); // flush BC_ENTER_LOOPER
 
-        epoll_fd = epoll_create1(0);
+        epoll_fd = epoll_create1(EPOLL_CLOEXEC);
         if (epoll_fd == -1) {
             return 1;
         }
diff --git a/libs/binder/tests/binderValueTypeTest.cpp b/libs/binder/tests/binderValueTypeTest.cpp
index 15949d4..f8922b0 100644
--- a/libs/binder/tests/binderValueTypeTest.cpp
+++ b/libs/binder/tests/binderValueTypeTest.cpp
@@ -75,13 +75,13 @@
 
 VALUE_TYPE_TEST(bool, Boolean, true)
 VALUE_TYPE_TEST(int32_t, Int, 31337)
-VALUE_TYPE_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_TEST(int64_t, Long, 13370133701337L)
 VALUE_TYPE_TEST(double, Double, 3.14159265358979323846)
 VALUE_TYPE_TEST(String16, String, String16("Lovely"))
 
 VALUE_TYPE_VECTOR_TEST(bool, Boolean, true)
 VALUE_TYPE_VECTOR_TEST(int32_t, Int, 31337)
-VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337L)
 VALUE_TYPE_VECTOR_TEST(double, Double, 3.14159265358979323846)
 VALUE_TYPE_VECTOR_TEST(String16, String, String16("Lovely"))
 
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 8b2f842..35296a9 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -47,6 +47,7 @@
         "android.hardware.camera.provider@2.4::ICameraProvider",
         "android.hardware.drm@1.0::IDrmFactory",
         "android.hardware.graphics.composer@2.1::IComposer",
+        "android.hardware.health@2.0::IHealth",
         "android.hardware.media.omx@1.0::IOmx",
         "android.hardware.media.omx@1.0::IOmxStore",
         "android.hardware.sensors@1.0::ISensors",
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index e22bc70..d2d27e8 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -332,6 +332,34 @@
         return result;
     }
 
+    virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+        Parcel data, reply;
+        status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            ALOGE("getDisplayViewport failed to writeInterfaceToken: %d", result);
+            return result;
+        }
+        result = data.writeStrongBinder(display);
+        if (result != NO_ERROR) {
+            ALOGE("getDisplayViewport failed to writeStrongBinder: %d", result);
+            return result;
+        }
+        result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_VIEWPORT, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("getDisplayViewport failed to transact: %d", result);
+            return result;
+        }
+        result = reply.readInt32();
+        if (result == NO_ERROR) {
+            result = reply.read(*outViewport);
+            if (result != NO_ERROR) {
+                ALOGE("getDisplayViewport failed to read: %d", result);
+                return result;
+            }
+        }
+        return result;
+    }
+
     virtual int getActiveConfig(const sp<IBinder>& display)
     {
         Parcel data, reply;
@@ -724,6 +752,26 @@
             }
             return NO_ERROR;
         }
+        case GET_DISPLAY_VIEWPORT: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            Rect outViewport;
+            sp<IBinder> display = nullptr;
+            status_t result = data.readStrongBinder(&display);
+            if (result != NO_ERROR) {
+                ALOGE("getDisplayViewport failed to readStrongBinder: %d", result);
+                return result;
+            }
+            result = getDisplayViewport(display, &outViewport);
+            result = reply->writeInt32(result);
+            if (result == NO_ERROR) {
+                result = reply->write(outViewport);
+                if (result != NO_ERROR) {
+                    ALOGE("getDisplayViewport failed to write: %d", result);
+                    return result;
+                }
+            }
+            return NO_ERROR;
+        }
         case GET_ACTIVE_CONFIG: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> display = data.readStrongBinder();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 63560c4..f3c6fd2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -718,6 +718,10 @@
     return NO_ERROR;
 }
 
+status_t SurfaceComposerClient::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+    return ComposerService::getComposerService()->getDisplayViewport(display, outViewport);
+}
+
 int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) {
     return ComposerService::getComposerService()->getActiveConfig(display);
 }
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index 3b89291..b1e44bb 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -896,7 +896,7 @@
     int const* constFds = static_cast<int const*>(baseFds.get());
     numFds = baseNumFds;
     if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        for (auto nhA : nhAA) {
+        for (const auto& nhA : nhAA) {
             for (auto nh : nhA) {
                 if (nh != nullptr) {
                     native_handle_close(nh);
@@ -907,8 +907,8 @@
         return false;
     }
 
-    for (auto nhA : nhAA) {
-        for (auto nh : nhA) {
+    for (const auto& nhA : nhAA) {
+        for (const auto& nh : nhA) {
             if (nh != nullptr) {
                 native_handle_delete(nh);
             }
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e401572..99a3a75 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -157,6 +157,9 @@
     virtual status_t getDisplayStats(const sp<IBinder>& display,
             DisplayStatInfo* stats) = 0;
 
+    /* returns display viewport information of the given display */
+    virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) = 0;
+
     /* indicates which of the configurations returned by getDisplayInfo is
      * currently active */
     virtual int getActiveConfig(const sp<IBinder>& display) = 0;
@@ -250,7 +253,8 @@
         ENABLE_VSYNC_INJECTIONS,
         INJECT_VSYNC,
         GET_LAYER_DEBUG_INFO,
-        CREATE_SCOPED_CONNECTION
+        CREATE_SCOPED_CONNECTION,
+        GET_DISPLAY_VIEWPORT
     };
 
     virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 377fe68..ad8a8b0 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -79,6 +79,9 @@
     static status_t getDisplayInfo(const sp<IBinder>& display,
             DisplayInfo* info);
 
+    // Get the display viewport for the given display
+    static status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
+
     // Get the index of the current active configuration (relative to the list
     // returned by getDisplayInfo)
     static int getActiveConfig(const sp<IBinder>& display);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 2c02ba6..6e196bf 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -581,6 +581,9 @@
             Vector<DisplayInfo>* /*configs*/) override { return NO_ERROR; }
     status_t getDisplayStats(const sp<IBinder>& /*display*/,
             DisplayStatInfo* /*stats*/) override { return NO_ERROR; }
+    status_t getDisplayViewport(const sp<IBinder>& /*display*/, Rect* /*outViewport*/) override {
+        return NO_ERROR;
+    }
     int getActiveConfig(const sp<IBinder>& /*display*/) override { return 0; }
     status_t setActiveConfig(const sp<IBinder>& /*display*/, int /*id*/)
             override {
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index a2d6a8a..2f39976 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -16,7 +16,6 @@
 
 cc_library {
     name: "libinput",
-    cpp_std: "c++17",
     host_supported: true,
     cflags: [
         "-Wall",
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 5fbb3b2..d74bdb3 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -43,10 +43,6 @@
         "-Wno-unused-function",
     ],
 
-    cppflags: [
-        "-std=c++1z"
-    ],
-
     version_script: "libnativewindow.map.txt",
 
     srcs: [
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 9ca4941..52b4582 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -15,12 +15,31 @@
  */
 
 /**
- * @addtogroup NativeActivity Native Activity
- * @{
- */
-
-/**
  * @file hardware_buffer.h
+ * @brief API for native hardware buffers.
+ */
+/**
+ * @defgroup AHardwareBuffer Native Hardware Buffer
+ *
+ * AHardwareBuffer objects represent chunks of memory that can be
+ * accessed by various hardware components in the system. It can be
+ * easily converted to the Java counterpart
+ * android.hardware.HardwareBuffer and passed between processes using
+ * Binder. All operations involving AHardwareBuffer and HardwareBuffer
+ * are zero-copy, i.e., passing AHardwareBuffer to another process
+ * creates a shared view of the same region of memory.
+ *
+ * AHardwareBuffers can be bound to EGL/OpenGL and Vulkan primitives.
+ * For EGL, use the extension function eglGetNativeClientBufferANDROID
+ * to obtain an EGLClientBuffer and pass it directly to
+ * eglCreateImageKHR. Refer to the EGL extensions
+ * EGL_ANDROID_get_native_client_buffer and
+ * EGL_ANDROID_image_native_buffer for more information. In Vulkan,
+ * the contents of the AHardwareBuffer can be accessed as external
+ * memory. See the VK_ANDROID_external_memory_android_hardware_buffer
+ * extension for details.
+ *
+ * @{
  */
 
 #ifndef ANDROID_HARDWARE_BUFFER_H
@@ -37,7 +56,7 @@
 /**
  * Buffer pixel formats.
  */
-enum {
+enum AHardwareBuffer_Format {
     /**
      * Corresponding formats:
      *   Vulkan: VK_FORMAT_R8G8B8A8_UNORM
@@ -83,8 +102,10 @@
     AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM        = 0x2b,
 
     /**
-     * An opaque binary blob format that must have height 1, with width equal to
-     * the buffer size in bytes.
+     * Opaque binary blob format.
+     * Must have height 1 and one layer, with width equal to the buffer
+     * size in bytes. Corresponds to Vulkan buffers and OpenGL buffer
+     * objects. Can be bound to the latter using GL_EXT_external_buffer.
      */
     AHARDWAREBUFFER_FORMAT_BLOB                     = 0x21,
 
@@ -134,21 +155,39 @@
 /**
  * Buffer usage flags, specifying how the buffer will be accessed.
  */
-enum {
-    /// The buffer will never be read by the CPU.
+enum AHardwareBuffer_UsageFlags {
+    /// The buffer will never be locked for direct CPU reads using the
+    /// AHardwareBuffer_lock() function. Note that reading the buffer
+    /// using OpenGL or Vulkan functions or memory mappings is still
+    /// allowed.
     AHARDWAREBUFFER_USAGE_CPU_READ_NEVER        = 0UL,
-    /// The buffer will sometimes be read by the CPU.
+    /// The buffer will sometimes be locked for direct CPU reads using
+    /// the AHardwareBuffer_lock() function. Note that reading the
+    /// buffer using OpenGL or Vulkan functions or memory mappings
+    /// does not require the presence of this flag.
     AHARDWAREBUFFER_USAGE_CPU_READ_RARELY       = 2UL,
-    /// The buffer will often be read by the CPU.
+    /// The buffer will often be locked for direct CPU reads using
+    /// the AHardwareBuffer_lock() function. Note that reading the
+    /// buffer using OpenGL or Vulkan functions or memory mappings
+    /// does not require the presence of this flag.
     AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN        = 3UL,
     /// CPU read value mask.
     AHARDWAREBUFFER_USAGE_CPU_READ_MASK         = 0xFUL,
 
-    /// The buffer will never be written by the CPU.
+    /// The buffer will never be locked for direct CPU writes using the
+    /// AHardwareBuffer_lock() function. Note that writing the buffer
+    /// using OpenGL or Vulkan functions or memory mappings is still
+    /// allowed.
     AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER       = 0UL << 4,
-    /// The buffer will sometimes be written to by the CPU.
+    /// The buffer will sometimes be locked for direct CPU writes using
+    /// the AHardwareBuffer_lock() function. Note that writing the
+    /// buffer using OpenGL or Vulkan functions or memory mappings
+    /// does not require the presence of this flag.
     AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY      = 2UL << 4,
-    /// The buffer will often be written to by the CPU.
+    /// The buffer will often be locked for direct CPU writes using
+    /// the AHardwareBuffer_lock() function. Note that writing the
+    /// buffer using OpenGL or Vulkan functions or memory mappings
+    /// does not require the presence of this flag.
     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN       = 3UL << 4,
     /// CPU write value mask.
     AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK        = 0xFUL << 4,
@@ -156,24 +195,51 @@
     /// The buffer will be read from by the GPU as a texture.
     AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE      = 1UL << 8,
     /**
-     * The buffer will be written to by the GPU as a framebuffer attachment.
-     * Note that the name of this flag is somewhat misleading: it does not imply
-     * that the buffer contains a color format. A buffer with depth or stencil
-     * format that will be used as a framebuffer attachment should also have
-     * this flag.
+     * The buffer will be written to by the GPU as a framebuffer
+     * attachment.
+     *
+     * Note that the name of this flag is somewhat misleading: it does
+     * not imply that the buffer contains a color format. A buffer with
+     * depth or stencil format that will be used as a framebuffer
+     * attachment should also have this flag.
      */
     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT       = 1UL << 9,
-    /// The buffer must not be used outside of a protected hardware path.
+    /**
+     * The buffer is protected from direct CPU access or being read by
+     * non-secure hardware, such as video encoders.
+     *
+     * This flag is incompatible with CPU read and write flags. It is
+     * mainly used when handling DRM video. Refer to the EGL extension
+     * EGL_EXT_protected_content and GL extension
+     * GL_EXT_protected_textures for more information on how these
+     * buffers are expected to behave.
+     */
     AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT      = 1UL << 14,
     /// The buffer will be read by a hardware video encoder.
     AHARDWAREBUFFER_USAGE_VIDEO_ENCODE           = 1UL << 16,
-    /// The buffer will be used for direct writes from sensors.
+    /**
+     * The buffer will be used for direct writes from sensors.
+     * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
+     */
     AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA     = 1UL << 23,
-    /// The buffer will be used as a shader storage or uniform buffer object.
+    /**
+     * The buffer will be used as a shader storage or uniform buffer object.
+     * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
+     */
     AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER        = 1UL << 24,
-    /// The buffer will be used as a cube map texture.
+    /**
+     * The buffer will be used as a cube map texture.
+     * When this flag is present, the buffer must have a layer count
+     * that is a multiple of 6. Note that buffers with this flag must be
+     * bound to OpenGL textures using the extension
+     * GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
+     */
     AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP               = 1UL << 25,
-    /// The buffer contains a complete mipmap hierarchy.
+    /**
+     * The buffer contains a complete mipmap hierarchy.
+     * Note that buffers with this flag must be bound to OpenGL textures using
+     * the extension GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
+     */
     AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE        = 1UL << 26,
 
     AHARDWAREBUFFER_USAGE_VENDOR_0  = 1ULL << 28,
@@ -199,27 +265,42 @@
 };
 
 /**
- * Buffer description. Used for allocating new buffers and querying parameters
- * of existing ones.
+ * Buffer description. Used for allocating new buffers and querying
+ * parameters of existing ones.
  */
 typedef struct AHardwareBuffer_Desc {
     uint32_t    width;      ///< Width in pixels.
     uint32_t    height;     ///< Height in pixels.
-    uint32_t    layers;     ///< Number of images in an image array.
-    uint32_t    format;     ///< One of AHARDWAREBUFFER_FORMAT_*
-    uint64_t    usage;      ///< Combination of AHARDWAREBUFFER_USAGE_*
+    /**
+     * Number of images in an image array. AHardwareBuffers with one
+     * layer correspond to regular 2D textures. AHardwareBuffers with
+     * more than layer correspond to texture arrays. If the layer count
+     * is a multiple of 6 and the usage flag
+     * AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP is present, the buffer is
+     * a cube map or a cube map array.
+     */
+    uint32_t    layers;
+    uint32_t    format;     ///< One of AHardwareBuffer_Format.
+    uint64_t    usage;      ///< Combination of AHardwareBuffer_UsageFlags.
     uint32_t    stride;     ///< Row stride in pixels, ignored for AHardwareBuffer_allocate()
     uint32_t    rfu0;       ///< Initialize to zero, reserved for future use.
     uint64_t    rfu1;       ///< Initialize to zero, reserved for future use.
 } AHardwareBuffer_Desc;
 
+/**
+ * Opaque handle for a native hardware buffer.
+ */
 typedef struct AHardwareBuffer AHardwareBuffer;
 
 #if __ANDROID_API__ >= 26
 
 /**
- * Allocates a buffer that backs an AHardwareBuffer using the passed
- * AHardwareBuffer_Desc.
+ * Allocates a buffer that matches the passed AHardwareBuffer_Desc.
+ *
+ * If allocation succeeds, the buffer can be used according to the
+ * usage flags specified in its description. If a buffer is used in ways
+ * not compatible with its usage flags, the results are undefined and
+ * may include program termination.
  *
  * \return 0 on success, or an error number of the allocation fails for
  * any reason. The returned buffer has a reference count of 1.
@@ -227,14 +308,16 @@
 int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
         AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
 /**
- * Acquire a reference on the given AHardwareBuffer object.  This prevents the
- * object from being deleted until the last reference is removed.
+ * Acquire a reference on the given AHardwareBuffer object.
+ *
+ * This prevents the object from being deleted until the last reference
+ * is removed.
  */
 void AHardwareBuffer_acquire(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
 /**
  * Remove a reference that was previously acquired with
- * AHardwareBuffer_acquire().
+ * AHardwareBuffer_acquire() or AHardwareBuffer_allocate().
  */
 void AHardwareBuffer_release(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
@@ -246,50 +329,73 @@
         AHardwareBuffer_Desc* outDesc) __INTRODUCED_IN(26);
 
 /**
- * Lock the AHardwareBuffer for reading or writing, depending on the usage flags
- * passed.  This call may block if the hardware needs to finish rendering or if
- * CPU caches need to be synchronized, or possibly for other implementation-
- * specific reasons.  If fence is not negative, then it specifies a fence file
- * descriptor that will be signaled when the buffer is locked, otherwise the
- * caller will block until the buffer is available.
+ * Lock the AHardwareBuffer for direct CPU access.
  *
- * If \a rect is not NULL, the caller promises to modify only data in the area
- * specified by rect. If rect is NULL, the caller may modify the contents of the
- * entire buffer.
+ * This function can lock the buffer for either reading or writing.
+ * It may block if the hardware needs to finish rendering, if CPU caches
+ * need to be synchronized, or possibly for other implementation-
+ * specific reasons.
  *
- * The content of the buffer outside of the specified rect is NOT modified
- * by this call.
+ * The passed AHardwareBuffer must have one layer, otherwise the call
+ * will fail.
  *
- * The \a usage parameter may only specify AHARDWAREBUFFER_USAGE_CPU_*. If set,
- * then outVirtualAddress is filled with the address of the buffer in virtual
+ * If \a fence is not negative, it specifies a fence file descriptor on
+ * which to wait before locking the buffer. If it's negative, the caller
+ * is responsible for ensuring that writes to the buffer have completed
+ * before calling this function.  Using this parameter is more efficient
+ * than waiting on the fence and then calling this function.
+ *
+ * The \a usage parameter may only specify AHARDWAREBUFFER_USAGE_CPU_*.
+ * If set, then outVirtualAddress is filled with the address of the
+ * buffer in virtual memory. The flags must also be compatible with
+ * usage flags specified at buffer creation: if a read flag is passed,
+ * the buffer must have been created with
+ * AHARDWAREBUFFER_USAGE_CPU_READ_RARELY or
+ * AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN. If a write flag is passed, it
+ * must have been created with AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY or
+ * AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN.
+ *
+ * If \a rect is not NULL, the caller promises to modify only data in
+ * the area specified by rect. If rect is NULL, the caller may modify
+ * the contents of the entire buffer. The content of the buffer outside
+ * of the specified rect is NOT modified by this call.
+ *
+ * It is legal for several different threads to lock a buffer for read
+ * access; none of the threads are blocked.
+ *
+ * Locking a buffer simultaneously for write or read/write is undefined,
+ * but will neither terminate the process nor block the caller.
+ * AHardwareBuffer_lock may return an error or leave the buffer's
+ * content in an indeterminate state.
+ *
+ * If the buffer has AHARDWAREBUFFER_FORMAT_BLOB, it is legal lock it
+ * for reading and writing in multiple threads and/or processes
+ * simultaneously, and the contents of the buffer behave like shared
  * memory.
  *
- * THREADING CONSIDERATIONS:
- *
- * It is legal for several different threads to lock a buffer for read access;
- * none of the threads are blocked.
- *
- * Locking a buffer simultaneously for write or read/write is undefined, but
- * will neither terminate the process nor block the caller; AHardwareBuffer_lock
- * may return an error or leave the buffer's content into an indeterminate
- * state.
- *
- * \return 0 on success, -EINVAL if \a buffer is NULL or if the usage
- * flags are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or an error
- * number of the lock fails for any reason.
+ * \return 0 on success. -EINVAL if \a buffer is NULL, the usage flags
+ * are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer
+ * has more than one layer. Error number if the lock fails for any other
+ * reason.
  */
 int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
         int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
 
 /**
- * Unlock the AHardwareBuffer; must be called after all changes to the buffer
- * are completed by the caller. If fence is not NULL then it will be set to a
- * file descriptor that is signaled when all pending work on the buffer is
- * completed. The caller is responsible for closing the fence when it is no
- * longer needed.
+ * Unlock the AHardwareBuffer from direct CPU access.
  *
- * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
- * number if the unlock fails for any reason.
+ * Must be called after all changes to the buffer are completed by the
+ * caller.  If \a fence is NULL, the function will block until all work
+ * is completed.  Otherwise, \a fence will be set either to a valid file
+ * descriptor or to -1.  The file descriptor will become signaled once
+ * the unlocking is complete and buffer contents are updated.
+ * The caller is responsible for closing the file descriptor once it's
+ * no longer needed.  The value -1 indicates that unlocking has already
+ * completed before the function returned and no further operations are
+ * necessary.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL. Error number if
+ * the unlock fails for any reason.
  */
 int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) __INTRODUCED_IN(26);
 
@@ -302,7 +408,7 @@
 int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) __INTRODUCED_IN(26);
 
 /**
- * Receive the AHardwareBuffer from an AF_UNIX socket.
+ * Receive an AHardwareBuffer from an AF_UNIX socket.
  *
  * \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
  * number if the operation fails for any reason.
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 6831f91..6730596 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -15,7 +15,13 @@
  */
 
 /**
- * @addtogroup NativeActivity Native Activity
+ * @defgroup ANativeWindow Native Window
+ *
+ * ANativeWindow represents the producer end of an image queue.
+ * It is the C counterpart of the android.view.Surface object in Java,
+ * and can be converted both ways. Depending on the consumer, images
+ * submitted to ANativeWindow can be shown on the display or sent to
+ * other consumers, such as video encoders.
  * @{
  */
 
@@ -41,7 +47,7 @@
  * Legacy window pixel format names, kept for backwards compatibility.
  * New code and APIs should use AHARDWAREBUFFER_FORMAT_*.
  */
-enum {
+enum ANativeWindow_LegacyFormat {
     // NOTE: these values must match the values from graphics/common/x.x/types.hal
 
     /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/
@@ -95,7 +101,7 @@
     /// memory. This may be >= width.
     int32_t stride;
 
-    /// The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
+    /// The format of the buffer. One of AHardwareBuffer_Format.
     int32_t format;
 
     /// The actual bits.
@@ -151,7 +157,7 @@
  *
  * \param width width of the buffers in pixels.
  * \param height height of the buffers in pixels.
- * \param format one of AHARDWAREBUFFER_FORMAT_* constants.
+ * \param format one of the AHardwareBuffer_Format constants.
  * \return 0 for success, or a negative value on error.
  */
 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS
index d4393d6..81099e8 100644
--- a/libs/sensor/OWNERS
+++ b/libs/sensor/OWNERS
@@ -1,2 +1,3 @@
 arthuri@google.com
 bduddie@google.com
+bstack@google.com
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index c1f1d25..4aa9f62 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -370,6 +370,10 @@
 
 status_t GraphicBuffer::unflatten(
         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
+    if (size < 12 * sizeof(int)) {
+        android_errorWriteLog(0x534e4554, "114223584");
+        return NO_MEMORY;
+    }
 
     int const* buf = static_cast<int const*>(buffer);
 
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
index 6e303a5..2f14f7c 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
@@ -28,7 +28,7 @@
       return -EALREADY;
     }
 
-    fd_.reset(epoll_create(64));
+    fd_.reset(epoll_create1(EPOLL_CLOEXEC));
 
     if (fd_.get() < 0)
       return -errno;
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
index fa0adf0..f72dabc 100644
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
@@ -66,7 +66,7 @@
   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);
 }
 
-constexpr uint64_t kNanosPerSecond = 1000000000llu;
+constexpr uint64_t kNanosPerSecond = 1000000000LLU;
 
 uint64_t GetClockNs() {
   timespec t;
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 4dc669b..233e0fc 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -84,9 +84,6 @@
         "-Wno-error=sign-compare", // to fix later
         "-Wno-unused-variable",
     ],
-    cppflags: [
-        "-std=c++1z"
-    ],
     shared_libs: sharedLibraries,
     whole_static_libs: staticLibraries,
     header_libs: headerLibraries,
diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
index 962c745..1cf5f17 100644
--- a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
+++ b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp
@@ -11,7 +11,7 @@
 namespace dvr {
 
 EpollEventDispatcher::EpollEventDispatcher() {
-  epoll_fd_.Reset(epoll_create(64));
+  epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
   if (!epoll_fd_) {
     ALOGE("Failed to create epoll fd: %s", strerror(errno));
     return;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 36deedc..e824238 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -552,15 +552,6 @@
                     break;
                 }
             }
-
-            // If the driver doesn't understand it, we should map sRGB-encoded P3 to
-            // sRGB rather than just dropping the colorspace on the floor.
-            // For this format, the driver is expected to apply the sRGB
-            // transfer function during framebuffer operations.
-            if (!copyAttribute && attr[1] == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
-                strippedAttribList->push_back(attr[0]);
-                strippedAttribList->push_back(EGL_GL_COLORSPACE_SRGB_KHR);
-            }
         }
         if (copyAttribute) {
             strippedAttribList->push_back(attr[0]);
diff --git a/services/gpuservice/Android.bp b/services/gpuservice/Android.bp
index 250bbee..47bed65 100644
--- a/services/gpuservice/Android.bp
+++ b/services/gpuservice/Android.bp
@@ -21,7 +21,6 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
-    cppflags: ["-std=c++1z"],
     srcs: [
         ":gpuservice_sources",
     ],
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 4d9a2a0..ccc24b9 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -206,7 +206,7 @@
         mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
 
-    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
     LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
 
     mINotifyFd = inotify_init();
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index b37b7fd..efa6f88 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -3089,6 +3089,7 @@
         InputMapper(device),
         mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
         mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+        mPhysicalWidth(-1), mPhysicalHeight(-1), mPhysicalLeft(0), mPhysicalTop(0),
         mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
 }
 
@@ -3596,6 +3597,11 @@
                 break;
             }
 
+            mPhysicalWidth = naturalPhysicalWidth;
+            mPhysicalHeight = naturalPhysicalHeight;
+            mPhysicalLeft = naturalPhysicalLeft;
+            mPhysicalTop = naturalPhysicalTop;
+
             mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
             mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
             mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
@@ -3604,6 +3610,11 @@
             mSurfaceOrientation = mParameters.orientationAware ?
                     mViewport.orientation : DISPLAY_ORIENTATION_0;
         } else {
+            mPhysicalWidth = rawWidth;
+            mPhysicalHeight = rawHeight;
+            mPhysicalLeft = 0;
+            mPhysicalTop = 0;
+
             mSurfaceWidth = rawWidth;
             mSurfaceHeight = rawHeight;
             mSurfaceLeft = 0;
@@ -3914,6 +3925,10 @@
     dump += StringPrintf(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
     dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
     dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
+    dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
+    dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
+    dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
+    dump += StringPrintf(INDENT3 "PhysicalTop: %d\n", mPhysicalTop);
     dump += StringPrintf(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
 }
 
@@ -5118,10 +5133,10 @@
             }
             break;
         case DISPLAY_ORIENTATION_180:
-            x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+            x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale;
             y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
-            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
-            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
+            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
+            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
             bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
             top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
             orientation -= M_PI;
@@ -5130,10 +5145,10 @@
             }
             break;
         case DISPLAY_ORIENTATION_270:
-            x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+            x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale;
             y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
-            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
+            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
+            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
             bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
             top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
             orientation += M_PI_2;
@@ -6531,8 +6546,12 @@
 }
 
 bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+    const float scaledX = x * mXScale;
+    const float scaledY = y * mYScale;
     return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
-            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
+            && scaledX >= mPhysicalLeft && scaledX <= mPhysicalLeft + mPhysicalWidth
+            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue
+            && scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
 }
 
 const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index cef3212..2f98e69 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1517,13 +1517,21 @@
     // in the natural orientation.
     // The surface origin specifies how the surface coordinates should be translated
     // to align with the logical display coordinate space.
-    // The orientation may be different from the viewport orientation as it specifies
-    // the rotation of the surface coordinates required to produce the viewport's
-    // requested orientation, so it will depend on whether the device is orientation aware.
     int32_t mSurfaceWidth;
     int32_t mSurfaceHeight;
     int32_t mSurfaceLeft;
     int32_t mSurfaceTop;
+
+    // Similar to the surface coordinates, but in the raw display coordinate space rather than in
+    // the logical coordinate space.
+    int32_t mPhysicalWidth;
+    int32_t mPhysicalHeight;
+    int32_t mPhysicalLeft;
+    int32_t mPhysicalTop;
+
+    // The orientation may be different from the viewport orientation as it specifies
+    // the rotation of the surface coordinates required to produce the viewport's
+    // requested orientation, so it will depend on whether the device is orientation aware.
     int32_t mSurfaceOrientation;
 
     // Translation and scaling factors, orientation-independent.
diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS
index d4393d6..81099e8 100644
--- a/services/sensorservice/OWNERS
+++ b/services/sensorservice/OWNERS
@@ -1,2 +1,3 @@
 arthuri@google.com
 bduddie@google.com
+bstack@google.com
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index d1ea84a..ce4daa5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -8,7 +8,6 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
-    cppflags: ["-std=c++1z"],
 }
 
 cc_defaults {
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 3db633b..f5b5eda 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -704,6 +704,8 @@
 }
 
 void BufferLayer::onFirstRef() {
+    Layer::onFirstRef();
+
     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
     sp<IGraphicBufferProducer> producer;
     sp<IGraphicBufferConsumer> consumer;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cf53930..28b447f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -981,6 +981,21 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+    if (outViewport == nullptr || display.get() == nullptr) {
+        return BAD_VALUE;
+    }
+
+    sp<const DisplayDevice> device(getDisplayDevice(display));
+    if (device == nullptr) {
+        return BAD_VALUE;
+    }
+
+    *outViewport = device->getViewport();
+
+    return NO_ERROR;
+}
+
 int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
     if (display == nullptr) {
         ALOGE("%s : display is nullptr", __func__);
@@ -2180,11 +2195,15 @@
         displayDevice->onSwapBuffersCompleted();
         displayDevice->makeCurrent();
         for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
+            sp<Fence> releaseFence = Fence::NO_FENCE;
+
             // The layer buffer from the previous frame (if any) is released
             // by HWC only when the release fence from this frame (if any) is
             // signaled.  Always get the release fence from HWC first.
             auto hwcLayer = layer->getHwcLayer(hwcId);
-            sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+            if (hwcId >= 0) {
+                releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);
+            }
 
             // If the layer was client composited in the previous frame, we
             // need to merge with the previous client target acquire fence.
@@ -2331,8 +2350,10 @@
         const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
     bool hasWideColorGamut = false;
     std::unordered_map<ColorMode, std::vector<RenderIntent>> hwcColorModes;
+    HdrCapabilities hdrCapabilities;
+    int32_t supportedPerFrameMetadata = 0;
 
-    if (hasWideColorDisplay) {
+    if (hasWideColorDisplay && hwcId >= 0) {
         std::vector<ColorMode> modes = getHwComposer().getColorModes(hwcId);
         for (ColorMode colorMode : modes) {
             switch (colorMode) {
@@ -2351,8 +2372,10 @@
         }
     }
 
-    HdrCapabilities hdrCapabilities;
-    getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);
+    if (hwcId >= 0) {
+        getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);
+        supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(hwcId);
+    }
 
     auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
     auto nativeWindow = nativeWindowSurface->getNativeWindow();
@@ -2386,8 +2409,7 @@
             new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
                               dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                               hasWideColorGamut, hdrCapabilities,
-                              getHwComposer().getSupportedPerFrameMetadata(hwcId),
-                              hwcColorModes, initialPowerMode);
+                              supportedPerFrameMetadata, hwcColorModes, initialPowerMode);
 
     if (maxFrameBufferAcquiredBuffers >= 3) {
         nativeWindowSurface->preallocateBuffers();
@@ -3038,22 +3060,17 @@
             }
         }
 
-        if (displayDevice->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
-            // just to be on the safe side, we don't set the
-            // scissor on the main display. It should never be needed
-            // anyways (though in theory it could since the API allows it).
-            const Rect& bounds(displayDevice->getBounds());
-            const Rect& scissor(displayDevice->getScissor());
-            if (scissor != bounds) {
-                // scissor doesn't match the screen's dimensions, so we
-                // need to clear everything outside of it and enable
-                // the GL scissor so we don't draw anything where we shouldn't
+        const Rect& bounds(displayDevice->getBounds());
+        const Rect& scissor(displayDevice->getScissor());
+        if (scissor != bounds) {
+            // scissor doesn't match the screen's dimensions, so we
+            // need to clear everything outside of it and enable
+            // the GL scissor so we don't draw anything where we shouldn't
 
-                // enable scissor for this frame
-                const uint32_t height = displayDevice->getHeight();
-                getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
-                        scissor.getWidth(), scissor.getHeight());
-            }
+            // enable scissor for this frame
+            const uint32_t height = displayDevice->getHeight();
+            getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
+                                              scissor.getWidth(), scissor.getHeight());
         }
     }
 
@@ -4821,6 +4838,16 @@
     const sp<const DisplayDevice> device(getDisplayDeviceLocked(display));
     if (CC_UNLIKELY(device == 0)) return BAD_VALUE;
 
+    const Rect& dispScissor = device->getScissor();
+    if (!dispScissor.isEmpty()) {
+        sourceCrop.set(dispScissor);
+        // adb shell screencap will default reqWidth and reqHeight to zeros.
+        if (reqWidth == 0 || reqHeight == 0) {
+            reqWidth = uint32_t(device->getViewport().width());
+            reqHeight = uint32_t(device->getViewport().height());
+        }
+    }
+
     DisplayRenderArea renderArea(device, sourceCrop, reqHeight, reqWidth, rotation);
 
     auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8f724e9..0148ab6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -429,6 +429,7 @@
                                    const Rect& sourceCrop, float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& display,
             DisplayStatInfo* stats);
+    virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
     virtual status_t getDisplayConfigs(const sp<IBinder>& display,
             Vector<DisplayInfo>* configs);
     virtual int getActiveConfig(const sp<IBinder>& display);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
index bef6b7c..b937f41 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp
@@ -17,7 +17,6 @@
     },
 
     cppflags: [
-        "-std=c++1z",
         "-Werror",
         "-Wno-c++98-compat-pedantic",
         "-Wno-disabled-macro-expansion",
diff --git a/services/utils/tests/PriorityDumper_test.cpp b/services/utils/tests/PriorityDumper_test.cpp
index 90cc6de..2320a90 100644
--- a/services/utils/tests/PriorityDumper_test.cpp
+++ b/services/utils/tests/PriorityDumper_test.cpp
@@ -54,7 +54,7 @@
 };
 
 static void addAll(Vector<String16>& av, const std::vector<std::string>& v) {
-    for (auto element : v) {
+    for (const auto& element : v) {
         av.add(String16(element.c_str()));
     }
 }
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index e4c50d5..09db37a 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -524,8 +524,8 @@
 @extension("VK_NV_shading_rate_image") define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
 
 // 166
-@extension("VK_NV_raytracing") define VK_NV_RAYTRACING_SPEC_VERSION 2
-@extension("VK_NV_raytracing") define VK_NV_RAYTRACING_EXTENSION_NAME "VK_NV_raytracing"
+@extension("VK_NV_ray_tracing") define VK_NV_RAY_TRACING_SPEC_VERSION 3
+@extension("VK_NV_ray_tracing") define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing"
 
 // 167
 @extension("VK_NV_representative_fragment_test") define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 1
@@ -703,7 +703,7 @@
 @extension("VK_EXT_validation_cache") @nonDispatchHandle type u64 VkValidationCacheEXT
 
 // 166
-@extension("VK_NV_raytracing") @nonDispatchHandle type u64 VkAccelerationStructureNV
+@extension("VK_NV_ray_tracing") @nonDispatchHandle type u64 VkAccelerationStructureNV
 
 /////////////
 //  Enums  //
@@ -804,7 +804,7 @@
     //@extension("VK_EXT_inline_uniform_block") // 139
     VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT             = 1000138000,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV            = 1000165000,
 }
 
@@ -816,7 +816,7 @@
     //@extension("VK_EXT_transform_feedback") // 29
     VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT             = 1000028004,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV  = 1000165000,
 }
 
@@ -833,7 +833,7 @@
     VK_PIPELINE_BIND_POINT_GRAPHICS                         = 0x00000000,
     VK_PIPELINE_BIND_POINT_COMPUTE                          = 0x00000001,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_PIPELINE_BIND_POINT_RAY_TRACING_NV                   = 1000165000,
 }
 
@@ -860,7 +860,7 @@
     VK_INDEX_TYPE_UINT16                                    = 0x00000000,
     VK_INDEX_TYPE_UINT32                                    = 0x00000001,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_INDEX_TYPE_NONE_NV                                   = 1000165000,
 }
 
@@ -1796,7 +1796,7 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
     VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV                   = 1000165000,
     VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV                 = 1000165001,
     VK_STRUCTURE_TYPE_GEOMETRY_NV                                           = 1000165003,
@@ -2030,7 +2030,7 @@
     //@extension("VK_EXT_validation_cache") // 161
     VK_OBJECT_TYPE_VALIDATION_CACHE_EXT                     = 1000160000,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV                = 1000165000,
 }
 
@@ -2154,7 +2154,7 @@
     //@extension("VK_KHR_sampler_ycbcr_conversion") // 157
     VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = 1000156000,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT   = 1000165000,
 }
 
@@ -2330,32 +2330,32 @@
     VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV             = 3,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 enum VkRayTracingShaderGroupTypeNV {
     VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV                 = 0,
     VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV     = 1,
     VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV    = 2,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 enum VkGeometryTypeNV {
     VK_GEOMETRY_TYPE_TRIANGLES_NV                           = 0,
     VK_GEOMETRY_TYPE_AABBS_NV                               = 1,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 enum VkAccelerationStructureTypeNV {
     VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV             = 0,
     VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV          = 1,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 enum VkCopyAccelerationStructureModeNV {
     VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV            = 0,
     VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV          = 1,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 enum VkAccelerationStructureMemoryRequirementsTypeNV {
     VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV            = 0,
     VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV     = 1,
@@ -2474,7 +2474,7 @@
     //@extension("VK_NV_shading_rate_image") // 165
     VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV                = 0x00800000,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV            = 0x00200000,
     VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV           = 0x00400000,
 
@@ -2500,7 +2500,7 @@
     //@extension("VK_EXT_conditional_rendering") // 82
     VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT           = 0x00000200,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_BUFFER_USAGE_RAY_TRACING_BIT_NV                      = 0x00000400,
 
     //@extension("VK_EXT_transform_feedback") // 29
@@ -2532,7 +2532,7 @@
 
     VK_SHADER_STAGE_ALL                                     = 0x7FFFFFFF,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_SHADER_STAGE_RAYGEN_BIT_NV                           = 0x00000100,
     VK_SHADER_STAGE_ANY_HIT_BIT_NV                          = 0x00000200,
     VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV                      = 0x00000400,
@@ -2636,7 +2636,7 @@
     VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008,
     VK_PIPELINE_CREATE_DISPATCH_BASE_KHR                    = 0x00000010,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV                 = 0x00000020,
 }
 
@@ -2832,7 +2832,7 @@
     //@extension("VK_NV_shading_rate_image") // 165
     VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV             = 0x00400000,
 
-    //@extension("VK_NV_raytracing") // 166
+    //@extension("VK_NV_ray_tracing") // 166
     VK_PIPELINE_STAGE_RAY_TRACING_BIT_NV                    = 0x00200000,
     VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV   = 0x02000000,
 
@@ -2842,6 +2842,9 @@
 
     //@extension("VK_EXT_transform_feedback") // 29
     VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT            = 0x01000000,
+
+    //@extension("VK_NV_ray_tracing") // 166
+    VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV   = 0x02000000,
 }
 
 /// Render pass attachment description flags
@@ -3520,17 +3523,17 @@
     VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT     = 0x00000008,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 type VkFlags VkGeometryFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 bitfield VkGeometryFlagBitsNV {
     VK_GEOMETRY_OPAQUE_BIT_NV                           = 0x00000001,
     VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV  = 0x00000002,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 type VkFlags VkGeometryInstanceFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 bitfield VkGeometryInstanceFlagBitsNV {
     VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV           = 0x00000001,
     VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002,
@@ -3538,9 +3541,9 @@
     VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV                 = 0x00000008,
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 type VkFlags VkBuildAccelerationStructureFlagsNV
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 bitfield VkBuildAccelerationStructureFlagBitsNV {
     VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV         = 0x00000001,
     VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV     = 0x00000002,
@@ -7276,7 +7279,7 @@
     const VkCoarseSampleOrderCustomNV*              pCustomSampleOrders
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkRayTracingShaderGroupCreateInfoNV {
     VkStructureType                  sType
     const void*                      pNext
@@ -7287,7 +7290,7 @@
     u32                              intersectionShader
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkRayTracingPipelineCreateInfoNV {
     VkStructureType                               sType
     const void*                                   pNext
@@ -7302,7 +7305,7 @@
     s32                                           basePipelineIndex
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkGeometryTrianglesNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7319,7 +7322,7 @@
     VkDeviceSize                                    transformOffset
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkGeometryAABBNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7329,13 +7332,13 @@
     VkDeviceSize                                    offset
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkGeometryDataNV {
     VkGeometryTrianglesNV                           triangles
     VkGeometryAABBNV                                aabbs
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkGeometryNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7344,7 +7347,7 @@
     VkGeometryFlagsNV                               flags
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkAccelerationStructureInfoNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7355,7 +7358,7 @@
     const VkGeometryNV*                             pGeometries
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkAccelerationStructureCreateInfoNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7363,7 +7366,7 @@
     VkAccelerationStructureInfoNV                   info
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkBindAccelerationStructureMemoryInfoNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7374,7 +7377,7 @@
     const u32*                                      pDeviceIndices
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkDescriptorAccelerationStructureInfoNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7382,7 +7385,7 @@
     const VkAccelerationStructureNV*                pAccelerationStructures
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkAccelerationStructureMemoryRequirementsInfoNV {
     VkStructureType                                 sType
     const void*                                     pNext
@@ -7390,7 +7393,7 @@
     VkAccelerationStructureNV                       accelerationStructure
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 class VkPhysicalDeviceRaytracingPropertiesNV {
     VkStructureType                                 sType
     void*                                           pNext
@@ -11502,7 +11505,7 @@
         const VkCoarseSampleOrderCustomNV*          pCustomSampleOrders) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkCreateAccelerationStructureNV(
         VkDevice                                    device,
         const VkAccelerationStructureCreateInfoNV*  pCreateInfo,
@@ -11511,21 +11514,21 @@
     return ?
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkDestroyAccelerationStructureNV(
         VkDevice                                    device,
         VkAccelerationStructureNV                   accelerationStructure,
         const VkAllocationCallbacks*                pAllocator) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkGetAccelerationStructureMemoryRequirementsNV(
         VkDevice                                                device,
         const VkAccelerationStructureMemoryRequirementsInfoNV*  pInfo,
         VkMemoryRequirements2KHR*                               pMemoryRequirements) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkBindAccelerationStructureMemoryNV(
         VkDevice                                        device,
         u32                                             bindInfoCount,
@@ -11533,7 +11536,7 @@
     return ?
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkCmdBuildAccelerationStructureNV(
         VkCommandBuffer                             commandBuffer,
         const VkAccelerationStructureInfoNV*        pInfo,
@@ -11546,7 +11549,7 @@
         VkDeviceSize                                scratchOffset) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkCmdCopyAccelerationStructureNV(
         VkCommandBuffer                             commandBuffer,
         VkAccelerationStructureNV                   dst,
@@ -11554,7 +11557,7 @@
         VkCopyAccelerationStructureModeNV           mode) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkCmdTraceRaysNV(
         VkCommandBuffer                             commandBuffer,
         VkBuffer                                    raygenShaderBindingTableBuffer,
@@ -11573,7 +11576,7 @@
         u32                                         depth) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkCreateRaytracingPipelinesNV(
         VkDevice                                    device,
         VkPipelineCache                             pipelineCache,
@@ -11584,7 +11587,7 @@
     return ?
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkGetRaytracingShaderHandlesNV(
         VkDevice                                    device,
         VkPipeline                                  pipeline,
@@ -11595,7 +11598,7 @@
     return ?
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkGetAccelerationStructureHandleNV(
         VkDevice                                    device,
         VkAccelerationStructureNV                   accelerationStructure,
@@ -11604,7 +11607,7 @@
     return ?
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd void vkCmdWriteAccelerationStructurePropertiesNV(
         VkCommandBuffer                             commandBuffer,
         u32                                         accelerationStructureCount,
@@ -11614,7 +11617,7 @@
         u32                                         firstQuery) {
 }
 
-@extension("VK_NV_raytracing") // 166
+@extension("VK_NV_ray_tracing") // 166
 cmd VkResult vkCompileDeferredNV(
         VkDevice                                    device,
         VkPipeline                                  pipeline,
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 7eaf7b2..fed8481 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -39,6 +39,9 @@
         "-Wno-switch-enum",
         "-Wno-undef",
 
+        // Have clang emit complete debug_info.
+        "-fstandalone-debug",
+
         //"-DLOG_NDEBUG=0",
     ],