Merge "Updating bugreport to dump only visible activities."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 8f2dee1..14eff03 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -1284,7 +1284,7 @@
             fflush(stdout);
             int outFd = STDOUT_FILENO;
             if (g_outputFile) {
-                outFd = open(g_outputFile, O_WRONLY | O_CREAT, 0644);
+                outFd = open(g_outputFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
             }
             if (outFd == -1) {
                 printf("Failed to open '%s', err=%d", g_outputFile, errno);
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index aa5e970..1cf00f5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1059,7 +1059,7 @@
 #endif
     DumpFile("INTERRUPTS (2)", "/proc/interrupts");
 
-    print_properties();
+    RunCommand("SYSTEM PROPERTIES", {"getprop"});
 
     RunCommand("VOLD DUMP", {"vdc", "dump"});
     RunCommand("SECURE CONTAINERS", {"vdc", "asec", "list"});
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index d988429..7fcb980 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -363,9 +363,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));
 
-/* prints all the system properties */
-void print_properties();
-
 /** opens a socket and returns its file descriptor */
 int open_socket(const char *service);
 
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index baa6458..4655d33 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -710,40 +710,6 @@
     RunCommand(title, dumpsys, options);
 }
 
-size_t num_props = 0;
-static char* props[2000];
-
-static void print_prop(const char *key, const char *name, void *user) {
-    (void) user;
-    if (num_props < sizeof(props) / sizeof(props[0])) {
-        char buf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 10];
-        snprintf(buf, sizeof(buf), "[%s]: [%s]\n", key, name);
-        props[num_props++] = strdup(buf);
-    }
-}
-
-static int compare_prop(const void *a, const void *b) {
-    return strcmp(*(char * const *) a, *(char * const *) b);
-}
-
-/* prints all the system properties */
-void print_properties() {
-    const char* title = "SYSTEM PROPERTIES";
-    DurationReporter duration_reporter(title);
-    printf("------ %s ------\n", title);
-    if (PropertiesHelper::IsDryRun()) return;
-    size_t i;
-    num_props = 0;
-    property_list(print_prop, NULL);
-    qsort(&props, num_props, sizeof(props[0]), compare_prop);
-
-    for (i = 0; i < num_props; ++i) {
-        fputs(props[i], stdout);
-        free(props[i]);
-    }
-    printf("\n");
-}
-
 int open_socket(const char *service) {
     int s = android_get_control_socket(service);
     if (s < 0) {
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 5aab35a..39e0ba3 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -18,8 +18,10 @@
         "libbase",
         "libutils",
         "libhidlbase",
-        "android.hidl.manager@1.0",
         "libhidltransport",
+        "libhidl-gen-utils",
+        "libvintf",
+        "android.hidl.manager@1.0",
     ],
     srcs: [
         "Lshal.cpp"
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 6fd9b21..e953ded 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -28,6 +28,9 @@
 #include <android-base/parseint.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
+#include <hidl-util/FQName.h>
+#include <vintf/HalManifest.h>
+#include <vintf/parse_xml.h>
 
 #include "Timeout.h"
 
@@ -58,12 +61,13 @@
     return os.str();
 }
 
-static std::pair<hidl_string, hidl_string> split(const hidl_string &s, char c) {
+template<typename String>
+static std::pair<String, String> splitFirst(const String &s, char c) {
     const char *pos = strchr(s.c_str(), c);
     if (pos == nullptr) {
         return {s, {}};
     }
-    return {hidl_string(s.c_str(), pos - s.c_str()), hidl_string(pos + 1)};
+    return {String(s.c_str(), pos - s.c_str()), String(pos + 1)};
 }
 
 static std::vector<std::string> split(const std::string &s, char c) {
@@ -81,6 +85,14 @@
     return components;
 }
 
+static void replaceAll(std::string *s, char from, char to) {
+    for (size_t i = 0; i < s->size(); ++i) {
+        if (s->at(i) == from) {
+            s->at(i) = to;
+        }
+    }
+}
+
 std::string getCmdline(pid_t pid) {
     std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
     std::string cmdline;
@@ -189,7 +201,78 @@
     mOut << std::endl;
 }
 
-void Lshal::dump() const {
+void Lshal::dumpVintf() const {
+    vintf::HalManifest manifest;
+    for (const TableEntry &entry : mTable) {
+
+        std::string fqInstanceName = entry.interfaceName;
+
+        if (entry.source == LIST_DLLIB) {
+            // Quick hack to work around *'s
+            replaceAll(&fqInstanceName, '*', 'D');
+        }
+        auto splittedFqInstanceName = splitFirst(fqInstanceName, '/');
+        FQName fqName(splittedFqInstanceName.first);
+        if (!fqName.isValid()) {
+            mErr << "Warning: '" << splittedFqInstanceName.first
+                 << "' is not a valid FQName." << std::endl;
+            continue;
+        }
+        // Strip out system libs.
+        // TODO(b/34772739): might want to add other framework HAL packages
+        if (fqName.inPackage("android.hidl")) {
+            continue;
+        }
+        std::string interfaceName =
+                entry.source == LIST_DLLIB ? "" : fqName.name();
+        std::string instanceName =
+                entry.source == LIST_DLLIB ? "" : splittedFqInstanceName.second;
+
+        vintf::Transport transport;
+        if (entry.transport == "hwbinder") {
+            transport = vintf::Transport::HWBINDER;
+        } else if (entry.transport == "passthrough") {
+            transport = vintf::Transport::PASSTHROUGH;
+        } else {
+            mErr << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
+            continue;
+        }
+
+        vintf::ManifestHal *hal = manifest.getHal(fqName.package());
+        if (hal == nullptr) {
+            if (!manifest.add(vintf::ManifestHal{
+                .format = vintf::HalFormat::HIDL,
+                .name = fqName.package(),
+                .impl = {.implLevel = vintf::ImplLevel::GENERIC, .impl = ""},
+                .transport = transport
+            })) {
+                mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
+                continue;
+            }
+            hal = manifest.getHal(fqName.package());
+        }
+        if (hal == nullptr) {
+            mErr << "Warning: cannot get hal '" << fqInstanceName
+                 << "' after adding it" << std::endl;
+            continue;
+        }
+        vintf::Version version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()};
+        if (std::find(hal->versions.begin(), hal->versions.end(), version) == hal->versions.end()) {
+            hal->versions.push_back(version);
+        }
+        if (entry.source != LIST_DLLIB) {
+            auto it = hal->interfaces.find(interfaceName);
+            if (it == hal->interfaces.end()) {
+                hal->interfaces.insert({interfaceName, {interfaceName, {{instanceName}}}});
+            } else {
+                it->second.instances.insert(instanceName);
+            }
+        }
+    }
+    mOut << vintf::gHalManifestConverter(manifest);
+}
+
+void Lshal::dumpTable() const {
     mOut << "All services:" << std::endl;
     mOut << std::left;
     printLine("Interface", "Transport", "Server", "Server CMD", "PTR", "Clients", "Clients CMD");
@@ -204,6 +287,20 @@
     }
 }
 
+void Lshal::dump() {
+    if (mVintf) {
+        dumpVintf();
+        if (!!mFileOutput) {
+            mFileOutput.buf().close();
+            delete &mFileOutput.buf();
+            mFileOutput = nullptr;
+        }
+        mOut = std::cout;
+    } else {
+        dumpTable();
+    }
+}
+
 void Lshal::putEntry(TableEntry &&entry) {
     mTable.push_back(std::forward<TableEntry>(entry));
 }
@@ -219,7 +316,8 @@
                 .transport = "passthrough",
                 .serverPid = NO_PID,
                 .serverObjectAddress = NO_PTR,
-                .clientPids = {}
+                .clientPids = {},
+                .source = LIST_DLLIB
             });
         }
     });
@@ -244,7 +342,8 @@
                 .transport = "passthrough",
                 .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
                 .serverObjectAddress = NO_PTR,
-                .clientPids = info.clientPids
+                .clientPids = info.clientPids,
+                .source = PTSERVICEMANAGER_REG_CLIENT
             });
         }
     });
@@ -262,79 +361,85 @@
     using namespace ::android::hidl::manager::V1_0;
     using namespace ::android::hidl::base::V1_0;
     const std::string mode = "hwbinder";
-    Status status = OK;
-    auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &fqInstanceNames) {
-        // server pid, .ptr value of binder object, child pids
-        std::map<std::string, DebugInfo> allDebugInfos;
-        std::map<pid_t, std::map<uint64_t, Pids>> allPids;
-        for (const auto &fqInstanceName : fqInstanceNames) {
-            const auto pair = split(fqInstanceName, '/');
-            const auto &serviceName = pair.first;
-            const auto &instanceName = pair.second;
-            auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
-            if (!getRet.isOk()) {
-                mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
-                     << "cannot be fetched from service manager:"
-                     << getRet.description() << std::endl;
-                status |= DUMP_BINDERIZED_ERROR;
-                continue;
-            }
-            sp<IBase> service = getRet;
-            if (service == nullptr) {
-                mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
-                     << "cannot be fetched from service manager (null)";
-                status |= DUMP_BINDERIZED_ERROR;
-                continue;
-            }
-            auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &debugInfo) {
-                allDebugInfos[fqInstanceName] = debugInfo;
-                if (debugInfo.pid >= 0) {
-                    allPids[static_cast<pid_t>(debugInfo.pid)].clear();
-                }
-            });
-            if (!debugRet.isOk()) {
-                mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
-                     << "debugging information cannot be retrieved:"
-                     << debugRet.description() << std::endl;
-                status |= DUMP_BINDERIZED_ERROR;
-            }
-        }
-        for (auto &pair : allPids) {
-            pid_t serverPid = pair.first;
-            if (!getReferencedPids(serverPid, &allPids[serverPid])) {
-                mErr << "Warning: no information for PID " << serverPid
-                          << ", are you root?" << std::endl;
-                status |= DUMP_BINDERIZED_ERROR;
-            }
-        }
-        for (const auto &fqInstanceName : fqInstanceNames) {
-            auto it = allDebugInfos.find(fqInstanceName);
-            if (it == allDebugInfos.end()) {
-                putEntry({
-                    .interfaceName = fqInstanceName,
-                    .transport = mode,
-                    .serverPid = NO_PID,
-                    .serverObjectAddress = NO_PTR,
-                    .clientPids = {}
-                });
-                continue;
-            }
-            const DebugInfo &info = it->second;
-            putEntry({
-                .interfaceName = fqInstanceName,
-                .transport = mode,
-                .serverPid = info.pid,
-                .serverObjectAddress = info.ptr,
-                .clientPids = info.pid == NO_PID || info.ptr == NO_PTR
-                        ? Pids{} : allPids[info.pid][info.ptr]
-            });
-        }
 
+    hidl_vec<hidl_string> fqInstanceNames;
+    // copying out for timeoutIPC
+    auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
+        fqInstanceNames = names;
     });
     if (!listRet.isOk()) {
         mErr << "Error: Failed to list services for " << mode << ": "
              << listRet.description() << std::endl;
-        status |= DUMP_BINDERIZED_ERROR;
+        return DUMP_BINDERIZED_ERROR;
+    }
+
+    Status status = OK;
+    // server pid, .ptr value of binder object, child pids
+    std::map<std::string, DebugInfo> allDebugInfos;
+    std::map<pid_t, std::map<uint64_t, Pids>> allPids;
+    for (const auto &fqInstanceName : fqInstanceNames) {
+        const auto pair = splitFirst(fqInstanceName, '/');
+        const auto &serviceName = pair.first;
+        const auto &instanceName = pair.second;
+        auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
+        if (!getRet.isOk()) {
+            mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                 << "cannot be fetched from service manager:"
+                 << getRet.description() << std::endl;
+            status |= DUMP_BINDERIZED_ERROR;
+            continue;
+        }
+        sp<IBase> service = getRet;
+        if (service == nullptr) {
+            mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                 << "cannot be fetched from service manager (null)";
+            status |= DUMP_BINDERIZED_ERROR;
+            continue;
+        }
+        auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &debugInfo) {
+            allDebugInfos[fqInstanceName] = debugInfo;
+            if (debugInfo.pid >= 0) {
+                allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+            }
+        });
+        if (!debugRet.isOk()) {
+            mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                 << "debugging information cannot be retrieved:"
+                 << debugRet.description() << std::endl;
+            status |= DUMP_BINDERIZED_ERROR;
+        }
+    }
+    for (auto &pair : allPids) {
+        pid_t serverPid = pair.first;
+        if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+            mErr << "Warning: no information for PID " << serverPid
+                      << ", are you root?" << std::endl;
+            status |= DUMP_BINDERIZED_ERROR;
+        }
+    }
+    for (const auto &fqInstanceName : fqInstanceNames) {
+        auto it = allDebugInfos.find(fqInstanceName);
+        if (it == allDebugInfos.end()) {
+            putEntry({
+                .interfaceName = fqInstanceName,
+                .transport = mode,
+                .serverPid = NO_PID,
+                .serverObjectAddress = NO_PTR,
+                .clientPids = {},
+                .source = HWSERVICEMANAGER_LIST
+            });
+            continue;
+        }
+        const DebugInfo &info = it->second;
+        putEntry({
+            .interfaceName = fqInstanceName,
+            .transport = mode,
+            .serverPid = info.pid,
+            .serverObjectAddress = info.ptr,
+            .clientPids = info.pid == NO_PID || info.ptr == NO_PTR
+                    ? Pids{} : allPids[info.pid][info.ptr],
+            .source = HWSERVICEMANAGER_LIST
+        });
     }
     return status;
 }
@@ -367,7 +472,7 @@
         << "           Dump all hals with default ordering and columns [-itpc]." << std::endl
         << "       lshal [--interface|-i] [--transport|-t]" << std::endl
         << "             [--pid|-p] [--address|-a] [--clients|-c] [--cmdline|-m]" << std::endl
-        << "             [--sort={interface|i|pid|p}]" << std::endl
+        << "             [--sort={interface|i|pid|p}] [--init-vintf[=path]]" << std::endl
         << "           -i, --interface: print the interface name column" << std::endl
         << "           -n, --instance: print the instance name column" << std::endl
         << "           -t, --transport: print the transport mode column" << std::endl
@@ -378,6 +483,8 @@
         << "           -m, --cmdline: print cmdline instead of PIDs" << std::endl
         << "           --sort=i, --sort=interface: sort by interface name" << std::endl
         << "           --sort=p, --sort=pid: sort by server pid" << std::endl
+        << "           --init-vintf=path: form a skeleton HAL manifest to specified file " << std::endl
+        << "                         (stdout if no file specified)" << std::endl
         << "       lshal [-h|--help]" << std::endl
         << "           -h, --help: show this help information." << std::endl;
 }
@@ -395,6 +502,7 @@
 
         // long options without short alternatives
         {"sort",      required_argument, 0, 's' },
+        {"init-vintf",optional_argument, 0, 'v' },
         { 0,          0,                 0,  0  }
     };
 
@@ -420,6 +528,17 @@
             }
             break;
         }
+        case 'v': {
+            if (optarg) {
+                mFileOutput = new std::ofstream{optarg};
+                mOut = mFileOutput;
+                if (!mFileOutput.buf().is_open()) {
+                    mErr << "Could not open file '" << optarg << "'." << std::endl;
+                    return IO_ERROR;
+                }
+            }
+            mVintf = true;
+        }
         case 'i': {
             mSelectedColumns |= ENABLE_INTERFACE_NAME;
             break;
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index ead99dc..1c30908 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -19,12 +19,13 @@
 
 #include <stdint.h>
 
-#include <iostream>
+#include <fstream>
 #include <string>
 #include <vector>
 
 #include <android/hidl/manager/1.0/IServiceManager.h>
 
+#include "NullableOStream.h"
 #include "TableEntry.h"
 
 namespace android {
@@ -38,6 +39,7 @@
     DUMP_BINDERIZED_ERROR                   = 1 << 3,
     DUMP_PASSTHROUGH_ERROR                  = 1 << 4,
     DUMP_ALL_LIBS_ERROR                     = 1 << 5,
+    IO_ERROR                                = 1 << 6,
 };
 using Status = unsigned int;
 
@@ -49,7 +51,7 @@
     Status parseArgs(int argc, char **argv);
     Status fetch();
     void postprocess();
-    void dump() const;
+    void dump();
     void usage() const;
     void putEntry(TableEntry &&entry);
     Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
@@ -57,6 +59,8 @@
     Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
     bool getReferencedPids(
         pid_t serverPid, std::map<uint64_t, Pids> *objects) const;
+    void dumpTable() const;
+    void dumpVintf() const;
     void printLine(
             const std::string &interfaceName,
             const std::string &transport, const std::string &server,
@@ -70,12 +74,14 @@
     void removeDeadProcesses(Pids *pids);
 
     Table mTable{};
-    std::ostream &mErr = std::cerr;
-    std::ostream &mOut = std::cout;
+    NullableOStream<std::ostream> mErr = std::cerr;
+    NullableOStream<std::ostream> mOut = std::cout;
+    NullableOStream<std::ofstream> mFileOutput = nullptr;
     TableEntryCompare mSortColumn = nullptr;
     TableEntrySelect mSelectedColumns = 0;
     // If true, cmdlines will be printed instead of pid.
-    bool mEnableCmdlines;
+    bool mEnableCmdlines = false;
+    bool mVintf = false;
     // If an entry does not exist, need to ask /proc/{pid}/cmdline to get it.
     // If an entry exist but is an empty string, process might have died.
     // If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline.
diff --git a/cmds/lshal/NullableOStream.h b/cmds/lshal/NullableOStream.h
new file mode 100644
index 0000000..ab37a04
--- /dev/null
+++ b/cmds/lshal/NullableOStream.h
@@ -0,0 +1,73 @@
+/*
+ * 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_CMDS_LSHAL_NULLABLE_O_STREAM_H_
+#define FRAMEWORK_NATIVE_CMDS_LSHAL_NULLABLE_O_STREAM_H_
+
+#include <iostream>
+
+namespace android {
+namespace lshal {
+
+template<typename S>
+class NullableOStream {
+public:
+    NullableOStream(S &os) : mOs(&os) {}
+    NullableOStream(S *os) : mOs(os) {}
+    NullableOStream &operator=(S &os) {
+        mOs = &os;
+        return *this;
+    }
+    NullableOStream &operator=(S *os) {
+        mOs = os;
+        return *this;
+    }
+    template<typename Other>
+    NullableOStream &operator=(const NullableOStream<Other> &other) {
+        mOs = other.mOs;
+        return *this;
+    }
+
+    const NullableOStream &operator<<(std::ostream& (*pf)(std::ostream&)) const {
+        if (mOs) {
+            (*mOs) << pf;
+        }
+        return *this;
+    }
+    template<typename T>
+    const NullableOStream &operator<<(const T &rhs) const {
+        if (mOs) {
+            (*mOs) << rhs;
+        }
+        return *this;
+    }
+    S& buf() const {
+        return *mOs;
+    }
+    operator bool() const {
+        return mOs != nullptr;
+    }
+private:
+    template<typename>
+    friend class NullableOStream;
+
+    S *mOs = nullptr;
+};
+
+}  // namespace lshal
+}  // namespace android
+
+#endif  // FRAMEWORK_NATIVE_CMDS_LSHAL_NULLABLE_O_STREAM_H_
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 4ec3a0c..e55806e 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -28,6 +28,13 @@
 
 using Pids = std::vector<int32_t>;
 
+enum : unsigned int {
+    HWSERVICEMANAGER_LIST, // through defaultServiceManager()->list()
+    PTSERVICEMANAGER_REG_CLIENT, // through registerPassthroughClient
+    LIST_DLLIB, // through listing dynamic libraries
+};
+using TableEntrySource = unsigned int;
+
 struct TableEntry {
     std::string interfaceName;
     std::string transport;
@@ -36,6 +43,7 @@
     uint64_t serverObjectAddress;
     Pids clientPids;
     std::vector<std::string> clientCmdlines;
+    TableEntrySource source;
 
     static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
         return a.interfaceName < b.interfaceName;
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index a49da37..35b63ec 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -22,8 +22,6 @@
 
 #include <android-base/file.h>
 
-#include <binder/IMemory.h>
-
 #include <gui/BufferQueue.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 4a00818..a5e5c05 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -56,6 +56,7 @@
 extern "C" {
 #endif
 
+typedef struct AHardwareBuffer AHardwareBuffer;
 
 /**
  * Sensor types.
@@ -144,6 +145,30 @@
     AREPORTING_MODE_SPECIAL_TRIGGER = 3
 };
 
+/**
+ * Sensor Direct Report Rates.
+ */
+enum {
+    /** stopped */
+    ASENSOR_DIRECT_RATE_STOP = 0,
+    /** nominal 50Hz */
+    ASENSOR_DIRECT_RATE_NORMAL = 1,
+    /** nominal 200Hz */
+    ASENSOR_DIRECT_RATE_FAST = 2,
+    /** nominal 800Hz */
+    ASENSOR_DIRECT_RATE_VERY_FAST = 3
+};
+
+/**
+ * Sensor Direct Channel Type.
+ */
+enum {
+    /** shared memory created by ASharedMemory_create */
+    ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY = 1,
+    /** AHardwareBuffer */
+    ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER = 2
+};
+
 /*
  * A few useful constants
  */
@@ -391,6 +416,97 @@
  */
 int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);
 
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Create direct channel based on shared memory
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY} to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param fd      file descriptor representing a shared memory created by
+ *                {@link ASharedMemory_create}
+ * \param size    size to be used, must be less or equal to size of shared memory.
+ *
+ * \return a positive integer as a channel id to be used in
+ *         {@link ASensorManager_destroyDirectChannel} and
+ *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createSharedMemoryDirectChannel(ASensorManager* manager, int fd, size_t size);
+
+/**
+ * Create direct channel based on AHardwareBuffer
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER} type to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param buffer  {@link AHardwareBuffer} instance created by {@link AHardwareBuffer_allocate}.
+ * \param size    the intended size to be used, must be less or equal to size of buffer.
+ *
+ * \return a positive integer as a channel id to be used in
+ *         {@link ASensorManager_destroyDirectChannel} and
+ *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createHardwareBufferDirectChannel(
+        ASensorManager* manager, AHardwareBuffer const * buffer, size_t size);
+
+/**
+ * Destroy a direct channel
+ *
+ * Destroy a direct channel previously created using {@link ASensorManager_createDirectChannel}.
+ * The buffer used for creating direct channel does not get destroyed with
+ * {@link ASensorManager_destroy} and has to be close or released separately.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param channelId channel id (a positive integer) returned from
+ *                  {@link ASensorManager_createSharedMemoryDirectChannel} or
+ *                  {@link ASensorManager_createHardwareBufferDirectChannel}.
+ */
+void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId);
+
+/**
+ * Configure direct report on channel
+ *
+ * Configure sensor direct report on a direct channel: set rate to value other than
+ * {@link ASENSOR_DIRECT_RATE_STOP} so that sensor event can be directly
+ * written into the shared memory region used for creating the buffer; set rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP} will stop the sensor direct report.
+ *
+ * To stop all active sensor direct report configured to a channel, set sensor to NULL and rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP}.
+ *
+ * In order to successfully configure a direct report, the sensor has to support the specified rate
+ * and the channel type, which can be checked by {@link ASensor_getHighestDirectReportRateLevel} and
+ * {@link ASensor_isDirectChannelTypeSupported}, respectively.
+ *
+ * Example:
+ * \code{.cpp}
+ *      ASensorManager *manager = ...;
+ *      ASensor *sensor = ...;
+ *      int channelId = ...;
+ *
+ *      ASensorManager_configureDirectReport(
+ *              manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
+ * \endcode
+ *
+ * \param manager   the {@link ASensorManager} instance obtained from
+ *                  {@link ASensorManager_getInstanceForPackage}.
+ * \param sensor    a {@link ASensor} to denote which sensor to be operate. It can be NULL if rate
+ *                  is {@link ASENSOR_DIRECT_RATE_STOP}, denoting stopping of all active sensor
+ *                  direct report.
+ * \param channelId channel id (a positive integer) returned from
+ *                  {@link ASensorManager_createSharedMemoryDirectChannel} or
+ *                  {@link ASensorManager_createHardwareBufferDirectChannel}.
+ *
+ * \return 0 for success or negative integer for failure.
+ */
+int ASensorManager_configureDirectReport(
+        ASensorManager* manager, ASensor const* sensor, int channelId, int rate);
+#endif
 
 /*****************************************************************************/
 
@@ -502,6 +618,29 @@
 bool ASensor_isWakeUpSensor(ASensor const* sensor);
 #endif /* __ANDROID_API__ >= 21 */
 
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Test if sensor supports a certain type of direct channel.
+ *
+ * \param sensor  a {@link ASensor} to denote the sensor to be checked.
+ * \param channelType  Channel type constant, either
+ *                     {@ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY}
+ *                     or {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER}.
+ * \returns true if sensor supports the specified direct channel type.
+ */
+bool ASensor_isDirectChannelTypeSupported(ASensor const* sensor, int channelType);
+/**
+ * Get the highest direct rate level that a sensor support.
+ *
+ * \param sensor  a {@link ASensor} to denote the sensor to be checked.
+ *
+ * \return a ASENSOR_DIRECT_RATE_... enum denoting the highest rate level supported by the sensor.
+ *         If return value is {@link ASENSOR_DIRECT_RATE_STOP}, it means the sensor
+ *         does not support direct report.
+ */
+int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor);
+#endif
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 8302160..1e8cf76 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <binder/IBinder.h>
-#include <binder/IMemory.h>
 
 #include <utils/RefBase.h>
 #include <utils/Singleton.h>
@@ -148,7 +147,7 @@
     status_t    setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent);
     status_t    setLayer(const sp<IBinder>& id, int32_t layer);
     status_t    setAlpha(const sp<IBinder>& id, float alpha=1.0f);
-    status_t    setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy);
+    status_t    setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dtdy, float dsdy);
     status_t    setPosition(const sp<IBinder>& id, float x, float y);
     status_t    setSize(const sp<IBinder>& id, uint32_t w, uint32_t h);
     status_t    setCrop(const sp<IBinder>& id, const Rect& crop);
@@ -156,8 +155,11 @@
     status_t    setLayerStack(const sp<IBinder>& id, uint32_t layerStack);
     status_t    deferTransactionUntil(const sp<IBinder>& id,
             const sp<IBinder>& handle, uint64_t frameNumber);
+    status_t    deferTransactionUntil(const sp<IBinder>& id,
+            const sp<Surface>& handle, uint64_t frameNumber);
     status_t    reparentChildren(const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t    detachChildren(const sp<IBinder>& id);
     status_t    setOverrideScalingMode(const sp<IBinder>& id,
             int32_t overrideScalingMode);
     status_t    setGeometryAppliesWithResize(const sp<IBinder>& id);
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 54c8fa9..8ee35bc 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -69,7 +69,7 @@
     status_t    setFlags(uint32_t flags, uint32_t mask);
     status_t    setTransparentRegionHint(const Region& transparent);
     status_t    setAlpha(float alpha=1.0f);
-    status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
+    status_t    setMatrix(float dsdx, float dtdx, float dtdy, float dsdy);
     status_t    setCrop(const Rect& crop);
     status_t    setFinalCrop(const Rect& crop);
 
@@ -80,11 +80,31 @@
     status_t    setGeometryAppliesWithResize();
 
     // Defers applying any changes made in this transaction until the Layer
-    // identified by handle reaches the given frameNumber
+    // identified by handle reaches the given frameNumber. If the Layer identified
+    // by handle is removed, then we will apply this transaction regardless of
+    // what frame number has been reached.
     status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+
+    // A variant of deferTransactionUntil which identifies the Layer we wait for by
+    // Surface instead of Handle. Useful for clients which may not have the
+    // SurfaceControl for some of their Surfaces. Otherwise behaves identically.
+    status_t deferTransactionUntil(const sp<Surface>& barrier, uint64_t frameNumber);
+
     // Reparents all children of this layer to the new parent handle.
     status_t reparentChildren(const sp<IBinder>& newParentHandle);
 
+    // Detaches all child surfaces (and their children recursively)
+    // from their SurfaceControl.
+    // The child SurfaceControl's will not throw exceptions or return errors,
+    // but transactions will have no effect.
+    // The child surfaces will continue to follow their parent surfaces,
+    // and remain eligible for rendering, but their relative state will be
+    // frozen. We use this in the WindowManager, in app shutdown/relaunch
+    // scenarios, where the app would otherwise clean up its child Surfaces.
+    // Sometimes the WindowManager needs to extend their lifetime slightly
+    // in order to perform an exit animation or prevent flicker.
+    status_t detachChildren();
+
     // Set an override scaling mode as documented in <system/window.h>
     // the override scaling mode will take precedence over any client
     // specified scaling mode. -1 will clear the override scaling mode.
diff --git a/include/private/binder/Static.h b/include/private/binder/Static.h
index d104646..3d10456 100644
--- a/include/private/binder/Static.h
+++ b/include/private/binder/Static.h
@@ -20,7 +20,6 @@
 #include <utils/threads.h>
 
 #include <binder/IBinder.h>
-#include <binder/IMemory.h>
 #include <binder/ProcessState.h>
 #include <binder/IPermissionController.h>
 #include <binder/IServiceManager.h>
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 2a1801b..20f51a5 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -24,6 +24,7 @@
 
 #include <ui/Region.h>
 #include <ui/Rect.h>
+#include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
@@ -57,6 +58,7 @@
         eOverrideScalingModeChanged = 0x00000800,
         eGeometryAppliesWithResize  = 0x00001000,
         eReparentChildren           = 0x00002000,
+        eDetachChildren             = 0x00004000
     };
 
     layer_state_t()
@@ -77,8 +79,8 @@
             struct matrix22_t {
                 float   dsdx{0};
                 float   dtdx{0};
-                float   dsdy{0};
                 float   dtdy{0};
+                float   dsdy{0};
             };
             sp<IBinder>     surface;
             uint32_t        what;
@@ -95,10 +97,13 @@
             matrix22_t      matrix;
             Rect            crop;
             Rect            finalCrop;
-            sp<IBinder>     handle;
+            sp<IBinder>     barrierHandle;
             sp<IBinder>     reparentHandle;
             uint64_t        frameNumber;
             int32_t         overrideScalingMode;
+
+            sp<IGraphicBufferProducer> barrierGbp;
+
             // non POD must be last. see write/read
             Region          transparentRegion;
 };
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 06d1261..4d2692f 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <binder/Parcel.h>
-#include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 5a3fa04..db8a517 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -22,7 +22,6 @@
 #include <sys/types.h>
 
 #include <binder/Parcel.h>
-#include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index bb552aa..2461cba 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -39,10 +39,11 @@
             output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
     output.write(crop);
     output.write(finalCrop);
-    output.writeStrongBinder(handle);
+    output.writeStrongBinder(barrierHandle);
     output.writeStrongBinder(reparentHandle);
     output.writeUint64(frameNumber);
     output.writeInt32(overrideScalingMode);
+    output.writeStrongBinder(IInterface::asBinder(barrierGbp));
     output.write(transparentRegion);
     return NO_ERROR;
 }
@@ -68,10 +69,12 @@
     }
     input.read(crop);
     input.read(finalCrop);
-    handle = input.readStrongBinder();
+    barrierHandle = input.readStrongBinder();
     reparentHandle = input.readStrongBinder();
     frameNumber = input.readUint64();
     overrideScalingMode = input.readInt32();
+    barrierGbp =
+        interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
     input.read(transparentRegion);
     return NO_ERROR;
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index ae81c8f..088933a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -26,7 +26,6 @@
 #include <utils/String8.h>
 #include <utils/threads.h>
 
-#include <binder/IMemory.h>
 #include <binder/IServiceManager.h>
 
 #include <system/graphics.h>
@@ -38,6 +37,7 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 
 #include <private/gui/ComposerService.h>
@@ -157,7 +157,7 @@
     status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
             float alpha);
     status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
-            float dsdx, float dtdx, float dsdy, float dtdy);
+            float dsdx, float dtdx, float dtdy, float dsdy);
     status_t setOrientation(int orientation);
     status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
             const Rect& crop);
@@ -168,9 +168,14 @@
     status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, const sp<IBinder>& handle,
             uint64_t frameNumber);
+    status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id, const sp<Surface>& barrierSurface,
+            uint64_t frameNumber);
     status_t reparentChildren(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t detachChildren(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id);
     status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, int32_t overrideScalingMode);
     status_t setGeometryAppliesWithResize(const sp<SurfaceComposerClient>& client,
@@ -392,7 +397,7 @@
 
 status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id, float dsdx, float dtdx,
-        float dsdy, float dtdy) {
+        float dtdy, float dsdy) {
     Mutex::Autolock _l(mLock);
     layer_state_t* s = getLayerStateLocked(client, id);
     if (!s)
@@ -439,7 +444,21 @@
         return BAD_INDEX;
     }
     s->what |= layer_state_t::eDeferTransaction;
-    s->handle = handle;
+    s->barrierHandle = handle;
+    s->frameNumber = frameNumber;
+    return NO_ERROR;
+}
+
+status_t Composer::deferTransactionUntil(
+        const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+        const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eDeferTransaction;
+    s->barrierGbp = barrierSurface->getIGraphicBufferProducer();
     s->frameNumber = frameNumber;
     return NO_ERROR;
 }
@@ -458,6 +477,18 @@
     return NO_ERROR;
 }
 
+status_t Composer::detachChildren(
+        const sp<SurfaceComposerClient>& client,
+        const sp<IBinder>& id) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eDetachChildren;
+    return NO_ERROR;
+}
+
 status_t Composer::setOverrideScalingMode(
         const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id, int32_t overrideScalingMode) {
@@ -768,8 +799,8 @@
 }
 
 status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx,
-        float dsdy, float dtdy) {
-    return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
+        float dtdy, float dsdy) {
+    return getComposer().setMatrix(this, id, dsdx, dtdx, dtdy, dsdy);
 }
 
 status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
@@ -777,11 +808,20 @@
     return getComposer().deferTransactionUntil(this, id, handle, frameNumber);
 }
 
+status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
+        const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+    return getComposer().deferTransactionUntil(this, id, barrierSurface, frameNumber);
+}
+
 status_t SurfaceComposerClient::reparentChildren(const sp<IBinder>& id,
         const sp<IBinder>& newParentHandle) {
     return getComposer().reparentChildren(this, id, newParentHandle);
 }
 
+status_t SurfaceComposerClient::detachChildren(const sp<IBinder>& id) {
+    return getComposer().detachChildren(this, id);
+}
+
 status_t SurfaceComposerClient::setOverrideScalingMode(
         const sp<IBinder>& id, int32_t overrideScalingMode) {
     return getComposer().setOverrideScalingMode(
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 0362216..1e69379 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -147,10 +147,10 @@
     if (err < 0) return err;
     return mClient->setAlpha(mHandle, alpha);
 }
-status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
     status_t err = validate();
     if (err < 0) return err;
-    return mClient->setMatrix(mHandle, dsdx, dtdx, dsdy, dtdy);
+    return mClient->setMatrix(mHandle, dsdx, dtdx, dtdy, dsdy);
 }
 status_t SurfaceControl::setCrop(const Rect& crop) {
     status_t err = validate();
@@ -170,12 +170,25 @@
     return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
 }
 
+status_t SurfaceControl::deferTransactionUntil(const sp<Surface>& handle,
+        uint64_t frameNumber) {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
+}
+
 status_t SurfaceControl::reparentChildren(const sp<IBinder>& newParentHandle) {
     status_t err = validate();
     if (err < 0) return err;
     return mClient->reparentChildren(mHandle, newParentHandle);
 }
 
+status_t SurfaceControl::detachChildren() {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->detachChildren(mHandle);
+}
+
 status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) {
     status_t err = validate();
     if (err < 0) return err;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ceeb90a..012dbe7 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -18,7 +18,6 @@
 
 #include <gtest/gtest.h>
 
-#include <binder/IMemory.h>
 #include <binder/ProcessState.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/ISurfaceComposer.h>
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index b4b5303..3fbab17 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -57,7 +57,8 @@
 
     uint64_t producerUsage = 0;
     uint64_t consumerUsage = 0;
-    AHardwareBuffer_convertToGrallocUsageBits(desc->usage0, &producerUsage, &consumerUsage);
+    AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, desc->usage0,
+            desc->usage1);
 
     sp<GraphicBuffer> gbuffer(new GraphicBuffer(
             desc->width, desc->height, format, desc->layers, producerUsage, consumerUsage,
@@ -97,9 +98,8 @@
     outDesc->width = gbuffer->getWidth();
     outDesc->height = gbuffer->getHeight();
     outDesc->layers = gbuffer->getLayerCount();
-    outDesc->usage0 = AHardwareBuffer_convertFromGrallocUsageBits(
+    AHardwareBuffer_convertFromGrallocUsageBits(&outDesc->usage0, &outDesc->usage1,
             gbuffer->getUsage(), gbuffer->getUsage());
-    outDesc->usage1 = 0;
     outDesc->format = AHardwareBuffer_convertFromPixelFormat(
             static_cast<uint32_t>(gbuffer->getPixelFormat()));
 }
@@ -117,7 +117,7 @@
 
     uint64_t producerUsage = 0;
     uint64_t consumerUsage = 0;
-    AHardwareBuffer_convertToGrallocUsageBits(usage0, &producerUsage, &consumerUsage);
+    AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, usage0, 0);
     GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
     Rect bounds;
     if (!rect) {
@@ -268,8 +268,76 @@
 
 namespace android {
 
+// A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks.
+struct UsageMaskMapping {
+    uint64_t hardwareBufferMask;
+    uint64_t grallocMask;
+};
+
+static constexpr UsageMaskMapping kUsage0ProducerMapping[] = {
+    { AHARDWAREBUFFER_USAGE0_CPU_WRITE, GRALLOC1_PRODUCER_USAGE_CPU_WRITE },
+    { AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN },
+    { AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET },
+    { AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT, GRALLOC1_PRODUCER_USAGE_PROTECTED },
+    { AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA },
+};
+
+static constexpr UsageMaskMapping kUsage1ProducerMapping[] = {
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0, GRALLOC1_PRODUCER_USAGE_PRIVATE_0 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1, GRALLOC1_PRODUCER_USAGE_PRIVATE_1 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2, GRALLOC1_PRODUCER_USAGE_PRIVATE_2 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3, GRALLOC1_PRODUCER_USAGE_PRIVATE_3 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4, GRALLOC1_PRODUCER_USAGE_PRIVATE_4 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5, GRALLOC1_PRODUCER_USAGE_PRIVATE_5 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6, GRALLOC1_PRODUCER_USAGE_PRIVATE_6 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7, GRALLOC1_PRODUCER_USAGE_PRIVATE_7 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8, GRALLOC1_PRODUCER_USAGE_PRIVATE_8 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9, GRALLOC1_PRODUCER_USAGE_PRIVATE_9 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10, GRALLOC1_PRODUCER_USAGE_PRIVATE_10 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11, GRALLOC1_PRODUCER_USAGE_PRIVATE_11 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12, GRALLOC1_PRODUCER_USAGE_PRIVATE_12 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13, GRALLOC1_PRODUCER_USAGE_PRIVATE_13 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14, GRALLOC1_PRODUCER_USAGE_PRIVATE_14 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15, GRALLOC1_PRODUCER_USAGE_PRIVATE_15 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16, GRALLOC1_PRODUCER_USAGE_PRIVATE_16 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17, GRALLOC1_PRODUCER_USAGE_PRIVATE_17 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18, GRALLOC1_PRODUCER_USAGE_PRIVATE_18 },
+    { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19, GRALLOC1_PRODUCER_USAGE_PRIVATE_19 },
+};
+
+static constexpr UsageMaskMapping kUsage0ConsumerMapping[] = {
+    { AHARDWAREBUFFER_USAGE0_CPU_READ, GRALLOC1_CONSUMER_USAGE_CPU_READ },
+    { AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN },
+    { AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE },
+    { AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER },
+    { AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER },
+};
+
+static constexpr UsageMaskMapping kUsage1ConsumerMapping[] = {
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0, GRALLOC1_CONSUMER_USAGE_PRIVATE_0 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1, GRALLOC1_CONSUMER_USAGE_PRIVATE_1 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2, GRALLOC1_CONSUMER_USAGE_PRIVATE_2 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3, GRALLOC1_CONSUMER_USAGE_PRIVATE_3 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4, GRALLOC1_CONSUMER_USAGE_PRIVATE_4 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5, GRALLOC1_CONSUMER_USAGE_PRIVATE_5 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6, GRALLOC1_CONSUMER_USAGE_PRIVATE_6 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7, GRALLOC1_CONSUMER_USAGE_PRIVATE_7 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8, GRALLOC1_CONSUMER_USAGE_PRIVATE_8 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9, GRALLOC1_CONSUMER_USAGE_PRIVATE_9 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10, GRALLOC1_CONSUMER_USAGE_PRIVATE_10 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11, GRALLOC1_CONSUMER_USAGE_PRIVATE_11 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12, GRALLOC1_CONSUMER_USAGE_PRIVATE_12 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13, GRALLOC1_CONSUMER_USAGE_PRIVATE_13 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14, GRALLOC1_CONSUMER_USAGE_PRIVATE_14 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15, GRALLOC1_CONSUMER_USAGE_PRIVATE_15 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16, GRALLOC1_CONSUMER_USAGE_PRIVATE_16 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17, GRALLOC1_CONSUMER_USAGE_PRIVATE_17 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18, GRALLOC1_CONSUMER_USAGE_PRIVATE_18 },
+    { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19, GRALLOC1_CONSUMER_USAGE_PRIVATE_19 },
+};
+
 static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
-    return (mask & bitsToCheck) == bitsToCheck;
+    return (mask & bitsToCheck) == bitsToCheck && bitsToCheck;
 }
 
 uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) {
@@ -300,58 +368,56 @@
     }
 }
 
-void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage, uint64_t* outProducerUsage,
-        uint64_t* outConsumerUsage) {
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
+    uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1) {
     *outProducerUsage = 0;
     *outConsumerUsage = 0;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ))
-        *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN))
-        *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE))
-        *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN))
-        *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE))
-        *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT))
-        *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
-    // Not sure what this should be.
-    //if (containsBits(usage0, AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP)) bits |= 0;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER))
-        *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE))
-        *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT))
-        *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
-    if (containsBits(usage, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA))
-        *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA;
+    for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
+        if (containsBits(usage0, mapping.hardwareBufferMask)) {
+            *outProducerUsage |= mapping.grallocMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
+        if (containsBits(usage1, mapping.hardwareBufferMask)) {
+            *outProducerUsage |= mapping.grallocMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
+        if (containsBits(usage0, mapping.hardwareBufferMask)) {
+            *outConsumerUsage |= mapping.grallocMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
+        if (containsBits(usage1, mapping.hardwareBufferMask)) {
+            *outConsumerUsage |= mapping.grallocMask;
+        }
+    }
 }
 
-uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t producerUsage, uint64_t consumerUsage) {
-    uint64_t bits = 0;
-    if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ))
-        bits |= AHARDWAREBUFFER_USAGE0_CPU_READ;
-    if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
-        bits |= AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN;
-    if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE))
-        bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE;
-    if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN))
-        bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN;
-    if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE))
-        bits |= AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE;
-    if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))
-        bits |= AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT;
-    if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER))
-        bits |= AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER;
-    if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER))
-        bits |= AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE;
-    if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_PROTECTED))
-        bits |= AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT;
-    if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA))
-        bits |= AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA;
-
-    return bits;
+void AHardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0, uint64_t* outUsage1,
+        uint64_t producerUsage, uint64_t consumerUsage) {
+    *outUsage0 = 0;
+    *outUsage1 = 0;
+    for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
+        if (containsBits(producerUsage, mapping.grallocMask)) {
+            *outUsage0 |= mapping.hardwareBufferMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
+        if (containsBits(producerUsage, mapping.grallocMask)) {
+            *outUsage1 |= mapping.hardwareBufferMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
+        if (containsBits(consumerUsage, mapping.grallocMask)) {
+            *outUsage0 |= mapping.hardwareBufferMask;
+        }
+    }
+    for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
+        if (containsBits(consumerUsage, mapping.grallocMask)) {
+            *outUsage1 |= mapping.hardwareBufferMask;
+        }
+    }
 }
 
 const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 46e5d50..9c5f096 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -13,13 +13,21 @@
 // limitations under the License.
 
 ndk_headers {
-    name: "libnativewindwow_headers",
+    name: "libnativewindow_headers",
     from: "include/android",
     to: "android",
     srcs: ["include/android/*.h"],
     license: "NOTICE",
 }
 
+ndk_library {
+    name: "libnativewindow.ndk",
+    symbol_file: "libnativewindow.map.txt",
+
+    // Android O
+    first_version: "26",
+}
+
 cc_library {
     name: "libnativewindow",
     export_include_dirs: ["include"],
@@ -48,3 +56,5 @@
         "libarect",
     ],
 }
+
+subdirs = ["tests"]
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 9c08c7b..ef49995 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -97,10 +97,6 @@
     AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE      = 1ULL << 10,
     /* The buffer will be written to by the GPU */
     AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT       = 1ULL << 11,
-    /* The buffer will be read from and written to by the GPU */
-    AHARDWAREBUFFER_USAGE0_GPU_STORAGE_IMAGE      =
-            AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE |
-            AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT,
     /* The buffer will be used as a cubemap texture */
     AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP            = 1ULL << 13,
     /* The buffer will be used as a shader storage or uniform buffer object*/
@@ -113,13 +109,57 @@
     AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE           = 1ULL << 21,
 };
 
+/* These flags are intended only for use by device-specific graphics drivers. */
+enum {
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19 = 1ULL << 24,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19 = 1ULL << 25,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18 = 1ULL << 26,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18 = 1ULL << 27,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17 = 1ULL << 28,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17 = 1ULL << 29,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16 = 1ULL << 30,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16 = 1ULL << 31,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15 = 1ULL << 32,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15 = 1ULL << 33,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14 = 1ULL << 34,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14 = 1ULL << 35,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13 = 1ULL << 36,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13 = 1ULL << 37,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12 = 1ULL << 38,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12 = 1ULL << 39,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11 = 1ULL << 40,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11 = 1ULL << 41,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10 = 1ULL << 42,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10 = 1ULL << 43,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9 = 1ULL << 44,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9 = 1ULL << 45,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8 = 1ULL << 46,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8 = 1ULL << 47,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7 = 1ULL << 48,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7 = 1ULL << 49,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6 = 1ULL << 50,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6 = 1ULL << 51,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5 = 1ULL << 52,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5 = 1ULL << 53,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4 = 1ULL << 54,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4 = 1ULL << 55,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3 = 1ULL << 56,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3 = 1ULL << 57,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2 = 1ULL << 58,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2 = 1ULL << 59,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1 = 1ULL << 60,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1 = 1ULL << 61,
+    AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0 = 1ULL << 62,
+    AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0 = 1ULL << 63,
+};
+
 typedef struct AHardwareBuffer_Desc {
     uint32_t    width;
     uint32_t    height;
     uint32_t    layers;
+    uint32_t    format;     // One of AHARDWAREBUFFER_FORMAT_*
     uint64_t    usage0;     // Combination of AHARDWAREBUFFER_USAGE0_*
     uint64_t    usage1;     // Initialize to zero, reserved for future use
-    uint32_t    format;     // One of AHARDWAREBUFFER_FORMAT_*
 } AHardwareBuffer_Desc;
 
 typedef struct AHardwareBuffer AHardwareBuffer;
diff --git a/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
index f138fa7..612ee80 100644
--- a/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
@@ -18,11 +18,11 @@
 #define ANDROID_PRIVATE_NATIVE_AHARDWARE_BUFFER_HELPERS_H
 
 /*
- * This file contains utility functions related to AHardwareBuffer, mostly to convert
- * to/from HAL formats.
+ * This file contains utility functions related to AHardwareBuffer, mostly to
+ * convert to/from HAL formats.
  *
- * These are PRIVATE methods, so this file can NEVER appear in a public NDK header.
- * They are used by higher level libraries such as core/jni.
+ * These are PRIVATE methods, so this file can NEVER appear in a public NDK
+ * header. They are used by higher level libraries such as core/jni.
  */
 
 #include <stdint.h>
@@ -35,12 +35,11 @@
 
 uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format);
 
-void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage,
-        uint64_t* outProducerUsage, uint64_t* outConsumerUsage);
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
+    uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1);
 
-uint64_t AHardwareBuffer_convertFromGrallocUsageBits(
-        uint64_t producerUsage, uint64_t consumerUsage);
-
+void AHardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0, uint64_t* outUsage1,
+    uint64_t producerUsage, uint64_t consumerUsage);
 
 class GraphicBuffer;
 const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer);
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
new file mode 100644
index 0000000..dcfabac
--- /dev/null
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -0,0 +1,26 @@
+LIBNATIVEWINDOW {
+  global:
+    AHardwareBuffer_acquire;
+    AHardwareBuffer_allocate;
+    AHardwareBuffer_describe;
+    AHardwareBuffer_fromHardwareBuffer;
+    AHardwareBuffer_getNativeHandle;
+    AHardwareBuffer_lock;
+    AHardwareBuffer_recvHandleFromUnixSocket;
+    AHardwareBuffer_release;
+    AHardwareBuffer_sendHandleToUnixSocket;
+    AHardwareBuffer_toHardwareBuffer;
+    AHardwareBuffer_unlock;
+    ANativeWindow_acquire;
+    ANativeWindow_fromSurface;
+    ANativeWindow_fromSurfaceTexture;
+    ANativeWindow_getFormat;
+    ANativeWindow_getHeight;
+    ANativeWindow_getWidth;
+    ANativeWindow_lock;
+    ANativeWindow_release;
+    ANativeWindow_setBuffersGeometry;
+    ANativeWindow_unlockAndPost;
+  local:
+    *;
+};
diff --git a/libs/nativewindow/tests/AHardwareBufferTest.cpp b/libs/nativewindow/tests/AHardwareBufferTest.cpp
new file mode 100644
index 0000000..1099043
--- /dev/null
+++ b/libs/nativewindow/tests/AHardwareBufferTest.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHardwareBuffer_test"
+//#define LOG_NDEBUG 0
+
+#include <android/hardware_buffer.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <hardware/gralloc1.h>
+
+#include <gtest/gtest.h>
+
+using namespace android;
+
+static ::testing::AssertionResult BuildHexFailureMessage(uint64_t expected,
+        uint64_t actual, const char* type) {
+    std::ostringstream ss;
+    ss << type << " 0x" << std::hex << actual
+            << " does not match expected " << type << " 0x" << std::hex
+            << expected;
+    return ::testing::AssertionFailure() << ss.str();
+}
+
+static ::testing::AssertionResult TestUsageConversion(
+        uint64_t grallocProducerUsage, uint64_t grallocConsumerUsage,
+        uint64_t hardwareBufferUsage0, uint64_t hardwareBufferUsage1) {
+    uint64_t producerUsage = 0;
+    uint64_t consumerUsage = 0;
+    uint64_t usage0 = 0;
+    uint64_t usage1 = 0;
+
+    AHardwareBuffer_convertToGrallocUsageBits(
+            &producerUsage, &consumerUsage, hardwareBufferUsage0, hardwareBufferUsage1);
+    if (producerUsage != grallocProducerUsage)
+        return BuildHexFailureMessage(grallocProducerUsage, producerUsage,
+                "producer");
+    if (consumerUsage != grallocConsumerUsage)
+        return BuildHexFailureMessage(grallocConsumerUsage, consumerUsage,
+                "consumer");
+
+    AHardwareBuffer_convertFromGrallocUsageBits(
+            &usage0, &usage1, grallocProducerUsage, grallocConsumerUsage);
+    if (usage0 != hardwareBufferUsage0)
+        return BuildHexFailureMessage(hardwareBufferUsage0, usage0, "usage0");
+    if (usage1 != hardwareBufferUsage1)
+        return BuildHexFailureMessage(hardwareBufferUsage1, usage1, "usage1");
+
+    return testing::AssertionSuccess();
+}
+
+// This is a unit test rather than going through AHardwareBuffer because not
+// all flags may be supported by the host device.
+TEST(AHardwareBufferTest, ConvertToAndFromGrallocBits) {
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_CPU_READ,
+            AHARDWAREBUFFER_USAGE0_CPU_READ, 0));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
+            AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE, 0,
+            AHARDWAREBUFFER_USAGE0_CPU_WRITE, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, 0,
+            AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, 0));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE,
+            AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+            0, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT, 0));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+            AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PROTECTED, 0,
+            AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA,
+            0, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, 0));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+            AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE, 0));
+
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_0, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_1, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_2, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_3, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_4, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_5, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_6, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_7, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_8, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_9, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_10, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_11, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_12, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_13, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_14, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_15, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_16, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_17, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_18, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_19, 0,
+            0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_0,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_1,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_2,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_3,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_4,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_5,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_6,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_7,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_8,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_9,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_10,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_11,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_12,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_13,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_14,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_15,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_16,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_17,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_18,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18));
+    EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_19,
+            0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19));
+
+    // Test some more complex flag combinations.
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+            GRALLOC1_CONSUMER_USAGE_CPU_READ,
+            AHARDWAREBUFFER_USAGE0_CPU_READ | AHARDWAREBUFFER_USAGE0_CPU_WRITE,
+            0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, 0,
+            AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, 0));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+            GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE |
+                    GRALLOC1_CONSUMER_USAGE_PRIVATE_17,
+            AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT |
+                    AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE,
+            AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17));
+    EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA,
+            GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+            AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER |
+                    AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, 0));
+}
diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp
new file mode 100644
index 0000000..437ab75
--- /dev/null
+++ b/libs/nativewindow/tests/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2017 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_test {
+    name: "AHardwareBufferTest",
+    shared_libs: ["libnativewindow"],
+    srcs: ["AHardwareBufferTest.cpp"],
+}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 37ebfb3..c4d8f76 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -17,6 +17,9 @@
 #define LOG_TAG "GraphicBuffer"
 
 #include <ui/GraphicBuffer.h>
+
+#include <cutils/atomic.h>
+
 #include <ui/GrallocMapper.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/GraphicBufferMapper.h>
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 6733505..b55c212 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -25,3 +25,9 @@
     shared_libs: ["libui"],
     srcs: ["colorspace_test.cpp"],
 }
+
+cc_test {
+    name: "Gralloc1Mapper_test",
+    shared_libs: ["libui", "libutils"],
+    srcs: ["Gralloc1Mapper_test.cpp"],
+}
diff --git a/libs/ui/tests/Gralloc1Mapper_test.cpp b/libs/ui/tests/Gralloc1Mapper_test.cpp
new file mode 100644
index 0000000..b7c9f0f
--- /dev/null
+++ b/libs/ui/tests/Gralloc1Mapper_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc1Mapper_test"
+//#define LOG_NDEBUG 0
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/Errors.h>
+
+#include <gtest/gtest.h>
+
+using namespace android;
+
+class Gralloc1MapperTest : public ::testing::Test
+{
+public:
+    ~Gralloc1MapperTest() override = default;
+
+protected:
+    void SetUp() override {
+        buffer = new GraphicBuffer(4, 8, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+                GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
+                GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, "Gralloc1MapperTest");
+        ASSERT_NE(nullptr, buffer.get());
+
+        handle = static_cast<buffer_handle_t>(buffer->handle);
+
+        mapper = &GraphicBufferMapper::get();
+    }
+
+    sp<GraphicBuffer> buffer;
+    buffer_handle_t handle;
+    GraphicBufferMapper* mapper;
+};
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getDimensions) {
+    uint32_t width = 0;
+    uint32_t height = 0;
+    status_t err = mapper->getDimensions(handle, &width, &height);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+    EXPECT_EQ(4U, width);
+    EXPECT_EQ(8U, height);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getFormat) {
+    int32_t value = 0;
+    status_t err = mapper->getFormat(handle, &value);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+    EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getLayerCount) {
+    uint32_t value = 0;
+    status_t err = mapper->getLayerCount(handle, &value);
+    if (err != GRALLOC1_ERROR_UNSUPPORTED) {
+        EXPECT_EQ(1U, value);
+    }
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getProducerUsage) {
+    uint64_t value = 0;
+    status_t err = mapper->getProducerUsage(handle, &value);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+    EXPECT_EQ(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getConsumerUsage) {
+    uint64_t value = 0;
+    status_t err = mapper->getConsumerUsage(handle, &value);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+    EXPECT_EQ(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getBackingStore) {
+    uint64_t value = 0;
+    status_t err = mapper->getBackingStore(handle, &value);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getStride) {
+    uint32_t value = 0;
+    status_t err = mapper->getStride(handle, &value);
+    ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+    // The stride should be at least the width of the buffer.
+    EXPECT_LE(4U, value);
+}
diff --git a/libs/vr/libeds/Android.mk b/libs/vr/libeds/Android.mk
index fd2c56e..d2e6526 100644
--- a/libs/vr/libeds/Android.mk
+++ b/libs/vr/libeds/Android.mk
@@ -37,7 +37,6 @@
 	libGLESv1_CM \
 	libGLESv2 \
 	libvulkan \
-	libandroid
 
 staticLibraries := \
 	libdisplay \
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index b1ca13d..9aedc61 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -17,26 +17,21 @@
 //#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <array>
-#include <ctype.h>
+#include "Loader.h"
+
 #include <dirent.h>
 #include <dlfcn.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 
 #include <android/dlext.h>
 #include <cutils/properties.h>
 #include <log/log.h>
+
+#include <utils/String8.h>
 #include <utils/Trace.h>
+
 #include <ui/GraphicsEnv.h>
 
-#include <EGL/egl.h>
-
 #include "egldefs.h"
-#include "Loader.h"
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -437,10 +432,10 @@
     return android_dlopen_ext(path, mode, info);
 }
 
-static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
+static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
     "ro.hardware.egl",
     "ro.board.platform",
-}};
+};
 
 static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
     ATRACE_CALL();
@@ -454,10 +449,10 @@
         if (property_get(key, prop, nullptr) > 0) {
             String8 name;
             name.appendFormat("lib%s_%s.so", kind, prop);
-            so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW,
-                    &dlextinfo);
-            if (so)
+            so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+            if (so) {
                 return so;
+            }
         }
     }
     return nullptr;
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index b0743a5..2dd4206 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -17,13 +17,10 @@
 #ifndef ANDROID_EGL_LOADER_H
 #define ANDROID_EGL_LOADER_H
 
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
+#include <stdint.h>
 
 #include <utils/Errors.h>
 #include <utils/Singleton.h>
-#include <utils/String8.h>
 
 #include <EGL/egl.h>
 
@@ -33,12 +30,10 @@
 
 struct egl_connection_t;
 
-class Loader : public Singleton<Loader>
-{
+class Loader : public Singleton<Loader> {
     friend class Singleton<Loader>;
 
-    typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
-            const char*);
+    typedef __eglMustCastToProperFunctionPointerType (* getProcAddressType)(const char*);
    
     enum {
         EGL         = 0x01,
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index ee83ada..34b0ba2 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -14,30 +14,26 @@
  ** limitations under the License.
  */
 
-#include <ctype.h>
 #include <stdlib.h>
-#include <string.h>
 
 #include <hardware/gralloc.h>
-#include <system/window.h>
 
 #include <EGL/egl.h>
-#include <EGL/eglext.h>
 
 #include <cutils/atomic.h>
 #include <cutils/properties.h>
+
 #include <log/log.h>
+
 #include <utils/CallStack.h>
-#include <utils/String8.h>
 
 #include "../egl_impl.h"
 
-#include "egl_tls.h"
 #include "egldefs.h"
-#include "Loader.h"
-
+#include "egl_tls.h"
 #include "egl_display.h"
 #include "egl_object.h"
+#include "Loader.h"
 
 typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;
 
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index c434d0e..3359c64 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -22,7 +22,6 @@
 #include <string.h>
 
 #include <hardware/gralloc1.h>
-#include <system/window.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -30,9 +29,7 @@
 #include <android/hardware_buffer.h>
 #include <private/android/AHardwareBufferHelpers.h>
 
-#include <cutils/atomic.h>
 #include <cutils/compiler.h>
-#include <cutils/memory.h>
 #include <cutils/properties.h>
 #include <log/log.h>
 
@@ -44,18 +41,17 @@
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 #include <utils/Trace.h>
+#include <utils/Thread.h>
 
 #include "binder/Binder.h"
 #include "binder/Parcel.h"
 #include "binder/IServiceManager.h"
 
 #include "../egl_impl.h"
-#include "../hooks.h"
 
 #include "egl_display.h"
 #include "egl_object.h"
 #include "egl_tls.h"
-#include "egldefs.h"
 
 using namespace android;
 
@@ -84,11 +80,10 @@
  * NOTE: Both strings MUST have a single space as the last character.
  */
 
-// CLion mistakenly warns about the extern keyword below.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wextern-initializer"
+extern char const * const gBuiltinExtensionString;
+extern char const * const gExtensionString;
 
-extern char const * const gBuiltinExtensionString =
+char const * const gBuiltinExtensionString =
         "EGL_KHR_get_all_proc_addresses "
         "EGL_ANDROID_presentation_time "
         "EGL_KHR_swap_buffers_with_damage "
@@ -97,7 +92,8 @@
         "EGL_ANDROID_front_buffer_auto_refresh "
         "EGL_ANDROID_get_frame_timestamps "
         ;
-extern char const * const gExtensionString  =
+
+char const * const gExtensionString  =
         "EGL_KHR_image "                        // mandatory
         "EGL_KHR_image_base "                   // mandatory
         "EGL_KHR_image_pixmap "
@@ -237,8 +233,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
 };
 
-#pragma clang diagnostic pop
-
 /*
  * These extensions entry-points should not be exposed to applications.
  * They're used internally by the Android EGL layer.
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 1fe322d..e46716c 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -14,18 +14,17 @@
  ** limitations under the License.
  */
 
+#include "egl_cache.h"
+
 #include "../egl_impl.h"
 
-#include "egl_cache.h"
 #include "egl_display.h"
-#include "egldefs.h"
 
-#include <fcntl.h>
 #include <inttypes.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
+
+#include <utils/Thread.h>
 
 // Cache size limits.
 static const size_t maxKeySize = 12 * 1024;
@@ -87,7 +86,7 @@
         bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
         bool atEnd = (bcExtLen+1) < extsLen &&
                 !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
-        bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
+        bool inMiddle = strstr(exts, " " BC_EXT_STR " ") != nullptr;
         if (equal || atStart || atEnd || inMiddle) {
             PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
             eglSetBlobCacheFuncsANDROID =
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
index 8760009..e7f1712 100644
--- a/opengl/libs/EGL/egl_cache.h
+++ b/opengl/libs/EGL/egl_cache.h
@@ -21,6 +21,7 @@
 #include <EGL/eglext.h>
 
 #include <utils/BlobCache.h>
+#include <utils/Mutex.h>
 #include <utils/String8.h>
 #include <utils/StrongPointer.h>
 
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index d7df40c..c804fa7 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -17,16 +17,16 @@
 #define __STDC_LIMIT_MACROS 1
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <string.h>
+#include "egl_display.h"
 
 #include "../egl_impl.h"
 
 #include "egl_cache.h"
-#include "egl_display.h"
 #include "egl_object.h"
 #include "egl_tls.h"
 #include "Loader.h"
 #include <cutils/properties.h>
+
 #include <utils/Trace.h>
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index e17558c..f5e7294 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -18,16 +18,16 @@
 #define ANDROID_EGL_DISPLAY_H
 
 
-#include <ctype.h>
 #include <stdint.h>
-#include <stdlib.h>
+#include <stddef.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
 #include <cutils/compiler.h>
 #include <utils/SortedVector.h>
-#include <utils/threads.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
 #include <utils/String8.h>
 
 #include "egldefs.h"
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 7fc5609..b553d71 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -14,19 +14,10 @@
  ** limitations under the License.
  */
 
-#include <string>
+#include "egl_object.h"
+
 #include <sstream>
 
-#include <ctype.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <utils/threads.h>
-
-#include "egl_object.h"
 
 // ----------------------------------------------------------------------------
 namespace android {
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 8ceba1d..f4012ab 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -17,15 +17,13 @@
 #ifndef ANDROID_EGL_OBJECT_H
 #define ANDROID_EGL_OBJECT_H
 
-#include <atomic>
-#include <ctype.h>
 #include <stdint.h>
-#include <stdlib.h>
+#include <stddef.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <utils/threads.h>
+#include <utils/StrongPointer.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
@@ -62,8 +60,8 @@
     template <typename N, typename T>
     class LocalRef {
         egl_object_t* ref;
-        LocalRef();
-        explicit LocalRef(const LocalRef* rhs);
+        LocalRef() = delete;
+        LocalRef(const LocalRef* rhs) = delete;
     public:
         ~LocalRef();
         explicit LocalRef(egl_object_t* rhs);
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index 6de5f27..ca8684e 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -14,16 +14,14 @@
  ** limitations under the License.
  */
 
-#include <pthread.h>
+#include "egl_tls.h"
+
 #include <stdlib.h>
 
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <utils/CallStack.h>
 
-#include <EGL/egl.h>
-
-#include "egl_tls.h"
 
 namespace android {
 
@@ -31,7 +29,7 @@
 pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT;
 
 egl_tls_t::egl_tls_t()
-    : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
+    : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(true) {
 }
 
 const char *egl_tls_t::egl_strerror(EGLint err) {
@@ -85,11 +83,12 @@
 
 bool egl_tls_t::logNoContextCall() {
     egl_tls_t* tls = getTLS();
-    if (tls->logCallWithNoContext == true) {
+    if (tls->logCallWithNoContext) {
         tls->logCallWithNoContext = false;
         return true;
     }
     return false;
+
 }
 
 egl_tls_t* egl_tls_t::getTLS() {
diff --git a/opengl/libs/EGL/egl_tls.h b/opengl/libs/EGL/egl_tls.h
index 00eae0b..9feae68 100644
--- a/opengl/libs/EGL/egl_tls.h
+++ b/opengl/libs/EGL/egl_tls.h
@@ -17,11 +17,9 @@
 #ifndef ANDROID_EGL_TLS_H
 #define ANDROID_EGL_TLS_H
 
-#include <pthread.h>
-
 #include <EGL/egl.h>
 
-#include "egldefs.h"
+#include <pthread.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -36,7 +34,7 @@
 
     EGLint      error;
     EGLContext  ctx;
-    EGLBoolean  logCallWithNoContext;
+    bool        logCallWithNoContext;
 
     egl_tls_t();
     static void validateTLSKey();
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index c0990ec..a8855ef 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -17,8 +17,6 @@
 #ifndef ANDROID_EGL_IMPL_H
 #define ANDROID_EGL_IMPL_H
 
-#include <ctype.h>
-
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <EGL/eglplatform.h>
@@ -30,8 +28,7 @@
 // ----------------------------------------------------------------------------
 
 EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
-EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name,
-                                                          GLuint index);
+EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name, GLuint index);
 EGLAPI GLint egl_get_num_extensions_for_current_context();
 
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 24c68ec..afaccd2 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -131,9 +131,11 @@
 
 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
 
+LOCAL_HEADER_LIBRARIES := \
+    android.hardware.configstore-utils
+
 LOCAL_STATIC_LIBRARIES := \
     libhwcomposer-command-buffer \
-    android.hardware.configstore-utils \
     libtrace_proto \
     libvkjson \
     libvr_manager \
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 2b4f4cb..9ddae2b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -49,7 +49,10 @@
 {
     const size_t count = mLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        mFlinger->removeLayer(mLayers.valueAt(i));
+        sp<Layer> l = mLayers.valueAt(i).promote();
+        if (l != nullptr) {
+            mFlinger->removeLayer(l);
+        }
     }
 }
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2f83c0e..24ebac7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1436,29 +1436,23 @@
 
     // If this transaction is waiting on the receipt of a frame, generate a sync
     // point and send it to the remote layer.
-    if (mCurrentState.handle != nullptr) {
-        sp<IBinder> strongBinder = mCurrentState.handle.promote();
-        sp<Handle> handle = nullptr;
-        sp<Layer> handleLayer = nullptr;
-        if (strongBinder != nullptr) {
-            handle = static_cast<Handle*>(strongBinder.get());
-            handleLayer = handle->owner.promote();
-        }
-        if (strongBinder == nullptr || handleLayer == nullptr) {
-            ALOGE("[%s] Unable to promote Layer handle", mName.string());
+    if (mCurrentState.barrierLayer != nullptr) {
+        sp<Layer> barrierLayer = mCurrentState.barrierLayer.promote();
+        if (barrierLayer == nullptr) {
+            ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mCurrentState.handle = nullptr;
+            mCurrentState.barrierLayer = nullptr;
         } else {
             auto syncPoint = std::make_shared<SyncPoint>(
                     mCurrentState.frameNumber);
-            if (handleLayer->addSyncPoint(syncPoint)) {
+            if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mCurrentState.handle = nullptr;
+                mCurrentState.barrierLayer = nullptr;
             }
         }
 
@@ -1481,7 +1475,7 @@
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
     while (!mPendingStates.empty()) {
-        if (mPendingStates[0].handle != nullptr) {
+        if (mPendingStates[0].barrierLayer != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -1733,7 +1727,7 @@
 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
     mCurrentState.sequence++;
     mCurrentState.requested.transform.set(
-            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+            matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
@@ -1828,17 +1822,24 @@
     return p->getLayerStack();
 }
 
-void Layer::deferTransactionUntil(const sp<IBinder>& handle,
+void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer,
         uint64_t frameNumber) {
-    mCurrentState.handle = handle;
+    mCurrentState.barrierLayer = barrierLayer;
     mCurrentState.frameNumber = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
     mCurrentState.modified = true;
     pushPendingState();
-    mCurrentState.handle = nullptr;
+    mCurrentState.barrierLayer = nullptr;
     mCurrentState.frameNumber = 0;
     mCurrentState.modified = false;
+    ALOGE("Deferred transaction");
+}
+
+void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle,
+        uint64_t frameNumber) {
+    sp<Handle> handle = static_cast<Handle*>(barrierHandle.get());
+    deferTransactionUntil(handle->owner.promote(), frameNumber);
 }
 
 void Layer::useSurfaceDamage() {
@@ -2454,6 +2455,21 @@
     return true;
 }
 
+bool Layer::detachChildren() {
+    traverseInZOrder([this](Layer* child) {
+        if (child == this) {
+            return;
+        }
+
+        sp<Client> client(child->mClientRef.promote());
+        if (client != nullptr) {
+            client->detachLayer(child);
+        }
+    });
+
+    return true;
+}
+
 void Layer::setParent(const sp<Layer>& layer) {
     mParent = layer;
 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c5fea73..f2e5f22 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -128,9 +128,9 @@
         // finalCrop is expressed in display space coordinate.
         Rect finalCrop;
 
-        // If set, defers this state update until the Layer identified by handle
+        // If set, defers this state update until the identified Layer
         // receives a frame with the given frameNumber
-        wp<IBinder> handle;
+        wp<Layer> barrierLayer;
         uint64_t frameNumber;
 
         // the transparentRegion hint is a bit special, it's latched only
@@ -171,10 +171,12 @@
     bool setLayerStack(uint32_t layerStack);
     bool setDataSpace(android_dataspace dataSpace);
     uint32_t getLayerStack() const;
-    void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+    void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
+    void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
     bool setOverrideScalingMode(int32_t overrideScalingMode);
     void setInfo(uint32_t type, uint32_t appId);
     bool reparentChildren(const sp<IBinder>& layer);
+    bool detachChildren();
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 842ff0b..4acdb82 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -33,7 +33,6 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
 #include <binder/PermissionCache.h>
 
 #include <dvr/vr_flinger.h>
@@ -167,7 +166,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mForceFullDamage(false),
-        mInterceptor(),
+        mInterceptor(this),
         mPrimaryDispSync("PrimaryDispSync"),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
@@ -629,6 +628,11 @@
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const {
     Mutex::Autolock _l(mStateLock);
+    return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const {
     sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
@@ -2530,14 +2534,7 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
-    Mutex::Autolock _l(mStateLock);
-    sp<Layer> layer = weakLayer.promote();
-    if (layer == nullptr) {
-        // The layer has already been removed, carry on
-        return NO_ERROR;
-    }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
     const auto& p = layer->getParent();
     const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
         mCurrentState.layersSortedByZ.remove(layer);
@@ -2799,7 +2796,19 @@
             }
         }
         if (what & layer_state_t::eDeferTransaction) {
-            layer->deferTransactionUntil(s.handle, s.frameNumber);
+            if (s.barrierHandle != nullptr) {
+                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+            } else if (s.barrierGbp != nullptr) {
+                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+                if (authenticateSurfaceTextureLocked(gbp)) {
+                    const auto& otherLayer =
+                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
+                } else {
+                    ALOGE("Attempt to defer transaction to to an"
+                            " unrecognized GraphicBufferProducer");
+                }
+            }
             // We don't trigger a traversal here because if no other state is
             // changed, we don't want this to cause any more work
         }
@@ -2808,6 +2817,9 @@
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
+        if (what & layer_state_t::eDetachChildren) {
+            layer->detachChildren();
+        }
         if (what & layer_state_t::eOverrideScalingModeChanged) {
             layer->setOverrideScalingMode(s.overrideScalingMode);
             // We don't trigger a traversal here because if no other state is
@@ -2904,7 +2916,7 @@
 
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
-    // called by the window manager when it wants to remove a Layer
+    // called by a client when it wants to remove a Layer
     status_t err = NO_ERROR;
     sp<Layer> l(client->getLayerUser(handle));
     if (l != NULL) {
@@ -2920,7 +2932,15 @@
 {
     // called by ~LayerCleaner() when all references to the IBinder (handle)
     // are gone
-    return removeLayer(layer);
+    sp<Layer> l = layer.promote();
+    if (l == nullptr) {
+        // The layer has already been removed, carry on
+        return NO_ERROR;
+    } if (l->getParent() != nullptr) {
+        // If we have a parent, then we can continue to live as long as it does.
+        return NO_ERROR;
+    }
+    return removeLayer(l);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c43786a..0b3deef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -36,8 +36,6 @@
 #include <utils/SortedVector.h>
 #include <utils/threads.h>
 
-#include <binder/IMemory.h>
-
 #include <ui/FenceTime.h>
 #include <ui/PixelFormat.h>
 #include <math/mat4.h>
@@ -160,6 +158,9 @@
         return *mRenderEngine;
     }
 
+    bool authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const;
+
 private:
     friend class Client;
     friend class DisplayEventConnection;
@@ -329,7 +330,7 @@
     status_t onLayerDestroyed(const wp<Layer>& layer);
 
     // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const wp<Layer>& layer);
+    status_t removeLayer(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 5aaaab1..fe8dd0c 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -33,7 +33,6 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
 #include <binder/PermissionCache.h>
 
 #include <ui/DisplayInfo.h>
@@ -155,7 +154,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mForceFullDamage(false),
-        mInterceptor(),
+        mInterceptor(this),
         mPrimaryDispSync("PrimaryDispSync"),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
@@ -628,6 +627,11 @@
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const {
     Mutex::Autolock _l(mStateLock);
+    return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const {
     sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
@@ -2313,14 +2317,7 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
-    Mutex::Autolock _l(mStateLock);
-    sp<Layer> layer = weakLayer.promote();
-    if (layer == nullptr) {
-        // The layer has already been removed, carry on
-        return NO_ERROR;
-    }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
     const auto& p = layer->getParent();
     const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
              mCurrentState.layersSortedByZ.remove(layer);
@@ -2582,7 +2579,19 @@
             }
         }
         if (what & layer_state_t::eDeferTransaction) {
-            layer->deferTransactionUntil(s.handle, s.frameNumber);
+            if (s.barrierHandle != nullptr) {
+                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+            } else if (s.barrierGbp != nullptr) {
+                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+                if (authenticateSurfaceTextureLocked(gbp)) {
+                    const auto& otherLayer =
+                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
+                } else {
+                    ALOGE("Attempt to defer transaction to to an"
+                            " unrecognized GraphicBufferProducer");
+                }
+            }
             // We don't trigger a traversal here because if no other state is
             // changed, we don't want this to cause any more work
         }
@@ -2591,6 +2600,9 @@
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
+        if (what & layer_state_t::eDetachChildren) {
+            layer->detachChildren();
+        }
         if (what & layer_state_t::eOverrideScalingModeChanged) {
             layer->setOverrideScalingMode(s.overrideScalingMode);
             // We don't trigger a traversal here because if no other state is
@@ -2687,7 +2699,7 @@
 
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
-    // called by the window manager when it wants to remove a Layer
+    // called by a client when it wants to remove a Layer
     status_t err = NO_ERROR;
     sp<Layer> l(client->getLayerUser(handle));
     if (l != NULL) {
@@ -2703,7 +2715,15 @@
 {
     // called by ~LayerCleaner() when all references to the IBinder (handle)
     // are gone
-    return removeLayer(layer);
+    sp<Layer> l = layer.promote();
+    if (l == nullptr) {
+        // The layer has already been removed, carry on
+        return NO_ERROR;
+    } if (l->getParent() != nullptr) {
+        // If we have a parent, then we can continue to live as long as it does.
+        return NO_ERROR;
+    }
+    return removeLayer(l);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 2d6472a..026fe80 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -31,6 +31,11 @@
 
 // ----------------------------------------------------------------------------
 
+SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger)
+    :   mFlinger(flinger)
+{
+}
+
 void SurfaceInterceptor::enable(const SortedVector<sp<Layer>>& layers,
         const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays)
 {
@@ -97,8 +102,8 @@
     addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion);
     addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
     addCropLocked(transaction, layerId, layer->mCurrentState.crop);
-    if (layer->mCurrentState.handle != nullptr) {
-        addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.handle,
+    if (layer->mCurrentState.barrierLayer != nullptr) {
+        addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.barrierLayer.promote(),
                 layer->mCurrentState.frameNumber);
     }
     addFinalCropLocked(transaction, layerId, layer->mCurrentState.finalCrop);
@@ -287,10 +292,9 @@
 }
 
 void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
-        const wp<const IBinder>& weakHandle, uint64_t frameNumber)
+        const sp<const Layer>& layer, uint64_t frameNumber)
 {
     SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
-    const sp<const Layer> layer(getLayer(weakHandle));
     if (layer == nullptr) {
         ALOGE("An existing layer could not be retrieved with the handle"
                 " for the deferred transaction");
@@ -349,7 +353,18 @@
         addCropLocked(transaction, layerId, state.crop);
     }
     if (state.what & layer_state_t::eDeferTransaction) {
-        addDeferTransactionLocked(transaction, layerId, state.handle, state.frameNumber);
+        sp<Layer> otherLayer = nullptr;
+        if (state.barrierHandle != nullptr) {
+            otherLayer = static_cast<Layer::Handle*>(state.barrierHandle.get())->owner.promote();
+        } else if (state.barrierGbp != nullptr) {
+            auto const& gbp = state.barrierGbp;
+            if (mFlinger->authenticateSurfaceTextureLocked(gbp)) {
+                otherLayer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+            } else {
+                ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer");
+            }
+        }
+        addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber);
     }
     if (state.what & layer_state_t::eFinalCropChanged) {
         addFinalCropLocked(transaction, layerId, state.finalCrop);
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 9af6e61..30ebcc6 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -28,6 +28,7 @@
 
 class BufferItem;
 class Layer;
+class SurfaceFlinger;
 struct DisplayState;
 struct layer_state_t;
 
@@ -39,6 +40,7 @@
  */
 class SurfaceInterceptor {
 public:
+    SurfaceInterceptor(SurfaceFlinger* const flinger);
     // Both vectors are used to capture the current state of SF as the initial snapshot in the trace
     void enable(const SortedVector<sp<Layer>>& layers,
             const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays);
@@ -102,7 +104,7 @@
     void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack);
     void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
     void addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
-            const wp<const IBinder>& weakHandle, uint64_t frameNumber);
+            const sp<const Layer>& layer, uint64_t frameNumber);
     void addFinalCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
     void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId,
             int32_t overrideScalingMode);
@@ -129,6 +131,7 @@
     std::string mOutputFileName {DEFAULT_FILENAME};
     std::mutex mTraceMutex {};
     Trace mTrace {};
+    SurfaceFlinger* const mFlinger;
 };
 
 }
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index d9f1438..aeb557a 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -18,8 +18,6 @@
 
 #include <android/native_window.h>
 
-#include <binder/IMemory.h>
-
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
@@ -199,9 +197,9 @@
     {
         SCOPED_TRACE("before move");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel(  0,  12,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(0, 12);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -211,9 +209,9 @@
         // This should reflect the new position, but not the new color.
         SCOPED_TRACE("after move, before redraw");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145, 195,  63,  63);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectFGColor(145, 145);
     }
 
     fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
@@ -222,9 +220,9 @@
         // This should reflect the new position and the new color.
         SCOPED_TRACE("after redraw");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145,  63, 195,  63);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->checkPixel(145, 145, 63, 195, 63);
     }
 }
 
@@ -233,9 +231,9 @@
     {
         SCOPED_TRACE("before resize");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel(  0,  12,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(0, 12);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     ALOGD("resizing");
@@ -248,9 +246,9 @@
         // has not yet received a buffer of the correct size.
         SCOPED_TRACE("after resize, before redraw");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel(  0,  12,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(0, 12);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     ALOGD("drawing");
@@ -261,9 +259,9 @@
         // This should reflect the new size and the new color.
         SCOPED_TRACE("after redraw");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63, 195,  63);
-        sc->checkPixel(145, 145,  63, 195,  63);
+        sc->expectBGColor(24, 24);
+        sc->checkPixel(75, 75, 63, 195, 63);
+        sc->checkPixel(145, 145, 63, 195, 63);
     }
 }
 
@@ -272,9 +270,9 @@
     {
         SCOPED_TRACE("before crop");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -285,11 +283,11 @@
         // This should crop the foreground surface.
         SCOPED_TRACE("after crop");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel( 95,  80, 195,  63,  63);
-        sc->checkPixel( 80,  95, 195,  63,  63);
-        sc->checkPixel( 96,  96,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectFGColor(95, 80);
+        sc->expectFGColor(80, 95);
+        sc->expectBGColor(96, 96);
     }
 }
 
@@ -298,9 +296,9 @@
     {
         SCOPED_TRACE("before crop");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
     SurfaceComposerClient::openGlobalTransaction();
     Rect cropRect(16, 16, 32, 32);
@@ -310,11 +308,11 @@
         // This should crop the foreground surface.
         SCOPED_TRACE("after crop");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel( 95,  80,  63,  63, 195);
-        sc->checkPixel( 80,  95,  63,  63, 195);
-        sc->checkPixel( 96,  96,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectBGColor(95, 80);
+        sc->expectBGColor(80, 95);
+        sc->expectBGColor(96, 96);
     }
 }
 
@@ -323,9 +321,9 @@
     {
         SCOPED_TRACE("before setLayer");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -335,9 +333,9 @@
         // This should hide the foreground surface beneath the background.
         SCOPED_TRACE("after setLayer");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -346,9 +344,9 @@
     {
         SCOPED_TRACE("before hide");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -358,9 +356,9 @@
         // This should hide the foreground surface.
         SCOPED_TRACE("after hide, before show");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -370,9 +368,9 @@
         // This should show the foreground surface.
         SCOPED_TRACE("after show");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -381,9 +379,9 @@
     {
         SCOPED_TRACE("before setAlpha");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -393,9 +391,9 @@
         // This should set foreground to be 75% opaque.
         SCOPED_TRACE("after setAlpha");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 162,  63,  96);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->checkPixel(75, 75, 162, 63, 96);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -404,9 +402,9 @@
     {
         SCOPED_TRACE("before setLayerStack");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -417,9 +415,9 @@
         // layer stack.
         SCOPED_TRACE("after setLayerStack");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -428,9 +426,9 @@
     {
         SCOPED_TRACE("before setFlags");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -441,9 +439,9 @@
         // This should hide the foreground surface
         SCOPED_TRACE("after setFlags");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 75,  75,  63,  63, 195);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectBGColor(75, 75);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -452,10 +450,10 @@
     {
         SCOPED_TRACE("before setMatrix");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 91,  96, 195,  63,  63);
-        sc->checkPixel( 96, 101, 195,  63,  63);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(91, 96);
+        sc->expectFGColor(96, 101);
+        sc->expectBGColor(145, 145);
     }
 
     SurfaceComposerClient::openGlobalTransaction();
@@ -465,10 +463,10 @@
     {
         SCOPED_TRACE("after setMatrix");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 24,  24,  63,  63, 195);
-        sc->checkPixel( 91,  96, 195,  63,  63);
-        sc->checkPixel( 96,  91,  63,  63, 195);
-        sc->checkPixel(145, 145,  63,  63, 195);
+        sc->expectBGColor(24, 24);
+        sc->expectFGColor(91, 96);
+        sc->expectBGColor(96, 91);
+        sc->expectBGColor(145, 145);
     }
 }
 
@@ -477,9 +475,9 @@
     {
         SCOPED_TRACE("before anything");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 32,  32,  63,  63, 195);
-        sc->checkPixel( 96,  96, 195,  63,  63);
-        sc->checkPixel(160, 160,  63,  63, 195);
+        sc->expectBGColor(32, 32);
+        sc->expectFGColor(96, 96);
+        sc->expectBGColor(160, 160);
     }
 
     // set up two deferred transactions on different frames
@@ -498,9 +496,9 @@
     {
         SCOPED_TRACE("before any trigger");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 32,  32,  63,  63, 195);
-        sc->checkPixel( 96,  96, 195,  63,  63);
-        sc->checkPixel(160, 160,  63,  63, 195);
+        sc->expectBGColor(32, 32);
+        sc->expectFGColor(96, 96);
+        sc->expectBGColor(160, 160);
     }
 
     // should trigger the first deferred transaction, but not the second one
@@ -508,9 +506,9 @@
     {
         SCOPED_TRACE("after first trigger");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 32,  32,  63,  63, 195);
-        sc->checkPixel( 96,  96, 162,  63,  96);
-        sc->checkPixel(160, 160,  63,  63, 195);
+        sc->expectBGColor(32, 32);
+        sc->checkPixel(96, 96, 162, 63, 96);
+        sc->expectBGColor(160, 160);
     }
 
     // should show up immediately since it's not deferred
@@ -523,9 +521,9 @@
     {
         SCOPED_TRACE("after second trigger");
         ScreenCapture::captureScreen(&sc);
-        sc->checkPixel( 32,  32,  63,  63, 195);
-        sc->checkPixel( 96,  96,  63,  63, 195);
-        sc->checkPixel(160, 160, 195,  63,  63);
+        sc->expectBGColor(32, 32);
+        sc->expectBGColor(96, 96);
+        sc->expectFGColor(160, 160);
     }
 }
 
@@ -630,4 +628,68 @@
         mCapture->expectFGColor(20, 20);
     }
 }
+
+TEST_F(ChildLayerTest, ReparentChildren) {
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->show();
+    mChild->setPosition(10, 10);
+    mFGSurfaceControl->setPosition(64, 64);
+    SurfaceComposerClient::closeGlobalTransaction(true);
+
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        // Top left of foreground must now be visible
+        mCapture->expectFGColor(64, 64);
+        // But 10 pixels in we should see the child surface
+        mCapture->expectChildColor(74, 74);
+        // And 10 more pixels we should be back to the foreground surface
+        mCapture->expectFGColor(84, 84);
+    }
+    mFGSurfaceControl->reparentChildren(mBGSurfaceControl->getHandle());
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        mCapture->expectFGColor(64, 64);
+        // In reparenting we should have exposed the entire foreground surface.
+        mCapture->expectFGColor(74, 74);
+        // And the child layer should now begin at 10, 10 (since the BG
+        // layer is at (0, 0)).
+        mCapture->expectBGColor(9, 9);
+        mCapture->expectChildColor(10, 10);
+    }
+}
+
+TEST_F(ChildLayerTest, DetachChildren) {
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->show();
+    mChild->setPosition(10, 10);
+    mFGSurfaceControl->setPosition(64, 64);
+    SurfaceComposerClient::closeGlobalTransaction(true);
+
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        // Top left of foreground must now be visible
+        mCapture->expectFGColor(64, 64);
+        // But 10 pixels in we should see the child surface
+        mCapture->expectChildColor(74, 74);
+        // And 10 more pixels we should be back to the foreground surface
+        mCapture->expectFGColor(84, 84);
+    }
+
+    SurfaceComposerClient::openGlobalTransaction();
+    mFGSurfaceControl->detachChildren();
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->hide();
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    // Nothing should have changed.
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        mCapture->expectFGColor(64, 64);
+        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(84, 84);
+    }
+}
+
 }
diff --git a/services/vr/sensord/pose_service.cpp b/services/vr/sensord/pose_service.cpp
index 40eb21d..32a2160 100644
--- a/services/vr/sensord/pose_service.cpp
+++ b/services/vr/sensord/pose_service.cpp
@@ -25,8 +25,6 @@
 #include <private/dvr/sensor_constants.h>
 #include <utils/Trace.h>
 
-#define arraysize(x) (static_cast<ssize_t>(std::extent<decltype(x)>::value))
-
 using android::pdx::LocalChannelHandle;
 using android::pdx::default_transport::Endpoint;
 using android::pdx::Status;
@@ -35,11 +33,8 @@
 namespace dvr {
 
 using Vector3d = vec3d;
-using Vector3f = vec3f;
 using Rotationd = quatd;
-using Rotationf = quatf;
 using AngleAxisd = Eigen::AngleAxis<double>;
-using AngleAxisf = Eigen::AngleAxis<float>;
 
 namespace {
 // Wait a few seconds before checking if we need to disable sensors.
@@ -69,7 +64,6 @@
 
 static constexpr int kDatasetIdLength = 36;
 static constexpr char kDatasetIdChars[] = "0123456789abcdef-";
-static constexpr char kDatasetLocation[] = "/data/sdcard/datasets/";
 
 // These are the flags used by BufferProducer::CreatePersistentUncachedBlob,
 // plus PRIVATE_ADSP_HEAP to allow access from the DSP.
@@ -77,14 +71,6 @@
     GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY |
     GRALLOC_USAGE_PRIVATE_UNCACHED | GRALLOC_USAGE_PRIVATE_ADSP_HEAP;
 
-// Extract yaw angle from a given quaternion rotation.
-// Y-axis is considered to be vertical. Result is in rad.
-template <typename T>
-T ExtractYaw(Eigen::Quaternion<T> rotation) {
-  const Eigen::Vector3<T> yaw_axis = rotation * vec3::UnitZ();
-  return std::atan2(yaw_axis.z(), yaw_axis.x());
-}
-
 std::string GetPoseModeString(DvrPoseMode mode) {
   switch (mode) {
     case DVR_POSE_MODE_6DOF:
@@ -110,19 +96,6 @@
   }
 }
 
-inline std::string GetVector3dString(const Vector3d& vector) {
-  std::ostringstream stream;
-  stream << "[" << vector[0] << "," << vector[1] << "," << vector[2] << "]";
-  return stream.str();
-}
-
-inline std::string GetRotationdString(const Rotationd& rotation) {
-  std::ostringstream stream;
-  stream << "[" << rotation.w() << ", " << GetVector3dString(rotation.vec())
-         << "]";
-  return stream.str();
-}
-
 }  // namespace
 
 PoseService::PoseService(SensorThread* sensor_thread)
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 31f8796..e105922 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -804,7 +804,8 @@
     int gralloc_usage = 0;
     if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
         uint64_t consumer_usage, producer_usage;
-        if (GetData(device).driver_version == 256587285) {
+        uint32_t driver_version = GetData(device).driver_version;
+        if (driver_version == 256587285 || driver_version == 96011958) {
             // HACK workaround for loader/driver mismatch during transition to
             // vkGetSwapchainGrallocUsage2ANDROID.
             typedef VkResult(VKAPI_PTR *