Merge "Fix 5x and 6P crash when using HWC2to1adapter"
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 194a565..69ed416 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -6,6 +6,10 @@
 
     shared_libs: [
         "libbinder",
+        "libhwbinder",
+        "android.hidl.manager@1.0",
+        "libhidlbase",
+        "libhidltransport",
         "liblog",
         "libcutils",
         "libutils",
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 8faf276..a217c5d 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -37,6 +37,8 @@
 #include <binder/IServiceManager.h>
 #include <binder/Parcel.h>
 
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
 #include <cutils/properties.h>
 
 #include <utils/String8.h>
@@ -47,6 +49,7 @@
 
 using namespace android;
 
+using std::string;
 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
 
 #define MAX_SYS_FILES 10
@@ -517,6 +520,35 @@
     return true;
 }
 
+// Poke all the HAL processes in the system to get them to re-read
+// their system properties.
+static void pokeHalServices()
+{
+    using ::android::hidl::manager::V1_0::IServiceManager;
+    using ::android::hardware::IBinder;
+    using ::android::hardware::hidl_string;
+    using ::android::hardware::Parcel;
+
+    Parcel data;
+
+    sp<IServiceManager> sm = ::android::hardware::defaultServiceManager();
+    sm->list([&](const auto &interfaces) {
+        for (size_t i = 0; i < interfaces.size(); i++) {
+            string fqInstanceName = interfaces[i];
+            string::size_type n = fqInstanceName.find("/");
+            if (n == std::string::npos || interfaces[i].size() == n+1)
+                continue;
+            hidl_string fqInterfaceName = fqInstanceName.substr(0, n);
+            hidl_string instanceName = fqInstanceName.substr(n+1, std::string::npos);
+            sm->get(fqInterfaceName, instanceName, [&](const auto &interface) {
+                // TODO(b/32756130)
+                // Once IServiceManager returns IBase, use interface->notifySyspropsChanged() here
+                interface->transact(IBinder::SYSPROPS_TRANSACTION, data, nullptr, 0, nullptr);
+            });
+        }
+    });
+}
+
 // Set the trace tags that userland tracing uses, and poke the running
 // processes to pick up the new value.
 static bool setTagsProperty(uint64_t tags)
@@ -759,6 +791,7 @@
     }
     ok &= setAppCmdlineProperty(&packageList[0]);
     ok &= pokeBinderServices();
+    pokeHalServices();
 
     // Disable all the sysfs enables.  This is done as a separate loop from
     // the enables to allow the same enable to exist in multiple categories.
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index e11bf30..7edc7de 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -14,6 +14,7 @@
 COMMON_SRC_FILES := \
         utils.cpp
 COMMON_SHARED_LIBRARIES := \
+        android.hardware.dumpstate@1.0 \
         libbase \
         libbinder \
         libcutils \
@@ -22,6 +23,27 @@
         liblog \
         libselinux \
         libutils
+COMMON_STATIC_LIBRARIES := \
+        libdumpstateutil \
+        $(COMMON_ZIP_LIBRARIES)
+
+# ====================#
+# libdumpstateutil #
+# ====================#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libdumpstateutil
+
+LOCAL_CFLAGS := $(COMMON_LOCAL_CFLAGS)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_SRC_FILES := \
+        utils.cpp # TODO: temporary, until functions are moved to DumpstateUtil.cpp
+# TODO: include just what it uses (libbase, libcutils, etc...) once split from utils.cpp
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
+LOCAL_STATIC_LIBRARIES := $(COMMON_ZIP_LIBRARIES)
+
+include $(BUILD_STATIC_LIBRARY)
 
 # ====================#
 # libdumpstateheaders #
@@ -35,7 +57,7 @@
 LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
         $(COMMON_SHARED_LIBRARIES)
 LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := \
-        $(COMMON_ZIP_LIBRARIES)
+        $(COMMON_STATIC_LIBRARIES)
 # Soong requires that whats is on LOCAL_EXPORTED_ is also on LOCAL_
 LOCAL_SHARED_LIBRARIES := $(LOCAL_EXPORT_SHARED_LIBRARY_HEADERS)
 LOCAL_STATIC_LIBRARIES := $(LOCAL_EXPORT_STATIC_LIBRARY_HEADERS)
@@ -81,7 +103,7 @@
 
 LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
 
-LOCAL_STATIC_LIBRARIES := $(COMMON_ZIP_LIBRARIES)
+LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES)
 
 LOCAL_HAL_STATIC_LIBRARIES := libdumpstate
 
@@ -106,7 +128,7 @@
         DumpstateService.cpp \
         tests/dumpstate_test.cpp
 
-LOCAL_STATIC_LIBRARIES := $(COMMON_ZIP_LIBRARIES) \
+LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES) \
         libgmock
 
 LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
diff --git a/cmds/dumpstate/DumpstateUtil.h b/cmds/dumpstate/DumpstateUtil.h
new file mode 100644
index 0000000..42a91db
--- /dev/null
+++ b/cmds/dumpstate/DumpstateUtil.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
+#define FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
+
+// TODO: use android::os::dumpstate (must wait until device code is refactored)
+
+/*
+ * Defines the Linux user that should be executing a command.
+ */
+enum RootMode {
+    /* Explicitly change the `uid` and `gid` to be `shell`.*/
+    DROP_ROOT,
+    /* Don't change the `uid` and `gid`. */
+    DONT_DROP_ROOT,
+    /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
+    SU_ROOT
+};
+
+/*
+ * Defines what should happen with the `stdout` stream of a command.
+ */
+enum StdoutMode {
+    /* Don't change `stdout`. */
+    NORMAL_STDOUT,
+    /* Redirect `stdout` to `stderr`. */
+    REDIRECT_TO_STDERR
+};
+
+/*
+ * Value object used to set command options.
+ *
+ * Typically constructed using a builder with chained setters. Examples:
+ *
+ *  CommandOptions::WithTimeout(20).AsRoot().Build();
+ *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
+ *
+ * Although the builder could be used to dynamically set values. Example:
+ *
+ *  CommandOptions::CommandOptionsBuilder options =
+ *  CommandOptions::WithTimeout(10);
+ *  if (!is_user_build()) {
+ *    options.AsRoot();
+ *  }
+ *  RunCommand("command", {"args"}, options.Build());
+ */
+class CommandOptions {
+  private:
+    class CommandOptionsValues {
+      private:
+        CommandOptionsValues(int64_t timeout);
+
+        int64_t timeout_;
+        bool always_;
+        RootMode root_mode_;
+        StdoutMode stdout_mode_;
+        std::string logging_message_;
+
+        friend class CommandOptions;
+        friend class CommandOptionsBuilder;
+    };
+
+    CommandOptions(const CommandOptionsValues& values);
+
+    const CommandOptionsValues values;
+
+  public:
+    class CommandOptionsBuilder {
+      public:
+        /* Sets the command to always run, even on `dry-run` mode. */
+        CommandOptionsBuilder& Always();
+        /* Sets the command's RootMode as `SU_ROOT` */
+        CommandOptionsBuilder& AsRoot();
+        /* Sets the command's RootMode as `DROP_ROOT` */
+        CommandOptionsBuilder& DropRoot();
+        /* Sets the command's StdoutMode `REDIRECT_TO_STDERR` */
+        CommandOptionsBuilder& RedirectStderr();
+        /* When not empty, logs a message before executing the command.
+         * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
+        CommandOptionsBuilder& Log(const std::string& message);
+        /* Builds the command options. */
+        CommandOptions Build();
+
+      private:
+        CommandOptionsBuilder(int64_t timeout);
+        CommandOptionsValues values;
+        friend class CommandOptions;
+    };
+
+    /** Gets the command timeout, in seconds. */
+    int64_t Timeout() const;
+    /* Checks whether the command should always be run, even on dry-run mode. */
+    bool Always() const;
+    /** Gets the RootMode of the command. */
+    RootMode RootMode() const;
+    /** Gets the StdoutMode of the command. */
+    StdoutMode StdoutMode() const;
+    /** Gets the logging message header, it any. */
+    std::string LoggingMessage() const;
+
+    /** Creates a builder with the requied timeout. */
+    static CommandOptionsBuilder WithTimeout(int64_t timeout);
+
+    // Common options.
+    static CommandOptions DEFAULT;
+    static CommandOptions AS_ROOT_5;
+    static CommandOptions AS_ROOT_10;
+    static CommandOptions AS_ROOT_20;
+};
+
+/*
+ * Forks a command, waits for it to finish, and returns its status.
+ *
+ * |fd| file descriptor that receives the command's 'stdout'.
+ * |full_command| array containing the command (first entry) and its arguments.
+ * Must contain at least one element.
+ * |options| optional argument defining the command's behavior.
+ * |description| optional description of the command to be used on log messages. If empty,
+ * the command path (without arguments) will be used instead.
+ */
+int RunCommandToFd(int fd, const std::vector<const char*>& full_command,
+                   const CommandOptions& options = CommandOptions::DEFAULT,
+                   const std::string& description = "");
+
+/*
+ * Dumps the contents of a file into a file descriptor.
+ *
+ * |fd| file descriptor where the file is dumped into.
+ * |path| location of the file to be dumped.
+ */
+int DumpFileToFd(int fd, const std::string& path);
+
+#endif  // FRAMEWORK_NATIVE_CMD_DUMPSTATE_UTIL_H_
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ea70fe5..8879ab8 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -41,6 +41,8 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
+#include <cutils/native_handle.h>
 #include <cutils/properties.h>
 #include <hardware_legacy/power.h>
 #include <openssl/sha.h>
@@ -90,7 +92,7 @@
     return ds.RunCommand(title, fullCommand, options);
 }
 static void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs,
-                       const CommandOptions& options = CommandOptions::DEFAULT_DUMPSYS,
+                       const CommandOptions& options = Dumpstate::DEFAULT_DUMPSYS,
                        long dumpsysTimeout = 0) {
     return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeout);
 }
@@ -462,6 +464,9 @@
         MYLOGE("Unable to add modem log %s to zip file\n", modem_log_file.c_str());
     } else {
         MYLOGD("Modem Log %s is added to zip\n", modem_log_file.c_str());
+        if (remove(modem_log_file.c_str())) {
+            MYLOGE("Error removing modem log %s\n", modem_log_file.c_str());
+        }
     }
 }
 
@@ -680,7 +685,8 @@
     printf("Network: %s\n", network.c_str());
 
     printf("Kernel: ");
-    JustDumpFile("", "/proc/version");
+    fflush(stdout);
+    DumpFileToFd(STDOUT_FILENO, "/proc/version");
     printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
     printf("Bugreport format version: %s\n", version_.c_str());
     printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
@@ -1088,15 +1094,7 @@
     DumpFile("BINDER STATS", "/sys/kernel/debug/binder/stats");
     DumpFile("BINDER STATE", "/sys/kernel/debug/binder/state");
 
-    printf("========================================================\n");
-    printf("== Board\n");
-    printf("========================================================\n");
-
-    {
-        DurationReporter tmpDr("dumpstate_board()");
-        dumpstate_board();
-        printf("\n");
-    }
+    ds.DumpstateBoard();
 
     /* Migrate the ril_dumpstate to a dumpstate_board()? */
     int rilDumpstateTimeout = android::base::GetIntProperty("ril.dumpstate.timeout", 0);
@@ -1161,6 +1159,57 @@
     printf("========================================================\n");
 }
 
+void Dumpstate::DumpstateBoard() {
+    DurationReporter duration_reporter("dumpstate_board()");
+    printf("========================================================\n");
+    printf("== Board\n");
+    printf("========================================================\n");
+    fflush(stdout);
+
+    android::sp<android::hardware::dumpstate::V1_0::IDumpstateDevice> dumpstate_device(
+        android::hardware::dumpstate::V1_0::IDumpstateDevice::getService("DumpstateDevice"));
+    if (dumpstate_device == nullptr) {
+        // TODO: temporary workaround until devices on master implement it
+        MYLOGE("no IDumpstateDevice implementation; using legacy dumpstate_board()\n");
+        dumpstate_board();
+        return;
+    }
+
+    if (!IsZipping()) {
+        MYLOGE("Not dumping board info because it's not a zipped bugreport\n");
+        return;
+    }
+
+    std::string path = ds.GetPath("-dumpstate-board.txt");
+    MYLOGI("Calling IDumpstateDevice implementation using path %s\n", path.c_str());
+
+    int fd =
+        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));
+    if (fd < 0) {
+        MYLOGE("Could not open file %s: %s\n", path.c_str(), strerror(errno));
+        return;
+    }
+
+    native_handle_t* handle = native_handle_create(1, 0);
+    if (handle == nullptr) {
+        MYLOGE("Could not create native_handle\n");
+        return;
+    }
+    handle->data[0] = fd;
+
+    dumpstate_device->dumpstateBoard(handle);
+
+    AddZipEntry("dumpstate-board.txt", path);
+
+    native_handle_close(handle);
+    native_handle_delete(handle);
+
+    if (remove(path.c_str()) != 0) {
+        MYLOGE("Could not remove(%s): %s\n", path.c_str(), strerror(errno));
+    }
+}
+
 static void ShowUsageAndExit(int exitCode = 1) {
     fprintf(stderr,
             "usage: dumpstate [-h] [-b soundfile] [-e soundfile] [-o file] [-d] [-p] "
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 3d3d7ed..969348f 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -40,6 +40,7 @@
 #include <android-base/macros.h>
 #include <ziparchive/zip_writer.h>
 
+#include "DumpstateUtil.h"
 #include "android/os/BnDumpstate.h"
 
 // Workaround for const char *args[MAX_ARGS_ARRAY_SIZE] variables until they're converted to
@@ -53,28 +54,6 @@
 #endif
 
 /*
- * Defines the Linux user that should be executing a command.
- */
-enum RootMode {
-    /* Explicitly change the `uid` and `gid` to be `shell`.*/
-    DROP_ROOT,
-    /* Don't change the `uid` and `gid`. */
-    DONT_DROP_ROOT,
-    /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
-    SU_ROOT
-};
-
-/*
- * Defines what should happen with the `stdout` stream of a command.
- */
-enum StdoutMode {
-    /* Don't change `stdout`. */
-    NORMAL_STDOUT,
-    /* Redirect `stdout` to `stderr`. */
-    REDIRECT_TO_STDERR
-};
-
-/*
  * Helper class used to report how long it takes for a section to finish.
  *
  * Typical usage:
@@ -102,88 +81,6 @@
 };
 
 /*
- * Value object used to set command options.
- *
- * Typically constructed using a builder with chained setters. Examples:
- *
- *  CommandOptions::WithTimeout(20).AsRoot().Build();
- *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
- *
- * Although the builder could be used to dynamically set values. Example:
- *
- *  CommandOptions::CommandOptionsBuilder options =
- *  CommandOptions::WithTimeout(10);
- *  if (!is_user_build()) {
- *    options.AsRoot();
- *  }
- *  RunCommand("command", {"args"}, options.Build());
- */
-class CommandOptions {
-  private:
-    class CommandOptionsValues {
-      private:
-        CommandOptionsValues(long timeout);
-
-        long timeout_;
-        bool always_;
-        RootMode root_mode_;
-        StdoutMode stdout_mode_;
-        std::string logging_message_;
-
-        friend class CommandOptions;
-        friend class CommandOptionsBuilder;
-    };
-
-    CommandOptions(const CommandOptionsValues& values);
-
-    const CommandOptionsValues values;
-
-  public:
-    class CommandOptionsBuilder {
-      public:
-        /* Sets the command to always run, even on `dry-run` mode. */
-        CommandOptionsBuilder& Always();
-        /* Sets the command's RootMode as `SU_ROOT` */
-        CommandOptionsBuilder& AsRoot();
-        /* Sets the command's RootMode as `DROP_ROOT` */
-        CommandOptionsBuilder& DropRoot();
-        /* Sets the command's StdoutMode `REDIRECT_TO_STDERR` */
-        CommandOptionsBuilder& RedirectStderr();
-        /* When not empty, logs a message before executing the command.
-         * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
-        CommandOptionsBuilder& Log(const std::string& message);
-        /* Builds the command options. */
-        CommandOptions Build();
-
-      private:
-        CommandOptionsBuilder(long timeout);
-        CommandOptionsValues values;
-        friend class CommandOptions;
-    };
-
-    /** Gets the command timeout, in seconds. */
-    long Timeout() const;
-    /* Checks whether the command should always be run, even on dry-run mode. */
-    bool Always() const;
-    /** Gets the RootMode of the command. */
-    RootMode RootMode() const;
-    /** Gets the StdoutMode of the command. */
-    StdoutMode StdoutMode() const;
-    /** Gets the logging message header, it any. */
-    std::string LoggingMessage() const;
-
-    /** Creates a builder with the requied timeout. */
-    static CommandOptionsBuilder WithTimeout(long timeout);
-
-    // Common options.
-    static CommandOptions DEFAULT;
-    static CommandOptions DEFAULT_DUMPSYS;
-    static CommandOptions AS_ROOT_5;
-    static CommandOptions AS_ROOT_10;
-    static CommandOptions AS_ROOT_20;
-};
-
-/*
  * Keeps track of current progress and estimated max, saving stats on file to tune up future runs.
  *
  * Each `dumpstate` section contributes to the total weight by an individual weight, so the overall
@@ -272,6 +169,8 @@
     friend class DumpstateTest;
 
   public:
+    static CommandOptions DEFAULT_DUMPSYS;
+
     static Dumpstate& GetInstance();
 
     /*
@@ -316,8 +215,7 @@
      * timeout from `options`)
      */
     void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args,
-                    const CommandOptions& options = CommandOptions::DEFAULT_DUMPSYS,
-                    long dumpsys_timeout = 0);
+                    const CommandOptions& options = DEFAULT_DUMPSYS, long dumpsys_timeout = 0);
 
     /*
      * Prints the contents of a file.
@@ -362,6 +260,8 @@
     // TODO: temporary method until Dumpstate object is properly set
     void SetProgress(std::unique_ptr<Progress> progress);
 
+    void DumpstateBoard();
+
     /*
      * Updates the overall progress of the bugreport generation by the given weight increment.
      */
@@ -454,13 +354,6 @@
     Dumpstate(const std::string& version = VERSION_CURRENT, bool dry_run = false,
               const std::string& build_type = "user");
 
-    // Internal version of RunCommand that just runs it, without updating progress.
-    int JustRunCommand(const char* command, const char* path, std::vector<const char*>& args,
-                       const CommandOptions& options) const;
-
-    // Internal version of RunCommand that just dumps it, without updating progress.
-    int JustDumpFile(const std::string& title, const std::string& path) const;
-
     // Whether this is a dry run.
     bool dry_run_;
 
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 0d68901..9613576 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -548,7 +548,7 @@
             android::base::StringPrintf("%d %d\n", expected_runs, expected_average);
         std::string actual_content;
         ASSERT_TRUE(android::base::ReadFileToString(path, &actual_content))
-            << "could not read statsfrom" << path;
+            << "could not read stats from " << path;
         ASSERT_THAT(actual_content, StrEq(expected_content)) << "invalid stats on " << path;
     }
 };
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index b5f328d..c322d9f 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -97,12 +97,12 @@
 static const long STATS_MAX_AVERAGE = 100000;
 
 CommandOptions CommandOptions::DEFAULT = CommandOptions::WithTimeout(10).Build();
-CommandOptions CommandOptions::DEFAULT_DUMPSYS = CommandOptions::WithTimeout(30).Build();
+CommandOptions Dumpstate::DEFAULT_DUMPSYS = CommandOptions::WithTimeout(30).Build();
 CommandOptions CommandOptions::AS_ROOT_5 = CommandOptions::WithTimeout(5).AsRoot().Build();
 CommandOptions CommandOptions::AS_ROOT_10 = CommandOptions::WithTimeout(10).AsRoot().Build();
 CommandOptions CommandOptions::AS_ROOT_20 = CommandOptions::WithTimeout(20).AsRoot().Build();
 
-CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(long timeout) : values(timeout) {
+CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout) : values(timeout) {
 }
 
 CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Always() {
@@ -135,7 +135,7 @@
     return CommandOptions(values);
 }
 
-CommandOptions::CommandOptionsValues::CommandOptionsValues(long timeout)
+CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout)
     : timeout_(timeout),
       always_(false),
       root_mode_(DONT_DROP_ROOT),
@@ -146,7 +146,7 @@
 CommandOptions::CommandOptions(const CommandOptionsValues& values) : values(values) {
 }
 
-long CommandOptions::Timeout() const {
+int64_t CommandOptions::Timeout() const {
     return values.timeout_;
 }
 
@@ -166,7 +166,7 @@
     return values.logging_message_;
 }
 
-CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(long timeout) {
+CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout) {
     return CommandOptions::CommandOptionsBuilder(timeout);
 }
 
@@ -657,9 +657,9 @@
 }
 
 // TODO: when converted to a Dumpstate function, it should be const
-static int _dump_file_from_fd(const std::string& title, const char* path, int fd) {
+static int _dump_file_from_fd_to_fd(const std::string& title, const char* path, int fd, int out_fd) {
     if (!title.empty()) {
-        printf("------ %s (%s", title.c_str(), path);
+        dprintf(out_fd, "------ %s (%s", title.c_str(), path);
 
         struct stat st;
         // Only show the modification time of non-device files.
@@ -671,9 +671,9 @@
             char stamp[80];
             time_t mtime = st.st_mtime;
             strftime(stamp, sizeof(stamp), "%Y-%m-%d %H:%M:%S", localtime(&mtime));
-            printf(": %s", stamp);
+            dprintf(out_fd, ": %s", stamp);
         }
-        printf(") ------\n");
+        dprintf(out_fd, ") ------\n");
     }
 
     bool newline = false;
@@ -688,24 +688,23 @@
         uint64_t elapsed = DurationReporter::Nanotime();
         int ret = TEMP_FAILURE_RETRY(select(fd + 1, &read_set, NULL, NULL, &tm));
         if (ret == -1) {
-            printf("*** %s: select failed: %s\n", path, strerror(errno));
+            dprintf(out_fd, "*** %s: select failed: %s\n", path, strerror(errno));
             newline = true;
             break;
         } else if (ret == 0) {
             elapsed = DurationReporter::Nanotime() - elapsed;
-            printf("*** %s: Timed out after %.3fs\n", path,
-                   (float) elapsed / NANOS_PER_SEC);
+            dprintf(out_fd, "*** %s: Timed out after %.3fs\n", path, (float)elapsed / NANOS_PER_SEC);
             newline = true;
             break;
         } else {
             char buffer[65536];
             ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
             if (bytes_read > 0) {
-                fwrite(buffer, bytes_read, 1, stdout);
+                android::base::WriteFully(out_fd, buffer, bytes_read);
                 newline = (buffer[bytes_read-1] == '\n');
             } else {
                 if (bytes_read == -1) {
-                    printf("*** %s: Failed to read from fd: %s", path, strerror(errno));
+                    dprintf(out_fd, "*** %s: Failed to read from fd: %s", path, strerror(errno));
                     newline = true;
                 }
                 break;
@@ -715,11 +714,31 @@
     UpdateProgress(WEIGHT_FILE);
     close(fd);
 
-    if (!newline) printf("\n");
-    if (!title.empty()) printf("\n");
+    if (!newline) dprintf(out_fd, "\n");
+    if (!title.empty()) dprintf(out_fd, "\n");
     return 0;
 }
 
+// Internal function used by both DumpFile and DumpFileToFd - the former wants to print title
+// information, while the later doesn't.
+static int DumpFileToFd(const std::string& title, int out_fd, const std::string& path) {
+    int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+    if (fd < 0) {
+        int err = errno;
+        if (title.empty()) {
+            printf("*** Error dumping %s: %s\n", path.c_str(), strerror(err));
+        } else {
+            printf("*** Error dumping %s (%s): %s\n", path.c_str(), title.c_str(), strerror(err));
+        }
+        return -1;
+    }
+    return _dump_file_from_fd_to_fd(title, path.c_str(), fd, out_fd);
+}
+
+int DumpFileToFd(int out_fd, const std::string& path) {
+    return DumpFileToFd("", out_fd, path);
+}
+
 int Dumpstate::DumpFile(const std::string& title, const std::string& path) {
     DurationReporter duration_reporter(title);
     if (IsDryRun()) {
@@ -730,21 +749,7 @@
         UpdateProgress(WEIGHT_FILE);
         return 0;
     }
-    return JustDumpFile(title, path);
-}
-
-int Dumpstate::JustDumpFile(const std::string& title, const std::string& path) const {
-    int fd = TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC));
-    if (fd < 0) {
-        int err = errno;
-        if (title.empty()) {
-            printf("*** Error dumping %s: %s\n", path.c_str(), strerror(err));
-        } else {
-            printf("*** Error dumping %s (%s): %s\n", path.c_str(), title.c_str(), strerror(err));
-        }
-        return -1;
-    }
-    return _dump_file_from_fd(title, path.c_str(), fd);
+    return DumpFileToFd(title, STDOUT_FILENO, path);
 }
 
 int read_file_as_long(const char *path, long int *output) {
@@ -855,7 +860,7 @@
         close(fd);
         return -1;
     }
-    return _dump_file_from_fd(title, path, fd);
+    return _dump_file_from_fd_to_fd(title, path, fd, STDOUT_FILENO);
 }
 
 bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
@@ -909,6 +914,8 @@
         return -1;
     }
 
+    // TODO: SU_ROOT logic must be moved to RunCommandToFd
+
     int size = full_command.size() + 1;  // null terminated
     int starting_index = 0;
     if (options.RootMode() == SU_ROOT) {
@@ -935,7 +942,6 @@
         }
     }
     args[i] = nullptr;
-    const char* path = args[0];
     const char* command = command_string.c_str();
 
     if (options.RootMode() == SU_ROOT && ds.IsUserBuild()) {
@@ -963,7 +969,7 @@
         return 0;
     }
 
-    int status = JustRunCommand(command, path, args, options);
+    int status = RunCommandToFd(STDOUT_FILENO, args, options, command);
 
     /* TODO: for now we're simplifying the progress calculation by using the
      * timeout as the weight. It's a good approximation for most cases, except when calling dumpsys,
@@ -978,8 +984,15 @@
     return status;
 }
 
-int Dumpstate::JustRunCommand(const char* command, const char* path, std::vector<const char*>& args,
-                              const CommandOptions& options) const {
+int RunCommandToFd(int fd, const std::vector<const char*>& full_command,
+                   const CommandOptions& options, const std::string& description) {
+    if (full_command.empty()) {
+        MYLOGE("No arguments on RunCommandToFd'\n");
+        return -1;
+    }
+    const char* path = full_command[0];
+    const char* command = description.empty() ? path : description.c_str();
+
     bool silent = (options.StdoutMode() == REDIRECT_TO_STDERR);
 
     uint64_t start = DurationReporter::Nanotime();
@@ -1001,9 +1014,13 @@
             return -1;
         }
 
+        if (STDOUT_FILENO != fd) {
+            TEMP_FAILURE_RETRY(dup2(fd, STDOUT_FILENO));
+            close(fd);
+        }
         if (silent) {
-            // Redirect stderr to stdout
-            dup2(STDERR_FILENO, STDOUT_FILENO);
+            // Redirect stderr to fd
+            dup2(STDERR_FILENO, fd);
         }
 
         /* make sure the child dies when dumpstate dies */
@@ -1015,11 +1032,10 @@
         sigact.sa_handler = SIG_IGN;
         sigaction(SIGPIPE, &sigact, NULL);
 
-        execvp(path, (char**)args.data());
+        execvp(path, (char**)full_command.data());
         // execvp's result will be handled after waitpid_with_timeout() below, but
         // if it failed, it's safer to exit dumpstate.
         MYLOGD("execvp on command '%s' failed (error: %s)\n", command, strerror(errno));
-        fflush(stdout);
         // Must call _exit (instead of exit), otherwise it will corrupt the zip
         // file.
         _exit(EXIT_FAILURE);
@@ -1028,6 +1044,8 @@
     /* handle parent case */
     int status;
     bool ret = waitpid_with_timeout(pid, options.Timeout(), &status);
+    fsync(fd);
+
     uint64_t elapsed = DurationReporter::Nanotime() - start;
     if (!ret) {
         if (errno == ETIMEDOUT) {
diff --git a/include/binder/AppOpsManager.h b/include/binder/AppOpsManager.h
index 042927c..4212776 100644
--- a/include/binder/AppOpsManager.h
+++ b/include/binder/AppOpsManager.h
@@ -91,7 +91,8 @@
         OP_USE_SIP = 53,
         OP_PROCESS_OUTGOING_CALLS = 54,
         OP_USE_FINGERPRINT = 55,
-        OP_BODY_SENSORS = 56
+        OP_BODY_SENSORS = 56,
+        OP_AUDIO_ACCESSIBILITY_VOLUME = 64,
     };
 
     AppOpsManager();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 128e2b0..06f67ba 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -26,6 +26,7 @@
 
 using hardware::Return;
 using hardware::hidl_vec;
+using hardware::hidl_handle;
 
 namespace Hwc2 {
 
@@ -39,14 +40,14 @@
         mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
     }
 
-    operator const native_handle_t*() const
+    operator const hidl_handle&() const
     {
         return mHandle;
     }
 
 private:
     NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
-    const native_handle_t* mHandle;
+    hidl_handle mHandle;
 };
 
 class FenceHandle
@@ -55,13 +56,15 @@
     FenceHandle(int fd, bool owned)
         : mOwned(owned)
     {
+        native_handle_t* handle;
         if (fd >= 0) {
-            mHandle = native_handle_init(mStorage, 1, 0);
-            mHandle->data[0] = fd;
+            handle = native_handle_init(mStorage, 1, 0);
+            handle->data[0] = fd;
         } else {
             // nullptr is not a valid handle to HIDL
-            mHandle = native_handle_init(mStorage, 0, 0);
+            handle = native_handle_init(mStorage, 0, 0);
         }
+        mHandle = handle;
     }
 
     ~FenceHandle()
@@ -71,7 +74,7 @@
         }
     }
 
-    operator const native_handle_t*() const
+    operator const hidl_handle&() const
     {
         return mHandle;
     }
@@ -79,7 +82,7 @@
 private:
     bool mOwned;
     NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
-    native_handle_t* mHandle;
+    hidl_handle mHandle;
 };
 
 // assume NO_RESOURCES when Status::isOk returns false