Merge "VirtualDisplaySurface propagate reallocation to VDS producer"
diff --git a/cmds/bugreport/bugreport.cpp b/cmds/bugreport/bugreport.cpp
index e5c52d8..f81994b 100644
--- a/cmds/bugreport/bugreport.cpp
+++ b/cmds/bugreport/bugreport.cpp
@@ -14,91 +14,19 @@
  * limitations under the License.
  */
 
-#include <errno.h>
 #include <stdio.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
 
-#include <cutils/properties.h>
-#include <cutils/sockets.h>
+// Only prints a warning redirecting to bugreportz.
+int main() {
+    fprintf(stderr,
+            "=============================================================================\n");
+    fprintf(stderr, "WARNING: Flat (text file, non-zipped) bugreports are deprecated.\n");
+    fprintf(stderr, "WARNING: Please generate zipped bugreports instead.\n");
+    fprintf(stderr, "WARNING: On the host use: adb bugreport filename.zip\n");
+    fprintf(stderr, "WARNING: On the device use: bugreportz\n");
+    fprintf(stderr, "WARNING: bugreportz will output the filename to use with adb pull.\n");
+    fprintf(stderr,
+            "=============================================================================\n\n\n");
 
-// This program will trigger the dumpstate service to start a call to
-// dumpstate, then connect to the dumpstate local client to read the
-// output. All of the dumpstate output is written to stdout, including
-// any errors encountered while reading/writing the output.
-int main(int argc, char* /*argv*/[]) {
-  fprintf(stderr, "=============================================================================\n");
-  fprintf(stderr, "WARNING: Flat (text file, non-zipped) bugreports are deprecated.\n");
-  fprintf(stderr, "WARNING: Please generate zipped bugreports instead.\n");
-  fprintf(stderr, "WARNING: On the host use: adb bugreport filename.zip\n");
-  fprintf(stderr, "WARNING: On the device use: bugreportz\n");
-  fprintf(stderr, "WARNING: bugreportz will output the filename to use with adb pull.\n");
-  fprintf(stderr, "=============================================================================\n\n\n");
-
-  if (argc != 1) {
-    fprintf(stderr, "usage: bugreport\n");
-    exit(1);
-  }
-
-  // Start the dumpstate service.
-  property_set("ctl.start", "dumpstate");
-
-  // Socket will not be available until service starts.
-  int s = -1;
-  for (int i = 0; i < 20; i++) {
-    s = socket_local_client("dumpstate", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                            SOCK_STREAM);
-    if (s >= 0)
-      break;
-    // Try again in 1 second.
-    sleep(1);
-  }
-
-  if (s == -1) {
-    printf("Failed to connect to dumpstate service: %s\n", strerror(errno));
-    return 1;
-  }
-
-  // Set a timeout so that if nothing is read in 3 minutes, we'll stop
-  // reading and quit. No timeout in dumpstate is longer than 60 seconds,
-  // so this gives lots of leeway in case of unforeseen time outs.
-  struct timeval tv;
-  tv.tv_sec = 3 * 60;
-  tv.tv_usec = 0;
-  if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
-    printf("WARNING: Cannot set socket timeout: %s\n", strerror(errno));
-  }
-
-  while (1) {
-    char buffer[65536];
-    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));
-    if (bytes_read == 0) {
-      break;
-    } else if (bytes_read == -1) {
-      // EAGAIN really means time out, so change the errno.
-      if (errno == EAGAIN) {
-        errno = ETIMEDOUT;
-      }
-      printf("\nBugreport read terminated abnormally (%s).\n", strerror(errno));
-      break;
-    }
-
-    ssize_t bytes_to_send = bytes_read;
-    ssize_t bytes_written;
-    do {
-      bytes_written = TEMP_FAILURE_RETRY(write(STDOUT_FILENO,
-                                               buffer + bytes_read - bytes_to_send,
-                                               bytes_to_send));
-      if (bytes_written == -1) {
-        printf("Failed to write data to stdout: read %zd, trying to send %zd (%s)\n",
-               bytes_read, bytes_to_send, strerror(errno));
-        return 1;
-      }
-      bytes_to_send -= bytes_written;
-    } while (bytes_written != 0 && bytes_to_send > 0);
-  }
-
-  close(s);
-  return 0;
+    return 0;
 }
diff --git a/cmds/bugreportz/bugreportz.cpp b/cmds/bugreportz/bugreportz.cpp
index ded0ed3..203d748 100644
--- a/cmds/bugreportz/bugreportz.cpp
+++ b/cmds/bugreportz/bugreportz.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#include "bugreportz.h"
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -22,11 +26,6 @@
 
 #include <string>
 
-#include <android-base/file.h>
-#include <android-base/strings.h>
-
-#include "bugreportz.h"
-
 static constexpr char BEGIN_PREFIX[] = "BEGIN:";
 static constexpr char PROGRESS_PREFIX[] = "PROGRESS:";
 
@@ -70,6 +69,30 @@
     }
     // Process final line, in case it didn't finish with newline
     write_line(line, show_progress);
+    return EXIT_SUCCESS;
+}
 
+int bugreportz_stream(int s) {
+    while (1) {
+        char buffer[65536];
+        ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));
+        if (bytes_read == 0) {
+            break;
+        } else if (bytes_read == -1) {
+            // EAGAIN really means time out, so change the errno.
+            if (errno == EAGAIN) {
+                errno = ETIMEDOUT;
+            }
+            printf("FAIL:Bugreport read terminated abnormally (%s)\n", strerror(errno));
+            return EXIT_FAILURE;
+        }
+
+        if (!android::base::WriteFully(android::base::borrowed_fd(STDOUT_FILENO), buffer,
+                                       bytes_read)) {
+            printf("Failed to write data to stdout: trying to send %zd bytes (%s)\n", bytes_read,
+                   strerror(errno));
+            return EXIT_FAILURE;
+        }
+    }
     return EXIT_SUCCESS;
 }
diff --git a/cmds/bugreportz/bugreportz.h b/cmds/bugreportz/bugreportz.h
index 7af289b..cdeceae 100644
--- a/cmds/bugreportz/bugreportz.h
+++ b/cmds/bugreportz/bugreportz.h
@@ -19,4 +19,8 @@
 // Ownership of the socket is not transferred.
 int bugreportz(int s, bool show_progress);
 
+// Calls dumpstate using the given socket and write the file content to stdout
+// instead of file location. Ownership of the socket is not transferred.
+int bugreportz_stream(int s);
+
 #endif  // BUGREPORTZ_H
diff --git a/cmds/bugreportz/main.cpp b/cmds/bugreportz/main.cpp
index 1d48e08..cd2652c 100644
--- a/cmds/bugreportz/main.cpp
+++ b/cmds/bugreportz/main.cpp
@@ -26,13 +26,14 @@
 
 #include "bugreportz.h"
 
-static constexpr char VERSION[] = "1.1";
+static constexpr char VERSION[] = "1.2";
 
 static void show_usage() {
     fprintf(stderr,
-            "usage: bugreportz [-hpv]\n"
+            "usage: bugreportz [-hpsv]\n"
             "  -h: to display this help message\n"
             "  -p: display progress\n"
+            "  -s: stream content to standard output\n"
             "  -v: to display the version\n"
             "  or no arguments to generate a zipped bugreport\n");
 }
@@ -43,10 +44,11 @@
 
 int main(int argc, char* argv[]) {
     bool show_progress = false;
+    bool stream_data = false;
     if (argc > 1) {
         /* parse arguments */
         int c;
-        while ((c = getopt(argc, argv, "hpv")) != -1) {
+        while ((c = getopt(argc, argv, "hpsv")) != -1) {
             switch (c) {
                 case 'h':
                     show_usage();
@@ -54,6 +56,9 @@
                 case 'p':
                     show_progress = true;
                     break;
+                case 's':
+                    stream_data = true;
+                    break;
                 case 'v':
                     show_version();
                     return EXIT_SUCCESS;
@@ -75,7 +80,11 @@
     // should be reused instead.
 
     // Start the dumpstatez service.
-    property_set("ctl.start", "dumpstatez");
+    if (stream_data) {
+        property_set("ctl.start", "dumpstate");
+    } else {
+        property_set("ctl.start", "dumpstatez");
+    }
 
     // Socket will not be available until service starts.
     int s = -1;
@@ -103,7 +112,12 @@
                 strerror(errno));
     }
 
-    int ret = bugreportz(s, show_progress);
+    int ret;
+    if (stream_data) {
+        ret = bugreportz_stream(s);
+    } else {
+        ret = bugreportz(s, show_progress);
+    }
 
     if (close(s) == -1) {
         fprintf(stderr, "WARNING: error closing socket: %s\n", strerror(errno));
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index eefc84f..67527b2 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -719,6 +719,9 @@
     return timeout_ms > MINIMUM_LOGCAT_TIMEOUT_MS ? timeout_ms : MINIMUM_LOGCAT_TIMEOUT_MS;
 }
 
+// Opens a socket and returns its file descriptor.
+static int open_socket(const char* service);
+
 Dumpstate::ConsentCallback::ConsentCallback() : result_(UNAVAILABLE), start_time_(Nanotime()) {
 }
 
@@ -1471,6 +1474,8 @@
 
     RunDumpsys("DUMPSYS NETWORK_SERVICE_LIMITED", {"wifi", "-a"},
                CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
+    RunDumpsys("DUMPSYS CONNECTIVITY REQUESTS", {"connectivity", "requests"},
+               CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
 
     printf("========================================================\n");
     printf("== Dropbox crashes\n");
@@ -2284,20 +2289,18 @@
 
 static void ShowUsage() {
     fprintf(stderr,
-            "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o directory] [-d] [-p] "
-            "[-z] [-s] [-S] [-q] [-P] [-R] [-L] [-V version]\n"
+            "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o directory] [-p] "
+            "[-s] [-S] [-q] [-P] [-R] [-L] [-V version]\n"
             "  -h: display this help message\n"
             "  -b: play sound file instead of vibrate, at beginning of job\n"
             "  -e: play sound file instead of vibrate, at end of job\n"
             "  -o: write to custom directory (only in limited mode)\n"
-            "  -d: append date to filename\n"
             "  -p: capture screenshot to filename.png\n"
-            "  -z: generate zipped file\n"
-            "  -s: write output to control socket (for init)\n"
-            "  -S: write file location to control socket (for init; requires -z)\n"
+            "  -s: write zipped file to control socket (for init)\n"
+            "  -S: write file location to control socket (for init)\n"
             "  -q: disable vibrate\n"
             "  -P: send broadcast when started and do progress updates\n"
-            "  -R: take bugreport in remote mode (requires -z and -d, shouldn't be used with -P)\n"
+            "  -R: take bugreport in remote mode (shouldn't be used with -P)\n"
             "  -w: start binder service and make it wait for a call to startBugreport\n"
             "  -L: output limited information that is safe for submission in feedback reports\n"
             "  -v: prints the dumpstate header and exit\n");
@@ -2396,21 +2399,17 @@
 
 /*
  * Prepares state like filename, screenshot path, etc in Dumpstate. Also initializes ZipWriter
- * if we are writing zip files and adds the version file.
+ * and adds the version file. Return false if zip_file could not be open to write.
  */
-static void PrepareToWriteToFile() {
+static bool PrepareToWriteToFile() {
     MaybeResolveSymlink(&ds.bugreport_internal_dir_);
 
     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_ = StringPrintf("bugreport-%s-%s", 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_));
-        ds.name_ = date;
-    } else {
-        ds.name_ = "undated";
-    }
+    char date[80];
+    strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", localtime(&ds.now_));
+    ds.name_ = date;
 
     if (ds.options_->telephony_only) {
         ds.base_name_ += "-telephony";
@@ -2437,18 +2436,17 @@
         destination.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(ds.CalledByApi() ? "-zip.tmp" : ".zip");
-        MYLOGD("Creating initial .zip file (%s)\n", ds.path_.c_str());
-        create_parent_dirs(ds.path_.c_str());
-        ds.zip_file.reset(fopen(ds.path_.c_str(), "wb"));
-        if (ds.zip_file == nullptr) {
-            MYLOGE("fopen(%s, 'wb'): %s\n", ds.path_.c_str(), strerror(errno));
-        } else {
-            ds.zip_writer_.reset(new ZipWriter(ds.zip_file.get()));
-        }
-        ds.AddTextZipEntry("version.txt", ds.version_);
+    ds.path_ = ds.GetPath(ds.CalledByApi() ? "-zip.tmp" : ".zip");
+    MYLOGD("Creating initial .zip file (%s)\n", ds.path_.c_str());
+    create_parent_dirs(ds.path_.c_str());
+    ds.zip_file.reset(fopen(ds.path_.c_str(), "wb"));
+    if (ds.zip_file == nullptr) {
+        MYLOGE("fopen(%s, 'wb'): %s\n", ds.path_.c_str(), strerror(errno));
+        return false;
     }
+    ds.zip_writer_.reset(new ZipWriter(ds.zip_file.get()));
+    ds.AddTextZipEntry("version.txt", ds.version_);
+    return true;
 }
 
 /*
@@ -2456,14 +2454,9 @@
  * printing zipped file status, etc.
  */
 static void FinalizeFile() {
-    bool do_text_file = true;
-    if (ds.options_->do_zip_file) {
-        if (!ds.FinishZipFile()) {
-            MYLOGE("Failed to finish zip file; sending text bugreport instead\n");
-            do_text_file = true;
-        } else {
-            do_text_file = false;
-        }
+    bool do_text_file = !ds.FinishZipFile();
+    if (do_text_file) {
+        MYLOGE("Failed to finish zip file; sending text bugreport instead\n");
     }
 
     std::string final_path = ds.path_;
@@ -2472,7 +2465,9 @@
         android::os::CopyFileToFile(ds.path_, final_path);
     }
 
-    if (ds.options_->use_control_socket) {
+    if (ds.options_->stream_to_socket) {
+        android::os::CopyFileToFd(ds.path_, ds.control_socket_fd_);
+    } else if (ds.options_->progress_updates_to_socket) {
         if (do_text_file) {
             dprintf(ds.control_socket_fd_,
                     "FAIL:could not create zip file, check %s "
@@ -2528,7 +2523,6 @@
             break;
         case Dumpstate::BugreportMode::BUGREPORT_WEAR:
             options->do_progress_updates = true;
-            options->do_zip_file = true;
             options->do_screenshot = is_screenshot_requested;
             options->dumpstate_hal_mode = DumpstateMode::WEAR;
             break;
@@ -2541,7 +2535,6 @@
             break;
         case Dumpstate::BugreportMode::BUGREPORT_WIFI:
             options->wifi_only = true;
-            options->do_zip_file = true;
             options->do_screenshot = false;
             options->dumpstate_hal_mode = DumpstateMode::WIFI;
             break;
@@ -2552,11 +2545,11 @@
 
 static void LogDumpOptions(const Dumpstate::DumpOptions& options) {
     MYLOGI(
-        "do_zip_file: %d do_vibrate: %d use_socket: %d use_control_socket: %d do_screenshot: %d "
+        "do_vibrate: %d stream_to_socket: %d progress_updates_to_socket: %d do_screenshot: %d "
         "is_remote_mode: %d show_header_only: %d telephony_only: %d "
         "wifi_only: %d do_progress_updates: %d fd: %d bugreport_mode: %s dumpstate_hal_mode: %s "
         "limited_only: %d args: %s\n",
-        options.do_zip_file, options.do_vibrate, options.use_socket, options.use_control_socket,
+        options.do_vibrate, options.stream_to_socket, options.progress_updates_to_socket,
         options.do_screenshot, options.is_remote_mode, options.show_header_only,
         options.telephony_only, options.wifi_only,
         options.do_progress_updates, options.bugreport_fd.get(), options.bugreport_mode.c_str(),
@@ -2567,11 +2560,6 @@
                                         const android::base::unique_fd& bugreport_fd_in,
                                         const android::base::unique_fd& screenshot_fd_in,
                                         bool is_screenshot_requested) {
-    // In the new API world, date is always added; output is always a zip file.
-    // TODO(111441001): remove these options once they are obsolete.
-    do_add_date = true;
-    do_zip_file = true;
-
     // Duplicate the fds because the passed in fds don't outlive the binder transaction.
     bugreport_fd.reset(dup(bugreport_fd_in.get()));
     screenshot_fd.reset(dup(screenshot_fd_in.get()));
@@ -2585,18 +2573,20 @@
     while ((c = getopt(argc, argv, "dho:svqzpLPBRSV:w")) != -1) {
         switch (c) {
             // clang-format off
-            case 'd': do_add_date = true;            break;
-            case 'z': do_zip_file = true;            break;
             case 'o': out_dir = optarg;              break;
-            case 's': use_socket = true;             break;
-            case 'S': use_control_socket = true;     break;
+            case 's': stream_to_socket = true;       break;
+            case 'S': progress_updates_to_socket = true;    break;
             case 'v': show_header_only = true;       break;
             case 'q': do_vibrate = false;            break;
             case 'p': do_screenshot = true;          break;
             case 'P': do_progress_updates = true;    break;
             case 'R': is_remote_mode = true;         break;
             case 'L': limited_only = true;           break;
-            case 'V':                                break;  // compatibility no-op
+            case 'V':
+            case 'd':
+            case 'z':
+                // compatibility no-op
+                break;
             case 'w':
                 // This was already processed
                 break;
@@ -2625,19 +2615,15 @@
 }
 
 bool Dumpstate::DumpOptions::ValidateOptions() const {
-    if (bugreport_fd.get() != -1 && !do_zip_file) {
+    if (bugreport_fd.get() != -1 && stream_to_socket) {
         return false;
     }
 
-    if ((do_zip_file || do_add_date || do_progress_updates) && !OutputToFile()) {
+    if ((progress_updates_to_socket || do_progress_updates) && stream_to_socket) {
         return false;
     }
 
-    if (use_control_socket && !do_zip_file) {
-        return false;
-    }
-
-    if (is_remote_mode && (do_progress_updates || !do_zip_file || !do_add_date)) {
+    if (is_remote_mode && (do_progress_updates || stream_to_socket)) {
         return false;
     }
     return true;
@@ -2712,11 +2698,9 @@
  * 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.
+ * A bunch of other files and dumps are added to the zip archive.
  *
- * 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.
+ * The temporary bugreport file and the log file also get added to the archive.
  *
  * Bugreports are first generated in a local directory and later copied to the caller's fd
  * or directory if supplied.
@@ -2764,14 +2748,9 @@
     MYLOGD("dumpstate calling_uid = %d ; calling package = %s \n",
             calling_uid, calling_package.c_str());
 
-    // Redirect output if needed
-    bool is_redirecting = options_->OutputToFile();
-
     // 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", bugreport_internal_dir_.c_str())
-            : "";
+        android::base::StringPrintf("%s/dumpstate-stats.txt", bugreport_internal_dir_.c_str());
     progress_.reset(new Progress(stats_path));
 
     if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
@@ -2794,35 +2773,33 @@
 
     // If we are going to use a socket, do it as early as possible
     // to avoid timeouts from bugreport.
-    if (options_->use_socket) {
-        if (!redirect_to_socket(stdout, "dumpstate")) {
-            return ERROR;
-        }
-    }
-
-    if (options_->use_control_socket) {
+    if (options_->stream_to_socket || options_->progress_updates_to_socket) {
         MYLOGD("Opening control socket\n");
-        control_socket_fd_ = open_socket("dumpstate");
+        control_socket_fd_ = open_socket_fn_("dumpstate");
         if (control_socket_fd_ == -1) {
             return ERROR;
         }
-        options_->do_progress_updates = 1;
+        if (options_->progress_updates_to_socket) {
+            options_->do_progress_updates = 1;
+        }
     }
 
-    if (is_redirecting) {
-        PrepareToWriteToFile();
+    if (!PrepareToWriteToFile()) {
+        return ERROR;
+    }
 
-        if (options_->do_progress_updates) {
-            // clang-format off
-            std::vector<std::string> am_args = {
-                 "--receiver-permission", "android.permission.DUMP",
-            };
-            // clang-format on
-            // Send STARTED broadcast for apps that listen to bugreport generation events
-            SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
-            if (options_->use_control_socket) {
-                dprintf(control_socket_fd_, "BEGIN:%s\n", path_.c_str());
-            }
+    // Interactive, wear & telephony modes are default to true.
+    // and may enable from cli option or when using control socket
+    if (options_->do_progress_updates) {
+        // clang-format off
+        std::vector<std::string> am_args = {
+                "--receiver-permission", "android.permission.DUMP",
+        };
+        // clang-format on
+        // Send STARTED broadcast for apps that listen to bugreport generation events
+        SendBroadcast("com.android.internal.intent.action.BUGREPORT_STARTED", am_args);
+        if (options_->progress_updates_to_socket) {
+            dprintf(control_socket_fd_, "BEGIN:%s\n", path_.c_str());
         }
     }
 
@@ -2837,40 +2814,38 @@
         Vibrate(150);
     }
 
-    if (options_->do_zip_file && zip_file != nullptr) {
+    if (zip_file != nullptr) {
         if (chown(path_.c_str(), AID_SHELL, AID_SHELL)) {
             MYLOGE("Unable to change ownership of zip file %s: %s\n", path_.c_str(),
-                   strerror(errno));
+                    strerror(errno));
         }
     }
 
     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)));
-        if (!redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()))) {
-            return ERROR;
-        }
-        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 stderr to log_path_ for debugging.
+    TEMP_FAILURE_RETRY(dup_stderr_fd = dup(fileno(stderr)));
+    if (!redirect_to_file(stderr, const_cast<char*>(log_path_.c_str()))) {
+        return ERROR;
+    }
+    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. */
-        if (!redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str()))) {
-            return ERROR;
-        }
-        if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) {
-            MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n",
-                   tmp_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. */
+    if (!redirect_to_file(stdout, const_cast<char*>(tmp_path_.c_str()))) {
+        return ERROR;
+    }
+    if (chown(tmp_path_.c_str(), AID_SHELL, AID_SHELL)) {
+        MYLOGE("Unable to change ownership of temporary bugreport file %s: %s\n",
+                tmp_path_.c_str(), strerror(errno));
     }
 
     // Don't buffer stdout
@@ -2924,14 +2899,10 @@
     }
 
     /* close output if needed */
-    if (is_redirecting) {
-        TEMP_FAILURE_RETRY(dup2(dup_stdout_fd, fileno(stdout)));
-    }
+    TEMP_FAILURE_RETRY(dup2(dup_stdout_fd, fileno(stdout)));
 
     // Zip the (now complete) .tmp file within the internal directory.
-    if (options_->OutputToFile()) {
-        FinalizeFile();
-    }
+    FinalizeFile();
 
     // Share the final file with the caller if the user has consented or Shell is the caller.
     Dumpstate::RunStatus status = Dumpstate::RunStatus::OK;
@@ -2974,11 +2945,9 @@
     progress_->Save();
     MYLOGI("done (id %d)\n", id_);
 
-    if (is_redirecting) {
-        TEMP_FAILURE_RETRY(dup2(dup_stderr_fd, fileno(stderr)));
-    }
+    TEMP_FAILURE_RETRY(dup2(dup_stderr_fd, fileno(stderr)));
 
-    if (options_->use_control_socket && control_socket_fd_ != -1) {
+    if (control_socket_fd_ != -1) {
         MYLOGD("Closing control socket\n");
         close(control_socket_fd_);
     }
@@ -3049,10 +3018,7 @@
 }
 
 void Dumpstate::EnableParallelRunIfNeeded() {
-    // The thread pool needs to create temporary files to receive dump results.
-    // That's why we only enable it when the bugreport client chooses to output
-    // to a file.
-    if (!PropertiesHelper::IsParallelRun() || !options_->OutputToFile()) {
+    if (!PropertiesHelper::IsParallelRun()) {
         return;
     }
     dump_pool_ = std::make_unique<DumpPool>(bugreport_internal_dir_);
@@ -3197,7 +3163,8 @@
       options_(new Dumpstate::DumpOptions()),
       last_reported_percent_progress_(0),
       version_(version),
-      now_(time(nullptr)) {
+      now_(time(nullptr)),
+      open_socket_fn_(open_socket) {
 }
 
 Dumpstate& Dumpstate::GetInstance() {
@@ -3831,7 +3798,7 @@
     RunCommand(title, dumpsys, options, false, out_fd);
 }
 
-int open_socket(const char *service) {
+static int open_socket(const char* service) {
     int s = android_get_control_socket(service);
     if (s < 0) {
         MYLOGE("android_get_control_socket(%s): %s\n", service, strerror(errno));
@@ -3866,19 +3833,6 @@
     return fd;
 }
 
-/* redirect output to a service control socket */
-bool redirect_to_socket(FILE* redirect, const char* service) {
-    int fd = open_socket(service);
-    if (fd == -1) {
-        return false;
-    }
-    fflush(redirect);
-    // TODO: handle dup2 failure
-    TEMP_FAILURE_RETRY(dup2(fd, fileno(redirect)));
-    close(fd);
-    return true;
-}
-
 // TODO: should call is_valid_output_file and/or be merged into it.
 void create_parent_dirs(const char *path) {
     char *chp = const_cast<char *> (path);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 9582c9d..efe06dc 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -54,6 +54,7 @@
 
 class DumpstateTest;
 class ProgressTest;
+class ZippedBugReportStreamTest;
 
 }  // namespace dumpstate
 }  // namespace os
@@ -197,6 +198,7 @@
  */
 class Dumpstate {
     friend class android::os::dumpstate::DumpstateTest;
+    friend class android::os::dumpstate::ZippedBugReportStreamTest;
 
   public:
     enum RunStatus { OK, HELP, INVALID_INPUT, ERROR, USER_CONSENT_DENIED, USER_CONSENT_TIMED_OUT };
@@ -388,12 +390,11 @@
      * Structure to hold options that determine the behavior of dumpstate.
      */
     struct DumpOptions {
-        bool do_add_date = false;
-        bool do_zip_file = false;
         bool do_vibrate = true;
-        // Writes bugreport content to a socket; only flatfile format is supported.
-        bool use_socket = false;
-        bool use_control_socket = false;
+        // Writes bugreport zipped file to a socket.
+        bool stream_to_socket = false;
+        // Writes generation progress updates to a socket.
+        bool progress_updates_to_socket = false;
         bool do_screenshot = false;
         bool is_screenshot_copied = false;
         bool is_remote_mode = false;
@@ -434,13 +435,6 @@
         /* Returns true if the options set so far are consistent. */
         bool ValidateOptions() const;
 
-        /* Returns if options specified require writing bugreport to a file */
-        bool OutputToFile() const {
-            // If we are not writing to socket, we will write to a file. If bugreport_fd is
-            // specified, it is preferred. If not bugreport is written to /bugreports.
-            return !use_socket;
-        }
-
         /* Returns if options specified require writing to custom file location */
         bool OutputToCustomFile() {
             // Custom location is only honored in limited mode.
@@ -466,7 +460,8 @@
 
     std::unique_ptr<Progress> progress_;
 
-    // When set, defines a socket file-descriptor use to report progress to bugreportz.
+    // When set, defines a socket file-descriptor use to report progress to bugreportz
+    // or to stream the zipped file to.
     int control_socket_fd_ = -1;
 
     // Bugreport format version;
@@ -478,8 +473,8 @@
     // `bugreport-BUILD_ID`.
     std::string base_name_;
 
-    // Name is the suffix part of the bugreport files - it's typically the date (when invoked with
-    // `-d`), but it could be changed by the user..
+    // Name is the suffix part of the bugreport files - it's typically the date,
+    // but it could be changed by the user..
     std::string name_;
 
     std::string bugreport_internal_dir_ = DUMPSTATE_DIRECTORY;
@@ -568,6 +563,8 @@
     // called by Shell.
     RunStatus CopyBugreportIfUserConsented(int32_t calling_uid);
 
+    std::function<int(const char *)> open_socket_fn_;
+
     // Used by GetInstance() only.
     explicit Dumpstate(const std::string& version = VERSION_CURRENT);
 
@@ -601,16 +598,6 @@
 int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
                int (*dump_from_fd)(const char* title, const char* path, int fd));
 
-/** opens a socket and returns its file descriptor */
-int open_socket(const char *service);
-
-/*
- * Redirects 'redirect' to a service control socket.
- *
- * Returns true if redirect succeeds.
- */
-bool redirect_to_socket(FILE* redirect, const char* service);
-
 /*
  * Redirects 'redirect' to a file indicated by 'path', truncating it.
  *
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index e491a4b..a80da4e 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -11,7 +11,7 @@
 
 # dumpstatez generates a zipped bugreport but also uses a socket to print the file location once
 # it is finished.
-service dumpstatez /system/bin/dumpstate -S -d -z
+service dumpstatez /system/bin/dumpstate -S
     socket dumpstate stream 0660 shell log
     class main
     disabled
diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
index 2c800c6..23c0d95 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -212,9 +212,7 @@
     static void GenerateBugreport() {
         // clang-format off
         char* argv[] = {
-            (char*)"dumpstate",
-            (char*)"-d",
-            (char*)"-z"
+            (char*)"dumpstate"
         };
         // clang-format on
         sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout)), sections));
@@ -401,7 +399,7 @@
     SectionExists("batterystats", /* bytes= */ 1000);
 }
 
-TEST_F(BugreportSectionTest, WifiSectionGenerated) {
+TEST_F(BugreportSectionTest, DISABLED_WifiSectionGenerated) {
     SectionExists("wifi", /* bytes= */ 100000);
 }
 
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 6b93692..306069f 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "dumpstate"
-#include <cutils/log.h>
+#define LOG_TAG "dumpstate_test"
 
 #include "DumpstateInternal.h"
 #include "DumpstateService.h"
@@ -24,6 +23,7 @@
 #include "DumpPool.h"
 
 #include <gmock/gmock.h>
+#include <gmock/gmock-matchers.h>
 #include <gtest/gtest.h>
 
 #include <fcntl.h>
@@ -39,7 +39,9 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/dumpstate/1.1/types.h>
+#include <cutils/log.h>
 #include <cutils/properties.h>
+#include <ziparchive/zip_archive.h>
 
 namespace android {
 namespace os {
@@ -176,11 +178,9 @@
 
     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
 
-    EXPECT_FALSE(options_.do_add_date);
-    EXPECT_FALSE(options_.do_zip_file);
     EXPECT_EQ("", options_.out_dir);
-    EXPECT_FALSE(options_.use_socket);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_TRUE(options_.do_vibrate);
     EXPECT_FALSE(options_.do_screenshot);
@@ -195,17 +195,13 @@
     char* argv[] = {
         const_cast<char*>("dumpstatez"),
         const_cast<char*>("-S"),
-        const_cast<char*>("-d"),
-        const_cast<char*>("-z"),
     };
     // 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_TRUE(options_.progress_updates_to_socket);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
@@ -213,7 +209,7 @@
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
@@ -229,13 +225,11 @@
     Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
 
     EXPECT_EQ(status, Dumpstate::RunStatus::OK);
-    EXPECT_TRUE(options_.use_socket);
+    EXPECT_TRUE(options_.stream_to_socket);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.do_add_date);
-    EXPECT_FALSE(options_.do_zip_file);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
@@ -246,105 +240,93 @@
 
 TEST_F(DumpOptionsTest, InitializeFullBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
-    EXPECT_TRUE(options_.do_add_date);
     EXPECT_TRUE(options_.do_screenshot);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::FULL);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_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_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
-    EXPECT_TRUE(options_.do_add_date);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.do_progress_updates);
     EXPECT_TRUE(options_.do_screenshot);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::INTERACTIVE);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd, false);
-    EXPECT_TRUE(options_.do_add_date);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.is_remote_mode);
     EXPECT_FALSE(options_.do_vibrate);
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::REMOTE);
 
     // Other options retain default values
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.do_progress_updates);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeWearBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
-    EXPECT_TRUE(options_.do_add_date);
     EXPECT_TRUE(options_.do_screenshot);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.do_progress_updates);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WEAR);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd, false);
-    EXPECT_TRUE(options_.do_add_date);
     EXPECT_FALSE(options_.do_screenshot);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.telephony_only);
     EXPECT_TRUE(options_.do_progress_updates);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::CONNECTIVITY);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.show_header_only);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
 TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
     options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
-    EXPECT_TRUE(options_.do_add_date);
     EXPECT_FALSE(options_.do_screenshot);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_TRUE(options_.wifi_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::WIFI);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_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_.stream_to_socket);
     EXPECT_FALSE(options_.limited_only);
 }
 
@@ -353,8 +335,6 @@
     char* argv[] = {
         const_cast<char*>("dumpstatez"),
         const_cast<char*>("-S"),
-        const_cast<char*>("-d"),
-        const_cast<char*>("-z"),
         const_cast<char*>("-q"),
         const_cast<char*>("-L"),
         const_cast<char*>("-o abc")
@@ -364,9 +344,7 @@
     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_TRUE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.do_vibrate);
     EXPECT_TRUE(options_.limited_only);
     EXPECT_EQ(" abc", std::string(options_.out_dir));
@@ -376,7 +354,7 @@
     EXPECT_FALSE(options_.do_screenshot);
     EXPECT_FALSE(options_.do_progress_updates);
     EXPECT_FALSE(options_.is_remote_mode);
-    EXPECT_FALSE(options_.use_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
 
@@ -393,18 +371,16 @@
     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_screenshot);
-    EXPECT_TRUE(options_.do_zip_file);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 
     // Other options retain default values
     EXPECT_TRUE(options_.do_vibrate);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.progress_updates_to_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_.stream_to_socket);
     EXPECT_FALSE(options_.wifi_only);
     EXPECT_FALSE(options_.limited_only);
 }
@@ -413,8 +389,6 @@
     // clang-format off
     char* argv[] = {
         const_cast<char*>("dumpstate"),
-        const_cast<char*>("-d"),
-        const_cast<char*>("-z"),
         const_cast<char*>("-s"),
         const_cast<char*>("-S"),
 
@@ -424,11 +398,9 @@
     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);
     // TODO: Maybe we should trim the filename
-    EXPECT_TRUE(options_.use_socket);
-    EXPECT_TRUE(options_.use_control_socket);
+    EXPECT_TRUE(options_.stream_to_socket);
+    EXPECT_TRUE(options_.progress_updates_to_socket);
 
     // Other options retain default values
     EXPECT_FALSE(options_.show_header_only);
@@ -462,10 +434,8 @@
     EXPECT_TRUE(options_.is_remote_mode);
 
     // Other options retain default values
-    EXPECT_FALSE(options_.do_add_date);
-    EXPECT_FALSE(options_.do_zip_file);
-    EXPECT_FALSE(options_.use_socket);
-    EXPECT_FALSE(options_.use_control_socket);
+    EXPECT_FALSE(options_.stream_to_socket);
+    EXPECT_FALSE(options_.progress_updates_to_socket);
     EXPECT_FALSE(options_.limited_only);
     EXPECT_EQ(options_.dumpstate_hal_mode, DumpstateMode::DEFAULT);
 }
@@ -498,40 +468,31 @@
     EXPECT_EQ(status, Dumpstate::RunStatus::INVALID_INPUT);
 }
 
-TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile1) {
-    options_.do_zip_file = true;
-    // Writing to socket = !writing to file.
-    options_.use_socket = true;
+TEST_F(DumpOptionsTest, ValidateOptionsSocketUsage1) {
+    options_.progress_updates_to_socket = true;
+    options_.stream_to_socket = true;
     EXPECT_FALSE(options_.ValidateOptions());
 
-    options_.use_socket = false;
+    options_.stream_to_socket = false;
     EXPECT_TRUE(options_.ValidateOptions());
 }
 
-TEST_F(DumpOptionsTest, ValidateOptionsNeedOutfile2) {
+TEST_F(DumpOptionsTest, ValidateOptionsSocketUsage2) {
     options_.do_progress_updates = true;
     // Writing to socket = !writing to file.
-    options_.use_socket = true;
+    options_.stream_to_socket = true;
     EXPECT_FALSE(options_.ValidateOptions());
 
-    options_.use_socket = false;
-    EXPECT_TRUE(options_.ValidateOptions());
-}
-
-TEST_F(DumpOptionsTest, ValidateOptionsNeedZipfile) {
-    options_.use_control_socket = true;
-    EXPECT_FALSE(options_.ValidateOptions());
-
-    options_.do_zip_file = true;
+    options_.stream_to_socket = false;
     EXPECT_TRUE(options_.ValidateOptions());
 }
 
 TEST_F(DumpOptionsTest, ValidateOptionsRemoteMode) {
+    options_.do_progress_updates = true;
     options_.is_remote_mode = true;
     EXPECT_FALSE(options_.ValidateOptions());
 
-    options_.do_zip_file = true;
-    options_.do_add_date = true;
+    options_.do_progress_updates = false;
     EXPECT_TRUE(options_.ValidateOptions());
 }
 
@@ -1018,23 +979,13 @@
     ds.listener_.clear();
 }
 
-TEST_F(DumpstateTest, DumpPool_withOutputToFileAndParallelRunEnabled_notNull) {
-    ds.options_->use_socket = false;
+TEST_F(DumpstateTest, DumpPool_withParallelRunEnabled_notNull) {
     SetParallelRun(true);
     EnableParallelRunIfNeeded();
-    EXPECT_TRUE(ds.options_->OutputToFile());
     EXPECT_TRUE(ds.zip_entry_tasks_);
     EXPECT_TRUE(ds.dump_pool_);
 }
 
-TEST_F(DumpstateTest, DumpPool_withNotOutputToFile_isNull) {
-    ds.options_->use_socket = true;
-    EnableParallelRunIfNeeded();
-    EXPECT_FALSE(ds.options_->OutputToFile());
-    EXPECT_FALSE(ds.zip_entry_tasks_);
-    EXPECT_FALSE(ds.dump_pool_);
-}
-
 TEST_F(DumpstateTest, DumpPool_withParallelRunDisabled_isNull) {
     SetParallelRun(false);
     EnableParallelRunIfNeeded();
@@ -1042,6 +993,69 @@
     EXPECT_FALSE(ds.dump_pool_);
 }
 
+class ZippedBugReportStreamTest : public DumpstateBaseTest {
+  public:
+    void SetUp() {
+        DumpstateBaseTest::SetUp();
+        ds_.options_.reset(new Dumpstate::DumpOptions());
+    }
+    void TearDown() {
+        CloseArchive(handle_);
+    }
+
+    // Set bugreport mode and options before here.
+    void GenerateBugreport() {
+        ds_.Initialize();
+        EXPECT_EQ(Dumpstate::RunStatus::OK, ds_.Run(/*calling_uid=*/-1, /*calling_package=*/""));
+    }
+
+    // Most bugreports droproot, ensure the file can be opened by shell to verify file content.
+    void CreateFd(const std::string& path, android::base::unique_fd* out_fd) {
+        out_fd->reset(TEMP_FAILURE_RETRY(open(path.c_str(),
+                                              O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+                                              S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+        ASSERT_GE(out_fd->get(), 0) << "could not create FD for path " << path;
+    }
+
+    void VerifyEntry(const ZipArchiveHandle archive, const std::string_view entry_name,
+                     ZipEntry* data) {
+        int32_t e = FindEntry(archive, entry_name, data);
+        EXPECT_EQ(0, e) << ErrorCodeString(e) << " entry name: " << entry_name;
+    }
+
+    // While testing dumpstate in process, using STDOUT may get confused about
+    // the internal fd redirection. Redirect to a dedicate fd to save content.
+    void RedirectOutputToFd(android::base::unique_fd& ufd) {
+        ds_.open_socket_fn_ = [&](const char*) -> int { return ufd.release(); };
+    };
+
+    Dumpstate& ds_ = Dumpstate::GetInstance();
+    ZipArchiveHandle handle_;
+};
+
+// Generate a quick wifi report redirected to a file, open it and verify entry exist.
+TEST_F(ZippedBugReportStreamTest, StreamWifiReport) {
+    std::string out_path = kTestDataPath + "out.zip";
+    android::base::unique_fd out_fd;
+    CreateFd(out_path, &out_fd);
+    ds_.options_->wifi_only = true;
+    ds_.options_->stream_to_socket = true;
+    RedirectOutputToFd(out_fd);
+
+    GenerateBugreport();
+    OpenArchive(out_path.c_str(), &handle_);
+
+    ZipEntry entry;
+    VerifyEntry(handle_, "main_entry.txt", &entry);
+    std::string bugreport_txt_name;
+    bugreport_txt_name.resize(entry.uncompressed_length);
+    ExtractToMemory(handle_, &entry, reinterpret_cast<uint8_t*>(bugreport_txt_name.data()),
+                    entry.uncompressed_length);
+    EXPECT_THAT(bugreport_txt_name,
+                testing::ContainsRegex("(bugreport-.+-wifi(-[[:digit:]]+){6}\\.txt)"));
+    VerifyEntry(handle_, bugreport_txt_name, &entry);
+}
+
 class DumpstateServiceTest : public DumpstateBaseTest {
   public:
     DumpstateService dss;
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5076ae6..594880a 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -450,6 +450,26 @@
             AddArg("--boot-image-merge");
         }
 
+        // The percent won't exceed 100, otherwise, don't set it and use the
+        // default one set in profman.
+        uint32_t min_new_classes_percent_change = ::android::base::GetUintProperty<uint32_t>(
+            "dalvik.vm.bgdexopt.new-classes-percent",
+            /*default*/std::numeric_limits<uint32_t>::max());
+        if (min_new_classes_percent_change <= 100) {
+          AddArg("--min-new-classes-percent-change=" +
+                 std::to_string(min_new_classes_percent_change));
+        }
+
+        // The percent won't exceed 100, otherwise, don't set it and use the
+        // default one set in profman.
+        uint32_t min_new_methods_percent_change = ::android::base::GetUintProperty<uint32_t>(
+            "dalvik.vm.bgdexopt.new-methods-percent",
+            /*default*/std::numeric_limits<uint32_t>::max());
+        if (min_new_methods_percent_change <= 100) {
+          AddArg("--min-new-methods-percent-change=" +
+                 std::to_string(min_new_methods_percent_change));
+        }
+
         // Do not add after dex2oat_flags, they should override others for debugging.
         PrepareArgs(profman_bin);
     }
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 987adaf..1994e56 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -72,15 +72,18 @@
 cc_test {
     name: "lshal_test",
     test_suites: ["device-tests"],
-    defaults: ["lshal_defaults"],
+    defaults: [
+        "libvintf_static_user_defaults",
+        "lshal_defaults"
+    ],
     gtest: true,
     static_libs: [
         "android.hardware.tests.inheritance@1.0",
         "libgmock",
+        "libvintf",
     ],
     shared_libs: [
         "libhidlbase",
-        "libvintf",
     ],
     srcs: [
         "test.cpp"
diff --git a/data/etc/android.hardware.uwb.xml b/data/etc/android.hardware.uwb.xml
new file mode 100644
index 0000000..794ba27
--- /dev/null
+++ b/data/etc/android.hardware.uwb.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- Adds the feature indicating support for the Ultra Wideband API -->
+<permissions>
+    <feature name="android.hardware.uwb" />
+</permissions>
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp
index 09a5f39..cdd7764 100644
--- a/libs/android_runtime_lazy/Android.bp
+++ b/libs/android_runtime_lazy/Android.bp
@@ -35,6 +35,11 @@
     vendor_available: true,
     double_loadable: true,
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
 
     cflags: [
         "-Wall",
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index d363ee9..ee0259d 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -31,6 +31,11 @@
         "libutils_headers",
     ],
     min_sdk_version: "29",
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 // These interfaces are android-specific implementation unrelated to binder
@@ -107,6 +112,7 @@
         "Stability.cpp",
         "Status.cpp",
         "TextOutput.cpp",
+        "Utils.cpp",
         ":libbinder_aidl",
     ],
 
@@ -122,6 +128,9 @@
         vendor: {
             exclude_srcs: libbinder_device_interface_sources,
         },
+        darwin: {
+            enabled: false,
+        },
     },
 
     aidl: {
@@ -135,8 +144,10 @@
     cflags: [
         "-Wall",
         "-Wextra",
+        "-Wextra-semi",
         "-Werror",
         "-Wzero-as-null-pointer-constant",
+        "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
     ],
     product_variables: {
         binder32bit: {
@@ -163,6 +174,15 @@
         misc_undefined: ["integer"],
     },
     min_sdk_version: "29",
+
+    tidy: true,
+    tidy_flags: [
+        // Only check our headers
+        "--header-filter=^.*frameworks/native/libs/binder/.*.h$",
+    ],
+    tidy_checks_as_errors: [
+        "*",
+    ],
 }
 
 // AIDL interface between libbinder and framework.jar
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 6ca3b16..d964d25 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -133,6 +133,7 @@
 public:
     // unlocked objects
     bool mRequestingSid = false;
+    bool mInheritRt = false;
     sp<IBinder> mExtension;
     int mPolicy = SCHED_NORMAL;
     int mPriority = 0;
@@ -173,6 +174,10 @@
 {
     data.setDataPosition(0);
 
+    if (reply != nullptr && (flags & FLAG_CLEAR_BUF)) {
+        reply->markSensitive();
+    }
+
     status_t err = NO_ERROR;
     switch (code) {
         case PING_TRANSACTION:
@@ -323,6 +328,27 @@
     return e->mPriority;
 }
 
+bool BBinder::isInheritRt() {
+    Extras* e = mExtras.load(std::memory_order_acquire);
+
+    return e && e->mInheritRt;
+}
+
+void BBinder::setInheritRt(bool inheritRt) {
+    Extras* e = mExtras.load(std::memory_order_acquire);
+
+    if (!e) {
+        if (!inheritRt) {
+            return;
+        }
+
+        e = getOrCreateExtras();
+        if (!e) return; // out of memory
+    }
+
+    e->mInheritRt = inheritRt;
+}
+
 pid_t BBinder::getDebugPid() {
     return getpid();
 }
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index c183d29..bf4387a 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -137,8 +137,8 @@
 }
 
 BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
-    : mHandle(handle)
-    , mStability(0)
+    : mStability(0)
+    , mHandle(handle)
     , mAlive(1)
     , mObitsSent(0)
     , mObituaries(nullptr)
@@ -223,13 +223,14 @@
         if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
             using android::internal::Stability;
 
-            auto stability = Stability::get(this);
-            auto required = privateVendor ? Stability::VENDOR : Stability::getLocalStability();
+            auto category = Stability::getCategory(this);
+            Stability::Level required = privateVendor ? Stability::VENDOR
+                : Stability::getLocalLevel();
 
-            if (CC_UNLIKELY(!Stability::check(stability, required))) {
+            if (CC_UNLIKELY(!Stability::check(category, required))) {
                 ALOGE("Cannot do a user transaction on a %s binder in a %s context.",
-                    Stability::stabilityString(stability).c_str(),
-                    Stability::stabilityString(required).c_str());
+                    category.debugString().c_str(),
+                    Stability::levelString(required).c_str());
                 return BAD_TYPE;
             }
         }
diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp
index 8cf6097..88c85bf 100644
--- a/libs/binder/BufferedTextOutput.cpp
+++ b/libs/binder/BufferedTextOutput.cpp
@@ -18,7 +18,6 @@
 #include <binder/Debug.h>
 
 #include <cutils/atomic.h>
-#include <cutils/threads.h>
 #include <utils/Log.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
@@ -91,22 +90,6 @@
 
 static pthread_mutex_t gMutex = PTHREAD_MUTEX_INITIALIZER;
 
-static thread_store_t   tls;
-
-BufferedTextOutput::ThreadState* BufferedTextOutput::getThreadState()
-{
-    ThreadState*  ts = (ThreadState*) thread_store_get( &tls );
-    if (ts) return ts;
-    ts = new ThreadState;
-    thread_store_set( &tls, ts, threadDestructor );
-    return ts;
-}
-
-void BufferedTextOutput::threadDestructor(void *st)
-{
-    delete ((ThreadState*)st);
-}
-
 static volatile int32_t gSequence = 0;
 
 static volatile int32_t gFreeBufferIndex = -1;
@@ -266,16 +249,14 @@
 BufferedTextOutput::BufferState* BufferedTextOutput::getBuffer() const
 {
     if ((mFlags&MULTITHREADED) != 0) {
-        ThreadState* ts = getThreadState();
-        if (ts) {
-            while (ts->states.size() <= (size_t)mIndex) ts->states.add(nullptr);
-            BufferState* bs = ts->states[mIndex].get();
-            if (bs != nullptr && bs->seq == mSeq) return bs;
-            
-            ts->states.editItemAt(mIndex) = new BufferState(mIndex);
-            bs = ts->states[mIndex].get();
-            if (bs != nullptr) return bs;
-        }
+        thread_local ThreadState ts;
+        while (ts.states.size() <= (size_t)mIndex) ts.states.add(nullptr);
+        BufferState* bs = ts.states[mIndex].get();
+        if (bs != nullptr && bs->seq == mSeq) return bs;
+
+        ts.states.editItemAt(mIndex) = new BufferState(mIndex);
+        bs = ts.states[mIndex].get();
+        if (bs != nullptr) return bs;
     }
     
     return mGlobalState;
diff --git a/libs/binder/BufferedTextOutput.h b/libs/binder/BufferedTextOutput.h
index 1b27bb2..fdd532a 100644
--- a/libs/binder/BufferedTextOutput.h
+++ b/libs/binder/BufferedTextOutput.h
@@ -47,10 +47,7 @@
 private:
     struct BufferState;
     struct ThreadState;
-    
-    static  ThreadState*getThreadState();
-    static  void        threadDestructor(void *st);
-    
+
             BufferState*getBuffer() const;
             
     uint32_t            mFlags;
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index 64c1ff6..3a62059 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -208,7 +208,7 @@
     }
 
     for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
-        long remain = length;
+        ssize_t remain = length;
 
         char* c = buffer;
         if (!oneLine && !cStyle) {
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 1eb5363..b81995c 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -108,6 +108,6 @@
 
 // ------------------------------------------------------------------------------------
 
-IMPLEMENT_META_INTERFACE(ActivityManager, "android.app.IActivityManager");
+IMPLEMENT_META_INTERFACE(ActivityManager, "android.app.IActivityManager")
 
 } // namespace android
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/binder/IAppOpsCallback.cpp
index b9eb281..2b3f462 100644
--- a/libs/binder/IAppOpsCallback.cpp
+++ b/libs/binder/IAppOpsCallback.cpp
@@ -43,7 +43,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(AppOpsCallback, "com.android.internal.app.IAppOpsCallback");
+IMPLEMENT_META_INTERFACE(AppOpsCallback, "com.android.internal.app.IAppOpsCallback")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index cd78866..1af5ab8 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -159,7 +159,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
+IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IBatteryStats.cpp b/libs/binder/IBatteryStats.cpp
index a47dbac..d0085df 100644
--- a/libs/binder/IBatteryStats.cpp
+++ b/libs/binder/IBatteryStats.cpp
@@ -130,7 +130,7 @@
 
 };
 
-IMPLEMENT_META_INTERFACE(BatteryStats, "com.android.internal.app.IBatteryStats");
+IMPLEMENT_META_INTERFACE(BatteryStats, "com.android.internal.app.IBatteryStats")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IMediaResourceMonitor.cpp b/libs/binder/IMediaResourceMonitor.cpp
index 4198e49..f5fa817 100644
--- a/libs/binder/IMediaResourceMonitor.cpp
+++ b/libs/binder/IMediaResourceMonitor.cpp
@@ -38,10 +38,11 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(MediaResourceMonitor, "android.media.IMediaResourceMonitor");
+IMPLEMENT_META_INTERFACE(MediaResourceMonitor, "android.media.IMediaResourceMonitor")
 
 // ----------------------------------------------------------------------
 
+// NOLINTNEXTLINE(google-default-arguments)
 status_t BnMediaResourceMonitor::onTransact( uint32_t code, const Parcel& data, Parcel* reply,
         uint32_t flags) {
     switch(code) {
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index d8b44f9..cca8f81 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -223,7 +223,7 @@
 
 // ---------------------------------------------------------------------------
 
-IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
+IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory")
 
 BnMemory::BnMemory() {
 }
@@ -388,7 +388,7 @@
 
 // ---------------------------------------------------------------------------
 
-IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
+IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap")
 
 BnMemoryHeap::BnMemoryHeap() {
 }
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 05fcc2b..d4c7acf 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -135,7 +135,7 @@
         out << "target.ptr=" << btd->target.ptr;
     }
     out << " (cookie " << btd->cookie << ")" << endl
-        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
+        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(uint64_t)btd->flags << endl
         << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
         << " bytes)" << endl
         << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
@@ -150,7 +150,7 @@
     uint32_t code = (uint32_t)*cmd++;
     size_t cmdIndex = code & 0xff;
     if (code == BR_ERROR) {
-        out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
+        out << "BR_ERROR: " << (void*)(uint64_t)(*cmd++) << endl;
         return cmd;
     } else if (cmdIndex >= N) {
         out << "Unknown reply: " << code << endl;
@@ -177,21 +177,21 @@
         case BR_DECREFS: {
             const int32_t b = *cmd++;
             const int32_t c = *cmd++;
-            out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
+            out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c << ")";
         } break;
 
         case BR_ATTEMPT_ACQUIRE: {
             const int32_t p = *cmd++;
             const int32_t b = *cmd++;
             const int32_t c = *cmd++;
-            out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
+            out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c
                 << "), pri=" << p;
         } break;
 
         case BR_DEAD_BINDER:
         case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
             const int32_t c = *cmd++;
-            out << ": death cookie " << (void*)(long)c;
+            out << ": death cookie " << (void*)(uint64_t)c;
         } break;
 
         default:
@@ -232,7 +232,7 @@
 
         case BC_FREE_BUFFER: {
             const int32_t buf = *cmd++;
-            out << ": buffer=" << (void*)(long)buf;
+            out << ": buffer=" << (void*)(uint64_t)buf;
         } break;
 
         case BC_INCREFS:
@@ -247,7 +247,7 @@
         case BC_ACQUIRE_DONE: {
             const int32_t b = *cmd++;
             const int32_t c = *cmd++;
-            out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
+            out << ": target=" << (void*)(uint64_t)b << " (cookie " << (void*)(uint64_t)c << ")";
         } break;
 
         case BC_ATTEMPT_ACQUIRE: {
@@ -260,12 +260,12 @@
         case BC_CLEAR_DEATH_NOTIFICATION: {
             const int32_t h = *cmd++;
             const int32_t c = *cmd++;
-            out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
+            out << ": handle=" << h << " (death cookie " << (void*)(uint64_t)c << ")";
         } break;
 
         case BC_DEAD_BINDER_DONE: {
             const int32_t c = *cmd++;
-            out << ": death cookie " << (void*)(long)c;
+            out << ": death cookie " << (void*)(uint64_t)c;
         } break;
 
         default:
@@ -895,21 +895,21 @@
                             tr.data_size,
                             reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                             tr.offsets_size/sizeof(binder_size_t),
-                            freeBuffer, this);
+                            freeBuffer);
                     } else {
                         err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
                         freeBuffer(nullptr,
                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                             tr.data_size,
                             reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
-                            tr.offsets_size/sizeof(binder_size_t), this);
+                            tr.offsets_size/sizeof(binder_size_t));
                     }
                 } else {
                     freeBuffer(nullptr,
                         reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                         tr.data_size,
                         reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
-                        tr.offsets_size/sizeof(binder_size_t), this);
+                        tr.offsets_size/sizeof(binder_size_t));
                     continue;
                 }
             }
@@ -1077,7 +1077,7 @@
 
 sp<BBinder> the_context_object;
 
-void IPCThreadState::setTheContextObject(sp<BBinder> obj)
+void IPCThreadState::setTheContextObject(const sp<BBinder>& obj)
 {
     the_context_object = obj;
 }
@@ -1183,7 +1183,7 @@
                 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                 tr.data_size,
                 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
-                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
+                tr.offsets_size/sizeof(binder_size_t), freeBuffer);
 
             const void* origServingStackPointer = mServingStackPointer;
             mServingStackPointer = &origServingStackPointer; // anything on the stack
@@ -1244,7 +1244,9 @@
             if ((tr.flags & TF_ONE_WAY) == 0) {
                 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                 if (error < NO_ERROR) reply.setError(error);
-                sendReply(reply, 0);
+
+                constexpr uint32_t kForwardReplyFlags = TF_CLEAR_BUF;
+                sendReply(reply, (tr.flags & kForwardReplyFlags));
             } else {
                 if (error != OK || reply.dataSize() != 0) {
                     alog << "oneway function results will be dropped but finished with status "
@@ -1368,7 +1370,7 @@
 void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
                                 size_t /*dataSize*/,
                                 const binder_size_t* /*objects*/,
-                                size_t /*objectsSize*/, void* /*cookie*/)
+                                size_t /*objectsSize*/)
 {
     //ALOGI("Freeing parcel %p", &parcel);
     IF_LOG_COMMANDS() {
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index d9bf3cc..f94f413 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -103,7 +103,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
+IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp
index a38a27a..570edb9 100644
--- a/libs/binder/IProcessInfoService.cpp
+++ b/libs/binder/IProcessInfoService.cpp
@@ -84,7 +84,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(ProcessInfoService, "android.os.IProcessInfoService");
+IMPLEMENT_META_INTERFACE(ProcessInfoService, "android.os.IProcessInfoService")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IResultReceiver.cpp b/libs/binder/IResultReceiver.cpp
index 556288c..cd92217 100644
--- a/libs/binder/IResultReceiver.cpp
+++ b/libs/binder/IResultReceiver.cpp
@@ -42,7 +42,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(ResultReceiver, "com.android.internal.os.IResultReceiver");
+IMPLEMENT_META_INTERFACE(ResultReceiver, "com.android.internal.os.IResultReceiver")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 6d728dc..ca067e2 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -221,7 +221,7 @@
 
     const bool isVendorService =
         strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
-    const long timeout = 5000;
+    constexpr int64_t timeout = 5000;
     int64_t startTime = uptimeMillis();
     // Vendor code can't access system properties
     if (!gSystemBootCompleted && !isVendorService) {
@@ -234,7 +234,7 @@
 #endif
     }
     // retry interval in millisecond; note that vendor services stay at 100ms
-    const long sleepTime = gSystemBootCompleted ? 1000 : 100;
+    const useconds_t sleepTime = gSystemBootCompleted ? 1000 : 100;
 
     ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
           ProcessState::self()->getDriverName().c_str());
@@ -310,7 +310,7 @@
     // Simple RAII object to ensure a function call immediately before going out of scope
     class Defer {
     public:
-        Defer(std::function<void()>&& f) : mF(std::move(f)) {}
+        explicit Defer(std::function<void()>&& f) : mF(std::move(f)) {}
         ~Defer() { mF(); }
     private:
         std::function<void()> mF;
diff --git a/libs/binder/IShellCallback.cpp b/libs/binder/IShellCallback.cpp
index a3e2b67..86dd5c4 100644
--- a/libs/binder/IShellCallback.cpp
+++ b/libs/binder/IShellCallback.cpp
@@ -52,7 +52,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(ShellCallback, "com.android.internal.os.IShellCallback");
+IMPLEMENT_META_INTERFACE(ShellCallback, "com.android.internal.os.IShellCallback")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/binder/IUidObserver.cpp b/libs/binder/IUidObserver.cpp
index b21af96..a1b08db 100644
--- a/libs/binder/IUidObserver.cpp
+++ b/libs/binder/IUidObserver.cpp
@@ -71,10 +71,11 @@
 
 // ----------------------------------------------------------------------
 
-IMPLEMENT_META_INTERFACE(UidObserver, "android.app.IUidObserver");
+IMPLEMENT_META_INTERFACE(UidObserver, "android.app.IUidObserver")
 
 // ----------------------------------------------------------------------
 
+// NOLINTNEXTLINE(google-default-arguments)
 status_t BnUidObserver::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index e4ea60f..e1cbc19 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -49,7 +49,7 @@
     int fd = ashmem_create_region(name == nullptr ? "MemoryHeapBase" : name, size);
     ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
     if (fd >= 0) {
-        if (mapfd(fd, size) == NO_ERROR) {
+        if (mapfd(fd, true, size) == NO_ERROR) {
             if (flags & READ_ONLY) {
                 ashmem_set_prot_region(fd, PROT_READ);
             }
@@ -70,7 +70,7 @@
     if (fd >= 0) {
         const size_t pagesize = getpagesize();
         size = ((size + pagesize-1) & ~(pagesize-1));
-        if (mapfd(fd, size) == NO_ERROR) {
+        if (mapfd(fd, false, size) == NO_ERROR) {
             mDevice = device;
         }
     }
@@ -82,7 +82,7 @@
 {
     const size_t pagesize = getpagesize();
     size = ((size + pagesize-1) & ~(pagesize-1));
-    mapfd(fcntl(fd, F_DUPFD_CLOEXEC, 0), size, offset);
+    mapfd(fcntl(fd, F_DUPFD_CLOEXEC, 0), false, size, offset);
 }
 
 status_t MemoryHeapBase::init(int fd, void *base, size_t size, int flags, const char* device)
@@ -98,7 +98,7 @@
     return NO_ERROR;
 }
 
-status_t MemoryHeapBase::mapfd(int fd, size_t size, off_t offset)
+status_t MemoryHeapBase::mapfd(int fd, bool writeableByCaller, size_t size, off_t offset)
 {
     if (size == 0) {
         // try to figure out the size automatically
@@ -116,8 +116,12 @@
     }
 
     if ((mFlags & DONT_MAP_LOCALLY) == 0) {
+        int prot = PROT_READ;
+        if (writeableByCaller || (mFlags & READ_ONLY) == 0) {
+            prot |= PROT_WRITE;
+        }
         void* base = (uint8_t*)mmap(nullptr, size,
-                PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
+                prot, MAP_SHARED, fd, offset);
         if (base == MAP_FAILED) {
             ALOGE("mmap(fd=%d, size=%zu) failed (%s)",
                     fd, size, strerror(errno));
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a9c19b3..3330a2e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -49,6 +49,7 @@
 
 #include <private/binder/binder_module.h>
 #include "Static.h"
+#include "Utils.h"
 
 #define LOG_REFS(...)
 //#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
@@ -77,9 +78,8 @@
 // many things compile this into prebuilts on the stack
 static_assert(sizeof(Parcel) == 60 || sizeof(Parcel) == 120);
 
-static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
-static size_t gParcelGlobalAllocSize = 0;
-static size_t gParcelGlobalAllocCount = 0;
+static std::atomic<size_t> gParcelGlobalAllocCount;
+static std::atomic<size_t> gParcelGlobalAllocSize;
 
 static size_t gMaxFds = 0;
 
@@ -164,14 +164,11 @@
     ALOGE("Invalid object type 0x%08x", obj.hdr.type);
 }
 
-status_t Parcel::finishFlattenBinder(
-    const sp<IBinder>& binder, const flat_binder_object& flat)
+status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder)
 {
-    status_t status = writeObject(flat, false);
-    if (status != OK) return status;
-
     internal::Stability::tryMarkCompilationUnit(binder.get());
-    return writeInt32(internal::Stability::get(binder.get()));
+    auto category = internal::Stability::getCategory(binder.get());
+    return writeInt32(category.repr());
 }
 
 status_t Parcel::finishUnflattenBinder(
@@ -181,7 +178,7 @@
     status_t status = readInt32(&stability);
     if (status != OK) return status;
 
-    status = internal::Stability::set(binder.get(), stability, true /*log*/);
+    status = internal::Stability::setRepr(binder.get(), stability, true /*log*/);
     if (status != OK) return status;
 
     *out = binder;
@@ -225,6 +222,9 @@
             if (local->isRequestingSid()) {
                 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
             }
+            if (local->isInheritRt()) {
+                obj.flags |= FLAT_BINDER_FLAG_INHERIT_RT;
+            }
             obj.hdr.type = BINDER_TYPE_BINDER;
             obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
             obj.cookie = reinterpret_cast<uintptr_t>(local);
@@ -237,7 +237,10 @@
 
     obj.flags |= schedBits;
 
-    return finishFlattenBinder(binder, obj);
+    status_t status = writeObject(obj, false);
+    if (status != OK) return status;
+
+    return finishFlattenBinder(binder);
 }
 
 status_t Parcel::unflattenBinder(sp<IBinder>* out) const
@@ -275,17 +278,11 @@
 }
 
 size_t Parcel::getGlobalAllocSize() {
-    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
-    size_t size = gParcelGlobalAllocSize;
-    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
-    return size;
+    return gParcelGlobalAllocSize.load();
 }
 
 size_t Parcel::getGlobalAllocCount() {
-    pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
-    size_t count = gParcelGlobalAllocCount;
-    pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
-    return count;
+    return gParcelGlobalAllocCount.load();
 }
 
 const uint8_t* Parcel::data() const
@@ -509,6 +506,11 @@
     return mHasFds;
 }
 
+void Parcel::markSensitive() const
+{
+    mDeallocZero = true;
+}
+
 void Parcel::updateWorkSourceRequestHeaderPosition() const {
     // Only update the request headers once. We only want to point
     // to the first headers read/written.
@@ -1075,6 +1077,7 @@
 {
     if (str == nullptr) return writeInt32(-1);
 
+    // NOTE: Keep this logic in sync with android_os_Parcel.cpp
     status_t err = writeInt32(len);
     if (err == NO_ERROR) {
         uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
@@ -1115,6 +1118,7 @@
 {
     if (str == nullptr) return writeInt32(-1);
 
+    // NOTE: Keep this logic in sync with android_os_Parcel.cpp
     status_t err = writeInt32(len);
     if (err == NO_ERROR) {
         len *= sizeof(char16_t);
@@ -1913,17 +1917,6 @@
 
 #endif
 
-status_t Parcel::readIntPtr(intptr_t *pArg) const
-{
-    return readAligned(pArg);
-}
-
-
-intptr_t Parcel::readIntPtr() const
-{
-    return readAligned<intptr_t>();
-}
-
 status_t Parcel::readBool(bool *pArg) const
 {
     int32_t tmp = 0;
@@ -2508,7 +2501,7 @@
 }
 
 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+    const binder_size_t* objects, size_t objectsCount, release_func relFunc)
 {
     binder_size_t minOffset = 0;
     freeDataNoInit();
@@ -2523,7 +2516,6 @@
     mNextObjectHint = 0;
     mObjectsSorted = false;
     mOwner = relFunc;
-    mOwnerCookie = relCookie;
     for (size_t i = 0; i < mObjectsSize; i++) {
         binder_size_t offset = mObjects[i];
         if (offset < minOffset) {
@@ -2624,22 +2616,17 @@
     if (mOwner) {
         LOG_ALLOC("Parcel %p: freeing other owner data", this);
         //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
-        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize);
     } else {
         LOG_ALLOC("Parcel %p: freeing allocated data", this);
         releaseObjects();
         if (mData) {
             LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
-            pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
-            if (mDataCapacity <= gParcelGlobalAllocSize) {
-              gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
-            } else {
-              gParcelGlobalAllocSize = 0;
+            gParcelGlobalAllocSize -= mDataCapacity;
+            gParcelGlobalAllocCount--;
+            if (mDeallocZero) {
+                zeroMemory(mData, mDataSize);
             }
-            if (gParcelGlobalAllocCount > 0) {
-              gParcelGlobalAllocCount--;
-            }
-            pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
             free(mData);
         }
         if (mObjects) free(mObjects);
@@ -2662,6 +2649,21 @@
             : continueWrite(std::max(newSize, (size_t) 128));
 }
 
+static uint8_t* reallocZeroFree(uint8_t* data, size_t oldCapacity, size_t newCapacity, bool zero) {
+    if (!zero) {
+        return (uint8_t*)realloc(data, newCapacity);
+    }
+    uint8_t* newData = (uint8_t*)malloc(newCapacity);
+    if (!newData) {
+        return nullptr;
+    }
+
+    memcpy(newData, data, std::min(oldCapacity, newCapacity));
+    zeroMemory(data, oldCapacity);
+    free(data);
+    return newData;
+}
+
 status_t Parcel::restartWrite(size_t desired)
 {
     if (desired > INT32_MAX) {
@@ -2675,7 +2677,7 @@
         return continueWrite(desired);
     }
 
-    uint8_t* data = (uint8_t*)realloc(mData, desired);
+    uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero);
     if (!data && desired > mDataCapacity) {
         mError = NO_MEMORY;
         return NO_MEMORY;
@@ -2685,13 +2687,15 @@
 
     if (data) {
         LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
-        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
-        gParcelGlobalAllocSize += desired;
-        gParcelGlobalAllocSize -= mDataCapacity;
+        if (mDataCapacity > desired) {
+            gParcelGlobalAllocSize -= (mDataCapacity - desired);
+        } else {
+            gParcelGlobalAllocSize += (desired - mDataCapacity);
+        }
+
         if (!mData) {
             gParcelGlobalAllocCount++;
         }
-        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
         mData = data;
         mDataCapacity = desired;
     }
@@ -2775,14 +2779,12 @@
             memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
         }
         //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
-        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize);
         mOwner = nullptr;
 
         LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
-        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
         gParcelGlobalAllocSize += desired;
         gParcelGlobalAllocCount++;
-        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
 
         mData = data;
         mObjects = objects;
@@ -2826,14 +2828,12 @@
 
         // We own the data, so we can just do a realloc().
         if (desired > mDataCapacity) {
-            uint8_t* data = (uint8_t*)realloc(mData, desired);
+            uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero);
             if (data) {
                 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
                         desired);
-                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                 gParcelGlobalAllocSize += desired;
                 gParcelGlobalAllocSize -= mDataCapacity;
-                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
                 mData = data;
                 mDataCapacity = desired;
             } else {
@@ -2865,10 +2865,8 @@
         }
 
         LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
-        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
         gParcelGlobalAllocSize += desired;
         gParcelGlobalAllocCount++;
-        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
 
         mData = data;
         mDataSize = mDataPos = 0;
@@ -2898,6 +2896,7 @@
     mHasFds = false;
     mFdsKnown = true;
     mAllowFds = true;
+    mDeallocZero = false;
     mOwner = nullptr;
     mOpenAshmemSize = 0;
     mWorkSourceRequestHeaderPosition = 0;
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
index 75a6d22..6eae5ef 100644
--- a/libs/binder/PermissionCache.cpp
+++ b/libs/binder/PermissionCache.cpp
@@ -27,7 +27,7 @@
 
 // ----------------------------------------------------------------------------
 
-ANDROID_SINGLETON_STATIC_INSTANCE(PermissionCache) ;
+ANDROID_SINGLETON_STATIC_INSTANCE(PermissionCache)
 
 // ----------------------------------------------------------------------------
 
diff --git a/libs/binder/PersistableBundle.cpp b/libs/binder/PersistableBundle.cpp
index 97a6c94..c807cfe 100644
--- a/libs/binder/PersistableBundle.cpp
+++ b/libs/binder/PersistableBundle.cpp
@@ -34,10 +34,22 @@
 using android::sp;
 using android::status_t;
 using android::UNEXPECTED_NULL;
+
+using android::binder::VAL_BOOLEAN;
+using android::binder::VAL_INTEGER;
+using android::binder::VAL_LONG;
+using android::binder::VAL_DOUBLE;
+using android::binder::VAL_STRING;
+using android::binder::VAL_BOOLEANARRAY;
+using android::binder::VAL_INTARRAY;
+using android::binder::VAL_LONGARRAY;
+using android::binder::VAL_DOUBLEARRAY;
+using android::binder::VAL_STRINGARRAY;
+using android::binder::VAL_PERSISTABLEBUNDLE;
+
 using std::map;
 using std::set;
 using std::vector;
-using namespace ::android::binder;
 
 enum {
     // Keep them in sync with BUNDLE_MAGIC* in frameworks/base/core/java/android/os/BaseBundle.java.
diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp
index 00d6eef..f75141e 100644
--- a/libs/binder/ProcessInfoService.cpp
+++ b/libs/binder/ProcessInfoService.cpp
@@ -99,6 +99,6 @@
     }
 }
 
-ANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService);
+ANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService)
 
 } // namespace android
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 83ca687..9aedf28 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -130,7 +130,7 @@
 
     // The root object is special since we get it directly from the driver, it is never
     // written by Parcell::writeStrongBinder.
-    internal::Stability::tryMarkCompilationUnit(context.get());
+    internal::Stability::markCompilationUnit(context.get());
 
     return context;
 }
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 6115aec..339c538 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -13,6 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "Stability"
+
 #include <binder/Stability.h>
 
 #include <binder/BpBinder.h>
@@ -21,34 +23,59 @@
 namespace android {
 namespace internal {
 
+// the libbinder parcel format is currently unstable
+
+// oldest version which is supported
+constexpr uint8_t kBinderWireFormatOldest = 1;
+// current version
+constexpr uint8_t kBinderWireFormatVersion = 1;
+
+Stability::Category Stability::Category::currentFromLevel(Level level) {
+    return {
+        .version = kBinderWireFormatVersion,
+        .reserved = {0},
+        .level = level,
+    };
+}
+
+std::string Stability::Category::debugString() {
+    return levelString(level) + " wire protocol version "
+        + std::to_string(version);
+}
+
 void Stability::markCompilationUnit(IBinder* binder) {
-    status_t result = set(binder, getLocalStability(), true /*log*/);
+    auto stability = Category::currentFromLevel(getLocalLevel());
+    status_t result = setRepr(binder, stability.repr(), true /*log*/);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 void Stability::markVintf(IBinder* binder) {
-    status_t result = set(binder, Level::VINTF, true /*log*/);
+    auto stability = Category::currentFromLevel(Level::VINTF);
+    status_t result = setRepr(binder, stability.repr(), true /*log*/);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& binder) {
-    ALOGE("%s: stability is %s", tag.c_str(), stabilityString(get(binder.get())).c_str());
+    auto stability = getCategory(binder.get());
+    ALOGE("%s: stability is %s", tag.c_str(), stability.debugString().c_str());
 }
 
 void Stability::markVndk(IBinder* binder) {
-    status_t result = set(binder, Level::VENDOR, true /*log*/);
+    auto stability = Category::currentFromLevel(Level::VENDOR);
+    status_t result = setRepr(binder, stability.repr(), true /*log*/);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
-    return check(get(binder.get()), Level::VINTF);
+    return check(getCategory(binder.get()), Level::VINTF);
 }
 
 void Stability::tryMarkCompilationUnit(IBinder* binder) {
-    (void) set(binder, getLocalStability(), false /*log*/);
+    auto stability = Category::currentFromLevel(getLocalLevel());
+    (void) setRepr(binder, stability.repr(), false /*log*/);
 }
 
-Stability::Level Stability::getLocalStability() {
+Stability::Level Stability::getLocalLevel() {
 #ifdef __ANDROID_VNDK__
     #ifdef __ANDROID_APEX__
         // TODO(b/142684679) avoid use_vendor on system APEXes
@@ -67,65 +94,81 @@
 #endif
 }
 
-status_t Stability::set(IBinder* binder, int32_t stability, bool log) {
-    Level currentStability = get(binder);
+status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
+    auto current = getCategory(binder);
+    auto setting = Category::fromRepr(representation);
+
+    // If we have ahold of a binder with a newer declared version, then it
+    // should support older versions, and we will simply write our parcels with
+    // the current wire parcel format.
+    if (setting.version < kBinderWireFormatOldest) {
+        // always log, because this shouldn't happen
+        ALOGE("Cannot accept binder with older binder wire protocol version "
+              "%u. Versions less than %u are unsupported.", setting.version,
+               kBinderWireFormatOldest);
+        return BAD_TYPE;
+    }
 
     // null binder is always written w/ 'UNDECLARED' stability
     if (binder == nullptr) {
-        if (stability == UNDECLARED) {
+        if (setting.level == UNDECLARED) {
             return OK;
         } else {
             if (log) {
                 ALOGE("Null binder written with stability %s.",
-                    stabilityString(stability).c_str());
+                    levelString(setting.level).c_str());
             }
             return BAD_TYPE;
         }
     }
 
-    if (!isDeclaredStability(stability)) {
+    if (!isDeclaredLevel(setting.level)) {
         if (log) {
-            ALOGE("Can only set known stability, not %d.", stability);
+            ALOGE("Can only set known stability, not %u.", setting.level);
         }
         return BAD_TYPE;
     }
 
-    if (currentStability != Level::UNDECLARED && currentStability != stability) {
+    if (current.repr() != 0 && current != setting) {
         if (log) {
-            ALOGE("Interface being set with %s but it is already marked as %s.",
-                stabilityString(stability).c_str(), stabilityString(currentStability).c_str());
+            ALOGE("Interface being set with %s but it is already marked as %s",
+                  setting.debugString().c_str(),
+                  current.debugString().c_str());
         }
         return BAD_TYPE;
     }
 
-    if (currentStability == stability) return OK;
+    if (current == setting) return OK;
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        local->mStability = static_cast<int32_t>(stability);
+        local->mStability = setting.repr();
     } else {
-        binder->remoteBinder()->mStability = static_cast<int32_t>(stability);
+        binder->remoteBinder()->mStability = setting.repr();
     }
 
     return OK;
 }
 
-Stability::Level Stability::get(IBinder* binder) {
-    if (binder == nullptr) return UNDECLARED;
+Stability::Category Stability::getCategory(IBinder* binder) {
+    if (binder == nullptr) {
+        return Category::currentFromLevel(Level::UNDECLARED);
+    }
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        return static_cast<Stability::Level>(local->mStability);
+        return Category::fromRepr(local->mStability);
     }
 
-    return static_cast<Stability::Level>(binder->remoteBinder()->mStability);
+    return Category::fromRepr(binder->remoteBinder()->mStability);
 }
 
-bool Stability::check(int32_t provided, Level required) {
-    bool stable = (provided & required) == required;
+bool Stability::check(Category provided, Level required) {
+    bool stable = (provided.level & required) == required;
 
-    if (!isDeclaredStability(provided) && provided != UNDECLARED) {
-        ALOGE("Unknown stability when checking interface stability %d.", provided);
+    if (provided.level != UNDECLARED && !isDeclaredLevel(provided.level)) {
+        ALOGE("Unknown stability when checking interface stability %d.",
+              provided.level);
 
         stable = false;
     }
@@ -133,18 +176,18 @@
     return stable;
 }
 
-bool Stability::isDeclaredStability(int32_t stability) {
+bool Stability::isDeclaredLevel(Level stability) {
     return stability == VENDOR || stability == SYSTEM || stability == VINTF;
 }
 
-std::string Stability::stabilityString(int32_t stability) {
-    switch (stability) {
+std::string Stability::levelString(Level level) {
+    switch (level) {
         case Level::UNDECLARED: return "undeclared stability";
         case Level::VENDOR: return "vendor stability";
         case Level::SYSTEM: return "system stability";
         case Level::VINTF: return "vintf stability";
     }
-    return "unknown stability " + std::to_string(stability);
+    return "unknown stability " + std::to_string(level);
 }
 
 }  // namespace internal
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index db0f1c7..565f2e2 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -33,7 +33,7 @@
 {
 public:
     LogTextOutput() : BufferedTextOutput(MULTITHREADED) { }
-    virtual ~LogTextOutput() { };
+    virtual ~LogTextOutput() { }
 
 protected:
     virtual status_t writeLines(const struct iovec& vec, size_t N)
@@ -49,7 +49,7 @@
 {
 public:
     explicit FdTextOutput(int fd) : BufferedTextOutput(MULTITHREADED), mFD(fd) { }
-    virtual ~FdTextOutput() { };
+    virtual ~FdTextOutput() { }
 
 protected:
     virtual status_t writeLines(const struct iovec& vec, size_t N)
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index 64ab7a9..b5a078c 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -245,10 +245,5 @@
     return ret;
 }
 
-std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
-    stream << s.toString8().string();
-    return stream;
-}
-
 }  // namespace binder
 }  // namespace android
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index c232283..97e282e 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -16,6 +16,13 @@
       "name": "binderTextOutputTest"
     },
     {
+      "name": "binderParcelTest"
+    },
+    {
+      "name": "binderParcelTest",
+      "host": true
+    },
+    {
       "name": "binderLibTest"
     },
     {
@@ -31,6 +38,9 @@
       "name": "aidl_lazy_test"
     },
     {
+      "name": "aidl_integration_test"
+    },
+    {
       "name": "libbinderthreadstateutils_test"
     },
     {
@@ -43,6 +53,15 @@
           "exclude-filter": "android.os.cts.StrictModeTest#testNonSdkApiUsage"
         }
       ]
+    },
+    {
+      "name": "libbinder_rs-internal_test"
+    },
+    {
+      "name": "rustBinderTest"
+    },
+    {
+      "name": "binderRustNdkInteropTest"
     }
   ]
 }
diff --git a/libs/binder/Utils.cpp b/libs/binder/Utils.cpp
new file mode 100644
index 0000000..90a4502
--- /dev/null
+++ b/libs/binder/Utils.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Utils.h"
+
+#include <string.h>
+
+namespace android {
+
+void zeroMemory(uint8_t* data, size_t size) {
+    memset(data, 0, size);
+}
+
+}   // namespace android
diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h
new file mode 100644
index 0000000..f94b158
--- /dev/null
+++ b/libs/binder/Utils.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdint>
+#include <stddef.h>
+
+namespace android {
+
+// avoid optimizations
+void zeroMemory(uint8_t* data, size_t size);
+
+}   // namespace android
diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include/binder/ActivityManager.h
index 9108e31..b90dc86 100644
--- a/libs/binder/include/binder/ActivityManager.h
+++ b/libs/binder/include/binder/ActivityManager.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ACTIVITY_MANAGER_H
-#define ANDROID_ACTIVITY_MANAGER_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -94,5 +93,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_ACTIVITY_MANAGER_H
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 6d04f13..18a8a98 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_APP_OPS_MANAGER_H
-#define ANDROID_APP_OPS_MANAGER_H
+#pragma once
 
 #include <binder/IAppOpsService.h>
 
@@ -175,5 +174,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_APP_OPS_MANAGER_H
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index f3fea16..7079544 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_BINDER_H
-#define ANDROID_BINDER_H
+#pragma once
 
 #include <atomic>
 #include <stdint.h>
@@ -88,6 +87,11 @@
     int                 getMinSchedulerPolicy();
     int                 getMinSchedulerPriority();
 
+    // Whether realtime scheduling policies are inherited.
+    bool                isInheritRt();
+    // This must be called before the object is sent to another process. Not thread safe.
+    void                setInheritRt(bool inheritRt);
+
     pid_t               getDebugPid();
 
 protected:
@@ -142,5 +146,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_BINDER_H
diff --git a/libs/binder/include/binder/BinderService.h b/libs/binder/include/binder/BinderService.h
index c17ae6f..5776f3c 100644
--- a/libs/binder/include/binder/BinderService.h
+++ b/libs/binder/include/binder/BinderService.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_BINDER_SERVICE_H
-#define ANDROID_BINDER_SERVICE_H
+#pragma once
 
 #include <stdint.h>
 
@@ -64,4 +63,3 @@
 
 } // namespace android
 // ---------------------------------------------------------------------------
-#endif // ANDROID_BINDER_SERVICE_H
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 378a911..2735315 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_BPBINDER_H
-#define ANDROID_BPBINDER_H
+#pragma once
 
 #include <binder/IBinder.h>
 #include <utils/KeyedVector.h>
@@ -29,7 +28,7 @@
 
 namespace internal {
 class Stability;
-};
+}
 
 using binder_proxy_limit_callback = void(*)(int);
 
@@ -110,19 +109,18 @@
         KeyedVector<const void*, entry_t> mObjects;
     };
 
-protected:
+private:
                         BpBinder(int32_t handle,int32_t trackedUid);
     virtual             ~BpBinder();
     virtual void        onFirstRef();
     virtual void        onLastStrongRef(const void* id);
     virtual bool        onIncStrongAttempted(uint32_t flags, const void* id);
 
-private:
-    const   int32_t             mHandle;
-
     friend ::android::internal::Stability;
             int32_t             mStability;
 
+    const   int32_t             mHandle;
+
     struct Obituary {
         wp<DeathRecipient> recipient;
         void* cookie;
@@ -153,5 +151,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_BPBINDER_H
diff --git a/libs/binder/include/binder/Debug.h b/libs/binder/include/binder/Debug.h
index 324e5c1..ac71e00 100644
--- a/libs/binder/include/binder/Debug.h
+++ b/libs/binder/include/binder/Debug.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_BINDER_DEBUG_H
-#define ANDROID_BINDER_DEBUG_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/cdefs.h>
@@ -45,5 +44,3 @@
 
 // ---------------------------------------------------------------------------
 } // namespace android
-
-#endif // ANDROID_BINDER_DEBUG_H
diff --git a/libs/binder/include/binder/Enums.h b/libs/binder/include/binder/Enums.h
index aec6f70..c6803bd 100644
--- a/libs/binder/include/binder/Enums.h
+++ b/libs/binder/include/binder/Enums.h
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #pragma once
 
 #include <iterator>
@@ -38,4 +39,4 @@
     constexpr auto end() const { return std::end(internal::enum_values<EnumType>); }
 };
 
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include/binder/IActivityManager.h
index e0248f6..fde56a0 100644
--- a/libs/binder/include/binder/IActivityManager.h
+++ b/libs/binder/include/binder/IActivityManager.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IACTIVITY_MANAGER_H
-#define ANDROID_IACTIVITY_MANAGER_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -56,5 +55,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_IACTIVITY_MANAGER_H
diff --git a/libs/binder/include/binder/IAppOpsCallback.h b/libs/binder/include/binder/IAppOpsCallback.h
index 7664260..eb76f57 100644
--- a/libs/binder/include/binder/IAppOpsCallback.h
+++ b/libs/binder/include/binder/IAppOpsCallback.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IAPP_OPS_CALLBACK_H
-#define ANDROID_IAPP_OPS_CALLBACK_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -57,6 +55,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_IAPP_OPS_CALLBACK_H
-
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/binder/include/binder/IAppOpsService.h
index a4a20c8..b0719d4 100644
--- a/libs/binder/include/binder/IAppOpsService.h
+++ b/libs/binder/include/binder/IAppOpsService.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IAPP_OPS_SERVICE_H
-#define ANDROID_IAPP_OPS_SERVICE_H
+#pragma once
 
 #include <binder/IAppOpsCallback.h>
 #include <binder/IInterface.h>
@@ -89,5 +87,3 @@
 // ----------------------------------------------------------------------
 
 } // namespace android
-
-#endif // ANDROID_IAPP_OPS_SERVICE_H
diff --git a/libs/binder/include/binder/IBatteryStats.h b/libs/binder/include/binder/IBatteryStats.h
index b786f89..6defc7f 100644
--- a/libs/binder/include/binder/IBatteryStats.h
+++ b/libs/binder/include/binder/IBatteryStats.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IBATTERYSTATS_H
-#define ANDROID_IBATTERYSTATS_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -82,5 +81,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_IBATTERYSTATS_H
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index eea0e89..c8fb448 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IBINDER_H
-#define ANDROID_IBINDER_H
+#pragma once
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -64,6 +63,10 @@
         // Corresponds to TF_ONE_WAY -- an asynchronous call.
         FLAG_ONEWAY             = 0x00000001,
 
+        // Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call
+        // is made
+        FLAG_CLEAR_BUF          = 0x00000020,
+
         // Private userspace flag for transaction which is being requested from
         // a vendor context.
         FLAG_PRIVATE_VENDOR     = 0x10000000,
@@ -253,5 +256,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_IBINDER_H
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index 7116154..f4a21dd 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IINTERFACE_H
-#define ANDROID_IINTERFACE_H
+#pragma once
 
 #include <binder/Binder.h>
 
@@ -335,5 +333,3 @@
 
 } // namespace internal
 } // namespace android
-
-#endif // ANDROID_IINTERFACE_H
diff --git a/libs/binder/include/binder/IMediaResourceMonitor.h b/libs/binder/include/binder/IMediaResourceMonitor.h
index da2b7cf..f92d557 100644
--- a/libs/binder/include/binder/IMediaResourceMonitor.h
+++ b/libs/binder/include/binder/IMediaResourceMonitor.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_I_MEDIA_RESOURCE_MONITOR_H
-#define ANDROID_I_MEDIA_RESOURCE_MONITOR_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -46,6 +45,7 @@
 
 class BnMediaResourceMonitor : public BnInterface<IMediaResourceMonitor> {
 public:
+    // NOLINTNEXTLINE(google-default-arguments)
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
             uint32_t flags = 0);
 };
@@ -57,5 +57,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_I_MEDIA_RESOURCE_MONITOR_H
diff --git a/libs/binder/include/binder/IMemory.h b/libs/binder/include/binder/IMemory.h
index 1a36eb0..d8b7ec1 100644
--- a/libs/binder/include/binder/IMemory.h
+++ b/libs/binder/include/binder/IMemory.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IMEMORY_H
-#define ANDROID_IMEMORY_H
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -124,5 +123,3 @@
 // ----------------------------------------------------------------------------
 
 } // namespace android
-
-#endif // ANDROID_IMEMORY_H
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 49ef253..4da8aa1 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IPC_THREAD_STATE_H
-#define ANDROID_IPC_THREAD_STATE_H
+#pragma once
 
 #include <utils/Errors.h>
 #include <binder/Parcel.h>
@@ -147,7 +146,7 @@
             void                blockUntilThreadAvailable();
 
             // Service manager registration
-            void                setTheContextObject(sp<BBinder> obj);
+            void                setTheContextObject(const sp<BBinder>& obj);
 
             // WARNING: DO NOT USE THIS API
             //
@@ -186,9 +185,8 @@
     static  void                threadDestructor(void *st);
     static  void                freeBuffer(Parcel* parcel,
                                            const uint8_t* data, size_t dataSize,
-                                           const binder_size_t* objects, size_t objectsSize,
-                                           void* cookie);
-    
+                                           const binder_size_t* objects, size_t objectsSize);
+
     const   sp<ProcessState>    mProcess;
             Vector<BBinder*>    mPendingStrongDerefs;
             Vector<RefBase::weakref_type*> mPendingWeakDerefs;
@@ -214,5 +212,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_IPC_THREAD_STATE_H
diff --git a/libs/binder/include/binder/IPermissionController.h b/libs/binder/include/binder/IPermissionController.h
index 4b66df8..a4f93d9 100644
--- a/libs/binder/include/binder/IPermissionController.h
+++ b/libs/binder/include/binder/IPermissionController.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IPERMISSION_CONTROLLER_H
-#define ANDROID_IPERMISSION_CONTROLLER_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -70,6 +68,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_IPERMISSION_CONTROLLER_H
-
diff --git a/libs/binder/include/binder/IProcessInfoService.h b/libs/binder/include/binder/IProcessInfoService.h
index ca30ad3..622f231 100644
--- a/libs/binder/include/binder/IProcessInfoService.h
+++ b/libs/binder/include/binder/IProcessInfoService.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_I_PROCESS_INFO_SERVICE_H
-#define ANDROID_I_PROCESS_INFO_SERVICE_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -51,5 +50,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_I_PROCESS_INFO_SERVICE_H
diff --git a/libs/binder/include/binder/IResultReceiver.h b/libs/binder/include/binder/IResultReceiver.h
index 70e99e7..5434445 100644
--- a/libs/binder/include/binder/IResultReceiver.h
+++ b/libs/binder/include/binder/IResultReceiver.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IRESULT_RECEIVER_H
-#define ANDROID_IRESULT_RECEIVER_H
+#pragma once
 
 #include <binder/IInterface.h>
 
@@ -51,6 +49,3 @@
 // ----------------------------------------------------------------------
 
 } // namespace android
-
-#endif // ANDROID_IRESULT_RECEIVER_H
-
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 3c5ccc1..5f0d056 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_ISERVICE_MANAGER_H
-#define ANDROID_ISERVICE_MANAGER_H
+#pragma once
 
 #include <binder/IInterface.h>
 #include <utils/Vector.h>
@@ -164,6 +162,3 @@
 bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
 
 } // namespace android
-
-#endif // ANDROID_ISERVICE_MANAGER_H
-
diff --git a/libs/binder/include/binder/IShellCallback.h b/libs/binder/include/binder/IShellCallback.h
index b7ab6ea..6d3fe4a 100644
--- a/libs/binder/include/binder/IShellCallback.h
+++ b/libs/binder/include/binder/IShellCallback.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_ISHELL_CALLBACK_H
-#define ANDROID_ISHELL_CALLBACK_H
+#pragma once
 
 #include <binder/IInterface.h>
 
@@ -27,7 +25,7 @@
 class IShellCallback : public IInterface
 {
 public:
-    DECLARE_META_INTERFACE(ShellCallback);
+    DECLARE_META_INTERFACE(ShellCallback)
 
     virtual int openFile(const String16& path, const String16& seLinuxContext,
             const String16& mode) = 0;
@@ -52,6 +50,3 @@
 // ----------------------------------------------------------------------
 
 } // namespace android
-
-#endif // ANDROID_ISHELL_CALLBACK_H
-
diff --git a/libs/binder/include/binder/IUidObserver.h b/libs/binder/include/binder/IUidObserver.h
index d070390..9291c0b 100644
--- a/libs/binder/include/binder/IUidObserver.h
+++ b/libs/binder/include/binder/IUidObserver.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-//
-#ifndef ANDROID_IUID_OBSERVER_H
-#define ANDROID_IUID_OBSERVER_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -64,5 +62,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_IUID_OBSERVER_H
diff --git a/libs/binder/include/binder/IpPrefix.h b/libs/binder/include/binder/IpPrefix.h
index c7e7a50..a8faa3f 100644
--- a/libs/binder/include/binder/IpPrefix.h
+++ b/libs/binder/include/binder/IpPrefix.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_IP_PREFIX_H
-#define ANDROID_IP_PREFIX_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -74,8 +73,8 @@
 private:
     union InternalUnion {
         InternalUnion() = default;
-        explicit InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { };
-        explicit InternalUnion(const struct in_addr &addr):mInAddr(addr) { };
+        explicit InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { }
+        explicit InternalUnion(const struct in_addr &addr):mInAddr(addr) { }
         struct in6_addr mIn6Addr;
         struct in_addr mInAddr;
     } mUnion;
@@ -90,5 +89,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif  // ANDROID_IP_PREFIX_H
diff --git a/libs/binder/include/binder/MemoryBase.h b/libs/binder/include/binder/MemoryBase.h
index 4dd3638..61a029c 100644
--- a/libs/binder/include/binder/MemoryBase.h
+++ b/libs/binder/include/binder/MemoryBase.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_MEMORY_BASE_H
-#define ANDROID_MEMORY_BASE_H
+#pragma once
 
 #include <stdlib.h>
 #include <stdint.h>
@@ -47,5 +46,3 @@
 
 // ---------------------------------------------------------------------------
 } // namespace android
-
-#endif // ANDROID_MEMORY_BASE_H
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index 6c1c412..e727772 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_MEMORY_DEALER_H
-#define ANDROID_MEMORY_DEALER_H
-
+#pragma once
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -60,5 +58,3 @@
 
 // ----------------------------------------------------------------------------
 } // namespace android
-
-#endif // ANDROID_MEMORY_DEALER_H
diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h
index 52bd5de..dd76943 100644
--- a/libs/binder/include/binder/MemoryHeapBase.h
+++ b/libs/binder/include/binder/MemoryHeapBase.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_MEMORY_HEAP_BASE_H
-#define ANDROID_MEMORY_HEAP_BASE_H
+#pragma once
 
 #include <stdlib.h>
 #include <stdint.h>
@@ -51,6 +50,8 @@
 
     /*
      * maps memory from ashmem, with the given name for debugging
+     * if the READ_ONLY flag is set, the memory will be writeable by the calling process,
+     * but not by others. this is NOT the case with the other ctors.
      */
     explicit MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = nullptr);
 
@@ -78,7 +79,7 @@
             int flags = 0, const char* device = nullptr);
 
 private:
-    status_t mapfd(int fd, size_t size, off_t offset = 0);
+    status_t mapfd(int fd, bool writeableByCaller, size_t size, off_t offset = 0);
 
     int         mFD;
     size_t      mSize;
@@ -91,5 +92,3 @@
 
 // ---------------------------------------------------------------------------
 } // namespace android
-
-#endif // ANDROID_MEMORY_HEAP_BASE_H
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index fbfd6c5..9f5260a 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PARCEL_H
-#define ANDROID_PARCEL_H
+#pragma once
 
 #include <map> // for legacy reasons
 #include <string>
@@ -34,18 +33,20 @@
 #include <binder/Parcelable.h>
 
 #ifdef BINDER_IPC_32BIT
+//NOLINTNEXTLINE(google-runtime-int) b/173188702
 typedef unsigned int binder_size_t;
 #else
+//NOLINTNEXTLINE(google-runtime-int) b/173188702
 typedef unsigned long long binder_size_t;
 #endif
 
+struct flat_binder_object;
 
 // ---------------------------------------------------------------------------
 namespace android {
 
 template <typename T> class Flattenable;
 template <typename T> class LightFlattenable;
-struct flat_binder_object;
 class IBinder;
 class IPCThreadState;
 class ProcessState;
@@ -84,6 +85,13 @@
 
     bool                hasFileDescriptors() const;
 
+    // Zeros data when reallocating. Other mitigations may be added
+    // in the future.
+    //
+    // WARNING: some read methods may make additional copies of data.
+    // In order to verify this, heap dumps should be used.
+    void                markSensitive() const;
+
     // Writes the RPC header.
     status_t            writeInterfaceToken(const String16& interface);
     status_t            writeInterfaceToken(const char16_t* str, size_t len);
@@ -123,7 +131,7 @@
     status_t            writeString8(const char* str, size_t len);
     status_t            writeString16(const String16& str);
     status_t            writeString16(const std::optional<String16>& str);
-    status_t            writeString16(const std::unique_ptr<String16>& str);
+    status_t            writeString16(const std::unique_ptr<String16>& str) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeString16(const char16_t* str, size_t len);
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeInt32Array(size_t len, const int32_t *val);
@@ -135,48 +143,48 @@
     // Take a UTF8 encoded string, convert to UTF16, write it to the parcel.
     status_t            writeUtf8AsUtf16(const std::string& str);
     status_t            writeUtf8AsUtf16(const std::optional<std::string>& str);
-    status_t            writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);
+    status_t            writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) __attribute__((deprecated("use std::optional version instead")));
 
     status_t            writeByteVector(const std::optional<std::vector<int8_t>>& val);
-    status_t            writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
+    status_t            writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeByteVector(const std::vector<int8_t>& val);
     status_t            writeByteVector(const std::optional<std::vector<uint8_t>>& val);
-    status_t            writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);
+    status_t            writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeByteVector(const std::vector<uint8_t>& val);
     status_t            writeInt32Vector(const std::optional<std::vector<int32_t>>& val);
-    status_t            writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
+    status_t            writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeInt32Vector(const std::vector<int32_t>& val);
     status_t            writeInt64Vector(const std::optional<std::vector<int64_t>>& val);
-    status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
+    status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeInt64Vector(const std::vector<int64_t>& val);
     status_t            writeUint64Vector(const std::optional<std::vector<uint64_t>>& val);
-    status_t            writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val);
+    status_t            writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeUint64Vector(const std::vector<uint64_t>& val);
     status_t            writeFloatVector(const std::optional<std::vector<float>>& val);
-    status_t            writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
+    status_t            writeFloatVector(const std::unique_ptr<std::vector<float>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeFloatVector(const std::vector<float>& val);
     status_t            writeDoubleVector(const std::optional<std::vector<double>>& val);
-    status_t            writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
+    status_t            writeDoubleVector(const std::unique_ptr<std::vector<double>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeDoubleVector(const std::vector<double>& val);
     status_t            writeBoolVector(const std::optional<std::vector<bool>>& val);
-    status_t            writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);
+    status_t            writeBoolVector(const std::unique_ptr<std::vector<bool>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeBoolVector(const std::vector<bool>& val);
     status_t            writeCharVector(const std::optional<std::vector<char16_t>>& val);
-    status_t            writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);
+    status_t            writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeCharVector(const std::vector<char16_t>& val);
     status_t            writeString16Vector(
                             const std::optional<std::vector<std::optional<String16>>>& val);
     status_t            writeString16Vector(
-                            const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
+                            const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeString16Vector(const std::vector<String16>& val);
     status_t            writeUtf8VectorAsUtf16Vector(
                             const std::optional<std::vector<std::optional<std::string>>>& val);
     status_t            writeUtf8VectorAsUtf16Vector(
-                            const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);
+                            const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);
 
     status_t            writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val);
-    status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
+    status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
 
     // Write an Enum vector with underlying type int8_t.
@@ -186,28 +194,30 @@
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::optional<std::vector<T>>& val);
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
-    status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
+    status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val) __attribute__((deprecated("use std::optional version instead")));
     // Write an Enum vector with underlying type != int8_t.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::vector<T>& val);
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            writeEnumVector(const std::optional<std::vector<T>>& val);
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
-    status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
+    status_t            writeEnumVector(const std::unique_ptr<std::vector<T>>& val) __attribute__((deprecated("use std::optional version instead")));
 
     template<typename T>
     status_t            writeParcelableVector(const std::optional<std::vector<std::optional<T>>>& val);
     template<typename T>
-    status_t            writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
+    status_t            writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
-    status_t            writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>>& val);
+    status_t            writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>>& val) __attribute__((deprecated("use std::optional version instead")));
+    template<typename T>
+    status_t            writeParcelableVector(const std::shared_ptr<std::vector<std::optional<T>>>& val);
     template<typename T>
     status_t            writeParcelableVector(const std::vector<T>& val);
 
     template<typename T>
     status_t            writeNullableParcelable(const std::optional<T>& parcelable);
     template<typename T>
-    status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable);
+    status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable) __attribute__((deprecated("use std::optional version instead")));
 
     status_t            writeParcelable(const Parcelable& parcelable);
 
@@ -222,7 +232,7 @@
     template<typename T>
     status_t            writeVectorSize(const std::optional<std::vector<T>>& val);
     template<typename T>
-    status_t            writeVectorSize(const std::unique_ptr<std::vector<T>>& val);
+    status_t            writeVectorSize(const std::unique_ptr<std::vector<T>>& val) __attribute__((deprecated("use std::optional version instead")));
 
     // Place a native_handle into the parcel (the native_handle's file-
     // descriptors are dup'ed, so it is safe to delete the native_handle
@@ -259,7 +269,7 @@
     status_t            writeUniqueFileDescriptorVector(
                             const std::optional<std::vector<base::unique_fd>>& val);
     status_t            writeUniqueFileDescriptorVector(
-                            const std::unique_ptr<std::vector<base::unique_fd>>& val);
+                            const std::unique_ptr<std::vector<base::unique_fd>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeUniqueFileDescriptorVector(
                             const std::vector<base::unique_fd>& val);
 
@@ -297,8 +307,6 @@
     status_t            readFloat(float *pArg) const;
     double              readDouble() const;
     status_t            readDouble(double *pArg) const;
-    intptr_t            readIntPtr() const;
-    status_t            readIntPtr(intptr_t *pArg) const;
     bool                readBool() const;
     status_t            readBool(bool *pArg) const;
     char16_t            readChar() const;
@@ -309,7 +317,7 @@
     // Read a UTF16 encoded string, convert to UTF8
     status_t            readUtf8FromUtf16(std::string* str) const;
     status_t            readUtf8FromUtf16(std::optional<std::string>* str) const;
-    status_t            readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;
+    status_t            readUtf8FromUtf16(std::unique_ptr<std::string>* str) const __attribute__((deprecated("use std::optional version instead")));
 
     const char*         readCString() const;
     String8             readString8() const;
@@ -318,7 +326,7 @@
     String16            readString16() const;
     status_t            readString16(String16* pArg) const;
     status_t            readString16(std::optional<String16>* pArg) const;
-    status_t            readString16(std::unique_ptr<String16>* pArg) const;
+    status_t            readString16(std::unique_ptr<String16>* pArg) const __attribute__((deprecated("use std::optional version instead")));
     const char16_t*     readString16Inplace(size_t* outLen) const;
     sp<IBinder>         readStrongBinder() const;
     status_t            readStrongBinder(sp<IBinder>* val) const;
@@ -329,14 +337,14 @@
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::vector<T>* val) const;
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
-    status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+    status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const __attribute__((deprecated("use std::optional version instead")));
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::optional<std::vector<T>>* val) const;
     // Read an Enum vector with underlying type != int8_t.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::vector<T>* val) const;
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
-    status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
+    status_t            readEnumVector(std::unique_ptr<std::vector<T>>* val) const __attribute__((deprecated("use std::optional version instead")));
     template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
     status_t            readEnumVector(std::optional<std::vector<T>>* val) const;
 
@@ -345,7 +353,7 @@
                             std::optional<std::vector<std::optional<T>>>* val) const;
     template<typename T>
     status_t            readParcelableVector(
-                            std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
+                            std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
     status_t            readParcelableVector(std::vector<T>* val) const;
 
@@ -354,7 +362,7 @@
     template<typename T>
     status_t            readParcelable(std::optional<T>* parcelable) const;
     template<typename T>
-    status_t            readParcelable(std::unique_ptr<T>* parcelable) const;
+    status_t            readParcelable(std::unique_ptr<T>* parcelable) const __attribute__((deprecated("use std::optional version instead")));
 
     template<typename T>
     status_t            readStrongBinder(sp<T>* val) const;
@@ -363,45 +371,45 @@
     status_t            readNullableStrongBinder(sp<T>* val) const;
 
     status_t            readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const;
-    status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
+    status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
 
     status_t            readByteVector(std::optional<std::vector<int8_t>>* val) const;
-    status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
+    status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readByteVector(std::vector<int8_t>* val) const;
     status_t            readByteVector(std::optional<std::vector<uint8_t>>* val) const;
-    status_t            readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;
+    status_t            readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readByteVector(std::vector<uint8_t>* val) const;
     status_t            readInt32Vector(std::optional<std::vector<int32_t>>* val) const;
-    status_t            readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
+    status_t            readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readInt32Vector(std::vector<int32_t>* val) const;
     status_t            readInt64Vector(std::optional<std::vector<int64_t>>* val) const;
-    status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
+    status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readInt64Vector(std::vector<int64_t>* val) const;
     status_t            readUint64Vector(std::optional<std::vector<uint64_t>>* val) const;
-    status_t            readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const;
+    status_t            readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readUint64Vector(std::vector<uint64_t>* val) const;
     status_t            readFloatVector(std::optional<std::vector<float>>* val) const;
-    status_t            readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
+    status_t            readFloatVector(std::unique_ptr<std::vector<float>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readFloatVector(std::vector<float>* val) const;
     status_t            readDoubleVector(std::optional<std::vector<double>>* val) const;
-    status_t            readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
+    status_t            readDoubleVector(std::unique_ptr<std::vector<double>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readDoubleVector(std::vector<double>* val) const;
     status_t            readBoolVector(std::optional<std::vector<bool>>* val) const;
-    status_t            readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;
+    status_t            readBoolVector(std::unique_ptr<std::vector<bool>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readBoolVector(std::vector<bool>* val) const;
     status_t            readCharVector(std::optional<std::vector<char16_t>>* val) const;
-    status_t            readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;
+    status_t            readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readCharVector(std::vector<char16_t>* val) const;
     status_t            readString16Vector(
                             std::optional<std::vector<std::optional<String16>>>* val) const;
     status_t            readString16Vector(
-                            std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
+                            std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readString16Vector(std::vector<String16>* val) const;
     status_t            readUtf8VectorFromUtf16Vector(
                             std::optional<std::vector<std::optional<std::string>>>* val) const;
     status_t            readUtf8VectorFromUtf16Vector(
-                            std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;
+                            std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;
 
     template<typename T>
@@ -415,7 +423,7 @@
     template<typename T>
     status_t            resizeOutVector(std::optional<std::vector<T>>* val) const;
     template<typename T>
-    status_t            resizeOutVector(std::unique_ptr<std::vector<T>>* val) const;
+    status_t            resizeOutVector(std::unique_ptr<std::vector<T>>* val) const __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
     status_t            reserveOutVector(std::vector<T>* val, size_t* size) const;
     template<typename T>
@@ -423,7 +431,7 @@
                                          size_t* size) const;
     template<typename T>
     status_t            reserveOutVector(std::unique_ptr<std::vector<T>>* val,
-                                         size_t* size) const;
+                                         size_t* size) const __attribute__((deprecated("use std::optional version instead")));
 
     // Like Parcel.java's readExceptionCode().  Reads the first int32
     // off of a Parcel's header, returning 0 or the negative error
@@ -459,7 +467,7 @@
     status_t            readUniqueFileDescriptorVector(
                             std::optional<std::vector<base::unique_fd>>* val) const;
     status_t            readUniqueFileDescriptorVector(
-                            std::unique_ptr<std::vector<base::unique_fd>>* val) const;
+                            std::unique_ptr<std::vector<base::unique_fd>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readUniqueFileDescriptorVector(
                             std::vector<base::unique_fd>* val) const;
 
@@ -481,24 +489,21 @@
     // uid.
     uid_t               readCallingWorkSourceUid() const;
 
+    void                print(TextOutput& to, uint32_t flags = 0) const;
+
 private:
     typedef void        (*release_func)(Parcel* parcel,
                                         const uint8_t* data, size_t dataSize,
-                                        const binder_size_t* objects, size_t objectsSize,
-                                        void* cookie);
-                        
+                                        const binder_size_t* objects, size_t objectsSize);
+
     uintptr_t           ipcData() const;
     size_t              ipcDataSize() const;
     uintptr_t           ipcObjects() const;
     size_t              ipcObjectsCount() const;
     void                ipcSetDataReference(const uint8_t* data, size_t dataSize,
                                             const binder_size_t* objects, size_t objectsCount,
-                                            release_func relFunc, void* relCookie);
-    
-public:
-    void                print(TextOutput& to, uint32_t flags = 0) const;
+                                            release_func relFunc);
 
-private:
                         Parcel(const Parcel& o);
     Parcel&             operator=(const Parcel& o);
     
@@ -517,8 +522,7 @@
     status_t            validateReadData(size_t len) const;
     void                updateWorkSourceRequestHeaderPosition() const;
 
-    status_t            finishFlattenBinder(const sp<IBinder>& binder,
-                                            const flat_binder_object& flat);
+    status_t            finishFlattenBinder(const sp<IBinder>& binder);
     status_t            finishUnflattenBinder(const sp<IBinder>& binder, sp<IBinder>* out) const;
     status_t            flattenBinder(const sp<IBinder>& binder);
     status_t            unflattenBinder(sp<IBinder>* out) const;
@@ -556,7 +560,7 @@
                                                 status_t(Parcel::*read_func)(T*) const) const;
     template<typename T>
     status_t            readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
-                                                status_t(Parcel::*read_func)(T*) const) const;
+                                                status_t(Parcel::*read_func)(T*) const) const __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
     status_t            readTypedVector(std::vector<T>* val,
                                         status_t(Parcel::*read_func)(T*) const) const;
@@ -568,13 +572,13 @@
                                                  status_t(Parcel::*write_func)(const T&));
     template<typename T>
     status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
-                                                 status_t(Parcel::*write_func)(const T&));
+                                                 status_t(Parcel::*write_func)(const T&)) __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
     status_t            writeNullableTypedVector(const std::optional<std::vector<T>>& val,
                                                  status_t(Parcel::*write_func)(T));
     template<typename T>
     status_t            writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
-                                                 status_t(Parcel::*write_func)(T));
+                                                 status_t(Parcel::*write_func)(T)) __attribute__((deprecated("use std::optional version instead")));
     template<typename T>
     status_t            writeTypedVector(const std::vector<T>& val,
                                          status_t(Parcel::*write_func)(const T&));
@@ -600,8 +604,14 @@
     mutable bool        mHasFds;
     bool                mAllowFds;
 
+    // if this parcelable is involved in a secure transaction, force the
+    // data to be overridden with zero when deallocated
+    mutable bool        mDeallocZero;
+
     release_func        mOwner;
-    void*               mOwnerCookie;
+
+    // TODO(167966510): reserved for binder/version/stability
+    void*               mReserved = reinterpret_cast<void*>(0xAAAAAAAA);
 
     class Blob {
     public:
@@ -1220,6 +1230,16 @@
     return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
 }
 
+template<typename T>
+status_t Parcel::writeParcelableVector(const std::shared_ptr<std::vector<std::optional<T>>>& val) {
+    if (val.get() == nullptr) {
+        return this->writeInt32(-1);
+    }
+
+    using NullableT = std::optional<T>;
+    return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
+}
+
 template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
 status_t Parcel::writeEnum(const T& val) {
     return writeInt32(static_cast<int32_t>(val));
@@ -1328,5 +1348,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_PARCEL_H
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
index 71e1d3c..9896fd7 100644
--- a/libs/binder/include/binder/ParcelFileDescriptor.h
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PARCEL_FILE_DESCRIPTOR_H_
-#define ANDROID_PARCEL_FILE_DESCRIPTOR_H_
+#pragma once
 
 #include <android-base/unique_fd.h>
 #include <binder/Parcel.h>
@@ -44,22 +43,22 @@
     android::status_t readFromParcel(const android::Parcel* parcel) override;
 
     inline bool operator!=(const ParcelFileDescriptor& rhs) const {
-        return mFd != rhs.mFd;
+        return mFd.get() != rhs.mFd.get();
     }
     inline bool operator<(const ParcelFileDescriptor& rhs) const {
-        return mFd < rhs.mFd;
+        return mFd.get() < rhs.mFd.get();
     }
     inline bool operator<=(const ParcelFileDescriptor& rhs) const {
-        return mFd <= rhs.mFd;
+        return mFd.get() <= rhs.mFd.get();
     }
     inline bool operator==(const ParcelFileDescriptor& rhs) const {
-        return mFd == rhs.mFd;
+        return mFd.get() == rhs.mFd.get();
     }
     inline bool operator>(const ParcelFileDescriptor& rhs) const {
-        return mFd > rhs.mFd;
+        return mFd.get() > rhs.mFd.get();
     }
     inline bool operator>=(const ParcelFileDescriptor& rhs) const {
-        return mFd >= rhs.mFd;
+        return mFd.get() >= rhs.mFd.get();
     }
 private:
     android::base::unique_fd mFd;
@@ -67,5 +66,3 @@
 
 } // namespace os
 } // namespace android
-
-#endif // ANDROID_OS_PARCEL_FILE_DESCRIPTOR_H_
diff --git a/libs/binder/include/binder/Parcelable.h b/libs/binder/include/binder/Parcelable.h
index a6e610c..2c652be 100644
--- a/libs/binder/include/binder/Parcelable.h
+++ b/libs/binder/include/binder/Parcelable.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PARCELABLE_H
-#define ANDROID_PARCELABLE_H
+#pragma once
 
 #include <vector>
 
@@ -74,5 +73,3 @@
 #endif
 
 }  // namespace android
-
-#endif // ANDROID_PARCELABLE_H
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 4ea3dd3..ce5027e 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -30,7 +30,7 @@
 class ParcelableHolder : public android::Parcelable {
 public:
     ParcelableHolder() = delete;
-    explicit ParcelableHolder(Stability stability) : mStability(stability){};
+    explicit ParcelableHolder(Stability stability) : mStability(stability){}
     virtual ~ParcelableHolder() = default;
     ParcelableHolder(const ParcelableHolder& other) {
         mParcelable = other.mParcelable;
@@ -40,7 +40,7 @@
             mParcelPtr->appendFrom(other.mParcelPtr.get(), 0, other.mParcelPtr->dataSize());
         }
         mStability = other.mStability;
-    };
+    }
 
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
diff --git a/libs/binder/include/binder/PermissionCache.h b/libs/binder/include/binder/PermissionCache.h
index c258215..835a3a8 100644
--- a/libs/binder/include/binder/PermissionCache.h
+++ b/libs/binder/include/binder/PermissionCache.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef BINDER_PERMISSION_H
-#define BINDER_PERMISSION_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -82,5 +81,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif /* BINDER_PERMISSION_H */
diff --git a/libs/binder/include/binder/PermissionController.h b/libs/binder/include/binder/PermissionController.h
index 4db522a..e658574 100644
--- a/libs/binder/include/binder/PermissionController.h
+++ b/libs/binder/include/binder/PermissionController.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PERMISSION_CONTROLLER_H
-#define ANDROID_PERMISSION_CONTROLLER_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -65,5 +64,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_PERMISSION_CONTROLLER_H
diff --git a/libs/binder/include/binder/PersistableBundle.h b/libs/binder/include/binder/PersistableBundle.h
index 322fef9..4517cf2 100644
--- a/libs/binder/include/binder/PersistableBundle.h
+++ b/libs/binder/include/binder/PersistableBundle.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PERSISTABLE_BUNDLE_H
-#define ANDROID_PERSISTABLE_BUNDLE_H
+#pragma once
 
 #include <map>
 #include <set>
@@ -128,5 +127,3 @@
 }  // namespace os
 
 }  // namespace android
-
-#endif  // ANDROID_PERSISTABLE_BUNDLE_H
diff --git a/libs/binder/include/binder/ProcessInfoService.h b/libs/binder/include/binder/ProcessInfoService.h
index 6bfd1bc..6b3b5ce 100644
--- a/libs/binder/include/binder/ProcessInfoService.h
+++ b/libs/binder/include/binder/ProcessInfoService.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PROCESS_INFO_SERVICE_H
-#define ANDROID_PROCESS_INFO_SERVICE_H
+#pragma once
 
 #ifndef __ANDROID_VNDK__
 
@@ -83,6 +82,3 @@
 #else // __ANDROID_VNDK__
 #error "This header is not visible to vendors"
 #endif // __ANDROID_VNDK__
-
-#endif // ANDROID_PROCESS_INFO_SERVICE_H
-
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index efb95f4..46457cd 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_PROCESS_STATE_H
-#define ANDROID_PROCESS_STATE_H
+#pragma once
 
 #include <binder/IBinder.h>
 #include <utils/KeyedVector.h>
@@ -132,5 +131,3 @@
 } // namespace android
 
 // ---------------------------------------------------------------------------
-
-#endif // ANDROID_PROCESS_STATE_H
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index 6566285..12272ba 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -26,6 +26,29 @@
 
 namespace internal {
 
+// Stability encodes how a binder changes over time. There are two levels of
+// stability:
+// 1). the interface stability - this is how a particular set of API calls (a
+//   particular ordering of things like writeInt32/readInt32) are changed over
+//   time. If one release, we have 'writeInt32' and the next release, we have
+//   'writeInt64', then this interface doesn't have a very stable
+//   Stability::Level. Usually this ordering is controlled by a .aidl file.
+// 2). the wire format stability - this is how these API calls map to actual
+//   bytes that are written to the wire (literally, this is how they are written
+//   to the kernel inside of IBinder::transact, but it may be expanded to other
+//   wires in the future). For instance, writeInt32 in binder translates to
+//   writing a 4-byte little-endian integer in two's complement. You can imagine
+//   in the future, we change writeInt32/readInt32 to instead write 8-bytes with
+//   that integer and some check bits. In this case, the wire format changes,
+//   but as long as a client libbinder knows to keep on writing a 4-byte value
+//   to old servers, and new servers know how to interpret the 8-byte result,
+//   they can still communicate.
+//
+// Every binder object has a stability level associated with it, and when
+// communicating with a binder, we make sure that the command we sent is one
+// that it knows how to process. The summary of stability of a binder is
+// represented by a Stability::Category object.
+
 // WARNING: These APIs are only ever expected to be called by auto-generated code.
 //     Instead of calling them, you should set the stability of a .aidl interface
 class Stability final {
@@ -73,7 +96,7 @@
 
     static void tryMarkCompilationUnit(IBinder* binder);
 
-    enum Level : int32_t {
+    enum Level : uint8_t {
         UNDECLARED = 0,
 
         VENDOR = 0b000011,
@@ -81,19 +104,54 @@
         VINTF = 0b111111,
     };
 
+    // This is the format of stability passed on the wire.
+    struct Category {
+        static inline Category fromRepr(int32_t representation) {
+            return *reinterpret_cast<Category*>(&representation);
+        }
+        int32_t repr() const {
+            return *reinterpret_cast<const int32_t*>(this);
+        }
+        static inline Category currentFromLevel(Level level);
+
+        bool operator== (const Category& o) const {
+            return repr() == o.repr();
+        }
+        bool operator!= (const Category& o) const {
+            return !(*this == o);
+        }
+
+        std::string debugString();
+
+        // This is the version of the wire protocol associated with the host
+        // process of a particular binder. As the wire protocol changes, if
+        // sending a transaction to a binder with an old version, the Parcel
+        // class must write parcels according to the version documented here.
+        uint8_t version;
+
+        uint8_t reserved[2];
+
+        // bitmask of Stability::Level
+        Level level;
+    };
+    static_assert(sizeof(Category) == sizeof(int32_t));
+
     // returns the stability according to how this was built
-    static Level getLocalStability();
+    static Level getLocalLevel();
 
     // applies stability to binder if stability level is known
     __attribute__((warn_unused_result))
-    static status_t set(IBinder* binder, int32_t stability, bool log);
+    static status_t setRepr(IBinder* binder, int32_t representation, bool log);
 
-    static Level get(IBinder* binder);
+    // get stability information as encoded on the wire
+    static Category getCategory(IBinder* binder);
 
-    static bool check(int32_t provided, Level required);
+    // whether a transaction on binder is allowed, if the transaction
+    // is done from a context with a specific stability level
+    static bool check(Category provided, Level required);
 
-    static bool isDeclaredStability(int32_t stability);
-    static std::string stabilityString(int32_t stability);
+    static bool isDeclaredLevel(Level level);
+    static std::string levelString(Level level);
 
     Stability();
 };
diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h
index 7d889b6..c30ae01 100644
--- a/libs/binder/include/binder/Status.h
+++ b/libs/binder/include/binder/Status.h
@@ -18,7 +18,8 @@
 #define ANDROID_BINDER_STATUS_H
 
 #include <cstdint>
-#include <sstream>
+#include <sstream> // historical
+#include <ostream>
 
 #include <binder/Parcel.h>
 #include <utils/String8.h>
@@ -153,8 +154,9 @@
     String8 mMessage;
 };  // class Status
 
-// For gtest output logging
-std::stringstream& operator<< (std::stringstream& stream, const Status& s);
+static inline std::ostream& operator<< (std::ostream& o, const Status& s) {
+    return o << s.toString8();
+}
 
 }  // namespace binder
 }  // namespace android
diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h
index c7e1e14..bf9c92b 100644
--- a/libs/binder/include/binder/TextOutput.h
+++ b/libs/binder/include/binder/TextOutput.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_TEXTOUTPUT_H
-#define ANDROID_TEXTOUTPUT_H
+#pragma once
 
 #include <utils/Errors.h>
 #include <utils/String8.h>
@@ -206,5 +205,3 @@
 
 // ---------------------------------------------------------------------------
 } // namespace android
-
-#endif // ANDROID_TEXTOUTPUT_H
diff --git a/libs/binder/include/private/binder/binder_module.h b/libs/binder/include/private/binder/binder_module.h
index 7be8f7b..5a719b8 100644
--- a/libs/binder/include/private/binder/binder_module.h
+++ b/libs/binder/include/private/binder/binder_module.h
@@ -17,10 +17,6 @@
 #ifndef _BINDER_MODULE_H_
 #define _BINDER_MODULE_H_
 
-#ifdef __cplusplus
-namespace android {
-#endif
-
 /* obtain structures and constants from the kernel header */
 
 // TODO(b/31559095): bionic on host
@@ -36,6 +32,10 @@
 #include <sys/ioctl.h>
 #include <linux/android/binder.h>
 
+#ifdef __cplusplus
+namespace android {
+#endif
+
 #ifndef BR_FROZEN_REPLY
 // Temporary definition of BR_FROZEN_REPLY. For production
 // this will come from UAPI binder.h
@@ -88,7 +88,9 @@
 };
 #endif //BINDER_GET_FROZEN_INFO
 
-
+enum transaction_flags_ext {
+    TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */
+};
 
 #ifdef __cplusplus
 }   // namespace android
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index e4d86ae..a57beee 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -26,6 +26,9 @@
                 "-D__ANDROID_API__=10000",
             ],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 }
 
@@ -84,6 +87,9 @@
         linux: {
             version_script: "libbinder_ndk.map.txt",
         },
+        darwin: {
+            enabled: false,
+        },
     },
     stubs: {
         symbol_file: "libbinder_ndk.map.txt",
@@ -92,6 +98,14 @@
             "30",
         ],
     },
+    tidy: true,
+    tidy_flags: [
+        // Only check our headers
+        "--header-filter=^.*frameworks/native/libs/binder/.*.h$",
+    ],
+    tidy_checks_as_errors: [
+        "*",
+    ],
 }
 
 ndk_headers {
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 2a2eed7..350c658 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include <android/binder_context.h>
 #include <android/binder_ibinder.h>
 #include <android/binder_ibinder_platform.h>
+#include <android/binder_libbinder.h>
 #include "ibinder_internal.h"
 
 #include <android/binder_stability.h>
@@ -181,7 +181,7 @@
 
         binder_status_t status = getClass()->onTransact(this, code, &in, &out);
         return PruneStatusT(status);
-    } else if (code == SHELL_COMMAND_TRANSACTION) {
+    } else if (code == SHELL_COMMAND_TRANSACTION && getClass()->handleShellCommand != nullptr) {
         int in = data.readFileDescriptor();
         int out = data.readFileDescriptor();
         int err = data.readFileDescriptor();
@@ -307,7 +307,8 @@
     : onCreate(onCreate),
       onDestroy(onDestroy),
       onTransact(onTransact),
-      mInterfaceDescriptor(interfaceDescriptor) {}
+      mInterfaceDescriptor(interfaceDescriptor),
+      mWideInterfaceDescriptor(interfaceDescriptor) {}
 
 AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
                                       AIBinder_Class_onCreate onCreate,
@@ -335,6 +336,12 @@
     clazz->handleShellCommand = handleShellCommand;
 }
 
+const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) {
+    CHECK(clazz != nullptr) << "getDescriptor requires non-null clazz";
+
+    return clazz->getInterfaceDescriptorUtf8();
+}
+
 void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
     CHECK(who == mWho);
 
@@ -367,7 +374,7 @@
                            mDeathRecipients.end());
 }
 
-binder_status_t AIBinder_DeathRecipient::linkToDeath(sp<IBinder> binder, void* cookie) {
+binder_status_t AIBinder_DeathRecipient::linkToDeath(const sp<IBinder>& binder, void* cookie) {
     CHECK(binder != nullptr);
 
     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
@@ -386,7 +393,7 @@
     return STATUS_OK;
 }
 
-binder_status_t AIBinder_DeathRecipient::unlinkToDeath(sp<IBinder> binder, void* cookie) {
+binder_status_t AIBinder_DeathRecipient::unlinkToDeath(const sp<IBinder>& binder, void* cookie) {
     CHECK(binder != nullptr);
 
     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
@@ -611,7 +618,7 @@
         return STATUS_UNKNOWN_TRANSACTION;
     }
 
-    constexpr binder_flags_t kAllFlags = FLAG_PRIVATE_VENDOR | FLAG_ONEWAY;
+    constexpr binder_flags_t kAllFlags = FLAG_PRIVATE_VENDOR | FLAG_ONEWAY | FLAG_CLEAR_BUF;
     if ((flags & ~kAllFlags) != 0) {
         LOG(ERROR) << __func__ << ": Unrecognized flags sent: " << flags;
         return STATUS_BAD_VALUE;
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index f601127..6824306 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -112,21 +112,24 @@
     AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
                    AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact);
 
-    const ::android::String16& getInterfaceDescriptor() const { return mInterfaceDescriptor; }
+    const ::android::String16& getInterfaceDescriptor() const { return mWideInterfaceDescriptor; }
+    const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); }
 
     // required to be non-null, implemented for every class
-    const AIBinder_Class_onCreate onCreate;
-    const AIBinder_Class_onDestroy onDestroy;
-    const AIBinder_Class_onTransact onTransact;
+    const AIBinder_Class_onCreate onCreate = nullptr;
+    const AIBinder_Class_onDestroy onDestroy = nullptr;
+    const AIBinder_Class_onTransact onTransact = nullptr;
 
     // optional methods for a class
-    AIBinder_onDump onDump;
-    AIBinder_handleShellCommand handleShellCommand;
+    AIBinder_onDump onDump = nullptr;
+    AIBinder_handleShellCommand handleShellCommand = nullptr;
 
    private:
+    // Copy of the raw char string for when we don't have to return UTF-16
+    const std::string mInterfaceDescriptor;
     // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to
     // one.
-    const ::android::String16 mInterfaceDescriptor;
+    const ::android::String16 mWideInterfaceDescriptor;
 };
 
 // Ownership is like this (when linked to death):
@@ -161,8 +164,8 @@
     };
 
     explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
-    binder_status_t linkToDeath(::android::sp<::android::IBinder>, void* cookie);
-    binder_status_t unlinkToDeath(::android::sp<::android::IBinder> binder, void* cookie);
+    binder_status_t linkToDeath(const ::android::sp<::android::IBinder>&, void* cookie);
+    binder_status_t unlinkToDeath(const ::android::sp<::android::IBinder>& binder, void* cookie);
 
    private:
     // When the user of this API deletes a Bp object but not the death recipient, the
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 18877af..2d85f90 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -74,6 +74,9 @@
      * ownership of that other object.
      */
     SpAIBinder& operator=(const SpAIBinder& other) {
+        if (this == &other) {
+            return *this;
+        }
         AIBinder_incStrong(other.mBinder);
         set(other.mBinder);
         return *this;
@@ -170,8 +173,10 @@
     ScopedAResource& operator=(const ScopedAResource&) = delete;
 
     // move-constructing/assignment is okay
-    ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) { other.mT = DEFAULT; }
-    ScopedAResource& operator=(ScopedAResource&& other) {
+    ScopedAResource(ScopedAResource&& other) noexcept : mT(std::move(other.mT)) {
+        other.mT = DEFAULT;
+    }
+    ScopedAResource& operator=(ScopedAResource&& other) noexcept {
         set(other.mT);
         other.mT = DEFAULT;
         return *this;
@@ -313,7 +318,8 @@
     /**
      * Takes ownership of a.
      */
-    explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {}
+    ScopedFileDescriptor() : ScopedFileDescriptor(-1) {}
+    explicit ScopedFileDescriptor(int a) : ScopedAResource(a) {}
     ~ScopedFileDescriptor() {}
     ScopedFileDescriptor(ScopedFileDescriptor&&) = default;
     ScopedFileDescriptor& operator=(ScopedFileDescriptor&&) = default;
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index dfcf4dc..4858514 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -82,13 +82,13 @@
     }
 
     template <typename T>
-    bool setParcelable(T* p) {
-        if (p && this->mStability > T::_aidl_stability) {
+    bool setParcelable(const T& p) {
+        if (this->mStability > T::_aidl_stability) {
             return false;
         }
         AParcel_reset(mParcel.get());
         AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor));
-        p->writeToParcel(mParcel.get());
+        p.writeToParcel(mParcel.get());
         return true;
     }
 
@@ -112,6 +112,8 @@
         return std::move(ret);
     }
 
+    void reset() { AParcel_reset(mParcel.get()); }
+
    private:
     mutable ndk::ScopedAParcel mParcel;
     parcelable_stability_t mStability;
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 33763d5..5e1ed46 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -43,7 +43,6 @@
 
 #if __ANDROID_API__ >= 29
 
-// Also see TF_* in kernel's binder.h
 typedef uint32_t binder_flags_t;
 enum {
     /**
@@ -643,6 +642,23 @@
 
 #endif  //__ANDROID_API__ >= 30
 
+#if __ANDROID_API__ >= 31
+
+/**
+ * Retrieve the class descriptor for the class.
+ *
+ * Available since API level 31.
+ *
+ * \param clazz the class to fetch the descriptor from
+ *
+ * \return the class descriptor string. This pointer will never be null; a
+ * descriptor is required to define a class. The pointer is owned by the class
+ * and will remain valid as long as the class does.
+ */
+const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) __INTRODUCED_IN(31);
+
+#endif  //__ANDROID_API__ >= 31
+
 __END_DECLS
 
 /** @} */
diff --git a/libs/binder/ndk/include_platform/android/binder_context.h b/libs/binder/ndk/include_platform/android/binder_context.h
deleted file mode 100644
index a99d555..0000000
--- a/libs/binder/ndk/include_platform/android/binder_context.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/binder_ibinder.h>
-
-__BEGIN_DECLS
-
-/**
- * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This
- * must be called on a local binder server before it is sent out to any othe
- * process. If this is a remote binder, it will abort. If the kernel doesn't
- * support this feature, you'll always get null from AIBinder_getCallingSid.
- *
- * \param binder local server binder to request security contexts on
- */
-__attribute__((weak)) void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid)
-        __INTRODUCED_IN(31);
-
-/**
- * Returns the selinux context of the callee.
- *
- * In order for this to work, the following conditions must be met:
- * - The kernel must be new enough to support this feature.
- * - The server must have called AIBinder_setRequestingSid.
- * - The callee must be a remote process.
- *
- * \return security context or null if unavailable. The lifetime of this context
- * is the lifetime of the transaction.
- */
-__attribute__((weak, warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
-
-__END_DECLS
diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
index 2af65cf..e315c79 100644
--- a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
@@ -16,39 +16,43 @@
 
 #pragma once
 
-// binder_context.h used to be part of this header and is included for backwards
-// compatibility.
-#include <android/binder_context.h>
-
-#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
-
 #include <android/binder_ibinder.h>
-#include <binder/IBinder.h>
+
+__BEGIN_DECLS
+
+// platform values for binder_flags_t
+enum {
+    /**
+     * The transaction and reply will be cleared by the kernel in read-only
+     * binder buffers storing transactions.
+     *
+     * Introduced in API level 31.
+     */
+    FLAG_CLEAR_BUF = 0x20,
+};
 
 /**
- * Get libbinder version of binder from AIBinder.
+ * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This
+ * must be called on a local binder server before it is sent out to any othe
+ * process. If this is a remote binder, it will abort. If the kernel doesn't
+ * support this feature, you'll always get null from AIBinder_getCallingSid.
  *
- * WARNING: function calls to a local object on the other side of this function
- * will parcel. When converting between binders, keep in mind it is not as
- * efficient as a direct function call.
- *
- * \param binder binder with ownership retained by the client
- * \return platform binder object
+ * \param binder local server binder to request security contexts on
  */
-android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder);
+__attribute__((weak)) void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid)
+        __INTRODUCED_IN(31);
 
 /**
- * Get libbinder_ndk version of binder from platform binder.
+ * Returns the selinux context of the callee.
  *
- * WARNING: function calls to a local object on the other side of this function
- * will parcel. When converting between binders, keep in mind it is not as
- * efficient as a direct function call.
+ * In order for this to work, the following conditions must be met:
+ * - The kernel must be new enough to support this feature.
+ * - The server must have called AIBinder_setRequestingSid.
+ * - The callee must be a remote process.
  *
- * \param binder platform binder which may be from anywhere (doesn't have to be
- * created with libbinder_ndK)
- * \return binder with one reference count of ownership given to the client. See
- * AIBinder_decStrong
+ * \return security context or null if unavailable. The lifetime of this context
+ * is the lifetime of the transaction.
  */
-AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder);
+__attribute__((weak, warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
 
-#endif
+__END_DECLS
diff --git a/libs/binder/ndk/include_platform/android/binder_libbinder.h b/libs/binder/ndk/include_platform/android/binder_libbinder.h
new file mode 100644
index 0000000..f0c00e8
--- /dev/null
+++ b/libs/binder/ndk/include_platform/android/binder_libbinder.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__)
+
+#include <android/binder_ibinder.h>
+#include <binder/IBinder.h>
+
+/**
+ * Get libbinder version of binder from AIBinder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder binder with ownership retained by the client
+ * \return platform binder object
+ */
+android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder);
+
+/**
+ * Get libbinder_ndk version of binder from platform binder.
+ *
+ * WARNING: function calls to a local object on the other side of this function
+ * will parcel. When converting between binders, keep in mind it is not as
+ * efficient as a direct function call.
+ *
+ * \param binder platform binder which may be from anywhere (doesn't have to be
+ * created with libbinder_ndK)
+ * \return binder with one reference count of ownership given to the client. See
+ * AIBinder_decStrong
+ */
+AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder);
+
+#endif
diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
index 114a781..d54c1a1 100644
--- a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
@@ -33,4 +33,15 @@
  */
 bool AParcel_getAllowFds(const AParcel*);
 
+/**
+ * Data written to the parcel will be zero'd before being deleted or realloced.
+ *
+ * The main use of this is marking a parcel that will be used in a transaction
+ * with FLAG_CLEAR_BUF. When FLAG_CLEAR_BUF is used, the reply parcel will
+ * automatically be marked as sensitive when it is created.
+ *
+ * \param parcel The parcel to clear associated data from.
+ */
+void AParcel_markSensitive(const AParcel* parcel);
+
 __END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 947cc98..e233ffd 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -121,15 +121,17 @@
     AServiceManager_registerLazyService; # llndk
     AServiceManager_waitForService; # apex llndk
 
-    AParcel_reset;
-    AParcel_getDataSize;
+    AIBinder_Class_getDescriptor;
     AParcel_appendFrom;
     AParcel_create;
+    AParcel_getDataSize;
+    AParcel_reset;
 };
 
 LIBBINDER_NDK_PLATFORM {
   global:
     AParcel_getAllowFds;
+    AParcel_markSensitive;
     extern "C++" {
         AIBinder_fromPlatformBinder*;
         AIBinder_toPlatformBinder*;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 2f95318..ec7c7d8 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -226,6 +226,10 @@
     return parcel->get()->dataPosition();
 }
 
+void AParcel_markSensitive(const AParcel* parcel) {
+    return parcel->get()->markSensitive();
+}
+
 binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
     sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
     return parcel->get()->writeStrongBinder(writeBinder);
@@ -257,7 +261,7 @@
 }
 
 binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
-    std::unique_ptr<ParcelFileDescriptor> parcelFd;
+    std::optional<ParcelFileDescriptor> parcelFd;
 
     status_t status = parcel->get()->readParcelable(&parcelFd);
     if (status != STATUS_OK) return PruneStatusT(status);
diff --git a/libs/binder/ndk/tests/iface.cpp b/libs/binder/ndk/tests/iface.cpp
index 64832f3..2afe5d2 100644
--- a/libs/binder/ndk/tests/iface.cpp
+++ b/libs/binder/ndk/tests/iface.cpp
@@ -25,7 +25,7 @@
 
 const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
 const char* IFoo::kInstanceNameToDieFor = "libbinder_ndk-test-IFoo-to-die";
-const char* kIFooDescriptor = "my-special-IFoo-class";
+const char* IFoo::kIFooDescriptor = "my-special-IFoo-class";
 
 struct IFoo_Class_Data {
     sp<IFoo> foo;
@@ -118,7 +118,7 @@
     AIBinder_Weak_delete(mWeakBinder);
 }
 
-binder_status_t IFoo::addService(const char* instance) {
+AIBinder* IFoo::getBinder() {
     AIBinder* binder = nullptr;
 
     if (mWeakBinder != nullptr) {
@@ -132,8 +132,18 @@
             AIBinder_Weak_delete(mWeakBinder);
         }
         mWeakBinder = AIBinder_Weak_new(binder);
+
+        // WARNING: it is important that this class does not implement debug or
+        // shell functions because it does not use special C++ wrapper
+        // functions, and so this is how we test those functions.
     }
 
+    return binder;
+}
+
+binder_status_t IFoo::addService(const char* instance) {
+    AIBinder* binder = getBinder();
+
     binder_status_t status = AServiceManager_addService(binder, instance);
     // Strong references we care about kept by remote process
     AIBinder_decStrong(binder);
diff --git a/libs/binder/ndk/tests/include/iface/iface.h b/libs/binder/ndk/tests/include/iface/iface.h
index cdf5493..7408d0c 100644
--- a/libs/binder/ndk/tests/include/iface/iface.h
+++ b/libs/binder/ndk/tests/include/iface/iface.h
@@ -27,9 +27,13 @@
    public:
     static const char* kSomeInstanceName;
     static const char* kInstanceNameToDieFor;
+    static const char* kIFooDescriptor;
 
     static AIBinder_Class* kClass;
 
+    // binder representing this interface with one reference count
+    AIBinder* getBinder();
+
     // Takes ownership of IFoo
     binder_status_t addService(const char* instance);
     static ::android::sp<IFoo> getService(const char* instance, AIBinder** outBinder = nullptr);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 44d8ebf..b7df115 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -18,9 +18,9 @@
 #include <aidl/BnBinderNdkUnitTest.h>
 #include <aidl/BnEmpty.h>
 #include <android-base/logging.h>
-#include <android/binder_context.h>
 #include <android/binder_ibinder_jni.h>
 #include <android/binder_ibinder_platform.h>
+#include <android/binder_libbinder.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <gtest/gtest.h>
@@ -39,6 +39,7 @@
 #include <condition_variable>
 #include <iostream>
 #include <mutex>
+#include "android/binder_ibinder.h"
 
 using namespace android;
 
@@ -185,6 +186,26 @@
     AIBinder_decStrong(binder);
 }
 
+TEST(NdkBinder, UnimplementedDump) {
+    sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
+    ASSERT_NE(foo, nullptr);
+    AIBinder* binder = foo->getBinder();
+    EXPECT_EQ(OK, AIBinder_dump(binder, STDOUT_FILENO, nullptr, 0));
+    AIBinder_decStrong(binder);
+}
+
+TEST(NdkBinder, UnimplementedShell) {
+    // libbinder_ndk doesn't support calling shell, so we are calling from the
+    // libbinder across processes to the NDK service which doesn't implement
+    // shell
+    static const sp<android::IServiceManager> sm(android::defaultServiceManager());
+    sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
+
+    Vector<String16> argsVec;
+    EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
+                                        argsVec, nullptr, nullptr));
+}
+
 TEST(NdkBinder, DoubleNumber) {
     sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
     ASSERT_NE(foo, nullptr);
@@ -523,6 +544,10 @@
     EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
 }
 
+TEST(NdkBinder, GetClassInterfaceDescriptor) {
+    ASSERT_STREQ(IFoo::kIFooDescriptor, AIBinder_Class_getDescriptor(IFoo::kClass));
+}
+
 int main(int argc, char* argv[]) {
     ::testing::InitGoogleTest(&argc, argv);
 
diff --git a/libs/binder/parcel_fuzzer/Android.bp b/libs/binder/parcel_fuzzer/Android.bp
index c5b3d80..3e6fe99 100644
--- a/libs/binder/parcel_fuzzer/Android.bp
+++ b/libs/binder/parcel_fuzzer/Android.bp
@@ -52,6 +52,11 @@
 cc_library_static {
     name: "libbinder_random_parcel",
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
     srcs: [
         "random_fd.cpp",
         "random_parcel.cpp",
diff --git a/libs/binder/parcel_fuzzer/binder.cpp b/libs/binder/parcel_fuzzer/binder.cpp
index e5c6333..394d222 100644
--- a/libs/binder/parcel_fuzzer/binder.cpp
+++ b/libs/binder/parcel_fuzzer/binder.cpp
@@ -86,6 +86,8 @@
     PARCEL_READ_WITH_STATUS(T, FUN), \
     PARCEL_READ_NO_STATUS(T, FUN)
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 // clang-format off
 std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS {
     PARCEL_READ_NO_STATUS(size_t, dataSize),
@@ -130,7 +132,6 @@
     PARCEL_READ_OPT_STATUS(uint64_t, readUint64),
     PARCEL_READ_OPT_STATUS(float, readFloat),
     PARCEL_READ_OPT_STATUS(double, readDouble),
-    PARCEL_READ_OPT_STATUS(intptr_t, readIntPtr),
     PARCEL_READ_OPT_STATUS(bool, readBool),
     PARCEL_READ_OPT_STATUS(char16_t, readChar),
     PARCEL_READ_OPT_STATUS(int8_t, readByte),
@@ -290,3 +291,4 @@
     PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
 };
 // clang-format on
+#pragma clang diagnostic pop
diff --git a/libs/binder/parcel_fuzzer/main.cpp b/libs/binder/parcel_fuzzer/main.cpp
index 386c70b..78606cc 100644
--- a/libs/binder/parcel_fuzzer/main.cpp
+++ b/libs/binder/parcel_fuzzer/main.cpp
@@ -20,12 +20,16 @@
 #include "hwbinder.h"
 #include "util.h"
 
+#include <iostream>
+
 #include <android-base/logging.h>
 #include <fuzzbinder/random_parcel.h>
 #include <fuzzer/FuzzedDataProvider.h>
 
 #include <cstdlib>
 #include <ctime>
+#include <sys/resource.h>
+#include <sys/time.h>
 
 using android::fillRandomParcel;
 
@@ -77,7 +81,25 @@
     }
 }
 
+size_t getHardMemoryLimit() {
+    struct rlimit limit;
+    CHECK(0 == getrlimit(RLIMIT_AS, &limit)) << errno;
+    return limit.rlim_max;
+}
+
+void setMemoryLimit(size_t cur, size_t max) {
+    const struct rlimit kLimit = {
+       .rlim_cur = cur,
+       .rlim_max = max,
+    };
+    CHECK(0 == setrlimit(RLIMIT_AS, &kLimit)) << errno;
+}
+
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    static constexpr size_t kMemLimit = 1 * 1024 * 1024;
+    size_t hardLimit = getHardMemoryLimit();
+    setMemoryLimit(std::min(kMemLimit, hardLimit), hardLimit);
+
     if (size <= 1) return 0;  // no use
 
     // avoid timeouts, see b/142617274, b/142473153
@@ -102,5 +124,7 @@
 
     provider.PickValueInArray(fuzzBackend)(std::move(provider));
 
+    setMemoryLimit(hardLimit, hardLimit);
+
     return 0;
 }
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index dc8270e..fd5f2f5 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -10,6 +10,11 @@
         "libbinder_ndk_sys",
     ],
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    }
 }
 
 rust_library {
@@ -23,6 +28,11 @@
         "libbinder_ndk",
     ],
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    }
 }
 
 rust_bindgen {
@@ -64,6 +74,9 @@
                 "-D__ANDROID_API__=10000",
             ],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 }
 
diff --git a/libs/binder/rust/TEST_MAPPING b/libs/binder/rust/TEST_MAPPING
deleted file mode 100644
index 50c474c..0000000
--- a/libs/binder/rust/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "libbinder_rs-internal_test"
-    }
-  ],
-  "postsubmit": [
-    {
-      "name": "rustBinderTest"
-    }
-  ]
-}
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 6d0a369..ed3b9ec 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -21,7 +21,8 @@
 use crate::proxy::{DeathRecipient, SpIBinder};
 use crate::sys;
 
-use std::ffi::{c_void, CString};
+use std::ffi::{c_void, CStr, CString};
+use std::os::raw::c_char;
 use std::os::unix::io::AsRawFd;
 use std::ptr;
 
@@ -33,8 +34,7 @@
 
 /// Additional operation flags.
 ///
-/// Can be either 0 for a normal RPC, or [`IBinder::FLAG_ONEWAY`] for a
-/// one-way RPC.
+/// `IBinder::FLAG_*` values.
 pub type TransactionFlags = u32;
 
 /// Super-trait for Binder interfaces.
@@ -91,6 +91,8 @@
 
     /// Corresponds to TF_ONE_WAY -- an asynchronous call.
     const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
+    /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made.
+    const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF;
 
     /// Is this object still alive?
     fn is_binder_alive(&self) -> bool;
@@ -204,6 +206,22 @@
     pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
         InterfaceClass(ptr)
     }
+
+    /// Get the interface descriptor string of this class.
+    pub fn get_descriptor(&self) -> String {
+        unsafe {
+            // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
+            // is always a two-byte null terminated sequence of u16s. Thus, we
+            // can continue reading from the pointer until we hit a null value,
+            // and this pointer can be a valid slice if the slice length is <=
+            // the number of u16 elements before the null terminator.
+
+            let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
+            CStr::from_ptr(raw_descriptor).to_str()
+                .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor")
+                .into()
+        }
+    }
 }
 
 impl From<InterfaceClass> for *const sys::AIBinder_Class {
@@ -506,12 +524,7 @@
             }
 
             fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
-                use $crate::AssociateClass;
-                if binder.associate_class(<$native as $crate::Remotable>::get_class()) {
-                    Ok(Self { binder, $($fname: $finit),* })
-                } else {
-                    Err($crate::StatusCode::BAD_TYPE)
-                }
+                Ok(Self { binder, $($fname: $finit),* })
             }
         }
 
@@ -566,16 +579,35 @@
         impl $crate::FromIBinder for dyn $interface {
             fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
                 use $crate::AssociateClass;
-                if !ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
-                    return Err($crate::StatusCode::BAD_TYPE.into());
+
+                let existing_class = ibinder.get_class();
+                if let Some(class) = existing_class {
+                    if class != <$native as $crate::Remotable>::get_class() &&
+                        class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
+                    {
+                        // The binder object's descriptor string matches what we
+                        // expect. We still need to treat this local or already
+                        // associated object as remote, because we can't cast it
+                        // into a Rust service object without a matching class
+                        // pointer.
+                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
+                    }
                 }
 
-                let service: $crate::Result<$crate::Binder<$native>> = std::convert::TryFrom::try_from(ibinder.clone());
-                if let Ok(service) = service {
-                    Ok(Box::new(service))
-                } else {
-                    Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))
+                if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
+                    let service: $crate::Result<$crate::Binder<$native>> =
+                        std::convert::TryFrom::try_from(ibinder.clone());
+                    if let Ok(service) = service {
+                        // We were able to associate with our expected class and
+                        // the service is local.
+                        return Ok(Box::new(service));
+                    } else {
+                        // Service is remote
+                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
+                    }
                 }
+
+                Err($crate::StatusCode::BAD_TYPE.into())
             }
         }
 
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 2c1e5a4..6c34824 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -100,6 +100,14 @@
 
 // Data serialization methods
 impl Parcel {
+    /// Data written to parcelable is zero'd before being deleted or reallocated.
+    pub fn mark_sensitive(&mut self) {
+        unsafe {
+            // Safety: guaranteed to have a parcel object, and this method never fails
+            sys::AParcel_markSensitive(self.as_native())
+        }
+    }
+
     /// Write a type that implements [`Serialize`] to the `Parcel`.
     pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
         parcelable.serialize(self)
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 5002fc6..485bb42 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -91,7 +91,7 @@
 
     /// Return the interface class of this binder object, if associated with
     /// one.
-    pub(crate) fn get_class(&mut self) -> Option<InterfaceClass> {
+    pub fn get_class(&mut self) -> Option<InterfaceClass> {
         unsafe {
             // Safety: `SpIBinder` guarantees that it always contains a valid
             // `AIBinder` pointer. `AIBinder_getClass` returns either a null
diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp
index 303f4a5..ef142b5 100644
--- a/libs/binder/rust/sys/BinderBindings.hpp
+++ b/libs/binder/rust/sys/BinderBindings.hpp
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-#include <android/binder_context.h>
 #include <android/binder_ibinder.h>
+#include <android/binder_ibinder_platform.h>
 #include <android/binder_manager.h>
 #include <android/binder_parcel.h>
+#include <android/binder_parcel_platform.h>
 #include <android/binder_process.h>
 #include <android/binder_shell.h>
 #include <android/binder_status.h>
@@ -78,6 +79,7 @@
 
 enum {
     FLAG_ONEWAY = FLAG_ONEWAY,
+    FLAG_CLEAR_BUF = FLAG_CLEAR_BUF,
 };
 
 } // namespace consts
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 3db40ba..5ae9c53 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -30,3 +30,52 @@
     auto_gen_config: false,
     test_suites: ["general-tests"],
 }
+
+cc_test {
+    name: "binderRustNdkInteropTest",
+    srcs: [
+        "binderRustNdkInteropTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "IBinderRustNdkInteropTest-ndk_platform",
+        "libbinder_ndk_rust_interop",
+    ],
+    test_suites: ["general-tests"],
+    require_root: true,
+
+    // rustBinderTestService uses a custom config
+    auto_gen_config: true,
+}
+
+aidl_interface {
+    name: "IBinderRustNdkInteropTest",
+    unstable: true,
+    srcs: [
+        "IBinderRustNdkInteropTest.aidl",
+        "IBinderRustNdkInteropTestOther.aidl",
+    ],
+    backend: {
+        ndk: {
+            enabled: true,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+}
+
+rust_ffi_static {
+    name: "libbinder_ndk_rust_interop",
+    crate_name: "binder_ndk_rust_interop",
+    srcs: [
+        "ndk_rust_interop.rs",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+        "IBinderRustNdkInteropTest-rust",
+    ],
+}
diff --git a/libs/binder/rust/tests/IBinderRustNdkInteropTest.aidl b/libs/binder/rust/tests/IBinderRustNdkInteropTest.aidl
new file mode 100644
index 0000000..7f5e837
--- /dev/null
+++ b/libs/binder/rust/tests/IBinderRustNdkInteropTest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface IBinderRustNdkInteropTest {
+    @utf8InCpp String echo(@utf8InCpp String str);
+}
diff --git a/libs/binder/rust/tests/IBinderRustNdkInteropTestOther.aidl b/libs/binder/rust/tests/IBinderRustNdkInteropTestOther.aidl
new file mode 100644
index 0000000..82a0323
--- /dev/null
+++ b/libs/binder/rust/tests/IBinderRustNdkInteropTestOther.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface IBinderRustNdkInteropTestOther {
+    @utf8InCpp String echo(@utf8InCpp String str);
+}
diff --git a/libs/binder/rust/tests/binderRustNdkInteropTest.cpp b/libs/binder/rust/tests/binderRustNdkInteropTest.cpp
new file mode 100644
index 0000000..59ca6ed
--- /dev/null
+++ b/libs/binder/rust/tests/binderRustNdkInteropTest.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/BnBinderRustNdkInteropTest.h>
+#include <aidl/IBinderRustNdkInteropTest.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/Status.h>
+#include <gtest/gtest.h>
+
+using namespace android;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+using ::ndk::SpAIBinder;
+
+static const char* kNdkServerName = "NdkServer-BinderRustNdkInteropTest";
+static const char* kRustServerName = "RustServer-BinderRustNdkInteropTest";
+
+extern "C" {
+int rust_call_ndk(const char* service_name);
+int rust_start_service(const char* service_name);
+}
+
+class NdkServer : public aidl::BnBinderRustNdkInteropTest {
+    ScopedAStatus echo(const std::string& in, std::string* out) override {
+        *out = in;
+        return ScopedAStatus::ok();
+    }
+};
+
+TEST(RustNdkInterop, RustCanCallNdk) {
+    ASSERT_EQ(STATUS_OK, rust_call_ndk(kNdkServerName));
+}
+
+TEST(RustNdkInterop, NdkCanCallRust) {
+    ASSERT_EQ(STATUS_OK, rust_start_service(kRustServerName));
+
+    SpAIBinder binder = SpAIBinder(AServiceManager_checkService(kRustServerName));
+    ASSERT_NE(nullptr, binder.get());
+    EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
+
+    auto interface = aidl::IBinderRustNdkInteropTest::fromBinder(binder);
+    // TODO(b/167723746): this test requires that fromBinder allow association
+    // with an already associated local binder by treating it as remote.
+    EXPECT_EQ(interface, nullptr);
+
+    // std::string in("testing");
+    // std::string out;
+    // EXPECT_TRUE(interface->echo(in, &out).isOk());
+    // EXPECT_EQ(in, out);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+
+    // so we can host a client and service concurrently
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<NdkServer> ndkServer = SharedRefBase::make<NdkServer>();
+    EXPECT_EQ(STATUS_OK, AServiceManager_addService(ndkServer->asBinder().get(), kNdkServerName));
+
+    return RUN_ALL_TESTS();
+}
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 953d328..bb8c492 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -173,6 +173,30 @@
     }
 }
 
+/// Trivial testing binder interface
+pub trait ITestSameDescriptor: Interface {}
+
+declare_binder_interface! {
+    ITestSameDescriptor["android.os.ITest"] {
+        native: BnTestSameDescriptor(on_transact_same_descriptor),
+        proxy: BpTestSameDescriptor,
+    }
+}
+
+fn on_transact_same_descriptor(
+    _service: &dyn ITestSameDescriptor,
+    _code: TransactionCode,
+    _data: &Parcel,
+    _reply: &mut Parcel,
+) -> binder::Result<()> {
+    Ok(())
+}
+
+impl ITestSameDescriptor for BpTestSameDescriptor {}
+
+impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {}
+
+
 #[cfg(test)]
 mod tests {
     use selinux_bindgen as selinux_sys;
@@ -185,9 +209,9 @@
     use std::thread;
     use std::time::Duration;
 
-    use binder::{DeathRecipient, FromIBinder, IBinder, SpIBinder, StatusCode};
+    use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode};
 
-    use super::{ITest, RUST_SERVICE_BINARY};
+    use super::{BnTest, ITest, ITestSameDescriptor, RUST_SERVICE_BINARY, TestService};
 
     pub struct ScopedServiceProcess(Child);
 
@@ -435,4 +459,40 @@
             assert_eq!(extension.test().unwrap(), extension_name);
         }
     }
+
+    /// Test re-associating a local binder object with a different class.
+    ///
+    /// This is needed because different binder service (e.g. NDK vs Rust)
+    /// implementations are incompatible and must not be interchanged. A local
+    /// service with the same descriptor string but a different class pointer
+    /// may have been created by an NDK service and is therefore incompatible
+    /// with the Rust service implementation. It must be treated as remote and
+    /// all API calls parceled and sent through transactions.
+    ///
+    /// Further tests of this behavior with the C NDK and Rust API are in
+    /// rust_ndk_interop.rs
+    #[test]
+    fn associate_existing_class() {
+        let service = Binder::new(BnTest(Box::new(TestService {
+            s: "testing_service".to_string(),
+        })));
+
+        // This should succeed although we will have to treat the service as
+        // remote.
+        let _interface: Box<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder())
+            .expect("Could not re-interpret service as the ITestSameDescriptor interface");
+    }
+
+    /// Test that we can round-trip a rust service through a generic IBinder
+    #[test]
+    fn reassociate_rust_binder() {
+        let service_name = "testing_service";
+        let service_ibinder = BnTest::new_binder(TestService { s: service_name.to_string() })
+            .as_binder();
+
+        let service: Box<dyn ITest> = service_ibinder.into_interface()
+            .expect("Could not reassociate the generic ibinder");
+
+        assert_eq!(service.test().unwrap(), service_name);
+    }
 }
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
new file mode 100644
index 0000000..70a6dc0
--- /dev/null
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Rust Binder NDK interop tests
+
+use std::ffi::CStr;
+use std::os::raw::{c_char, c_int};
+use ::IBinderRustNdkInteropTest::binder::{self, Interface, StatusCode};
+use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTest::{
+    BnBinderRustNdkInteropTest, IBinderRustNdkInteropTest,
+};
+use ::IBinderRustNdkInteropTest::aidl::IBinderRustNdkInteropTestOther::{
+    IBinderRustNdkInteropTestOther,
+};
+
+/// Look up the provided AIDL service and call its echo method.
+///
+/// # Safety
+///
+/// service_name must be a valid, non-null C-style string (null-terminated).
+#[no_mangle]
+pub unsafe extern "C" fn rust_call_ndk(service_name: *const c_char) -> c_int {
+    let service_name = CStr::from_ptr(service_name).to_str().unwrap();
+
+    // The Rust class descriptor pointer will not match the NDK one, but the
+    // descriptor strings match so this needs to still associate.
+    let service: Box<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) {
+        Err(e) => {
+            eprintln!("Could not find Ndk service {}: {:?}", service_name, e);
+            return StatusCode::NAME_NOT_FOUND as c_int;
+        }
+        Ok(service) => service,
+    };
+
+    match service.echo("testing") {
+        Ok(s) => if s != "testing" {
+            return StatusCode::BAD_VALUE as c_int;
+        },
+        Err(e) => return e.into(),
+    }
+
+    // Try using the binder service through the wrong interface type
+    let wrong_service: Result<Box<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
+        binder::get_interface(service_name);
+    match wrong_service {
+        Err(e) if e == StatusCode::BAD_TYPE => {}
+        Err(e) => {
+            eprintln!("Trying to use a service via the wrong interface errored with unexpected error {:?}", e);
+            return e as c_int;
+        }
+        Ok(_) => {
+            eprintln!("We should not be allowed to use a service via the wrong interface");
+            return StatusCode::BAD_TYPE as c_int;
+        }
+    }
+
+    StatusCode::OK as c_int
+}
+
+struct Service;
+
+impl Interface for Service {}
+
+impl IBinderRustNdkInteropTest for Service {
+    fn echo(&self, s: &str) -> binder::Result<String> {
+        Ok(s.to_string())
+    }
+}
+
+/// Start the interop Echo test service with the given service name.
+///
+/// # Safety
+///
+/// service_name must be a valid, non-null C-style string (null-terminated).
+#[no_mangle]
+pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
+    let service_name = CStr::from_ptr(service_name).to_str().unwrap();
+    let service = BnBinderRustNdkInteropTest::new_binder(Service);
+    match binder::add_service(&service_name, service.as_binder()) {
+        Ok(_) => StatusCode::OK as c_int,
+        Err(e) => e as c_int,
+    }
+}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index a03835b..87f1d45 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -60,6 +60,23 @@
     require_root: true,
 }
 
+// unit test only, which can run on host and doesn't use /dev/binder
+cc_test {
+    name: "binderParcelTest",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    srcs: ["binderParcelTest.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libutils",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_test {
     name: "binderLibTest",
     defaults: ["binder_test_defaults"],
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 98f0868..0f7d159 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -30,6 +30,7 @@
 #include <binder/IServiceManager.h>
 
 #include <private/binder/binder_module.h>
+#include <linux/sched.h>
 #include <sys/epoll.h>
 #include <sys/prctl.h>
 
@@ -53,6 +54,7 @@
 
 static constexpr int kSchedPolicy = SCHED_RR;
 static constexpr int kSchedPriority = 7;
+static constexpr int kSchedPriorityMore = 8;
 
 static String16 binderLibTestServiceName = String16("test.binderLib");
 
@@ -402,6 +404,14 @@
     EXPECT_EQ(NO_ERROR, ret);
 }
 
+TEST_F(BinderLibTest, NopTransactionClear) {
+    status_t ret;
+    Parcel data, reply;
+    // make sure it accepts the transaction flag
+    ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply, TF_CLEAR_BUF);
+    EXPECT_EQ(NO_ERROR, ret);
+}
+
 TEST_F(BinderLibTest, Freeze) {
     status_t ret;
     Parcel data, reply, replypid;
@@ -1080,6 +1090,25 @@
     EXPECT_EQ(kSchedPriority, priority);
 }
 
+TEST_F(BinderLibTest, InheritRt) {
+    sp<IBinder> server = addServer();
+    ASSERT_TRUE(server != nullptr);
+
+    const struct sched_param param {
+        .sched_priority = kSchedPriorityMore,
+    };
+    EXPECT_EQ(0, sched_setscheduler(getpid(), SCHED_RR, &param));
+
+    Parcel data, reply;
+    status_t ret = server->transact(BINDER_LIB_TEST_GET_SCHEDULING_POLICY, data, &reply);
+    EXPECT_EQ(NO_ERROR, ret);
+
+    int policy = reply.readInt32();
+    int priority = reply.readInt32();
+
+    EXPECT_EQ(kSchedPolicy, policy & (~SCHED_RESET_ON_FORK));
+    EXPECT_EQ(kSchedPriorityMore, priority);
+}
 
 TEST_F(BinderLibTest, VectorSent) {
     Parcel data, reply;
@@ -1452,6 +1481,8 @@
 
         testService->setMinSchedulerPolicy(kSchedPolicy, kSchedPriority);
 
+        testService->setInheritRt(true);
+
         /*
          * Normally would also contain functionality as well, but we are only
          * testing the extension mechanism.
diff --git a/libs/binder/tests/binderParcelTest.cpp b/libs/binder/tests/binderParcelTest.cpp
new file mode 100644
index 0000000..1764228
--- /dev/null
+++ b/libs/binder/tests/binderParcelTest.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <gtest/gtest.h>
+
+using android::IPCThreadState;
+using android::OK;
+using android::Parcel;
+using android::String16;
+using android::String8;
+using android::status_t;
+
+// Tests a second operation results in a parcel at the same location as it
+// started.
+void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) {
+    Parcel p;
+    a(&p);
+    size_t end = p.dataPosition();
+    p.setDataPosition(0);
+    b(&p);
+    EXPECT_EQ(end, p.dataPosition());
+}
+
+TEST(Parcel, InverseInterfaceToken) {
+    const String16 token = String16("asdf");
+    parcelOpSameLength([&] (Parcel* p) {
+        p->writeInterfaceToken(token);
+    }, [&] (Parcel* p) {
+        EXPECT_TRUE(p->enforceInterface(token, IPCThreadState::self()));
+    });
+}
+
+TEST(Parcel, Utf8FromUtf16Read) {
+    const char* token = "asdf";
+    parcelOpSameLength([&] (Parcel* p) {
+        p->writeString16(String16(token));
+    }, [&] (Parcel* p) {
+        std::string s;
+        EXPECT_EQ(OK, p->readUtf8FromUtf16(&s));
+        EXPECT_EQ(token, s);
+    });
+}
+
+TEST(Parcel, Utf8AsUtf16Write) {
+    std::string token = "asdf";
+    parcelOpSameLength([&] (Parcel* p) {
+        p->writeUtf8AsUtf16(token);
+    }, [&] (Parcel* p) {
+        String16 s;
+        EXPECT_EQ(OK, p->readString16(&s));
+        EXPECT_EQ(s, String16(token.c_str()));
+    });
+}
+
+template <typename T>
+using readFunc = status_t (Parcel::*)(T* out) const;
+template <typename T>
+using writeFunc = status_t (Parcel::*)(const T& in);
+template <typename T>
+using copyWriteFunc = status_t (Parcel::*)(T in);
+
+template <typename T, typename WRITE_FUNC>
+void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, WRITE_FUNC w) {
+    for (const T& value : ts) {
+        parcelOpSameLength([&] (Parcel* p) {
+            (*p.*w)(value);
+        }, [&] (Parcel* p) {
+            T outValue;
+            EXPECT_EQ(OK, (*p.*r)(&outValue));
+            EXPECT_EQ(value, outValue);
+        });
+    }
+}
+
+template <typename T>
+void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, writeFunc<T> w) {
+    readWriteInverse<T, writeFunc<T>>(std::move(ts), r, w);
+}
+template <typename T>
+void readWriteInverse(std::vector<T>&& ts, readFunc<T> r, copyWriteFunc<T> w) {
+    readWriteInverse<T, copyWriteFunc<T>>(std::move(ts), r, w);
+}
+
+#define TEST_READ_WRITE_INVERSE(type, name, ...) \
+    TEST(Parcel, Inverse##name) { \
+        readWriteInverse<type>(__VA_ARGS__, &Parcel::read##name, &Parcel::write##name); \
+    }
+
+TEST_READ_WRITE_INVERSE(int32_t, Int32, {-2, -1, 0, 1, 2});
+TEST_READ_WRITE_INVERSE(uint32_t, Uint32, {0, 1, 2});
+TEST_READ_WRITE_INVERSE(int64_t, Int64, {-2, -1, 0, 1, 2});
+TEST_READ_WRITE_INVERSE(uint64_t, Uint64, {0, 1, 2});
+TEST_READ_WRITE_INVERSE(float, Float, {-1.0f, 0.0f, 3.14f});
+TEST_READ_WRITE_INVERSE(double, Double, {-1.0, 0.0, 3.14});
+TEST_READ_WRITE_INVERSE(bool, Bool, {true, false});
+TEST_READ_WRITE_INVERSE(char16_t, Char, {u'a', u'\0'});
+TEST_READ_WRITE_INVERSE(int8_t, Byte, {-1, 0, 1});
+TEST_READ_WRITE_INVERSE(String8, String8, {String8(), String8("a"), String8("asdf")});
+TEST_READ_WRITE_INVERSE(String16, String16, {String16(), String16("a"), String16("asdf")});
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index 09f58cc..ffb3ef2 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -36,12 +36,15 @@
 #include <optional>
 
 #include <sys/eventfd.h>
+#include <sys/prctl.h>
 
 using namespace std::chrono_literals; // NOLINT - google-build-using-namespace
 
 namespace android {
 namespace tests {
 
+static const String16 kServiceName("SafeInterfaceTest");
+
 enum class TestEnum : uint32_t {
     INVALID = 0,
     INITIAL = 1,
@@ -184,7 +187,7 @@
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wexit-time-destructors"
-IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback");
+IMPLEMENT_META_INTERFACE(Callback, "android.gfx.tests.ICallback")
 #pragma clang diagnostic pop
 
 class BnCallback : public SafeBnInterface<ICallback> {
@@ -373,7 +376,7 @@
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wexit-time-destructors"
-IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest");
+IMPLEMENT_META_INTERFACE(SafeInterfaceTest, "android.gfx.tests.ISafeInterfaceTest")
 
 static sp<IBinder::DeathRecipient> getDeathRecipient() {
     static sp<IBinder::DeathRecipient> recipient = new ExitOnDeath;
@@ -601,40 +604,13 @@
     static constexpr const char* getLogTag() { return "SafeInterfaceTest"; }
 
     sp<ISafeInterfaceTest> getRemoteService() {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wexit-time-destructors"
-        static std::mutex sMutex;
-        static sp<ISafeInterfaceTest> sService;
-        static sp<IBinder> sDeathToken = new BBinder;
-#pragma clang diagnostic pop
+        sp<IBinder> binder = defaultServiceManager()->getService(kServiceName);
+        sp<ISafeInterfaceTest> iface = interface_cast<ISafeInterfaceTest>(binder);
+        EXPECT_TRUE(iface != nullptr);
 
-        std::unique_lock<decltype(sMutex)> lock;
-        if (sService == nullptr) {
-            ALOG(LOG_INFO, getLogTag(), "Forking remote process");
-            pid_t forkPid = fork();
-            EXPECT_NE(forkPid, -1);
+        iface->setDeathToken(new BBinder);
 
-            const String16 serviceName("SafeInterfaceTest");
-
-            if (forkPid == 0) {
-                ALOG(LOG_INFO, getLogTag(), "Remote process checking in");
-                sp<ISafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
-                defaultServiceManager()->addService(serviceName,
-                                                    IInterface::asBinder(nativeService));
-                ProcessState::self()->startThreadPool();
-                IPCThreadState::self()->joinThreadPool();
-                // We shouldn't get to this point
-                [&]() { FAIL(); }();
-            }
-
-            sp<IBinder> binder = defaultServiceManager()->getService(serviceName);
-            sService = interface_cast<ISafeInterfaceTest>(binder);
-            EXPECT_TRUE(sService != nullptr);
-
-            sService->setDeathToken(sDeathToken);
-        }
-
-        return sService;
+        return iface;
     }
 };
 
@@ -840,5 +816,23 @@
     ASSERT_EQ(b + 1, bPlusOne);
 }
 
+extern "C" int main(int argc, char **argv) {
+    testing::InitGoogleTest(&argc, argv);
+
+    if (fork() == 0) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP);
+        sp<BnSafeInterfaceTest> nativeService = new BnSafeInterfaceTest;
+        status_t status = defaultServiceManager()->addService(kServiceName, nativeService);
+        if (status != OK) {
+            ALOG(LOG_INFO, "SafeInterfaceServer", "could not register");
+            return EXIT_FAILURE;
+        }
+        IPCThreadState::self()->joinThreadPool();
+        return EXIT_FAILURE;
+    }
+
+    return RUN_ALL_TESTS();
+}
+
 } // namespace tests
 } // namespace android
diff --git a/libs/binder/tests/fuzzers/Android.bp b/libs/binder/tests/fuzzers/Android.bp
index 46379fc..c465bed 100644
--- a/libs/binder/tests/fuzzers/Android.bp
+++ b/libs/binder/tests/fuzzers/Android.bp
@@ -26,6 +26,11 @@
         "libutils",
         "libbase",
     ],
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    }
 }
 
 cc_fuzz {
diff --git a/libs/binder/tests/fuzzers/BinderFuzzFunctions.h b/libs/binder/tests/fuzzers/BinderFuzzFunctions.h
index 9ac65bb..69f1b9d 100644
--- a/libs/binder/tests/fuzzers/BinderFuzzFunctions.h
+++ b/libs/binder/tests/fuzzers/BinderFuzzFunctions.h
@@ -37,8 +37,8 @@
                                   bbinder->isRequestingSid();
                               },
                               [](FuzzedDataProvider* fdp, const sp<BBinder>& bbinder) -> void {
-                                  bool request_sid = fdp->ConsumeBool();
-                                  bbinder->setRequestingSid(request_sid);
+                                  bool requestSid = fdp->ConsumeBool();
+                                  bbinder->setRequestingSid(requestSid);
                               },
                               [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
                                   bbinder->getExtension();
@@ -63,6 +63,13 @@
                               [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
                                   bbinder->getMinSchedulerPriority();
                               },
+                              [](FuzzedDataProvider* fdp, const sp<BBinder>& bbinder) -> void {
+                                  bool inheritRt = fdp->ConsumeBool();
+                                  bbinder->setInheritRt(inheritRt);
+                              },
+                              [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
+                                  bbinder->isInheritRt();
+                              },
                               [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
                                   bbinder->getDebugPid();
                               }};
diff --git a/libs/binder/tests/schd-dbg.cpp b/libs/binder/tests/schd-dbg.cpp
index ab4c56a..56d958c 100644
--- a/libs/binder/tests/schd-dbg.cpp
+++ b/libs/binder/tests/schd-dbg.cpp
@@ -245,7 +245,7 @@
     double best = (double)m_best / 1.0E6;
     double worst = (double)m_worst / 1.0E6;
     double average = (double)m_total_time / m_transactions / 1.0E6;
-    // FIXME: libjson?
+    // TODO: libjson?
     int W = DUMP_PRESICION + 2;
     cout << setprecision(DUMP_PRESICION) << "{ \"avg\":" << setw(W) << left
          << average << ",\"wst\":" << setw(W) << left << worst
@@ -376,7 +376,7 @@
   if (is_client(num)) {
     int no_trans = iterations * 2;
     double sync_ratio = (1.0 - (double)no_sync / no_trans);
-    // FIXME: libjson?
+    // TODO: libjson?
     cout << "\"P" << (num - server_count) << "\":{\"SYNC\":\""
          << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
          << "\"S\":" << (no_trans - no_sync) << ",\"I\":" << no_trans << ","
@@ -466,7 +466,7 @@
   }
   vector<Pipe> pipes;
   thread_dump("main");
-  // FIXME: libjson?
+  // TODO: libjson?
   cout << "{" << endl;
   cout << "\"cfg\":{\"pair\":" << (no_process / 2)
        << ",\"iterations\":" << iterations << ",\"deadline_us\":" << deadline_us
@@ -495,7 +495,7 @@
     // detected in the child process
     no_inherent += status;
   }
-  // FIXME: libjson?
+  // TODO: libjson?
   cout << "\"inheritance\": " << (no_inherent == 0 ? "\"PASS\"" : "\"FAIL\"")
        << endl;
   cout << "}" << endl;
diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp
index 88752ee..08c62df 100644
--- a/libs/binderthreadstate/Android.bp
+++ b/libs/binderthreadstate/Android.bp
@@ -19,6 +19,11 @@
     double_loadable: true,
     vendor_available: true,
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
 
     shared_libs: [
         "libbinder",
diff --git a/libs/cputimeinstate/Android.bp b/libs/cputimeinstate/Android.bp
index b1943a4..e3cd085 100644
--- a/libs/cputimeinstate/Android.bp
+++ b/libs/cputimeinstate/Android.bp
@@ -33,5 +33,6 @@
         "-Wall",
         "-Wextra",
     ],
+    require_root: true,
 }
 
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index 5e785b6..4209dc5 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -59,6 +59,7 @@
 static unique_fd gTisMapFd;
 static unique_fd gConcurrentMapFd;
 static unique_fd gUidLastUpdateMapFd;
+static unique_fd gPidTisMapFd;
 
 static std::optional<std::vector<uint32_t>> readNumbersFromFile(const std::string &path) {
     std::string data;
@@ -139,6 +140,12 @@
             unique_fd{bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_last_update_map")};
     if (gUidLastUpdateMapFd < 0) return false;
 
+    gPidTisMapFd = unique_fd{mapRetrieveRO(BPF_FS_PATH "map_time_in_state_pid_time_in_state_map")};
+    if (gPidTisMapFd < 0) return false;
+
+    unique_fd trackedPidMapFd(mapRetrieveWO(BPF_FS_PATH "map_time_in_state_pid_tracked_map"));
+    if (trackedPidMapFd < 0) return false;
+
     gInitialized = true;
     return true;
 }
@@ -222,7 +229,8 @@
     }
 
     gTracking = attachTracepointProgram("sched", "sched_switch") &&
-            attachTracepointProgram("power", "cpu_frequency");
+            attachTracepointProgram("power", "cpu_frequency") &&
+            attachTracepointProgram("sched", "sched_process_free");
     return gTracking;
 }
 
@@ -425,6 +433,7 @@
 
     uint64_t newLastUpdate = lastUpdate ? *lastUpdate : 0;
     do {
+        if (key.bucket > (gNCpus - 1) / CPUS_PER_ENTRY) return {};
         if (lastUpdate) {
             auto uidUpdated = uidUpdatedSince(key.uid, *lastUpdate, &newLastUpdate);
             if (!uidUpdated.has_value()) return {};
@@ -501,5 +510,106 @@
     return true;
 }
 
+bool startTrackingProcessCpuTimes(pid_t pid) {
+    if (!gInitialized && !initGlobals()) return false;
+
+    unique_fd trackedPidHashMapFd(
+            mapRetrieveWO(BPF_FS_PATH "map_time_in_state_pid_tracked_hash_map"));
+    if (trackedPidHashMapFd < 0) return false;
+
+    unique_fd trackedPidMapFd(mapRetrieveWO(BPF_FS_PATH "map_time_in_state_pid_tracked_map"));
+    if (trackedPidMapFd < 0) return false;
+
+    for (uint32_t index = 0; index < MAX_TRACKED_PIDS; index++) {
+        // Find first available [index, pid] entry in the pid_tracked_hash_map map
+        if (writeToMapEntry(trackedPidHashMapFd, &index, &pid, BPF_NOEXIST) != 0) {
+            if (errno != EEXIST) {
+                return false;
+            }
+            continue; // This index is already taken
+        }
+
+        tracked_pid_t tracked_pid = {.pid = pid, .state = TRACKED_PID_STATE_ACTIVE};
+        if (writeToMapEntry(trackedPidMapFd, &index, &tracked_pid, BPF_ANY) != 0) {
+            return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+// Marks the specified task identified by its PID (aka TID) for CPU time-in-state tracking
+// aggregated with other tasks sharing the same TGID and aggregation key.
+bool startAggregatingTaskCpuTimes(pid_t pid, uint16_t aggregationKey) {
+    if (!gInitialized && !initGlobals()) return false;
+
+    unique_fd taskAggregationMapFd(
+            mapRetrieveWO(BPF_FS_PATH "map_time_in_state_pid_task_aggregation_map"));
+    if (taskAggregationMapFd < 0) return false;
+
+    return writeToMapEntry(taskAggregationMapFd, &pid, &aggregationKey, BPF_ANY) == 0;
+}
+
+// Retrieves the times in ns that each thread spent running at each CPU freq, aggregated by
+// aggregation key.
+// Return contains no value on error, otherwise it contains a map from aggregation keys
+// to vectors of vectors using the format:
+// { aggKey0 -> [[t0_0_0, t0_0_1, ...], [t0_1_0, t0_1_1, ...], ...],
+//   aggKey1 -> [[t1_0_0, t1_0_1, ...], [t1_1_0, t1_1_1, ...], ...], ... }
+// where ti_j_k is the ns tid i spent running on the jth cluster at the cluster's kth lowest freq.
+std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
+getAggregatedTaskCpuFreqTimes(pid_t tgid, const std::vector<uint16_t> &aggregationKeys) {
+    if (!gInitialized && !initGlobals()) return {};
+
+    uint32_t maxFreqCount = 0;
+    std::vector<std::vector<uint64_t>> mapFormat;
+    for (const auto &freqList : gPolicyFreqs) {
+        if (freqList.size() > maxFreqCount) maxFreqCount = freqList.size();
+        mapFormat.emplace_back(freqList.size(), 0);
+    }
+
+    bool dataCollected = false;
+    std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>> map;
+    std::vector<tis_val_t> vals(gNCpus);
+    for (uint16_t aggregationKey : aggregationKeys) {
+        map.emplace(aggregationKey, mapFormat);
+
+        aggregated_task_tis_key_t key{.tgid = tgid, .aggregation_key = aggregationKey};
+        for (key.bucket = 0; key.bucket <= (maxFreqCount - 1) / FREQS_PER_ENTRY; ++key.bucket) {
+            if (findMapEntry(gPidTisMapFd, &key, vals.data()) != 0) {
+                if (errno != ENOENT) {
+                    return {};
+                }
+                continue;
+            } else {
+                dataCollected = true;
+            }
+
+            // Combine data by aggregating time-in-state data grouped by CPU cluster aka policy.
+            uint32_t offset = key.bucket * FREQS_PER_ENTRY;
+            uint32_t nextOffset = offset + FREQS_PER_ENTRY;
+            for (uint32_t j = 0; j < gNPolicies; ++j) {
+                if (offset >= gPolicyFreqs[j].size()) continue;
+                auto begin = map[key.aggregation_key][j].begin() + offset;
+                auto end = nextOffset < gPolicyFreqs[j].size() ? begin + FREQS_PER_ENTRY
+                                                               : map[key.aggregation_key][j].end();
+                for (const auto &cpu : gPolicyCpus[j]) {
+                    std::transform(begin, end, std::begin(vals[cpu].ar), begin,
+                                   std::plus<uint64_t>());
+                }
+            }
+        }
+    }
+
+    if (!dataCollected) {
+        // Check if eBPF is supported on this device. If it is, gTisMap should not be empty.
+        time_key_t key;
+        if (getFirstMapKey(gTisMapFd, &key) != 0) {
+            return {};
+        }
+    }
+    return map;
+}
+
 } // namespace bpf
 } // namespace android
diff --git a/libs/cputimeinstate/cputimeinstate.h b/libs/cputimeinstate/cputimeinstate.h
index b7600f5..87a328a 100644
--- a/libs/cputimeinstate/cputimeinstate.h
+++ b/libs/cputimeinstate/cputimeinstate.h
@@ -41,5 +41,10 @@
     getUidsUpdatedConcurrentTimes(uint64_t *lastUpdate);
 bool clearUidTimes(unsigned int uid);
 
+bool startTrackingProcessCpuTimes(pid_t pid);
+bool startAggregatingTaskCpuTimes(pid_t pid, uint16_t aggregationKey);
+std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>>
+getAggregatedTaskCpuFreqTimes(pid_t pid, const std::vector<uint16_t> &aggregationKeys);
+
 } // namespace bpf
 } // namespace android
diff --git a/libs/cputimeinstate/testtimeinstate.cpp b/libs/cputimeinstate/testtimeinstate.cpp
index ea2a200..519689b 100644
--- a/libs/cputimeinstate/testtimeinstate.cpp
+++ b/libs/cputimeinstate/testtimeinstate.cpp
@@ -19,6 +19,8 @@
 
 #include <sys/sysinfo.h>
 
+#include <pthread.h>
+#include <semaphore.h>
 #include <numeric>
 #include <unordered_map>
 #include <vector>
@@ -387,6 +389,28 @@
     }
 }
 
+TEST(TimeInStateTest, AllUidConcurrentTimesFailsOnInvalidBucket) {
+    uint32_t uid = 0;
+    {
+        // Find an unused UID
+        auto map = getUidsConcurrentTimes();
+        ASSERT_TRUE(map.has_value());
+        ASSERT_FALSE(map->empty());
+        for (const auto &kv : *map) uid = std::max(uid, kv.first);
+        ++uid;
+    }
+    android::base::unique_fd fd{
+        bpf_obj_get(BPF_FS_PATH "map_time_in_state_uid_concurrent_times_map")};
+    ASSERT_GE(fd, 0);
+    uint32_t nCpus = get_nprocs_conf();
+    uint32_t maxBucket = (nCpus - 1) / CPUS_PER_ENTRY;
+    time_key_t key = {.uid = uid, .bucket = maxBucket + 1};
+    std::vector<concurrent_val_t> vals(nCpus);
+    ASSERT_FALSE(writeToMapEntry(fd, &key, vals.data(), BPF_NOEXIST));
+    EXPECT_FALSE(getUidsConcurrentTimes().has_value());
+    ASSERT_FALSE(deleteMapEntry(fd, &key));
+}
+
 TEST(TimeInStateTest, AllUidTimesConsistent) {
     auto tisMap = getUidsCpuFreqTimes();
     ASSERT_TRUE(tisMap.has_value());
@@ -482,5 +506,85 @@
     for (size_t i = 0; i < freqs->size(); ++i) EXPECT_EQ((*freqs)[i].size(), (*times)[i].size());
 }
 
+uint64_t timeNanos() {
+    struct timespec spec;
+    clock_gettime(CLOCK_MONOTONIC, &spec);
+    return spec.tv_sec * 1000000000 + spec.tv_nsec;
+}
+
+// Keeps CPU busy with some number crunching
+void useCpu() {
+    long sum = 0;
+    for (int i = 0; i < 100000; i++) {
+        sum *= i;
+    }
+}
+
+sem_t pingsem, pongsem;
+
+void *testThread(void *) {
+    for (int i = 0; i < 10; i++) {
+        sem_wait(&pingsem);
+        useCpu();
+        sem_post(&pongsem);
+    }
+    return nullptr;
+}
+
+TEST(TimeInStateTest, GetAggregatedTaskCpuFreqTimes) {
+    uint64_t startTimeNs = timeNanos();
+
+    sem_init(&pingsem, 0, 1);
+    sem_init(&pongsem, 0, 0);
+
+    pthread_t thread;
+    ASSERT_EQ(pthread_create(&thread, NULL, &testThread, NULL), 0);
+
+    // This process may have been running for some time, so when we start tracking
+    // CPU time, the very first switch may include the accumulated time.
+    // Yield the remainder of this timeslice to the newly created thread.
+    sem_wait(&pongsem);
+    sem_post(&pingsem);
+
+    pid_t tgid = getpid();
+    startTrackingProcessCpuTimes(tgid);
+
+    pid_t tid = pthread_gettid_np(thread);
+    startAggregatingTaskCpuTimes(tid, 42);
+
+    // Play ping-pong with the other thread to ensure that both threads get
+    // some CPU time.
+    for (int i = 0; i < 9; i++) {
+        sem_wait(&pongsem);
+        useCpu();
+        sem_post(&pingsem);
+    }
+
+    pthread_join(thread, NULL);
+
+    std::optional<std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>>> optionalMap =
+            getAggregatedTaskCpuFreqTimes(tgid, {0, 42});
+    ASSERT_TRUE(optionalMap);
+
+    std::unordered_map<uint16_t, std::vector<std::vector<uint64_t>>> map = *optionalMap;
+    ASSERT_EQ(map.size(), 2u);
+
+    uint64_t testDurationNs = timeNanos() - startTimeNs;
+    for (auto pair : map) {
+        uint16_t aggregationKey = pair.first;
+        ASSERT_TRUE(aggregationKey == 0 || aggregationKey == 42);
+
+        std::vector<std::vector<uint64_t>> timesInState = pair.second;
+        uint64_t totalCpuTime = 0;
+        for (size_t i = 0; i < timesInState.size(); i++) {
+            for (size_t j = 0; j < timesInState[i].size(); j++) {
+                totalCpuTime += timesInState[i][j];
+            }
+        }
+        ASSERT_GT(totalCpuTime, 0ul);
+        ASSERT_LE(totalCpuTime, testDurationNs);
+    }
+}
+
 } // namespace bpf
 } // namespace android
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 2e14408..3faf792 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -56,6 +56,7 @@
         "android.hardware.audio@4.0::IDevicesFactory",
         "android.hardware.audio@5.0::IDevicesFactory",
         "android.hardware.audio@6.0::IDevicesFactory",
+        "android.hardware.audio@7.0::IDevicesFactory",
         "android.hardware.automotive.audiocontrol@1.0::IAudioControl",
         "android.hardware.automotive.audiocontrol@2.0::IAudioControl",
         "android.hardware.automotive.evs@1.0::IEvsCamera",
diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp
index 6909637..76518c1 100644
--- a/libs/fakeservicemanager/Android.bp
+++ b/libs/fakeservicemanager/Android.bp
@@ -9,6 +9,11 @@
         "libbinder",
         "libutils",
     ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library {
diff --git a/libs/gralloc/OWNERS b/libs/gralloc/OWNERS
index 4a95778..93879d8 100644
--- a/libs/gralloc/OWNERS
+++ b/libs/gralloc/OWNERS
@@ -1,2 +1 @@
 chrisforbes@google.com
-vhau@google.com
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index cc31cd5..243d7f1 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -21,6 +21,11 @@
         "-Wno-enum-compare",
     ],
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
 
     vendor_available: true,
     vndk: {
diff --git a/libs/gralloc/types/fuzzer/Android.bp b/libs/gralloc/types/fuzzer/Android.bp
index 8444883..8933dc3 100644
--- a/libs/gralloc/types/fuzzer/Android.bp
+++ b/libs/gralloc/types/fuzzer/Android.bp
@@ -2,6 +2,11 @@
     name: "libgralloctypes_fuzzer",
     defaults: ["libbinder_ndk_host_user"],
     host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
 
     fuzz_config: {
         cc: ["marissaw@google.com"],
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index ecccf29..1667fb0 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -7,9 +7,7 @@
 lpy@google.com
 mathias@google.com
 racarr@google.com
-steventhomas@google.com
 stoza@google.com
-vhau@google.com
 vishnun@google.com
 
 per-file EndToEndNativeInputTest.cpp = svv@google.com
@@ -22,4 +20,4 @@
 per-file include/gui/BufferQueue* = set noparent
 per-file include/gui/BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com
 per-file include/gui/IGraphicBuffer* = set noparent
-per-file include/gui/IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com
\ No newline at end of file
+per-file include/gui/IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com
diff --git a/libs/gui/view/Surface.cpp b/libs/gui/view/Surface.cpp
index d64dfd5..d98ffc6 100644
--- a/libs/gui/view/Surface.cpp
+++ b/libs/gui/view/Surface.cpp
@@ -72,13 +72,9 @@
 }
 
 String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
-    size_t len;
-    const char16_t* str = parcel->readString16Inplace(&len);
-    if (str != nullptr) {
-        return String16(str, len);
-    } else {
-        return String16();
-    }
+    std::optional<String16> str;
+    parcel->readString16(&str);
+    return str.value_or(String16());
 }
 
 } // namespace view
diff --git a/libs/renderengine/Description.cpp b/libs/renderengine/Description.cpp
index b9cea10..245c9e1 100644
--- a/libs/renderengine/Description.cpp
+++ b/libs/renderengine/Description.cpp
@@ -52,5 +52,10 @@
     return colorMatrix != identity;
 }
 
+bool Description::hasDisplayColorMatrix() const {
+    const mat4 identity;
+    return displayColorMatrix != identity;
+}
+
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 2139acb..02021c9 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -1048,6 +1048,7 @@
 
     setOutputDataSpace(display.outputDataspace);
     setDisplayMaxLuminance(display.maxLuminance);
+    setDisplayColorTransform(display.colorTransform);
 
     const mat4 projectionMatrix =
             ui::Transform(display.orientation).asMatrix4() * mState.projectionMatrix;
@@ -1114,7 +1115,7 @@
         position[3] = vec2(bounds.right, bounds.top);
 
         setupLayerCropping(*layer, mesh);
-        setColorTransform(display.colorTransform * layer->colorTransform);
+        setColorTransform(layer->colorTransform);
 
         bool usePremultipliedAlpha = true;
         bool disableTexture = true;
@@ -1271,6 +1272,10 @@
     mState.colorMatrix = colorTransform;
 }
 
+void GLESRenderEngine::setDisplayColorTransform(const mat4& colorTransform) {
+    mState.displayColorMatrix = colorTransform;
+}
+
 void GLESRenderEngine::disableTexturing() {
     mState.textureEnabled = false;
 }
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 61986ff..0e003a0 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -159,6 +159,7 @@
     void setupLayerTexturing(const Texture& texture);
     void setupFillWithColor(float r, float g, float b, float a);
     void setColorTransform(const mat4& colorTransform);
+    void setDisplayColorTransform(const mat4& colorTransform);
     void disableTexturing();
     void disableBlending();
     void setupCornerRadiusCropSize(float width, float height);
diff --git a/libs/renderengine/gl/Program.cpp b/libs/renderengine/gl/Program.cpp
index f4fbf35..a172c56 100644
--- a/libs/renderengine/gl/Program.cpp
+++ b/libs/renderengine/gl/Program.cpp
@@ -66,6 +66,7 @@
         mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
         mSamplerLoc = glGetUniformLocation(programId, "sampler");
         mColorLoc = glGetUniformLocation(programId, "color");
+        mDisplayColorMatrixLoc = glGetUniformLocation(programId, "displayColorMatrix");
         mDisplayMaxLuminanceLoc = glGetUniformLocation(programId, "displayMaxLuminance");
         mMaxMasteringLuminanceLoc = glGetUniformLocation(programId, "maxMasteringLuminance");
         mMaxContentLuminanceLoc = glGetUniformLocation(programId, "maxContentLuminance");
@@ -129,6 +130,9 @@
         const float color[4] = {desc.color.r, desc.color.g, desc.color.b, desc.color.a};
         glUniform4fv(mColorLoc, 1, color);
     }
+    if (mDisplayColorMatrixLoc >= 0) {
+        glUniformMatrix4fv(mDisplayColorMatrixLoc, 1, GL_FALSE, desc.displayColorMatrix.asArray());
+    }
     if (mInputTransformMatrixLoc >= 0) {
         mat4 inputTransformMatrix = desc.inputTransformMatrix;
         glUniformMatrix4fv(mInputTransformMatrixLoc, 1, GL_FALSE, inputTransformMatrix.asArray());
diff --git a/libs/renderengine/gl/Program.h b/libs/renderengine/gl/Program.h
index fc3755e..4292645 100644
--- a/libs/renderengine/gl/Program.h
+++ b/libs/renderengine/gl/Program.h
@@ -104,6 +104,7 @@
     /* location of transform matrix */
     GLint mInputTransformMatrixLoc;
     GLint mOutputTransformMatrixLoc;
+    GLint mDisplayColorMatrixLoc;
 
     /* location of corner radius uniform */
     GLint mCornerRadiusLoc;
diff --git a/libs/renderengine/gl/ProgramCache.cpp b/libs/renderengine/gl/ProgramCache.cpp
index 3ae35ec..dc8ce54 100644
--- a/libs/renderengine/gl/ProgramCache.cpp
+++ b/libs/renderengine/gl/ProgramCache.cpp
@@ -180,6 +180,10 @@
                  description.hasOutputTransformMatrix() || description.hasColorMatrix()
                          ? Key::OUTPUT_TRANSFORM_MATRIX_ON
                          : Key::OUTPUT_TRANSFORM_MATRIX_OFF)
+            .set(Key::Key::DISPLAY_COLOR_TRANSFORM_MATRIX_MASK,
+                 description.hasDisplayColorMatrix()
+                         ? Key::DISPLAY_COLOR_TRANSFORM_MATRIX_ON
+                         : Key::DISPLAY_COLOR_TRANSFORM_MATRIX_OFF)
             .set(Key::ROUNDED_CORNERS_MASK,
                  description.cornerRadius > 0 ? Key::ROUNDED_CORNERS_ON : Key::ROUNDED_CORNERS_OFF)
             .set(Key::SHADOW_MASK, description.drawShadows ? Key::SHADOW_ON : Key::SHADOW_OFF);
@@ -661,7 +665,9 @@
             )__SHADER__";
     }
 
-    if (needs.hasTransformMatrix() || (needs.getInputTF() != needs.getOutputTF())) {
+    if (needs.hasTransformMatrix() ||
+        (needs.getInputTF() != needs.getOutputTF()) ||
+        needs.hasDisplayColorMatrix()) {
         if (needs.needsToneMapping()) {
             fs << "uniform float displayMaxLuminance;";
             fs << "uniform float maxMasteringLuminance;";
@@ -700,6 +706,21 @@
             )__SHADER__";
         }
 
+        if (needs.hasDisplayColorMatrix()) {
+            fs << "uniform mat4 displayColorMatrix;";
+            fs << R"__SHADER__(
+                highp vec3 DisplayColorMatrix(const highp vec3 color) {
+                    return clamp(vec3(displayColorMatrix * vec4(color, 1.0)), 0.0, 1.0);
+                }
+            )__SHADER__";
+        } else {
+            fs << R"__SHADER__(
+                highp vec3 DisplayColorMatrix(const highp vec3 color) {
+                    return color;
+                }
+            )__SHADER__";
+        }
+
         generateEOTF(fs, needs);
         generateOOTF(fs, needs);
         generateOETF(fs, needs);
@@ -732,14 +753,17 @@
         }
     }
 
-    if (needs.hasTransformMatrix() || (needs.getInputTF() != needs.getOutputTF())) {
+    if (needs.hasTransformMatrix() ||
+        (needs.getInputTF() != needs.getOutputTF()) ||
+        needs.hasDisplayColorMatrix()) {
         if (!needs.isOpaque() && needs.isPremultiplied()) {
             // un-premultiply if needed before linearization
             // avoid divide by 0 by adding 0.5/256 to the alpha channel
             fs << "gl_FragColor.rgb = gl_FragColor.rgb / (gl_FragColor.a + 0.0019);";
         }
         fs << "gl_FragColor.rgb = "
-              "OETF(OutputTransform(OOTF(InputTransform(EOTF(gl_FragColor.rgb)))));";
+              "DisplayColorMatrix(OETF(OutputTransform(OOTF(InputTransform(EOTF(gl_FragColor.rgb))))));";
+
         if (!needs.isOpaque() && needs.isPremultiplied()) {
             // and re-premultiply if needed after gamma correction
             fs << "gl_FragColor.rgb = gl_FragColor.rgb * (gl_FragColor.a + 0.0019);";
diff --git a/libs/renderengine/gl/ProgramCache.h b/libs/renderengine/gl/ProgramCache.h
index 901e631..b492cb3 100644
--- a/libs/renderengine/gl/ProgramCache.h
+++ b/libs/renderengine/gl/ProgramCache.h
@@ -117,6 +117,11 @@
             SHADOW_MASK = 1 << SHADOW_SHIFT,
             SHADOW_OFF = 0 << SHADOW_SHIFT,
             SHADOW_ON = 1 << SHADOW_SHIFT,
+
+            DISPLAY_COLOR_TRANSFORM_MATRIX_SHIFT = 14,
+            DISPLAY_COLOR_TRANSFORM_MATRIX_MASK = 1 << DISPLAY_COLOR_TRANSFORM_MATRIX_SHIFT,
+            DISPLAY_COLOR_TRANSFORM_MATRIX_OFF = 0 << DISPLAY_COLOR_TRANSFORM_MATRIX_SHIFT,
+            DISPLAY_COLOR_TRANSFORM_MATRIX_ON = 1 << DISPLAY_COLOR_TRANSFORM_MATRIX_SHIFT,
         };
 
         inline Key() : mKey(0) {}
@@ -143,6 +148,9 @@
         inline bool hasOutputTransformMatrix() const {
             return (mKey & OUTPUT_TRANSFORM_MATRIX_MASK) == OUTPUT_TRANSFORM_MATRIX_ON;
         }
+        inline bool hasDisplayColorMatrix() const {
+            return (mKey & DISPLAY_COLOR_TRANSFORM_MATRIX_MASK) == DISPLAY_COLOR_TRANSFORM_MATRIX_ON;
+        }
         inline bool hasTransformMatrix() const {
             return hasInputTransformMatrix() || hasOutputTransformMatrix();
         }
diff --git a/libs/renderengine/include/renderengine/private/Description.h b/libs/renderengine/include/renderengine/private/Description.h
index a62161a..fa6ec10 100644
--- a/libs/renderengine/include/renderengine/private/Description.h
+++ b/libs/renderengine/include/renderengine/private/Description.h
@@ -44,6 +44,7 @@
     bool hasInputTransformMatrix() const;
     bool hasOutputTransformMatrix() const;
     bool hasColorMatrix() const;
+    bool hasDisplayColorMatrix() const;
 
     // whether textures are premultiplied
     bool isPremultipliedAlpha = false;
@@ -79,6 +80,8 @@
 
     // The color matrix will be applied in linear space right before OETF.
     mat4 colorMatrix;
+    // The display color matrix will be applied in gamma space after OETF
+    mat4 displayColorMatrix;
     mat4 inputTransformMatrix;
     mat4 outputTransformMatrix;
 
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 0b5b1e4..a720a27 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -38,22 +38,27 @@
 
 struct RenderEngineTest : public ::testing::Test {
     static void SetUpTestSuite() {
-        sRE = renderengine::gl::GLESRenderEngine::create(
-                renderengine::RenderEngineCreationArgs::Builder()
-                    .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
-                    .setImageCacheSize(1)
-                    .setUseColorManagerment(false)
-                    .setEnableProtectedContext(false)
-                    .setPrecacheToneMapperShaderOnly(false)
-                    .setSupportsBackgroundBlur(true)
-                    .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
-        .build());
+        renderengine::RenderEngineCreationArgs reCreationArgs =
+            renderengine::RenderEngineCreationArgs::Builder()
+                .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
+                .setImageCacheSize(1)
+                .setUseColorManagerment(false)
+                .setEnableProtectedContext(false)
+                .setPrecacheToneMapperShaderOnly(false)
+                .setSupportsBackgroundBlur(true)
+                .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
+                .build();
+        sRE = renderengine::gl::GLESRenderEngine::create(reCreationArgs);
+
+        reCreationArgs.useColorManagement = true;
+        sRECM = renderengine::gl::GLESRenderEngine::create(reCreationArgs);
     }
 
     static void TearDownTestSuite() {
         // The ordering here is important - sCurrentBuffer must live longer
         // than RenderEngine to avoid a null reference on tear-down.
         sRE = nullptr;
+        sRECM = nullptr;
         sCurrentBuffer = nullptr;
     }
 
@@ -82,6 +87,9 @@
         for (uint32_t texName : mTexNames) {
             sRE->deleteTextures(1, &texName);
         }
+        for (uint32_t texName : mTexNamesCM) {
+            sRECM->deleteTextures(1, &texName);
+        }
     }
 
     void writeBufferToFile(const char* basename) {
@@ -250,9 +258,13 @@
 
     void invokeDraw(renderengine::DisplaySettings settings,
                     std::vector<const renderengine::LayerSettings*> layers,
-                    sp<GraphicBuffer> buffer) {
+                    sp<GraphicBuffer> buffer,
+                    bool useColorManagement = false) {
         base::unique_fd fence;
-        status_t status = sRE->drawLayers(settings, layers, buffer->getNativeBuffer(), true,
+        status_t status = useColorManagement ?
+                          sRECM ->drawLayers(settings, layers, buffer->getNativeBuffer(), true,
+                                             base::unique_fd(), &fence) :
+                          sRE->drawLayers(settings, layers, buffer->getNativeBuffer(), true,
                                           base::unique_fd(), &fence);
         sCurrentBuffer = buffer;
 
@@ -264,7 +276,11 @@
 
         ASSERT_EQ(NO_ERROR, status);
         if (layers.size() > 0) {
-            ASSERT_TRUE(sRE->isFramebufferImageCachedForTesting(buffer->getId()));
+            if (useColorManagement) {
+                ASSERT_TRUE(sRECM->isFramebufferImageCachedForTesting(buffer->getId()));
+            } else {
+                ASSERT_TRUE(sRE->isFramebufferImageCachedForTesting(buffer->getId()));
+            }
         }
     }
 
@@ -319,12 +335,15 @@
     void fillBufferLayerTransform();
 
     template <typename SourceVariant>
-    void fillBufferWithColorTransform();
+    void fillBufferWithColorTransform(bool useColorManagement = false);
 
     template <typename SourceVariant>
     void fillBufferColorTransform();
 
     template <typename SourceVariant>
+    void fillBufferColorTransformCM();
+
+    template <typename SourceVariant>
     void fillRedBufferWithRoundedCorners();
 
     template <typename SourceVariant>
@@ -363,6 +382,8 @@
     // For now, exercise the GL backend directly so that some caching specifics
     // can be tested without changing the interface.
     static std::unique_ptr<renderengine::gl::GLESRenderEngine> sRE;
+    // renderengine object with Color Management enabled
+    static std::unique_ptr<renderengine::gl::GLESRenderEngine> sRECM;
     // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to
     // be freed *after* RenderEngine is destroyed, so that the EGL image is
     // destroyed first.
@@ -371,14 +392,17 @@
     sp<GraphicBuffer> mBuffer;
 
     std::vector<uint32_t> mTexNames;
+    std::vector<uint32_t> mTexNamesCM;
 };
 
 std::unique_ptr<renderengine::gl::GLESRenderEngine> RenderEngineTest::sRE = nullptr;
+std::unique_ptr<renderengine::gl::GLESRenderEngine> RenderEngineTest::sRECM = nullptr;
+
 sp<GraphicBuffer> RenderEngineTest::sCurrentBuffer = nullptr;
 
 struct ColorSourceVariant {
     static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
-                          RenderEngineTest* /*fixture*/) {
+                          RenderEngineTest* /*fixture*/, bool /*useColorManagement*/ = false) {
         layer.source.solidColor = half3(r, g, b);
     }
 };
@@ -406,11 +430,17 @@
 template <typename OpaquenessVariant>
 struct BufferSourceVariant {
     static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
-                          RenderEngineTest* fixture) {
+                          RenderEngineTest* fixture,
+                          bool useColorManagement = false) {
         sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
         uint32_t texName;
-        fixture->sRE->genTextures(1, &texName);
-        fixture->mTexNames.push_back(texName);
+        if (useColorManagement) {
+            fixture->sRECM->genTextures(1, &texName);
+            fixture->mTexNamesCM.push_back(texName);
+        } else {
+            fixture->sRE->genTextures(1, &texName);
+            fixture->mTexNames.push_back(texName);
+        }
 
         uint8_t* pixels;
         buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
@@ -640,7 +670,7 @@
 }
 
 template <typename SourceVariant>
-void RenderEngineTest::fillBufferWithColorTransform() {
+void RenderEngineTest::fillBufferWithColorTransform(bool useColorManagement) {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
     settings.clip = Rect(1, 1);
@@ -649,12 +679,12 @@
 
     renderengine::LayerSettings layer;
     layer.geometry.boundaries = Rect(1, 1).toFloatRect();
-    SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
+    SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this, useColorManagement);
     layer.alpha = 1.0f;
 
     // construct a fake color matrix
     // annihilate green and blue channels
-    settings.colorTransform = mat4::scale(vec4(1, 0, 0, 1));
+    settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
     // set red channel to red + green
     layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
 
@@ -663,13 +693,19 @@
 
     layers.push_back(&layer);
 
-    invokeDraw(settings, layers, mBuffer);
+    invokeDraw(settings, layers, mBuffer, useColorManagement);
 }
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferColorTransform() {
     fillBufferWithColorTransform<SourceVariant>();
-    expectBufferColor(fullscreenRect(), 191, 0, 0, 255);
+    expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
+}
+
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferColorTransformCM() {
+    fillBufferWithColorTransform<SourceVariant>(true);
+    expectBufferColor(fullscreenRect(), 126, 0, 0, 255, 1);
 }
 
 template <typename SourceVariant>
@@ -1072,7 +1108,11 @@
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
-    fillBufferLayerTransform<ColorSourceVariant>();
+    fillBufferColorTransform<ColorSourceVariant>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_colorSource) {
+    fillBufferColorTransformCM<ColorSourceVariant>();
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
@@ -1128,7 +1168,11 @@
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
-    fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+    fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_opaqueBufferSource) {
+    fillBufferColorTransformCM<BufferSourceVariant<ForceOpaqueBufferVariant>>();
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
@@ -1184,7 +1228,11 @@
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
-    fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+    fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransformCM_bufferSource) {
+    fillBufferColorTransformCM<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
 
 TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
diff --git a/libs/vibrator/Android.bp b/libs/vibrator/Android.bp
index e95a080..33ab8ba 100644
--- a/libs/vibrator/Android.bp
+++ b/libs/vibrator/Android.bp
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-cc_library_shared {
+cc_library {
     name: "libvibrator",
 
     shared_libs: [
@@ -45,4 +45,11 @@
     ],
 
     export_include_dirs: ["include"],
+
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
diff --git a/libs/vibrator/OWNERS b/libs/vibrator/OWNERS
new file mode 100644
index 0000000..0997e9f
--- /dev/null
+++ b/libs/vibrator/OWNERS
@@ -0,0 +1,2 @@
+lsandrade@google.com
+michaelwr@google.com
diff --git a/libs/vibrator/fuzzer/Android.bp b/libs/vibrator/fuzzer/Android.bp
new file mode 100644
index 0000000..8020151
--- /dev/null
+++ b/libs/vibrator/fuzzer/Android.bp
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+cc_fuzz {
+    name: "vibrator_fuzzer",
+
+    host_supported: true,
+
+    srcs: [
+        "vibrator_fuzzer.cpp",
+    ],
+
+    static_libs: [
+        "liblog",
+        "libvibrator",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libbase",
+        "libutils",
+    ],
+
+    fuzz_config: {
+        componentid: 155276,
+    },
+}
diff --git a/libs/vibrator/fuzzer/README.md b/libs/vibrator/fuzzer/README.md
new file mode 100644
index 0000000..43eb2d2
--- /dev/null
+++ b/libs/vibrator/fuzzer/README.md
@@ -0,0 +1,65 @@
+# Fuzzer for libvibrator
+
+## Plugin Design Considerations
+This fuzzer fuzzes native code present in libvibrator and does not cover the Java implementation ExternalVibration
+The fuzzer plugin is designed based on the understanding of the
+library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libvibrator supports the following parameters:
+1. Uid (parameter name: `uid`)
+2. Package Name (parameter name: `pkg`)
+3. Audio Content Type (parameter name: `content_type`)
+4. Audio Usage (parameter name: `usage`)
+5. Audio Source (parameter name: `source`)
+6. Audio flags (parameter name: `flags`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `uid` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `pkg`   | Any std::string value | Value obtained from FuzzedDataProvider |
+| `content_type`   | 0.`AUDIO_CONTENT_TYPE_UNKNOWN` 1.`AUDIO_CONTENT_TYPE_SPEECH` 2.`AUDIO_CONTENT_TYPE_MUSIC` 3.`AUDIO_CONTENT_TYPE_MOVIE` 4.`AUDIO_CONTENT_TYPE_SONIFICATION`| Value obtained from FuzzedDataProvider in the range 0 to 4|
+| `usage`   | 0.`AUDIO_USAGE_UNKNOWN` 1.`AUDIO_USAGE_MEDIA` 2.`AUDIO_USAGE_VOICE_COMMUNICATION` 3.`AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING` 4.`AUDIO_USAGE_ALARM` 5.`AUDIO_USAGE_NOTIFICATION` 6.`AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE`  7.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST` 8.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT` 9.`AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED` 10.`AUDIO_USAGE_NOTIFICATION_EVENT` 11.`AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY` 12.`AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE` 13.`AUDIO_USAGE_ASSISTANCE_SONIFICATION` 14.`AUDIO_USAGE_GAME` 15.`AUDIO_USAGE_VIRTUAL_SOURCE` 16.`AUDIO_USAGE_ASSISTANT` 17.`AUDIO_USAGE_CALL_ASSISTANT` 18.`AUDIO_USAGE_EMERGENCY` 19.`AUDIO_USAGE_SAFETY` 20.`AUDIO_USAGE_VEHICLE_STATUS` 21.`AUDIO_USAGE_ANNOUNCEMENT`| Value obtained from FuzzedDataProvider in the range 0 to 21|
+| `source`   |  0.`AUDIO_SOURCE_DEFAULT` 1.`AUDIO_SOURCE_MIC` 2.`AUDIO_SOURCE_VOICE_UPLINK` 3.`AUDIO_SOURCE_VOICE_DOWNLINK` 4.`AUDIO_SOURCE_VOICE_CALL` 5.`AUDIO_SOURCE_CAMCORDER` 6.`AUDIO_SOURCE_VOICE_RECOGNITION` 7.`AUDIO_SOURCE_VOICE_COMMUNICATION` 8.`AUDIO_SOURCE_REMOTE_SUBMIX` 9.`AUDIO_SOURCE_UNPROCESSED` 10.`AUDIO_SOURCE_VOICE_PERFORMANCE` 11.`AUDIO_SOURCE_ECHO_REFERENCE` 12.`AUDIO_SOURCE_FM_TUNER` | Value obtained from FuzzedDataProvider in the range 0 to 12 |
+| `flags`   | `UINT32_MIN` to `UINT32_MAX` | Value obtained from FuzzedDataProvider |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesn't `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build vibrator_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) vibrator_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/vibrator_fuzzer/vibrator_fuzzer CORPUS_DIR
+```
+
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/x86_64/vibrator_fuzzer/vibrator_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/libs/vibrator/fuzzer/vibrator_fuzzer.cpp b/libs/vibrator/fuzzer/vibrator_fuzzer.cpp
new file mode 100644
index 0000000..68b3ca6
--- /dev/null
+++ b/libs/vibrator/fuzzer/vibrator_fuzzer.cpp
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ */
+
+#include <binder/Parcel.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <vibrator/ExternalVibration.h>
+
+using namespace android;
+
+constexpr size_t MAX_STRING_LENGTH = 100;
+constexpr audio_content_type_t AUDIO_CONTENT_TYPE[] = {AUDIO_CONTENT_TYPE_UNKNOWN,
+                                                       AUDIO_CONTENT_TYPE_SPEECH,
+                                                       AUDIO_CONTENT_TYPE_MUSIC,
+                                                       AUDIO_CONTENT_TYPE_MOVIE,
+                                                       AUDIO_CONTENT_TYPE_SONIFICATION};
+constexpr audio_usage_t AUDIO_USAGE[] = {
+        AUDIO_USAGE_UNKNOWN,
+        AUDIO_USAGE_MEDIA,
+        AUDIO_USAGE_VOICE_COMMUNICATION,
+        AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
+        AUDIO_USAGE_ALARM,
+        AUDIO_USAGE_NOTIFICATION,
+        AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
+        AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+        AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+        AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+        AUDIO_USAGE_NOTIFICATION_EVENT,
+        AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY,
+        AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+        AUDIO_USAGE_ASSISTANCE_SONIFICATION,
+        AUDIO_USAGE_GAME,
+        AUDIO_USAGE_VIRTUAL_SOURCE,
+        AUDIO_USAGE_ASSISTANT,
+        AUDIO_USAGE_CALL_ASSISTANT,
+        AUDIO_USAGE_EMERGENCY,
+        AUDIO_USAGE_SAFETY,
+        AUDIO_USAGE_VEHICLE_STATUS,
+        AUDIO_USAGE_ANNOUNCEMENT,
+};
+constexpr audio_source_t AUDIO_SOURCE[] = {
+        AUDIO_SOURCE_DEFAULT,           AUDIO_SOURCE_MIC,
+        AUDIO_SOURCE_VOICE_UPLINK,      AUDIO_SOURCE_VOICE_DOWNLINK,
+        AUDIO_SOURCE_VOICE_CALL,        AUDIO_SOURCE_CAMCORDER,
+        AUDIO_SOURCE_VOICE_RECOGNITION, AUDIO_SOURCE_VOICE_COMMUNICATION,
+        AUDIO_SOURCE_REMOTE_SUBMIX,     AUDIO_SOURCE_UNPROCESSED,
+        AUDIO_SOURCE_VOICE_PERFORMANCE, AUDIO_SOURCE_ECHO_REFERENCE,
+        AUDIO_SOURCE_FM_TUNER,
+};
+constexpr size_t NUM_AUDIO_CONTENT_TYPE = std::size(AUDIO_CONTENT_TYPE);
+constexpr size_t NUM_AUDIO_USAGE = std::size(AUDIO_USAGE);
+constexpr size_t NUM_AUDIO_SOURCE = std::size(AUDIO_SOURCE);
+
+class TestVibrationController : public os::IExternalVibrationController {
+public:
+    explicit TestVibrationController() {}
+    IBinder *onAsBinder() override { return nullptr; }
+    binder::Status mute(/*out*/ bool *ret) override {
+        *ret = false;
+        return binder::Status::ok();
+    };
+    binder::Status unmute(/*out*/ bool *ret) override {
+        *ret = false;
+        return binder::Status::ok();
+    };
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    // Initialize the parameters using FuzzedDataProvider
+    int32_t uid = fdp.ConsumeIntegral<int32_t>();
+    std::string pkg = fdp.ConsumeRandomLengthString(MAX_STRING_LENGTH);
+    audio_attributes_t attributes;
+    attributes.content_type =
+            AUDIO_CONTENT_TYPE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_CONTENT_TYPE - 1)];
+    attributes.usage = AUDIO_USAGE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_USAGE - 1)];
+    attributes.source = AUDIO_SOURCE[fdp.ConsumeIntegralInRange<uint32_t>(0, NUM_AUDIO_SOURCE - 1)];
+    attributes.flags = static_cast<audio_flags_mask_t>(fdp.ConsumeIntegral<uint32_t>());
+
+    // Create an instance of TestVibrationController
+    sp<TestVibrationController> vibrationController = new TestVibrationController();
+    if (!vibrationController) {
+        return 0;
+    }
+
+    // Set all the parameters in the constructor call
+    sp<os::ExternalVibration> extVibration =
+            new os::ExternalVibration(uid, pkg, attributes, vibrationController);
+    if (!extVibration) {
+        return 0;
+    }
+
+    // Get all the parameters that were previously set
+    extVibration->getUid();
+    extVibration->getPackage();
+    extVibration->getAudioAttributes();
+    extVibration->getController();
+
+    // Set the parameters in a Parcel object and send it to libvibrator
+    // This parcel shall be read by libvibrator
+    Parcel parcel;
+    parcel.writeInt32(uid);
+    parcel.writeString16(String16(pkg.c_str()));
+    parcel.writeStrongBinder(IInterface::asBinder(vibrationController));
+    parcel.setDataPosition(0);
+    extVibration->readFromParcel(&parcel);
+
+    // Send a Parcel to libvibrator
+    // Parameters shall be written to this parcel by libvibrator
+    extVibration->writeToParcel(&parcel);
+    return 0;
+}
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 340d7bf..d5a19d3 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -80,6 +80,7 @@
 
 cc_library_shared {
     name: "libdvr.google",
+    system_ext_specific: true,
     owner: "google",
     cflags: cflags,
     header_libs: ["libdvr_headers"],
diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
index afde5f7..f5c5a5a 100644
--- a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
+++ b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
@@ -52,7 +52,7 @@
 
 // Fuzzer for Serialization operations, this is mostly just lifted from the
 // existing test cases to use fuzzed values as inputs.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+void FuzzSerializeDeserialize(const uint8_t* data, size_t size) {
   FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
   Payload result;
 
@@ -106,6 +106,183 @@
   Deserialize(&vec_val, &result);
   Serialize(t1_val, &result);
   Deserialize(&t1_val, &result);
+}
+
+void FuzzDeserializeUint8(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_UINT8, fdp.ConsumeIntegral<uint8_t>()};
+  std::uint8_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeUint16(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_UINT16, fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  std::uint16_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeUint32(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_UINT32, fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  std::uint32_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeUint64(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {
+      ENCODING_TYPE_UINT64,           fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>()};
+  std::uint64_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeInt8(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_INT8, fdp.ConsumeIntegral<uint8_t>()};
+  std::int8_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeInt16(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_INT16, fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  std::int16_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeInt32(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_INT32, fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  std::int32_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeInt64(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_INT64,
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  std::int64_t result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeFloat32(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_FLOAT32, fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  float floatResult;
+  Deserialize(&floatResult, &buffer);
+
+  buffer.Rewind();
+  double doubleResult;
+  Deserialize(&doubleResult, &buffer);
+}
+
+void FuzzDeserializeFloat64(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {
+      ENCODING_TYPE_FLOAT64,          fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
+      fdp.ConsumeIntegral<uint8_t>()};
+  double result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeFixstr(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  std::string s_val = fdp.ConsumeRemainingBytesAsString();
+  Payload buffer = {ENCODING_TYPE_FIXSTR_MAX};
+  for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
+       iter++) {
+    buffer.Append(1, *iter);
+  }
+  std::string result;
+  Deserialize(&result, &buffer);
+}
+
+void FuzzDeserializeFixmap(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_FIXMAP_MAX};
+  // Fill the map with the fuzzed data, not attempting to
+  // make a valid map
+  while (fdp.remaining_bytes() > 0) {
+    buffer.Append(1, fdp.ConsumeIntegral<uint8_t>());
+  }
+
+  std::map<std::uint32_t, std::uint32_t> result;
+  Deserialize(&result, &buffer);
+
+  buffer.Rewind();
+  std::unordered_map<std::uint32_t, std::uint32_t> unorderedResult;
+  Deserialize(&unorderedResult, &buffer);
+}
+
+void FuzzDeserializeVariant(const uint8_t* data, size_t size) {
+  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+  Payload buffer = {ENCODING_TYPE_INT16,
+                    ENCODING_TYPE_FLOAT32,
+                    ENCODING_TYPE_FIXSTR_MAX,
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>(),
+                    fdp.ConsumeIntegral<uint8_t>()};
+  // Add the rest of the data as a string
+  std::string s_val = fdp.ConsumeRemainingBytesAsString();
+  for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
+       iter++) {
+    buffer.Append(1, *iter);
+  }
+  Variant<int, float, std::string> result;
+  Deserialize(&result, &buffer);
+}
+
+// Attempts to deserialize fuzzed data as various types
+void FuzzDeserialize(const uint8_t* data, size_t size) {
+  FuzzDeserializeUint8(data, size);
+  FuzzDeserializeUint16(data, size);
+  FuzzDeserializeUint32(data, size);
+  FuzzDeserializeUint64(data, size);
+  FuzzDeserializeInt8(data, size);
+  FuzzDeserializeInt16(data, size);
+  FuzzDeserializeInt32(data, size);
+  FuzzDeserializeInt64(data, size);
+  FuzzDeserializeFloat32(data, size);
+  FuzzDeserializeFloat64(data, size);
+  FuzzDeserializeFixstr(data, size);
+  FuzzDeserializeFixmap(data, size);
+  FuzzDeserializeVariant(data, size);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzSerializeDeserialize(data, size);
+  FuzzDeserialize(data, size);
 
   return 0;
 }
diff --git a/libs/vr/libpdx_default_transport/Android.bp b/libs/vr/libpdx_default_transport/Android.bp
index 1ce9c99..b3534de 100644
--- a/libs/vr/libpdx_default_transport/Android.bp
+++ b/libs/vr/libpdx_default_transport/Android.bp
@@ -45,6 +45,7 @@
 
 cc_binary {
     name: "pdx_tool",
+    system_ext_specific: true,
     defaults: ["pdx_default_transport_compiler_defaults"],
     srcs: [
         "pdx_tool.cpp",
diff --git a/services/gpuservice/tests/unittests/AndroidTest.xml b/services/gpuservice/tests/unittests/AndroidTest.xml
index 66f51c7..72976a8 100644
--- a/services/gpuservice/tests/unittests/AndroidTest.xml
+++ b/services/gpuservice/tests/unittests/AndroidTest.xml
@@ -18,6 +18,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="gpuservice_unittest->/data/local/tmp/gpuservice_unittest" />
     </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
     <option name="test-suite-tag" value="apct" />
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index cfc2919..0b541fb 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -781,12 +781,17 @@
         mOrientedRanges.clear();
     }
 
-    // Create pointer controller if needed.
+    // Create pointer controller if needed, and keep it around if Pointer Capture is enabled to
+    // preserve the cursor position.
     if (mDeviceMode == DeviceMode::POINTER ||
-        (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches)) {
+        (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches) ||
+        (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerCapture)) {
         if (mPointerController == nullptr) {
             mPointerController = getContext()->getPointerController(getDeviceId());
         }
+        if (mConfig.pointerCapture) {
+            mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
+        }
     } else {
         mPointerController.reset();
     }
@@ -3433,7 +3438,6 @@
 void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags, bool down,
                                              bool hovering) {
     int32_t metaState = getContext()->getGlobalMetaState();
-    int32_t displayId = mViewport.displayId;
 
     if (down || hovering) {
         mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER);
@@ -3443,7 +3447,7 @@
     } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
         mPointerController->fade(PointerControllerInterface::Transition::GRADUAL);
     }
-    displayId = mPointerController->getDisplayId();
+    int32_t displayId = mPointerController->getDisplayId();
 
     float xCursorPosition;
     float yCursorPosition;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index cb467ea..ca7119e 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -313,7 +313,7 @@
             logicalOrientation = ui::Rotation::Rotation90;
         }
 
-        const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation;
+        const ui::Rotation orientation = logicalOrientation;
 
         switch (orientation) {
             case ui::ROTATION_0:
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index c5a4689..f273725 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -4,7 +4,5 @@
 chaviw@google.com
 lpy@google.com
 racarr@google.com
-steventhomas@google.com
 stoza@google.com
-vhau@google.com
 vishnun@google.com
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9d65f2f..6862e62 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5747,7 +5747,7 @@
 
     // TODO(b/116112787) Make buffer usage a parameter.
     const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
-            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
+            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER;
     *outBuffer =
             getFactory().createGraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
                                              static_cast<android_pixel_format>(reqPixelFormat), 1,
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 2861013..3535fbb 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -8,12 +8,12 @@
          "FakeComposerUtils.cpp",
          "SFFakeHwc_test.cpp"
     ],
+    require_root: true,
     shared_libs: [
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.2",
         "android.hardware.graphics.composer@2.3",
         "android.hardware.graphics.composer@2.4",
-        "android.hardware.graphics.composer@2.1-resources",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@3.0",
         "android.hardware.graphics.mapper@4.0",
@@ -33,6 +33,7 @@
         "libutils",
     ],
     static_libs: [
+        "android.hardware.graphics.composer@2.1-resources",
         "libcompositionengine",
         "libgmock",
         "libperfetto_client_experimental",
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
index afb3004..7097e7a 100644
--- a/services/vr/bufferhubd/Android.bp
+++ b/services/vr/bufferhubd/Android.bp
@@ -15,7 +15,6 @@
 sharedLibraries = [
     "libbase",
     "libcutils",
-    "libgtest_prod",
     "libgui",
     "liblog",
     "libpdx_default_transport",
@@ -48,6 +47,7 @@
 
 cc_binary {
     srcs: ["bufferhubd.cpp"],
+    system_ext_specific: true,
     cflags: [
         "-DLOG_TAG=\"bufferhubd\"",
         "-DTRACE=0",
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 4df7b7c..3728731 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -1,6 +1,8 @@
 cc_library_shared {
     name: "libvr_hwc-hal",
 
+    system_ext_specific: true,
+
     srcs: [
         "impl/vr_hwc.cpp",
         "impl/vr_composer_client.cpp",
@@ -97,6 +99,7 @@
 
 cc_binary {
     name: "vr_hwc",
+    system_ext_specific: true,
     vintf_fragments: ["manifest_vr_hwc.xml"],
     srcs: [
         "vr_hardware_composer_service.cpp",
diff --git a/services/vr/performanced/Android.bp b/services/vr/performanced/Android.bp
index 20301f6..0ef8cc4 100644
--- a/services/vr/performanced/Android.bp
+++ b/services/vr/performanced/Android.bp
@@ -30,6 +30,7 @@
 
 cc_binary {
     name: "performanced",
+    system_ext_specific: true,
     defaults: ["performanced_defaults"],
     srcs: [
         "cpu_set.cpp",