Merge "Remove TARGET_USES_QCOM_BSP from vr/sensord"
diff --git a/aidl/gui/android/view/Surface.aidl b/aidl/gui/android/view/Surface.aidl
index 674c163..7e89220 100644
--- a/aidl/gui/android/view/Surface.aidl
+++ b/aidl/gui/android/view/Surface.aidl
@@ -17,4 +17,4 @@
 
 package android.view;
 
-parcelable Surface cpp_header "gui/Surface.h";
+parcelable Surface cpp_header "gui/view/Surface.h";
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index efc050b..d1e94ed 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -103,8 +103,7 @@
 
 LOCAL_MODULE := dumpstate
 
-LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES) \
-    android.hardware.vibrator@1.0
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
 
 LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES)
 
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 67172b6..b323624 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -42,7 +42,6 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
-#include <android/hardware/vibrator/1.0/IVibrator.h>
 #include <cutils/native_handle.h>
 #include <cutils/properties.h>
 #include <openssl/sha.h>
@@ -54,8 +53,6 @@
 #include "dumpstate.h"
 
 using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using VibratorStatus = ::android::hardware::vibrator::V1_0::Status;
 
 // TODO: remove once moved to namespace
 using android::os::dumpstate::CommandOptions;
@@ -1363,6 +1360,16 @@
                    .Build());
 }
 
+static void Vibrate(int duration_ms) {
+    // clang-format off
+    RunCommand("", {"cmd", "vibrator", "vibrate", std::to_string(duration_ms), "dumpstate"},
+               CommandOptions::WithTimeout(10)
+                   .Log("Vibrate: '%s'\n")
+                   .Always()
+                   .Build());
+    // clang-format on
+}
+
 int main(int argc, char *argv[]) {
     int do_add_date = 0;
     int do_zip_file = 0;
@@ -1608,22 +1615,8 @@
         fclose(cmdline);
     }
 
-    ::android::sp<IVibrator> vibrator = nullptr;
     if (do_vibrate) {
-        vibrator = IVibrator::getService();
-
-        if (vibrator != nullptr) {
-            // cancel previous vibration if any
-            ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
-            if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
-                MYLOGE("Vibrator off failed.");
-            } else {
-                ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(150);
-                if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
-                    MYLOGE("Vibrator on failed.");
-                }
-            }
-        }
+        Vibrate(150);
     }
 
     if (do_fb && ds.do_early_screenshot_) {
@@ -1803,21 +1796,9 @@
     }
 
     /* vibrate a few but shortly times to let user know it's finished */
-    if (vibrator != nullptr) {
-        // in case dumpstate magically completes before the above vibration
-        ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
-        if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
-            MYLOGE("Vibrator off failed.");
-        } else {
-            for (int i = 0; i < 3; i++) {
-                ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(75);
-                if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
-                    MYLOGE("Vibrator on failed.");
-                    break;
-                }
-                usleep((75 + 50) * 1000);
-            }
-        }
+    for (int i = 0; i < 3; i++) {
+        Vibrate(75);
+        usleep((75 + 50) * 1000);
     }
 
     /* tell activity manager we're done */
diff --git a/cmds/dumpsys/Android.bp b/cmds/dumpsys/Android.bp
index c5ae9d2..3476964 100644
--- a/cmds/dumpsys/Android.bp
+++ b/cmds/dumpsys/Android.bp
@@ -15,8 +15,6 @@
         "libutils",
         "liblog",
         "libbinder",
-        "android.hidl.manager@1.0",
-        "libhidlbase"
     ],
 
     clang: true,
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 860b7b4..f0e7200 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -45,7 +45,8 @@
 using android::base::unique_fd;
 using android::base::WriteFully;
 
-static int sort_func(const String16* lhs, const String16* rhs) {
+static int sort_func(const String16* lhs, const String16* rhs)
+{
     return lhs->compare(*rhs);
 }
 
@@ -54,11 +55,10 @@
         "usage: dumpsys\n"
             "         To dump all services.\n"
             "or:\n"
-            "       dumpsys [-t TIMEOUT] [--help | --hw | -l | --skip SERVICES | SERVICE [ARGS]]\n"
+            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
             "         --help: shows this help\n"
             "         -l: only list services, do not dump them\n"
             "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
-            "         --hw: list all hw services running on the device\n"
             "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
             "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
 }
@@ -72,42 +72,16 @@
     return false;
 }
 
-static void ListHardwareServices(android::hidl::manager::V1_0::IServiceManager* hm) {
-    using android::hardware::hidl_vec;
-    using android::hardware::hidl_string;
-    using android::hardware::Return;
-    using android::sp;
-
-    if (hm == nullptr) {
-        ALOGE("Unable to get hardware service manager!");
-        aerr << "Failed to get hardware service manager!";
-        return;
-    }
-
-    Return<void> ret = hm->list([](const hidl_vec<hidl_string> &registered){
-        aout << "Currently running hardware services:" << endl;
-        for (const auto &service : registered) {
-            aout << "  " << service << endl;
-        }
-    });
-
-    if (!ret.isOk()) {
-        aerr << "Failed to list hardware services: " << ret.description();
-    }
-}
-
 int Dumpsys::main(int argc, char* const argv[]) {
     Vector<String16> services;
     Vector<String16> args;
     Vector<String16> skippedServices;
     bool showListOnly = false;
-    bool listHwOnly = false;
     bool skipServices = false;
     int timeoutArg = 10;
     static struct option longOptions[] = {
         {"skip", no_argument, 0,  0 },
         {"help", no_argument, 0,  0 },
-        {"hw",   no_argument, 0,  0 },
         {     0,           0, 0,  0 }
     };
 
@@ -131,8 +105,6 @@
             } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                 usage();
                 return 0;
-            } else if (!strcmp(longOptions[optionIndex].name, "hw")) {
-                listHwOnly = true;
             }
             break;
 
@@ -171,17 +143,11 @@
     }
 
     if ((skipServices && skippedServices.empty()) ||
-            (showListOnly && (!services.empty() || !skippedServices.empty())) ||
-            (listHwOnly && (skipServices || services.size() > 0 || showListOnly))) {
+            (showListOnly && (!services.empty() || !skippedServices.empty()))) {
         usage();
         return -1;
     }
 
-    if (listHwOnly) {
-        ListHardwareServices(hm_);
-        return 0;
-    }
-
     if (services.empty() || showListOnly) {
         // gets all services
         services = sm_->listServices();
diff --git a/cmds/dumpsys/dumpsys.h b/cmds/dumpsys/dumpsys.h
index 20d515d..2534dde 100644
--- a/cmds/dumpsys/dumpsys.h
+++ b/cmds/dumpsys/dumpsys.h
@@ -17,21 +17,18 @@
 #ifndef FRAMEWORK_NATIVE_CMD_DUMPSYS_H_
 #define FRAMEWORK_NATIVE_CMD_DUMPSYS_H_
 
-#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/IServiceManager.h>
 
 namespace android {
 
 class Dumpsys {
   public:
-    Dumpsys(android::IServiceManager* sm,
-            android::hidl::manager::V1_0::IServiceManager* hm) : sm_(sm), hm_(hm) {
+    Dumpsys(android::IServiceManager* sm) : sm_(sm) {
     }
     int main(int argc, char* const argv[]);
 
   private:
     android::IServiceManager* sm_;
-    android::hidl::manager::V1_0::IServiceManager* hm_;
 };
 }
 
diff --git a/cmds/dumpsys/main.cpp b/cmds/dumpsys/main.cpp
index b180c98..8ba0eba 100644
--- a/cmds/dumpsys/main.cpp
+++ b/cmds/dumpsys/main.cpp
@@ -27,7 +27,6 @@
 #include <stdio.h>
 
 using namespace android;
-using HServiceManager = android::hidl::manager::V1_0::IServiceManager;
 
 int main(int argc, char* const argv[]) {
     signal(SIGPIPE, SIG_IGN);
@@ -39,8 +38,6 @@
         return 20;
     }
 
-    sp<HServiceManager> hm = HServiceManager::getService("manager");
-
-    Dumpsys dumpsys(sm.get(), hm.get());
+    Dumpsys dumpsys(sm.get());
     return dumpsys.main(argc, argv);
 }
diff --git a/cmds/dumpsys/tests/Android.bp b/cmds/dumpsys/tests/Android.bp
index e00444f..7698ed5 100644
--- a/cmds/dumpsys/tests/Android.bp
+++ b/cmds/dumpsys/tests/Android.bp
@@ -5,12 +5,8 @@
     srcs: ["dumpsys_test.cpp"],
 
     shared_libs: [
-        "android.hidl.manager@1.0",
         "libbase",
         "libbinder",
-        "liblog",
-        "libhidlbase",
-        "libhidltransport",
         "libutils",
     ],
 
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 01a2fa3..a61cb00 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -44,12 +44,6 @@
 using ::testing::internal::GetCapturedStderr;
 using ::testing::internal::GetCapturedStdout;
 
-using android::hardware::hidl_vec;
-using android::hardware::hidl_string;
-using android::hardware::Void;
-using HServiceManager = android::hidl::manager::V1_0::IServiceManager;
-using IServiceNotification = android::hidl::manager::V1_0::IServiceNotification;
-
 class ServiceManagerMock : public IServiceManager {
   public:
     MOCK_CONST_METHOD1(getService, sp<IBinder>(const String16&));
@@ -61,27 +55,6 @@
     MOCK_METHOD0(onAsBinder, IBinder*());
 };
 
-class HardwareServiceManagerMock : public HServiceManager {
-  public:
-    template<typename T>
-    using R = android::hardware::Return<T>; // conflicts with ::testing::Return
-
-    MOCK_METHOD2(get, R<sp<IBase>>(const hidl_string&, const hidl_string&));
-    MOCK_METHOD3(add,
-        R<bool>(const hidl_vec<hidl_string>&,
-                const hidl_string&,
-                const sp<IBase>&));
-    MOCK_METHOD1(list, R<void>(list_cb));
-    MOCK_METHOD2(listByInterface,
-        R<void>(const hidl_string&, listByInterface_cb));
-    MOCK_METHOD3(registerForNotifications,
-        R<bool>(const hidl_string&,
-                const hidl_string&,
-                const sp<IServiceNotification>&));
-    MOCK_METHOD1(debugDump, R<void>(debugDump_cb));
-
-};
-
 class BinderMock : public BBinder {
   public:
     BinderMock() {
@@ -111,26 +84,6 @@
     return MakeAction(new WriteOnFdAction(output));
 }
 
-// gmock black magic to provide a WithArg<0>(List(services)) matcher
-typedef void HardwareListFunction(HServiceManager::list_cb);
-
-class HardwareListAction : public ActionInterface<HardwareListFunction> {
-  public:
-    explicit HardwareListAction(const hidl_vec<hidl_string> &services) : services_(services) {
-    }
-    virtual Result Perform(const ArgumentTuple& args) {
-        auto cb = ::std::tr1::get<0>(args);
-        cb(services_);
-    }
-
-  private:
-    hidl_vec<hidl_string> services_;
-};
-
-Action<HardwareListFunction> HardwareList(const  hidl_vec<hidl_string> &services) {
-    return MakeAction(new HardwareListAction(services));
-}
-
 // Matcher for args using Android's Vector<String16> format
 // TODO: move it to some common testing library
 MATCHER_P(AndroidElementsAre, expected, "") {
@@ -168,7 +121,7 @@
 
 class DumpsysTest : public Test {
   public:
-    DumpsysTest() : sm_(), hm_(), dump_(&sm_, &hm_), stdout_(), stderr_() {
+    DumpsysTest() : sm_(), dump_(&sm_), stdout_(), stderr_() {
     }
 
     void ExpectListServices(std::vector<std::string> services) {
@@ -176,22 +129,9 @@
         for (auto& service : services) {
             services16.add(String16(service.c_str()));
         }
-
         EXPECT_CALL(sm_, listServices()).WillRepeatedly(Return(services16));
     }
 
-    void ExpectListHardwareServices(std::vector<std::string> services) {
-        hidl_vec<hidl_string> hidl_services;
-        hidl_services.resize(services.size());
-        for (size_t i = 0; i < services.size(); i++) {
-            hidl_services[i] = services[i];
-        }
-
-        EXPECT_CALL(hm_, list(_)).WillRepeatedly(DoAll(
-                WithArg<0>(HardwareList(hidl_services)),
-                Return(Void())));
-    }
-
     sp<BinderMock> ExpectCheckService(const char* name, bool running = true) {
         sp<BinderMock> binder_mock;
         if (running) {
@@ -235,10 +175,8 @@
         EXPECT_THAT(status, Eq(0));
     }
 
-    void AssertRunningServices(const std::vector<std::string>& services,
-                               const std::string &message = "Currently running services:") {
-        std::string expected(message);
-        expected.append("\n");
+    void AssertRunningServices(const std::vector<std::string>& services) {
+        std::string expected("Currently running services:\n");
         for (const std::string& service : services) {
             expected.append("  ").append(service).append("\n");
         }
@@ -266,21 +204,12 @@
     }
 
     ServiceManagerMock sm_;
-    HardwareServiceManagerMock hm_;
     Dumpsys dump_;
 
   private:
     std::string stdout_, stderr_;
 };
 
-TEST_F(DumpsysTest, ListHwServices) {
-    ExpectListHardwareServices({"Locksmith", "Valet"});
-
-    CallMain({"--hw"});
-
-    AssertRunningServices({"Locksmith", "Valet"}, "Currently running hardware services:");
-}
-
 // Tests 'dumpsys -l' when all services are running
 TEST_F(DumpsysTest, ListAllServices) {
     ExpectListServices({"Locksmith", "Valet"});
diff --git a/cmds/lshal/lshal.cpp b/cmds/lshal/lshal.cpp
index bc5eaf2..9998a46 100644
--- a/cmds/lshal/lshal.cpp
+++ b/cmds/lshal/lshal.cpp
@@ -28,31 +28,60 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
-template <typename A, typename B, typename C, typename D, typename E>
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_0::IServiceManager;
+
+template <typename A, typename B, typename C, typename D, typename E, typename F>
 void printColumn(std::stringstream &stream,
-        const A &a, const B &b, const C &c, const D &d, const E &e) {
+        const A &a, const B &b, const C &c, const D &d, const E &, const F &f) {
     using namespace ::std;
     stream << left
            << setw(70) << a << "\t"
            << setw(20) << b << "\t"
            << setw(10) << c << "\t"
            << setw(5)  << d << "\t"
-           << setw(0)  << e
+           // TODO(b/34984175): enable selecting columns
+           // << setw(16) << e << "\t"
+           << setw(0)  << f
            << endl;
 }
 
+template <typename A>
+std::string join(const A &components, const std::string &separator) {
+    std::stringstream out;
+    bool first = true;
+    for (const auto &component : components) {
+        if (!first) {
+            out << separator;
+        }
+        out << component;
+
+        first = false;
+    }
+    return out.str();
+}
+
 std::string toHexString(uint64_t t) {
     std::ostringstream os;
     os << std::hex << std::setfill('0') << std::setw(16) << t;
     return os.str();
 }
 
-::android::status_t getReferencedPids(
+std::pair<hidl_string, hidl_string> split(const hidl_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)};
+}
+
+bool getReferencedPids(
         pid_t serverPid, std::map<uint64_t, std::string> *objects) {
 
     std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid));
     if (!ifs.is_open()) {
-        return ::android::PERMISSION_DENIED;
+        return false;
     }
 
     static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
@@ -77,66 +106,165 @@
             (*objects)[ptr] += line.substr(pos + proc.size());
         }
     }
-    return ::android::OK;
+    return true;
 }
 
+void dumpAllLibraries(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->list([&] (const auto &fqInstanceNames) {
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                "N/A",
+                "N/A",
+                "N/A");
+        }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
+
+void dumpPassthrough(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->debugDump([&] (const auto &infos) {
+        for (const auto &info : infos) {
+
+            printColumn(stream,
+                info.interfaceName,
+                info.instanceName,
+                mode,
+                info.clientPids.size() == 1 ? std::to_string(info.clientPids[0]) : "N/A",
+                "N/A",
+                join(info.clientPids, " "));
+        }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
+
+void dumpBinderized(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto listRet = manager->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, std::string>> allPids;
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto getRet = manager->get(serviceName, instanceName);
+            if (!getRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager:"
+                     << getRet.description() << endl;
+                continue;
+            }
+            sp<IBase> service = getRet;
+            if (service == nullptr) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager (null)";
+                continue;
+            }
+            auto debugRet = service->getDebugInfo([&] (const auto &debugInfo) {
+                allDebugInfos[fqInstanceName] = debugInfo;
+                if (debugInfo.pid >= 0) {
+                    allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+                }
+            });
+            if (!debugRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "debugging information cannot be retrieved:"
+                     << debugRet.description() << endl;
+            }
+        }
+        for (auto &pair : allPids) {
+            pid_t serverPid = pair.first;
+            if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+                std::cerr << "Warning: no information for PID " << serverPid
+                          << ", are you root?" << std::endl;
+            }
+        }
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto it = allDebugInfos.find(fqInstanceName);
+            if (it == allDebugInfos.end()) {
+                printColumn(stream,
+                    serviceName,
+                    instanceName,
+                    mode,
+                    "N/A",
+                    "N/A",
+                    ""
+                );
+                continue;
+            }
+            const DebugInfo &info = it->second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                info.pid < 0 ? "N/A" : std::to_string(info.pid),
+                info.ptr == 0 ? "N/A" : toHexString(info.ptr),
+                info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]
+            );
+        }
+
+    });
+    if (!listRet.isOk()) {
+        cerr << "Error: Failed to list services for " << mode << ": "
+             << listRet.description() << endl;
+    }
+}
 
 int dump() {
     using namespace ::std;
     using namespace ::android::hardware;
-    using namespace ::android::hidl::manager::V1_0;
-
-    std::map<std::string, ::android::sp<IServiceManager>> mapping = {
-            {"hwbinder", defaultServiceManager()},
-            {"passthrough", getPassthroughServiceManager()}
-    };
 
     std::stringstream stream;
 
     stream << "All services:" << endl;
     stream << left;
-    printColumn(stream, "Interface", "Instance", "Transport", "Server", "Clients");
+    printColumn(stream, "Interface", "Instance", "Transport", "Server", "PTR", "Clients");
 
-    for (const auto &pair : mapping) {
-        const std::string &mode = pair.first;
-        const ::android::sp<IServiceManager> &manager = pair.second;
-
-        if (manager == nullptr) {
-            cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
-            continue;
-        }
-
-        auto ret = manager->debugDump([&](const auto &registered) {
-            // server pid, .ptr value of binder object, child pids
-            std::map<pid_t, std::map<uint64_t, std::string>> allPids;
-            for (const auto &info : registered) {
-                if (info.pid < 0) {
-                    continue;
-                }
-                pid_t serverPid = info.pid;
-                allPids[serverPid].clear();
-            }
-            for (auto &pair : allPids) {
-                pid_t serverPid = pair.first;
-                if (getReferencedPids(serverPid, &allPids[serverPid]) != ::android::OK) {
-                    std::cerr << "Warning: no information for PID " << serverPid
-                              << ", are you root?" << std::endl;
-                }
-            }
-            for (const auto &info : registered) {
-                printColumn(stream,
-                    info.interfaceName,
-                    info.instanceName.empty() ? "N/A" : info.instanceName,
-                    mode,
-                    info.pid < 0 ? "N/A" : std::to_string(info.pid),
-                    info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]);
-            }
-        });
-        if (!ret.isOk()) {
-            cerr << "Failed to list services for " << mode << ": "
-                 << ret.description() << endl;
-        }
+    auto bManager = defaultServiceManager();
+    if (bManager == nullptr) {
+        cerr << "Failed to get defaultServiceManager()!" << endl;
+    } else {
+        dumpBinderized(stream, "hwbinder", bManager);
+        // Passthrough PIDs are registered to the binderized manager as well.
+        dumpPassthrough(stream, "passthrough", bManager);
     }
+
+    auto pManager = getPassthroughServiceManager();
+    if (pManager == nullptr) {
+        cerr << "Failed to get getPassthroughServiceManager()!" << endl;
+    } else {
+        dumpAllLibraries(stream, "passthrough", pManager);
+    }
+
     cout << stream.rdbuf();
     return 0;
 }
diff --git a/include/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h
index 9e18907..54c9829 100644
--- a/include/gui/GraphicBufferAlloc.h
+++ b/include/gui/GraphicBufferAlloc.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,10 +25,16 @@
 #include <utils/Errors.h>
 
 namespace android {
-// ---------------------------------------------------------------------------
 
 class GraphicBuffer;
 
+/*
+ * Concrete implementation of the IGraphicBufferAlloc interface.
+ *
+ * This can create GraphicBuffer instance across processes. This is mainly used
+ * by surfaceflinger.
+ */
+
 class GraphicBufferAlloc : public BnGraphicBufferAlloc {
 public:
     GraphicBufferAlloc();
@@ -40,7 +46,6 @@
 };
 
 
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
-#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 60203f7..966e70d 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -17,8 +17,6 @@
 #ifndef ANDROID_GUI_SURFACE_H
 #define ANDROID_GUI_SURFACE_H
 
-#include <binder/Parcelable.h>
-
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/BufferQueueDefs.h>
 
@@ -206,6 +204,7 @@
     int dispatchSetSurfaceDamage(va_list args);
     int dispatchSetSharedBufferMode(va_list args);
     int dispatchSetAutoRefresh(va_list args);
+    int dispatchGetNextFrameId(va_list args);
     int dispatchEnableFrameTimestamps(va_list args);
     int dispatchGetFrameTimestamps(va_list args);
     int dispatchGetDisplayRefreshCycleDuration(va_list args);
@@ -410,43 +409,6 @@
     std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory;
 };
 
-namespace view {
-
-/**
- * A simple holder for an IGraphicBufferProducer, to match the managed-side
- * android.view.Surface parcelable behavior.
- *
- * This implements android/view/Surface.aidl
- *
- * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
- * used in managed Binder calls.
- */
-class Surface : public Parcelable {
-  public:
-
-    String16 name;
-    sp<IGraphicBufferProducer> graphicBufferProducer;
-
-    virtual status_t writeToParcel(Parcel* parcel) const override;
-    virtual status_t readFromParcel(const Parcel* parcel) override;
-
-    // nameAlreadyWritten set to true by Surface.java, because it splits
-    // Parceling itself between managed and native code, so it only wants a part
-    // of the full parceling to happen on its native side.
-    status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
-
-    // nameAlreadyRead set to true by Surface.java, because it splits
-    // Parceling itself between managed and native code, so it only wants a part
-    // of the full parceling to happen on its native side.
-    status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
-
-  private:
-
-    static String16 readMaybeEmptyString16(const Parcel* parcel);
-};
-
-} // namespace view
-
-}; // namespace android
+} // namespace android
 
 #endif  // ANDROID_GUI_SURFACE_H
diff --git a/include/gui/view/Surface.h b/include/gui/view/Surface.h
new file mode 100644
index 0000000..cc64fd4
--- /dev/null
+++ b/include/gui/view/Surface.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_VIEW_SURFACE_H
+#define ANDROID_GUI_VIEW_SURFACE_H
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/String16.h>
+
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class IGraphicBufferProducer;
+
+namespace view {
+
+/**
+ * A simple holder for an IGraphicBufferProducer, to match the managed-side
+ * android.view.Surface parcelable behavior.
+ *
+ * This implements android/view/Surface.aidl
+ *
+ * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
+ * used in managed Binder calls.
+ */
+class Surface : public Parcelable {
+  public:
+
+    String16 name;
+    sp<IGraphicBufferProducer> graphicBufferProducer;
+
+    virtual status_t writeToParcel(Parcel* parcel) const override;
+    virtual status_t readFromParcel(const Parcel* parcel) override;
+
+    // nameAlreadyWritten set to true by Surface.java, because it splits
+    // Parceling itself between managed and native code, so it only wants a part
+    // of the full parceling to happen on its native side.
+    status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
+
+    // nameAlreadyRead set to true by Surface.java, because it splits
+    // Parceling itself between managed and native code, so it only wants a part
+    // of the full parceling to happen on its native side.
+    status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
+
+  private:
+
+    static String16 readMaybeEmptyString16(const Parcel* parcel);
+};
+
+} // namespace view
+} // namespace android
+
+#endif  // ANDROID_GUI_VIEW_SURFACE_H
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 95ca0f3..759c9ec 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -76,11 +76,6 @@
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inUsage, std::string requestorName = "<Unknown>");
 
-    // creates w * h buffer with a layer count
-    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint32_t inUsage,
-            std::string requestorName = "<Unknown>");
-
     // creates w * h buffer with a layer count using gralloc1
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inLayerCount, uint64_t inProducerUsage,
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 8e93f72..001769f 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -39,7 +39,9 @@
 public:
     static inline GraphicBufferMapper& get() { return getInstance(); }
 
+    // This may NOT work on devices without a valid Gralloc2::Mapper.
     status_t registerBuffer(buffer_handle_t handle);
+
     status_t registerBuffer(const GraphicBuffer* buffer);
 
     status_t unregisterBuffer(buffer_handle_t handle);
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index cb17da4..ddf1072 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -96,6 +96,7 @@
         "SurfaceControl.cpp",
         "SurfaceComposerClient.cpp",
         "SyncFeatures.cpp",
+        "view/Surface.cpp",
     ],
 
     shared_libs: [
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index f2d3677..cc7d403 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -15,21 +15,15 @@
  ** limitations under the License.
  */
 
-#include <log/log.h>
-
-#include <ui/GraphicBuffer.h>
-
 #include <gui/GraphicBufferAlloc.h>
 
-// ----------------------------------------------------------------------------
+#include <log/log.h>
+
+
 namespace android {
-// ----------------------------------------------------------------------------
 
-GraphicBufferAlloc::GraphicBufferAlloc() {
-}
-
-GraphicBufferAlloc::~GraphicBufferAlloc() {
-}
+GraphicBufferAlloc::GraphicBufferAlloc() = default;
+GraphicBufferAlloc::~GraphicBufferAlloc() = default;
 
 sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
         uint32_t height, PixelFormat format, uint32_t layerCount,
@@ -44,15 +38,12 @@
         if (err == NO_MEMORY) {
             GraphicBuffer::dumpAllocationsToSystemLog();
         }
-        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) "
-             "failed (%s), handle=%p",
+        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
                 width, height, layerCount, strerror(-err),
                 graphicBuffer->handle);
-        return 0;
+        graphicBuffer.clear();
     }
     return graphicBuffer;
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 2fd29d5..e2f733a 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -210,6 +210,10 @@
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
         break;
+    case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT:
+        mStringType = SENSOR_STRING_TYPE_LOW_LATENCY_OFFBODY_DETECT;
+        mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+        break;
     case SENSOR_TYPE_WRIST_TILT_GESTURE:
         mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE;
         mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 46eaf28..513b889 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -196,7 +196,8 @@
         if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
             type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE ||
             type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE ||
-            type == SENSOR_TYPE_WRIST_TILT_GESTURE) {
+            type == SENSOR_TYPE_WRIST_TILT_GESTURE ||
+            type == SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT) {
             wakeUpSensor = true;
         }
         // For now we just return the first sensor of that type we find.
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c663620..d1f9f6a 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -18,9 +18,9 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
-#include <android/native_window.h>
+#include <gui/Surface.h>
 
-#include <binder/Parcel.h>
+#include <android/native_window.h>
 
 #include <utils/Log.h>
 #include <utils/Trace.h>
@@ -32,7 +32,6 @@
 
 #include <gui/BufferItem.h>
 #include <gui/IProducerListener.h>
-#include <gui/Surface.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <private/gui/ComposerService.h>
@@ -832,6 +831,9 @@
     case NATIVE_WINDOW_SET_AUTO_REFRESH:
         res = dispatchSetAutoRefresh(args);
         break;
+    case NATIVE_WINDOW_GET_NEXT_FRAME_ID:
+        res = dispatchGetNextFrameId(args);
+        break;
     case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS:
         res = dispatchEnableFrameTimestamps(args);
         break;
@@ -961,6 +963,12 @@
     return setAutoRefresh(autoRefresh);
 }
 
+int Surface::dispatchGetNextFrameId(va_list args) {
+    uint64_t* nextFrameId = va_arg(args, uint64_t*);
+    *nextFrameId = getNextFrameNumber();
+    return NO_ERROR;
+}
+
 int Surface::dispatchEnableFrameTimestamps(va_list args) {
     bool enable = va_arg(args, int);
     enableFrameTimestamps(enable);
@@ -968,7 +976,7 @@
 }
 
 int Surface::dispatchGetFrameTimestamps(va_list args) {
-    uint32_t framesAgo = va_arg(args, uint32_t);
+    uint64_t frameId = va_arg(args, uint64_t);
     nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*);
     nsecs_t* outAcquireTime = va_arg(args, int64_t*);
     nsecs_t* outLatchTime = va_arg(args, int64_t*);
@@ -979,7 +987,7 @@
     nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
     nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*);
     nsecs_t* outReleaseTime = va_arg(args, int64_t*);
-    return getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
+    return getFrameTimestamps(frameId,
             outRequestedPresentTime, outAcquireTime, outLatchTime,
             outFirstRefreshStartTime, outLastRefreshStartTime,
             outGlCompositionDoneTime, outDisplayPresentTime,
@@ -1539,74 +1547,4 @@
     return mGraphicBufferProducer->getUniqueId(outId);
 }
 
-namespace view {
-
-status_t Surface::writeToParcel(Parcel* parcel) const {
-    return writeToParcel(parcel, false);
-}
-
-status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
-    if (parcel == nullptr) return BAD_VALUE;
-
-    status_t res = OK;
-
-    if (!nameAlreadyWritten) {
-        res = parcel->writeString16(name);
-        if (res != OK) return res;
-
-        /* isSingleBuffered defaults to no */
-        res = parcel->writeInt32(0);
-        if (res != OK) return res;
-    }
-
-    res = parcel->writeStrongBinder(
-            IGraphicBufferProducer::asBinder(graphicBufferProducer));
-
-    return res;
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel) {
-    return readFromParcel(parcel, false);
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
-    if (parcel == nullptr) return BAD_VALUE;
-
-    status_t res = OK;
-    if (!nameAlreadyRead) {
-        name = readMaybeEmptyString16(parcel);
-        // Discard this for now
-        int isSingleBuffered;
-        res = parcel->readInt32(&isSingleBuffered);
-        if (res != OK) {
-            ALOGE("Can't read isSingleBuffered");
-            return res;
-        }
-    }
-
-    sp<IBinder> binder;
-
-    res = parcel->readNullableStrongBinder(&binder);
-    if (res != OK) {
-        ALOGE("%s: Can't read strong binder", __FUNCTION__);
-        return res;
-    }
-
-    graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
-
-    return OK;
-}
-
-String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
-    size_t len;
-    const char16_t* str = parcel->readString16Inplace(&len);
-    if (str != nullptr) {
-        return String16(str, len);
-    } else {
-        return String16();
-    }
-}
-
-} // namespace view
-
 }; // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 412c0f6..3f56665 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -598,8 +598,8 @@
         mFrameTimestampsEnabled = true;
     }
 
-    int getAllFrameTimestamps(uint32_t framesAgo) {
-        return native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    int getAllFrameTimestamps(uint64_t frameId) {
+        return native_window_get_frame_timestamps(mWindow.get(), frameId,
                 &outRequestedPresentTime, &outAcquireTime, &outLatchTime,
                 &outFirstRefreshStartTime, &outLastRefreshStartTime,
                 &outGpuCompositionDoneTime, &outDisplayPresentTime,
@@ -619,6 +619,13 @@
         outReleaseTime = -1;
     }
 
+    uint64_t getNextFrameId() {
+        uint64_t frameId = -1;
+        int status = native_window_get_next_frame_id(mWindow.get(), &frameId);
+        EXPECT_EQ(status, NO_ERROR);
+        return frameId;
+    }
+
     void dequeueAndQueue(uint64_t frameIndex) {
         int fence = -1;
         ANativeWindowBuffer* buffer = nullptr;
@@ -748,6 +755,8 @@
     EXPECT_EQ(0, mFakeConsumer->mAddFrameTimestampsCount);
     EXPECT_EQ(0, mFakeConsumer->mGetFrameTimestampsCount);
 
+    const uint64_t fId = getNextFrameId();
+
     // Verify the producer doesn't get frame timestamps piggybacked on dequeue.
     ASSERT_EQ(NO_ERROR, mWindow->dequeueBuffer(mWindow.get(), &buffer, &fence));
     EXPECT_EQ(0, mFakeConsumer->mAddFrameTimestampsCount);
@@ -761,8 +770,7 @@
     EXPECT_EQ(0, mFakeConsumer->mGetFrameTimestampsCount);
 
     // Verify attempts to get frame timestamps fail.
-    const uint32_t framesAgo = 0;
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId);
     EXPECT_EQ(INVALID_OPERATION, result);
     EXPECT_EQ(0, mFakeConsumer->mGetFrameTimestampsCount);
 }
@@ -778,6 +786,8 @@
     EXPECT_EQ(0, mFakeConsumer->mAddFrameTimestampsCount);
     EXPECT_EQ(0, mFakeConsumer->mGetFrameTimestampsCount);
 
+    const uint64_t fId1 = getNextFrameId();
+
     // Verify getFrameTimestamps is piggybacked on dequeue.
     ASSERT_EQ(NO_ERROR, mWindow->dequeueBuffer(mWindow.get(), &buffer, &fence));
     EXPECT_EQ(0, mFakeConsumer->mAddFrameTimestampsCount);
@@ -802,8 +812,7 @@
 
     // Verify queries for timestamps that the producer doesn't know about
     // triggers a call to see if the consumer has any new timestamps.
-    const uint32_t framesAgo = 0;
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(3, mFakeConsumer->mGetFrameTimestampsCount);
 }
@@ -833,16 +842,17 @@
    QueryPresentRetireSupported(false, true);
 }
 
-// This test verifies that:
-// 1) The timestamps recorded in the consumer's FrameTimestampsHistory are
-//    properly retrieved by the producer for the correct frames.
-// 2) When framesAgo is 0, it is querying for the most recently queued frame.
+// This verifies the timestamps recorded in the consumer's
+// FrameTimestampsHistory are properly retrieved by the producer for the
+// correct frames.
 TEST_F(GetFrameTimestampsTest, TimestampsAssociatedWithCorrectFrame) {
     enableFrameTimestamps();
 
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
     mFrames[0].signalQueueFences();
 
+    const uint64_t fId2 = getNextFrameId();
     dequeueAndQueue(1);
     mFrames[1].signalQueueFences();
 
@@ -853,9 +863,8 @@
     mFrames[1].signalRefreshFences();
 
     // Verify timestamps are correct for frame 1.
-    uint32_t framesAgo = 1;
     resetTimestamps();
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
     EXPECT_EQ(mFrames[0].kProducerAcquireTime, outAcquireTime);
@@ -870,9 +879,8 @@
     EXPECT_EQ(mFrames[0].kReleaseTime, outReleaseTime);
 
     // Verify timestamps are correct for frame 2.
-    framesAgo = 0;
     resetTimestamps();
-    result = getAllFrameTimestamps(framesAgo);
+    result = getAllFrameTimestamps(fId2);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[1].kRequestedPresentTime, outRequestedPresentTime);
     EXPECT_EQ(mFrames[1].kProducerAcquireTime, outAcquireTime);
@@ -893,9 +901,8 @@
     enableFrameTimestamps();
     mSurface->mFakeSurfaceComposer->setSupportedTimestamps(true, true);
 
-    const uint32_t framesAgo = 0;
-
     // Dequeue and queue frame 1.
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
 
     // Verify queue-related timestamps for f1 are available immediately in the
@@ -903,7 +910,7 @@
     // acquire fence.
     resetTimestamps();
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    int result = native_window_get_frame_timestamps(mWindow.get(), fId1,
             &outRequestedPresentTime, &outAcquireTime, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
@@ -915,7 +922,7 @@
     mFrames[0].signalQueueFences();
 
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    result = native_window_get_frame_timestamps(mWindow.get(), fId1,
             &outRequestedPresentTime, &outAcquireTime, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
@@ -924,6 +931,7 @@
     EXPECT_EQ(mFrames[0].kProducerAcquireTime, outAcquireTime);
 
     // Dequeue and queue frame 2.
+    const uint64_t fId2 = getNextFrameId();
     dequeueAndQueue(1);
 
     // Verify queue-related timestamps for f2 are available immediately in the
@@ -931,7 +939,7 @@
     // acquire fence.
     resetTimestamps();
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    result = native_window_get_frame_timestamps(mWindow.get(), fId2,
             &outRequestedPresentTime, &outAcquireTime, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
@@ -943,7 +951,7 @@
     mFrames[1].signalQueueFences();
 
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    result = native_window_get_frame_timestamps(mWindow.get(), fId2,
             &outRequestedPresentTime, &outAcquireTime, nullptr, nullptr,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
@@ -961,6 +969,7 @@
     mFrames[0].signalQueueFences();
 
     // Dequeue and queue frame 2.
+    const uint64_t fId2 = getNextFrameId();
     dequeueAndQueue(1);
     mFrames[1].signalQueueFences();
 
@@ -971,9 +980,8 @@
     mFrames[1].signalRefreshFences();
 
     // Verify a request for no timestamps doesn't result in a sync call.
-    const uint32_t framesAgo = 0;
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    int result = native_window_get_frame_timestamps(mWindow.get(), fId2,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
             nullptr, nullptr, nullptr);
     EXPECT_EQ(NO_ERROR, result);
@@ -987,6 +995,7 @@
     mSurface->mFakeSurfaceComposer->setSupportedTimestamps(true, true);
 
     // Dequeue and queue frame 1.
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
     mFrames[0].signalQueueFences();
 
@@ -1001,10 +1010,9 @@
     // fence has been signaled.
     // Note: A sync call is necessary here since the events triggered by
     // addFrameEvents didn't get to piggyback on the earlier queues/dequeues.
-    uint32_t framesAgo = 1;
     resetTimestamps();
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount + 1, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1021,10 +1029,9 @@
     // Verify available timestamps are correct for frame 1 again, before any
     // fence has been signaled.
     // This time a sync call should not be necessary.
-    framesAgo = 1;
     resetTimestamps();
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = getAllFrameTimestamps(framesAgo);
+    result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1043,10 +1050,9 @@
     mFrames[0].signalReleaseFences();
 
     // Verify all timestamps are available without a sync call.
-    framesAgo = 1;
     resetTimestamps();
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = getAllFrameTimestamps(framesAgo);
+    result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1069,9 +1075,8 @@
     enableFrameTimestamps();
     mSurface->mFakeSurfaceComposer->setSupportedTimestamps(true, true);
 
-    const uint32_t framesAgo = 1;
-
     // Dequeue and queue frame 1.
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
     mFrames[0].signalQueueFences();
 
@@ -1088,7 +1093,7 @@
     // addFrameEvents didn't get to piggyback on the earlier queues/dequeues.
     resetTimestamps();
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount + 1, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1110,7 +1115,7 @@
     // sync call.
     resetTimestamps();
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = getAllFrameTimestamps(framesAgo);
+    result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1132,10 +1137,12 @@
     mSurface->mFakeSurfaceComposer->setSupportedTimestamps(true, true);
 
     // Dequeue and queue frame 1.
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
     mFrames[0].signalQueueFences();
 
     // Dequeue and queue frame 2.
+    const uint64_t fId2 = getNextFrameId();
     dequeueAndQueue(1);
     mFrames[1].signalQueueFences();
 
@@ -1146,10 +1153,9 @@
     // fence has been signaled.
     // Note: A sync call is necessary here since the events triggered by
     // addFrameEvents didn't get to piggyback on the earlier queues/dequeues.
-    uint32_t framesAgo = 1;
     resetTimestamps();
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = getAllFrameTimestamps(framesAgo);
+    int result = getAllFrameTimestamps(fId1);
     EXPECT_EQ(oldCount + 1, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
@@ -1167,15 +1173,14 @@
     mFrames[0].signalReleaseFences();
     mFrames[1].signalRefreshFences();
 
-    // Verify querying for all timestmaps of f2 does not do a sync call.
-    // Even though the lastRefresh, retire, dequeueReady, and release times aren't
+    // Verify querying for all timestmaps of f2 does not do a sync call. Even
+    // though the lastRefresh, retire, dequeueReady, and release times aren't
     // available, a sync call should not occur because it's not possible for f2
     // to encounter the final value for those events until another frame is
     // queued.
-    framesAgo = 0;
     resetTimestamps();
     oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    result = getAllFrameTimestamps(framesAgo);
+    result = getAllFrameTimestamps(fId2);
     EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
     EXPECT_EQ(NO_ERROR, result);
     EXPECT_EQ(mFrames[1].kRequestedPresentTime, outRequestedPresentTime);
@@ -1200,14 +1205,14 @@
         displayPresentSupported, displayRetireSupported);
 
     // Dequeue and queue frame 1.
+    const uint64_t fId1 = getNextFrameId();
     dequeueAndQueue(0);
 
     // Verify a query for the Present and Retire times do not trigger
     // a sync call if they are not supported.
-    const uint32_t framesAgo = 0;
     resetTimestamps();
     int oldCount = mFakeConsumer->mGetFrameTimestampsCount;
-    int result = native_window_get_frame_timestamps(mWindow.get(), framesAgo,
+    int result = native_window_get_frame_timestamps(mWindow.get(), fId1,
             nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
             displayPresentSupported ? nullptr : &outDisplayPresentTime,
             displayRetireSupported ? nullptr : &outDisplayRetireTime,
diff --git a/libs/gui/view/Surface.cpp b/libs/gui/view/Surface.cpp
new file mode 100644
index 0000000..5ed3d3b
--- /dev/null
+++ b/libs/gui/view/Surface.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 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 "Surface"
+
+#include <gui/view/Surface.h>
+
+#include <binder/Parcel.h>
+
+#include <utils/Log.h>
+
+#include <gui/IGraphicBufferProducer.h>
+
+namespace android {
+namespace view {
+
+status_t Surface::writeToParcel(Parcel* parcel) const {
+    return writeToParcel(parcel, false);
+}
+
+status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
+    if (parcel == nullptr) return BAD_VALUE;
+
+    status_t res = OK;
+
+    if (!nameAlreadyWritten) {
+        res = parcel->writeString16(name);
+        if (res != OK) return res;
+
+        /* isSingleBuffered defaults to no */
+        res = parcel->writeInt32(0);
+        if (res != OK) return res;
+    }
+
+    res = parcel->writeStrongBinder(
+            IGraphicBufferProducer::asBinder(graphicBufferProducer));
+
+    return res;
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel) {
+    return readFromParcel(parcel, false);
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
+    if (parcel == nullptr) return BAD_VALUE;
+
+    status_t res = OK;
+    if (!nameAlreadyRead) {
+        name = readMaybeEmptyString16(parcel);
+        // Discard this for now
+        int isSingleBuffered;
+        res = parcel->readInt32(&isSingleBuffered);
+        if (res != OK) {
+            ALOGE("Can't read isSingleBuffered");
+            return res;
+        }
+    }
+
+    sp<IBinder> binder;
+
+    res = parcel->readNullableStrongBinder(&binder);
+    if (res != OK) {
+        ALOGE("%s: Can't read strong binder", __FUNCTION__);
+        return res;
+    }
+
+    graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
+
+    return OK;
+}
+
+String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
+    size_t len;
+    const char16_t* str = parcel->readString16Inplace(&len);
+    if (str != nullptr) {
+        return String16(str, len);
+    } else {
+        return String16();
+    }
+}
+
+} // namespace view
+} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 5ef95ec..b544426 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -50,8 +50,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
 }
 
@@ -64,8 +64,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
     mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
             std::move(requestorName));
@@ -81,8 +81,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
     mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
             producerUsage, consumerUsage, std::move(requestorName));
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index b0ed2df..a3b6e18 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -63,7 +63,14 @@
     if (mMapper->valid()) {
         error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
     } else {
+        // This always returns GRALLOC1_BAD_HANDLE when handle is from a
+        // remote process and mDevice is backed by Gralloc1On0Adapter.
         error = mDevice->retain(handle);
+        if (error == GRALLOC1_ERROR_BAD_HANDLE &&
+                mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+            ALOGE("registerBuffer by handle is not supported with "
+                  "Gralloc1On0Adapter");
+        }
     }
 
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
diff --git a/services/vr/vr_manager/Android.mk b/libs/vr/libvr_manager/Android.mk
similarity index 79%
rename from services/vr/vr_manager/Android.mk
rename to libs/vr/libvr_manager/Android.mk
index 54b1c1a..e9987f7 100644
--- a/services/vr/vr_manager/Android.mk
+++ b/libs/vr/libvr_manager/Android.mk
@@ -14,11 +14,16 @@
 
 LOCAL_PATH := $(call my-dir)
 
+exported_include_dirs := \
+  $(LOCAL_PATH)/include
+
+include_dirs := \
+  frameworks/native/include/vr/vr_manager \
+  $(exported_include_dirs)
+
 src_files := \
   vr_manager.cpp \
-
-inc_files := \
-  frameworks/native/include/vr/vr_manager
+  trusted_uids.cpp
 
 static_libs := \
   libutils \
@@ -26,13 +31,12 @@
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src_files)
-LOCAL_C_INCLUDES := $(inc_files)
+LOCAL_C_INCLUDES := $(include_dirs)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(exported_include_dirs)
 LOCAL_CFLAGS += -Wall
 LOCAL_CFLAGS += -Werror
 LOCAL_CFLAGS += -Wunused
 LOCAL_CFLAGS += -Wunreachable-code
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(inc_files)
-#LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_MODULE := libvr_manager
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
new file mode 100644
index 0000000..4496fbf
--- /dev/null
+++ b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
@@ -0,0 +1,33 @@
+#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
+#define ANDROID_DVR_TRUSTED_UIDS_H_
+
+#include <sys/types.h>
+
+namespace android {
+namespace dvr {
+
+/**
+ * Tells if a provided UID can be trusted to access restricted VR APIs.
+ *
+ * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
+ * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
+ *
+ * UIDs are guaranteed not to be reused until the next reboot even in case
+ * of package reinstall. For performance reasons this method caches results by
+ * default, as otherwise every check would trigger a Java call.
+ *
+ * This function is thread-safe.
+ *
+ * @param uid The uid to check.
+ * @param use_cache If true any cached result for the provided uid will be
+ *     reused. If false this call will reach the Application Manager Service
+ *     in Java to get updated values. Any updates will be stored in the cache.
+ * @return true if the uid is trusted, false if not or if the VR Manager Service
+ *         could not be reached to verify the uid.
+ */
+bool IsTrustedUid(uid_t uid, bool use_cache = true);
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
new file mode 100644
index 0000000..4228a05
--- /dev/null
+++ b/libs/vr/libvr_manager/trusted_uids.cpp
@@ -0,0 +1,51 @@
+#include "private/dvr/trusted_uids.h"
+
+#include <mutex>
+#include <unordered_map>
+
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <private/android_filesystem_config.h>
+#include <utils/String16.h>
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+namespace dvr {
+
+bool IsTrustedUid(uid_t uid, bool use_cache) {
+  static std::unordered_map<uid_t, bool> uid_cache;
+  static std::mutex uid_cache_mutex;
+
+  // Whitelist requests from the system UID.
+  // These are already whitelisted by the permission service, but it might not
+  // be available if the ActivityManagerService is up during boot.
+  // This ensures the correct result for system services while booting up.
+  if (uid == AID_SYSTEM)
+    return true;
+
+  std::lock_guard<std::mutex> lock(uid_cache_mutex);
+
+  if (use_cache) {
+    auto it = uid_cache.find(uid);
+    if (it != uid_cache.end())
+      return it->second;
+  }
+
+  sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+  if (binder == 0) {
+    ALOGW("Could not access permission service");
+    return false;
+  }
+
+  // Note: we ignore the pid because it's only used to automatically reply
+  // true if the caller is the Activity Manager Service.
+  bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
+      String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
+
+  // Cache the information for this uid to avoid future Java calls.
+  uid_cache[uid] = trusted;
+  return trusted;
+}
+
+}  // namespace dvr
+}  // namespace android
diff --git a/services/vr/vr_manager/vr_manager.cpp b/libs/vr/libvr_manager/vr_manager.cpp
similarity index 100%
rename from services/vr/vr_manager/vr_manager.cpp
rename to libs/vr/libvr_manager/vr_manager.cpp
diff --git a/libs/vr/libvrflinger/Android.mk b/libs/vr/libvrflinger/Android.mk
index 6b5e7cc..1706f30 100644
--- a/libs/vr/libvrflinger/Android.mk
+++ b/libs/vr/libvrflinger/Android.mk
@@ -45,6 +45,7 @@
 	libperformance \
 	libsensor \
 	libpdx_default_transport \
+	libvr_manager \
 
 sharedLibraries := \
 	android.dvr.composer@1.0 \
@@ -76,11 +77,6 @@
 LOCAL_CFLAGS += -DTRACE=0
 LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_GRAPHICS
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_USES_QCOM_BSP), true)
-    LOCAL_C_INCLUDES += hardware/qcom/display/libgralloc
-    LOCAL_C_INCLUDES += hardware/qcom/display/libqdutils
-    LOCAL_SHARED_LIBRARIES += libqdutils
-endif
 LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_WHOLE_STATIC_LIBRARIES := $(staticLibraries)
 LOCAL_MODULE := libvrflinger
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index c464c98..5309acf 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -318,6 +318,10 @@
   return hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
 }
 
+void DisplayService::OnHardwareComposerRefresh() {
+  hardware_composer_.OnHardwareComposerRefresh();
+}
+
 void DisplayService::SetDisplayConfigurationUpdateNotifier(
     DisplayConfigurationUpdateNotifier update_notifier) {
   update_notifier_ = update_notifier;
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index ebd97de..5de4f1d 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -68,6 +68,8 @@
     }
   }
 
+  void OnHardwareComposerRefresh();
+
  private:
   friend BASE;
   friend DisplaySurface;
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 5253b26..e6ed665 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -1287,6 +1287,10 @@
   // TODO(eieio): implement display hotplug callbacks.
 }
 
+void HardwareComposer::OnHardwareComposerRefresh() {
+  // TODO(steventhomas): Handle refresh.
+}
+
 void HardwareComposer::SetBacklightBrightness(int brightness) {
   if (backlight_brightness_fd_) {
     std::array<char, 32> text;
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index 33f090d..b6aa807 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -224,6 +224,8 @@
 
   Compositor* GetCompositor() { return &compositor_; }
 
+  void OnHardwareComposerRefresh();
+
  private:
   int32_t EnableVsync(bool enabled);
 
diff --git a/libs/vr/libvrflinger/include/dvr/vr_flinger.h b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
index 04c8363..17dce96 100644
--- a/libs/vr/libvrflinger/include/dvr/vr_flinger.h
+++ b/libs/vr/libvrflinger/include/dvr/vr_flinger.h
@@ -21,6 +21,7 @@
 
   void EnterVrMode();
   void ExitVrMode();
+  void OnHardwareComposerRefresh();
 
  private:
   std::thread displayd_thread_;
diff --git a/libs/vr/libvrflinger/screenshot_service.cpp b/libs/vr/libvrflinger/screenshot_service.cpp
index e174943..fd1c582 100644
--- a/libs/vr/libvrflinger/screenshot_service.cpp
+++ b/libs/vr/libvrflinger/screenshot_service.cpp
@@ -3,7 +3,9 @@
 #include <utils/Trace.h>
 
 #include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
 #include <private/dvr/display_types.h>
+#include <private/dvr/trusted_uids.h>
 
 using android::pdx::Message;
 using android::pdx::MessageInfo;
@@ -40,6 +42,12 @@
 
 ScreenshotData ScreenshotService::OnTakeScreenshot(pdx::Message& message,
                                                    int layer_index) {
+  // Also allow AID_SHELL to support vrscreencap commands.
+  if (message.GetEffectiveUserId() != AID_SHELL &&
+      !IsTrustedUid(message.GetEffectiveUserId())) {
+    REPLY_ERROR_RETURN(message, EACCES, {});
+  }
+
   AddWaiter(std::move(message), layer_index);
   return {};
 }
diff --git a/libs/vr/libvrflinger/vr_flinger.cpp b/libs/vr/libvrflinger/vr_flinger.cpp
index 82ce067..9163e71 100644
--- a/libs/vr/libvrflinger/vr_flinger.cpp
+++ b/libs/vr/libvrflinger/vr_flinger.cpp
@@ -106,5 +106,13 @@
   }
 }
 
+void VrFlinger::OnHardwareComposerRefresh() {
+  if (display_service_) {
+    display_service_->OnHardwareComposerRefresh();
+  } else {
+    ALOGE("OnHardwareComposerRefresh failed : Display service is not started.");
+  }
+}
+
 }  // namespace dvr
 }  // namespace android
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 027c18d..6485ae5 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -643,10 +643,12 @@
 #define EGL_DEQUEUE_READY_TIME_ANDROID 0x3156
 #define EGL_READS_DONE_TIME_ANDROID 0x3157
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+EGLAPI EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
 EGLAPI EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
 #else
-typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROID) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYTIMESTAMPSUPPORTEDANDROID) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
 #endif
 #endif
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 2782ed7..2d02b72 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -216,6 +216,8 @@
             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
 
     // EGL_ANDROID_get_frame_timestamps
+    { "eglGetNextFrameIdANDROID",
+            (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
     { "eglGetFrameTimestampsANDROID",
             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
     { "eglQueryTimestampSupportedANDROID",
@@ -2048,8 +2050,42 @@
     return EGL_FALSE;
 }
 
+EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
+            EGLuint64KHR *frameId) {
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    SurfaceRef _s(dp.get(), surface);
+    if (!_s.get()) {
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    egl_surface_t const * const s = get_surface(surface);
+
+    if (!s->win.get()) {
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    uint64_t nextFrameId = 0;
+    status_t ret = native_window_get_next_frame_id(s->win.get(), &nextFrameId);
+
+    if (ret != NO_ERROR) {
+        // This should not happen. Return an error that is not in the spec
+        // so it's obvious something is very wrong.
+        ALOGE("eglGetNextFrameId: Unexpected error.");
+        return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+    }
+
+    *frameId = nextFrameId;
+    return EGL_TRUE;
+}
+
 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
-        EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps,
+        EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
         EGLnsecsANDROID *values)
 {
     clearError();
@@ -2118,7 +2154,7 @@
         }
     }
 
-    status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo,
+    status_t ret = native_window_get_frame_timestamps(s->win.get(), frameId,
             requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
             lastRefreshStartTime, GLCompositionDoneTime, displayPresentTime,
             displayRetireTime, dequeueReadyTime, releaseTime);
@@ -2135,6 +2171,7 @@
       default:
         // This should not happen. Return an error that is not in the spec
         // so it's obvious something is very wrong.
+        ALOGE("eglGetFrameTimestamps: Unexpected error.");
         return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
     }
 }
diff --git a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
index 7aa0d30..f24d634 100644
--- a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
+++ b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
@@ -57,9 +57,12 @@
 
 New Procedures and Functions
 
+    EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
+            EGLuint64KHR *frameId);
+
     EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
-            EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps,
-            EGLnsecsANDROID *values);
+            EGLuint64KHR frameId, EGLint numTimestamps,
+            const EGLint *timestamps, EGLnsecsANDROID *values);
 
     EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface
             surface, EGLint timestamp);
@@ -95,23 +98,31 @@
 
     The function
 
-        EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface
-            surface, EGLint framesAgo, EGLint numTimestamps,
+        EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
+            EGLuint64KHR *frameId);
+
+    Returns an identifier for the next frame to be swapped. The identifier can
+    be used to correlate a particular eglSwapBuffers with its timestamps in
+    eglGetFrameTimestampsANDROID. If any error is generated, the function will
+    return EGL_FALSE.
+
+    The function
+
+        EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy,
+            EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps,
             const EGLint *timestamps, EGLnsecsANDROID *values);
 
-    allows querying various timestamps related to the composition and display of
-    a window surface.
+    allows querying various timestamps related to the composition and display
+    of specific frames of a window surface.
 
-    The framesAgo parameter indicates how many frames before the last queued
-    frame to query. So a value of zero would indicate that the query is for the
-    last queued frame. Note that the implementation maintains a limited history
-    of timestamp data. If a query is made for a frame whose timestamp history
-    no longer exists then EGL_BAD_ACCESS is generated. If timestamp collection
-    has not been enabled for the surface then EGL_BAD_SURFACE is generated.
-    Timestamps for events that will not occur or have not yet occurred will be
-    zero. Timestamp queries that are not supported will generate an
-    EGL_BAD_PARAMETER error. If any error is generated the function will return
-    EGL_FALSE.
+    The frameId indicates which frame to query. The implementation maintains a
+    limited history of timestamp data. If a query is made for a frame whose
+    timestamp history no longer exists then EGL_BAD_ACCESS is generated. If
+    timestamp collection has not been enabled for the surface then
+    EGL_BAD_SURFACE is generated.  Timestamps for events that will not occur or
+    have not yet occurred will be zero. Timestamp queries that are not
+    supported will generate an EGL_BAD_PARAMETER error. If any error is
+    generated the function will return EGL_FALSE.
 
     The eglGetFrameTimestampsANDROID function takes an array of timestamps to
     query and returns timestamps in the corresponding indices of the values
@@ -175,3 +186,6 @@
     - Add EGL_COMPOSITION_LATCH_TIME_ANDROID,
       EGL_LAST_COMPOSITION_START_TIME_ANDROID, and
       EGL_DEQUEUE_READY_TIME_ANDROID.
+
+#4 (Brian Anderson, January 10, 2017)
+    - Use an absolute frameId rather than a relative framesAgo.
diff --git a/opengl/specs/README b/opengl/specs/README
index 8a3a7aa..1853214 100644
--- a/opengl/specs/README
+++ b/opengl/specs/README
@@ -1,5 +1,5 @@
 This directory contains OpenGL ES and EGL extension specifications that have
-been or are being defined for Android.  
+been or are being defined for Android.
 
 The table below tracks usage of EGL enumerant values that have been reserved
 for use by Android extensions.
diff --git a/services/sensorservice/SensorServiceUtils.cpp b/services/sensorservice/SensorServiceUtils.cpp
index 1996a00..34cd8dd 100644
--- a/services/sensorservice/SensorServiceUtils.cpp
+++ b/services/sensorservice/SensorServiceUtils.cpp
@@ -54,6 +54,7 @@
         case SENSOR_TYPE_STATIONARY_DETECT:
         case SENSOR_TYPE_MOTION_DETECT:
         case SENSOR_TYPE_HEART_BEAT:
+        case SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT:
             return 1;
 
         default:
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 2b603cc..a6171f5 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -2010,7 +2010,8 @@
     mZ(0),
     mReleaseFence(),
     mHwc1Id(0),
-    mHasUnsupportedPlaneAlpha(false) {}
+    mHasUnsupportedPlaneAlpha(false),
+    mHasUnsupportedBackgroundColor(false) {}
 
 bool HWC2On1Adapter::SortLayersByZ::operator()(
         const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs)
@@ -2466,7 +2467,7 @@
         }
     }
 
-    if (mHwc1DisplayMap.count(0) == 0) {
+    if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
         ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
         return false;
     }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 1c99036..4a281d4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -60,9 +60,8 @@
 
 // ---------------------------------------------------------------------------
 
-HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer)
-    : mFlinger(flinger),
-      mAdapter(),
+HWComposer::HWComposer(bool useVrComposer)
+    : mAdapter(),
       mHwcDevice(),
       mDisplayData(2),
       mFreeDisplaySlots(),
@@ -211,7 +210,7 @@
 }
 
 void HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
-    mFlinger->repaintEverything();
+    mEventHandler->onInvalidateReceived(this);
 }
 
 void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
@@ -257,7 +256,7 @@
     snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
     ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
 
-    mEventHandler->onVSyncReceived(disp, timestamp);
+    mEventHandler->onVSyncReceived(this, disp, timestamp);
 }
 
 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -915,6 +914,10 @@
         const sp<GraphicBuffer>& buffer,
         uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
 {
+#ifdef BYPASS_IHWC
+    *outSlot = slot;
+    *outBuffer = buffer;
+#else
     if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
         // default to slot 0
         slot = 0;
@@ -935,6 +938,7 @@
         // update cache
         mBuffers[slot] = buffer;
     }
+#endif
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 7b61e0e..0713709 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -64,15 +64,16 @@
 class NativeHandle;
 class Region;
 class String8;
-class SurfaceFlinger;
 
 class HWComposer
 {
 public:
     class EventHandler {
         friend class HWComposer;
-        virtual void onVSyncReceived(int32_t disp, nsecs_t timestamp) = 0;
+        virtual void onVSyncReceived(
+            HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
         virtual void onHotplugReceived(int32_t disp, bool connected) = 0;
+        virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
     };
@@ -80,7 +81,7 @@
     // useVrComposer is passed to the composer HAL. When true, the composer HAL
     // will use the vr composer service, otherwise it uses the real hardware
     // composer.
-    HWComposer(const sp<SurfaceFlinger>& flinger, bool useVrComposer);
+    HWComposer(bool useVrComposer);
 
     ~HWComposer();
 
@@ -211,7 +212,6 @@
         HWC2::Vsync vsyncEnabled;
     };
 
-    sp<SurfaceFlinger>              mFlinger;
     std::unique_ptr<HWC2On1Adapter> mAdapter;
     std::unique_ptr<HWC2::Device>   mHwcDevice;
     std::vector<DisplayData>        mDisplayData;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index cc5578d..0bfc56e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -277,7 +277,7 @@
 }
 
 void HWComposer::invalidate() {
-    mFlinger->repaintEverything();
+    mEventHandler.onInvalidateReceived(this);
 }
 
 void HWComposer::vsync(int disp, int64_t timestamp) {
@@ -302,7 +302,7 @@
         snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
         ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
 
-        mEventHandler.onVSyncReceived(disp, timestamp);
+        mEventHandler.onVSyncReceived(this, disp, timestamp);
     }
 }
 
@@ -1318,7 +1318,7 @@
     } while (err<0 && errno == EINTR);
 
     if (err == 0) {
-        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
+        mHwc.mEventHandler.onVSyncReceived(&mHwc, 0, next_vsync);
     }
 
     return true;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index bca25ac..a94bc1e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -62,8 +62,10 @@
 public:
     class EventHandler {
         friend class HWComposer;
-        virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
+        virtual void onVSyncReceived(
+            HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
         virtual void onHotplugReceived(int disp, bool connected) = 0;
+        virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
     };
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3a9bca6..6e0a489 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -427,7 +427,9 @@
     Rect bounds = win;
     const auto& p = getParent();
     if (p != nullptr) {
-        bounds = p->computeScreenBounds();
+        // Look in computeScreenBounds recursive call for explanation of
+        // why we pass false here.
+        bounds = p->computeScreenBounds(false /* reduceTransparentRegion */);
     }
 
     Transform t = getTransform();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 30bce55..cbc209d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -579,7 +579,7 @@
     // the lock because on creation, it will call back into SurfaceFlinger to
     // initialize the primary display.
     LOG_ALWAYS_FATAL_IF(mEnterVrMode, "Starting in vr mode is not currently supported.");
-    mRealHwc = new HWComposer(this, false);
+    mRealHwc = new HWComposer(false);
     mHwc = mRealHwc;
     mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
 
@@ -1102,7 +1102,14 @@
     }
 }
 
-void SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
+void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type,
+                                     nsecs_t timestamp) {
+    Mutex::Autolock lock(mStateLock);
+    // Ignore any vsyncs from the non-active hardware composer.
+    if (composer != mHwc) {
+        return;
+    }
+
     bool needsHwVsync = false;
 
     { // Scope for the lock
@@ -1163,6 +1170,20 @@
     }
 }
 
+void SurfaceFlinger::onInvalidateReceived(HWComposer* composer) {
+    Mutex::Autolock lock(mStateLock);
+    if (composer == mHwc) {
+        repaintEverything();
+    } else {
+        // This isn't from our current hardware composer. If it's a callback
+        // from the real composer, forward the refresh request to vr
+        // flinger. Otherwise ignore it.
+        if (!composer->isUsingVrComposer()) {
+            mVrFlinger->OnHardwareComposerRefresh();
+        }
+    }
+}
+
 void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
     ATRACE_CALL();
     getHwComposer().setVsyncEnabled(disp,
@@ -1209,7 +1230,7 @@
             }
 
             if (!mVrHwc) {
-                mVrHwc = new HWComposer(this, true);
+                mVrHwc = new HWComposer(true);
                 ALOGV("Vr HWC created");
             }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6dfdf08..02e4a0c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -247,8 +247,9 @@
     /* ------------------------------------------------------------------------
      * HWComposer::EventHandler interface
      */
-    virtual void onVSyncReceived(int type, nsecs_t timestamp);
+    virtual void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp);
     virtual void onHotplugReceived(int disp, bool connected);
+    virtual void onInvalidateReceived(HWComposer* composer);
 
     /* ------------------------------------------------------------------------
      * Message handling
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 7e6eb03..40a27e8 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -1018,7 +1018,8 @@
     }
 }
 
-void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
+void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type,
+                                     nsecs_t timestamp) {
     bool needsHwVsync = false;
 
     { // Scope for the lock
@@ -1058,6 +1059,10 @@
     }
 }
 
+void SurfaceFlinger::onInvalidateReceived(HWComposer* /*composer*/) {
+    repaintEverything();
+}
+
 void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
     ATRACE_CALL();
     getHwComposer().eventControl(disp, event, enabled);
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
index 47d9dcc..85f8e1f 100644
--- a/services/vr/vr_window_manager/Android.mk
+++ b/services/vr/vr_window_manager/Android.mk
@@ -110,6 +110,7 @@
 LOCAL_LDLIBS := -llog
 LOCAL_MODULE := libvr_window_manager_jni
 LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
 LOCAL_MULTILIB := 64
 LOCAL_CXX_STL := libc++_static
 include $(BUILD_SHARED_LIBRARY)
@@ -126,6 +127,7 @@
 LOCAL_LDLIBS := -llog
 LOCAL_MODULE := vr_wm
 LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
 LOCAL_INIT_RC := vr_wm.rc
 include $(BUILD_EXECUTABLE)
 
@@ -147,6 +149,7 @@
 LOCAL_AAPT_FLAGS += --auto-add-overlay
 LOCAL_AAPT_FLAGS += --extra-packages com.google.vr.cardboard
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
 include $(BUILD_PACKAGE)
 
 
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 5a67d36..a89fed9 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -2908,14 +2908,20 @@
     platform.HWND                               hwnd
 }
 
+@internal class Gralloc1Usage {
+    u64                                         consumer
+    u64                                         producer
+}
+
 @extension("VK_ANDROID_native_buffer")
 class VkNativeBufferANDROID {
     VkStructureType                             sType
     const void*                                 pNext
     platform.buffer_handle_t                    handle
-    int                                         stride
-    int                                         format
-    int                                         usage
+    s32                                         stride
+    s32                                         format
+    s32                                         usage
+    Gralloc1Usage                               usage2
 }
 
 @extension("VK_ANDROID_native_buffer")
@@ -5833,21 +5839,24 @@
 }
 
 @extension("VK_ANDROID_native_buffer")
+@optional
 cmd VkResult vkGetSwapchainGrallocUsageANDROID(
         VkDevice                                device,
         VkFormat                                format,
         VkImageUsageFlags                       imageUsage,
-        int*                                    grallocUsage) {
+        s32*                                    grallocUsage) {
     return ?
 }
 
 @extension("VK_ANDROID_native_buffer")
+@optional
 cmd VkResult vkGetSwapchainGrallocUsage2ANDROID(
         VkDevice                                device,
         VkFormat                                format,
         VkImageUsageFlags                       imageUsage,
         VkSwapchainImageUsageFlagsANDROID       swapchainImageUsage,
-        int*                                    grallocUsage) {
+        u64*                                    grallocConsumerUsage,
+        u64*                                    grallocProducerUsage) {
     return ?
 }
 
diff --git a/vulkan/doc/implementors_guide/implementors_guide.adoc b/vulkan/doc/implementors_guide/implementors_guide.adoc
index 009472a..24af950 100644
--- a/vulkan/doc/implementors_guide/implementors_guide.adoc
+++ b/vulkan/doc/implementors_guide/implementors_guide.adoc
@@ -47,19 +47,7 @@
 
 The +vk_wsi_swapchin+ and +vk_wsi_device_swapchain+ extensions are primarily be implemented by the platform and live in +libvulkan.so+. The +VkSwapchain+ object and all interaction with +ANativeWindow+ will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver's +vkGetDeviceProcAddr+ functions, after passing through any enabled layers.
 
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
-[source,c]
-----
-VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
-    VkDevice            device,
-    VkFormat            format,
-    VkImageUsageFlags   imageUsage,
-    int*                grallocUsage
-);
-----
-The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
-
-Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The additional usage bits are defined as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The swapchain usage bits are defined as
 [source,c]
 ----
 typedef enum VkSwapchainImageUsageFlagBitsANDROID {
@@ -69,7 +57,7 @@
 typedef VkFlags VkSwapchainImageUsageFlagsANDROID;
 ----
 
-If the driver provides the +vkGetSwapchainGrallocUsage2ANDROID+ function, the platform will use it in preference to +vkGetSwapchainGrallocUsageANDROID+ when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. +vkGetSwapchainGrallocUsage2ANDROID+ behaves in the same way as +vkGetSwapchainGrallocUsageANDROID+, and is declared as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
 [source,c]
 ----
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
@@ -77,6 +65,19 @@
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
+    uint64_t*           grallocConsumerUsage,
+    uint64_t*           grallocProducerUsage,
+);
+----
+The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocConsumerUsage+ and +*grallocProducerUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
+
+An older version of this function is deprecated but still supported for backwards compatibility; it will be used if +vkGetSwapchainGrallocUsage2ANDROID+ is not supported:
+[source,c]
+----
+VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
+    VkDevice            device,
+    VkFormat            format,
+    VkImageUsageFlags   imageUsage,
     int*                grallocUsage
 );
 ----
@@ -95,7 +96,11 @@
 
     // Gralloc format and usage requested when the buffer was allocated.
     int                         format;
-    int                         usage;
+    int                         usage; // deprecated
+    struct {
+        uint64_t                consumer;
+        uint64_t                producer;
+    } usage2;
 } VkNativeBufferANDROID;
 ----
 
@@ -200,3 +205,5 @@
    * Added VkSwapchainImageUsageFlagBitsANDROID
    * Added vkGetSwapchainGrallocUsage2ANDROID
    * Added VkSwapchainImageCreateInfoANDROID
+. *2017-02-09*
+   * Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
\ No newline at end of file
diff --git a/vulkan/doc/implementors_guide/implementors_guide.html b/vulkan/doc/implementors_guide/implementors_guide.html
index 4e74a78..9fecce5 100644
--- a/vulkan/doc/implementors_guide/implementors_guide.html
+++ b/vulkan/doc/implementors_guide/implementors_guide.html
@@ -730,7 +730,7 @@
 /*]]>*/
 </script>
 </head>
-<body class="article">
+<body class="book">
 <div id="header">
 <h1>Vulkan on Android Implementor&#8217;s Guide</h1>
 <span id="revnumber">version 5</span>
@@ -793,20 +793,7 @@
 <h2 id="_window_system_integration">2. Window System Integration</h2>
 <div class="sectionbody">
 <div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver&#8217;s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
-    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span><span style="color: #990000">*</span>                grallocUsage
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
-<div class="paragraph"><p>Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The additional usage bits are defined as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
@@ -817,7 +804,7 @@
     VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span>
 <span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span>
 <span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>If the driver provides the <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> function, the platform will use it in preference to <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span> when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> behaves in the same way as <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span>, and is declared as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
@@ -828,6 +815,20 @@
     <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
     <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
     <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span>
+    uint64_t<span style="color: #990000">*</span>           grallocConsumerUsage<span style="color: #990000">,</span>
+    uint64_t<span style="color: #990000">*</span>           grallocProducerUsage<span style="color: #990000">,</span>
+<span style="color: #990000">);</span></tt></pre></div></div>
+<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
+<div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.6
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
+    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
+    <span style="color: #008080">VkFormat</span>            format<span style="color: #990000">,</span>
+    <span style="color: #008080">VkImageUsageFlags</span>   imageUsage<span style="color: #990000">,</span>
     <span style="color: #009900">int</span><span style="color: #990000">*</span>                grallocUsage
 <span style="color: #990000">);</span></tt></pre></div></div>
 <div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div>
@@ -846,7 +847,11 @@
 
     <span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span>
     <span style="color: #009900">int</span>                         format<span style="color: #990000">;</span>
-    <span style="color: #009900">int</span>                         usage<span style="color: #990000">;</span>
+    <span style="color: #009900">int</span>                         usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span>
+    <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
+        <span style="color: #008080">uint64_t</span>                consumer<span style="color: #990000">;</span>
+        <span style="color: #008080">uint64_t</span>                producer<span style="color: #990000">;</span>
+    <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span>
 <span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div>
 <div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div>
 <div class="listingblock">
@@ -1044,6 +1049,18 @@
 </li>
 </ul></div>
 </li>
+<li>
+<p>
+<strong>2017-02-09</strong>
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
+</p>
+</li>
+</ul></div>
+</li>
 </ol></div>
 </div>
 </div>
@@ -1052,7 +1069,7 @@
 <div id="footer">
 <div id="footer-text">
 Version 5<br>
-Last updated 2017-01-12 14:25:30 NZDT
+Last updated 2017-02-09 22:40:30 PST
 </div>
 </div>
 </body>
diff --git a/vulkan/include/vulkan/vk_android_native_buffer.h b/vulkan/include/vulkan/vk_android_native_buffer.h
index db23e79..d7c5a07 100644
--- a/vulkan/include/vulkan/vk_android_native_buffer.h
+++ b/vulkan/include/vulkan/vk_android_native_buffer.h
@@ -27,6 +27,16 @@
 #define VK_ANDROID_native_buffer 1
 
 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NUMBER 11
+/* NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 6
+ *
+ * This version of the extension transitions from gralloc0 to gralloc1 usage
+ * flags (int -> 2x uint64_t). The WSI implementation will temporarily continue
+ * to fill out deprecated fields in VkNativeBufferANDROID, and will call the
+ * deprecated vkGetSwapchainGrallocUsageANDROID if the new
+ * vkGetSwapchainGrallocUsage2ANDROID is not supported. This transitionary
+ * backwards-compatibility support is temporary, and will likely be removed in
+ * (along with all gralloc0 support) in a future release.
+ */
 #define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION     6
 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME   "VK_ANDROID_native_buffer"
 
@@ -50,7 +60,12 @@
 
     // Gralloc format and usage requested when the buffer was allocated.
     int                         format;
-    int                         usage;
+    int                         usage; // DEPRECATED in SPEC_VERSION 6
+    // -- Added in SPEC_VERSION 6 --
+    struct {
+        uint64_t                consumer;
+        uint64_t                producer;
+    } usage2;
 } VkNativeBufferANDROID;
 
 typedef struct {
@@ -60,24 +75,30 @@
     VkSwapchainImageUsageFlagsANDROID      usage;
 } VkSwapchainImageCreateInfoANDROID;
 
+// -- DEPRECATED in SPEC_VERSION 6 --
 typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsageANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+// -- ADDED in SPEC_VERSION 6 --
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
 typedef VkResult (VKAPI_PTR *PFN_vkAcquireImageANDROID)(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
 typedef VkResult (VKAPI_PTR *PFN_vkQueueSignalReleaseImageANDROID)(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
 
 #ifndef VK_NO_PROTOTYPES
+
+// -- DEPRECATED in SPEC_VERSION 6 --
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsageANDROID(
     VkDevice            device,
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     int*                grallocUsage
 );
+// -- ADDED in SPEC_VERSION 6 --
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
     VkDevice            device,
     VkFormat            format,
     VkImageUsageFlags   imageUsage,
     VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
-    int*                grallocUsage
+    uint64_t*           grallocConsumerUsage,
+    uint64_t*           grallocProducerUsage
 );
 VKAPI_ATTR VkResult VKAPI_CALL vkAcquireImageANDROID(
     VkDevice            device,
@@ -93,17 +114,6 @@
     VkImage             image,
     int*                pNativeFenceFd
 );
-// -- DEPRECATED --
-VKAPI_ATTR VkResult VKAPI_CALL vkImportNativeFenceANDROID(
-    VkDevice            device,
-    VkSemaphore         semaphore,
-    int                 nativeFenceFd
-);
-VKAPI_ATTR VkResult VKAPI_CALL vkQueueSignalNativeFenceANDROID(
-    VkQueue             queue,
-    int*                pNativeFenceFd
-);
-// ----------------
 #endif
 
 #ifdef __cplusplus
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 501877c..e3c44d2 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -413,13 +413,14 @@
   {{AssertType $ "Function"}}
 
   {{$ext := GetAnnotation $ "extension"}}
-  {{$required := (Macro "IsRequiredFunction" $)}}
   {{if $ext}}
-    INIT_PROC_EXT({{Macro "BaseName" $ext}}, {{$required}}, §
+    INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
   {{else}}
-    INIT_PROC({{$required}}, §
+    INIT_PROC(§
   {{end}}
 
+  {{if GetAnnotation $ "optional"}}false{{else}}true{{end}}, §
+
   {{if (Macro "IsInstanceDispatched" $)}}
     instance, §
   {{else}}
@@ -432,25 +433,6 @@
 
 {{/*
 ------------------------------------------------------------------------------
-  Emits true if a function /must/ be resolved. The only time this is not
-  the case is for extension-added functions added in a later revision of the
-  extension, and where we have to cope with drivers written against an older
-  revision.
-------------------------------------------------------------------------------
-*/}}
-{{define "IsRequiredFunction"}}
-  {{AssertType $ "Function"}}
-
-  {{if eq $.Name "vkGetSwapchainGrallocUsage2ANDROID"}}
-    false
-  {{else}}
-    true
-  {{end}}
-{{end}}
-
-
-{{/*
-------------------------------------------------------------------------------
   Emits true if a function is exported and instance-dispatched.
 ------------------------------------------------------------------------------
 */}}
@@ -981,6 +963,8 @@
     {{else if eq $.Name "vkCreateImage"}}true
     {{else if eq $.Name "vkDestroyImage"}}true
 
+    {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
+
     {{end}}
 
     {{$ext := GetAnnotation $ "extension"}}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 991c3ed..a23056c 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -739,8 +739,10 @@
     const InstanceData& data = GetData(physicalDevice);
     static const std::array<VkExtensionProperties, 2> loader_extensions = {{
         // WSI extensions
+#if 0 // Remove this "#if 0" once the VK_KHR_incremental_present extension is ratified
         {VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
          VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION},
+#endif
         {VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
          VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION},
     }};
@@ -899,7 +901,29 @@
 
         return VK_ERROR_INCOMPATIBLE_DRIVER;
     }
+
+    // sanity check ANDROID_native_buffer implementation, whose set of
+    // entrypoints varies according to the spec version.
+    if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
+        !data->driver.GetSwapchainGrallocUsageANDROID &&
+        !data->driver.GetSwapchainGrallocUsage2ANDROID) {
+        ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
+              " must expose at least one of "
+              "vkGetSwapchainGrallocUsageANDROID or "
+              "vkGetSwapchainGrallocUsage2ANDROID");
+
+        data->driver.DestroyDevice(dev, pAllocator);
+        FreeDeviceData(data, data_allocator);
+
+        return VK_ERROR_INCOMPATIBLE_DRIVER;
+    }
+
+    VkPhysicalDeviceProperties properties;
+    instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
+                                                     &properties);
+
     data->driver_device = dev;
+    data->driver_version = properties.driverVersion;
 
     *pDevice = dev;
 
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index e058439..5383f59 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -102,6 +102,7 @@
 
     VkDevice driver_device;
     DeviceDriverTable driver;
+    uint32_t driver_version;
 };
 
 bool Debuggable();
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index 689a228..951ea6e 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -387,6 +387,7 @@
     INIT_PROC(true, instance, DestroyInstance);
     INIT_PROC(true, instance, EnumeratePhysicalDevices);
     INIT_PROC(true, instance, GetInstanceProcAddr);
+    INIT_PROC(true, instance, GetPhysicalDeviceProperties);
     INIT_PROC(true, instance, CreateDevice);
     INIT_PROC(true, instance, EnumerateDeviceExtensionProperties);
     INIT_PROC_EXT(EXT_debug_report, true, instance, CreateDebugReportCallbackEXT);
@@ -410,7 +411,7 @@
     INIT_PROC(true, dev, CreateImage);
     INIT_PROC(true, dev, DestroyImage);
     INIT_PROC(true, dev, AllocateCommandBuffers);
-    INIT_PROC_EXT(ANDROID_native_buffer, true, dev, GetSwapchainGrallocUsageANDROID);
+    INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 9f3b705..95c70f8 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -60,6 +60,7 @@
     PFN_vkDestroyInstance DestroyInstance;
     PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+    PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
     PFN_vkCreateDevice CreateDevice;
     PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
     PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index f4ee375..9630ac9 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -20,7 +20,7 @@
 #include <gui/BufferQueue.h>
 #include <sync/sync.h>
 #include <utils/StrongPointer.h>
-#include <utils/SortedVector.h>
+#include <utils/Vector.h>
 
 #include "driver.h"
 
@@ -108,19 +108,11 @@
 
 class TimingInfo {
    public:
-    TimingInfo()
-        : vals_{0, 0, 0, 0, 0},
-          timestamp_desired_present_time_(0),
-          timestamp_actual_present_time_(0),
-          timestamp_render_complete_time_(0),
-          timestamp_composition_latch_time_(0) {}
-    TimingInfo(const VkPresentTimeGOOGLE* qp)
+    TimingInfo() = default;
+    TimingInfo(const VkPresentTimeGOOGLE* qp, uint64_t nativeFrameId)
         : vals_{qp->presentID, qp->desiredPresentTime, 0, 0, 0},
-          timestamp_desired_present_time_(0),
-          timestamp_actual_present_time_(0),
-          timestamp_render_complete_time_(0),
-          timestamp_composition_latch_time_(0) {}
-    bool ready() {
+          native_frame_id_(nativeFrameId) {}
+    bool ready() const {
         return (timestamp_desired_present_time_ &&
                 timestamp_actual_present_time_ &&
                 timestamp_render_complete_time_ &&
@@ -148,27 +140,20 @@
         vals_.earliestPresentTime = early_time;
         vals_.presentMargin = margin;
     }
-    void get_values(VkPastPresentationTimingGOOGLE* values) { *values = vals_; }
+    void get_values(VkPastPresentationTimingGOOGLE* values) const {
+        *values = vals_;
+    }
 
    public:
-    VkPastPresentationTimingGOOGLE vals_;
+    VkPastPresentationTimingGOOGLE vals_ { 0, 0, 0, 0, 0 };
 
-    uint64_t timestamp_desired_present_time_;
-    uint64_t timestamp_actual_present_time_;
-    uint64_t timestamp_render_complete_time_;
-    uint64_t timestamp_composition_latch_time_;
+    uint64_t native_frame_id_ { 0 };
+    uint64_t timestamp_desired_present_time_ { 0 };
+    uint64_t timestamp_actual_present_time_ { 0 };
+    uint64_t timestamp_render_complete_time_ { 0 };
+    uint64_t timestamp_composition_latch_time_ { 0 };
 };
 
-static inline int compare_type(const TimingInfo& lhs, const TimingInfo& rhs) {
-    // TODO(ianelliott): Change this from presentID to the frame ID once
-    // brianderson lands the appropriate patch:
-    if (lhs.vals_.presentID < rhs.vals_.presentID)
-        return -1;
-    if (lhs.vals_.presentID > rhs.vals_.presentID)
-        return 1;
-    return 0;
-}
-
 // ----------------------------------------------------------------------------
 
 struct Surface {
@@ -191,11 +176,13 @@
 enum { MIN_NUM_FRAMES_AGO = 5 };
 
 struct Swapchain {
-    Swapchain(Surface& surface_, uint32_t num_images_)
+    Swapchain(Surface& surface_,
+              uint32_t num_images_,
+              VkPresentModeKHR present_mode)
         : surface(surface_),
           num_images(num_images_),
+          mailbox_mode(present_mode == VK_PRESENT_MODE_MAILBOX_KHR),
           frame_timestamps_enabled(false) {
-        timing.clear();
         ANativeWindow* window = surface.window.get();
         int64_t rdur;
         native_window_get_refresh_cycle_duration(
@@ -206,6 +193,7 @@
 
     Surface& surface;
     uint32_t num_images;
+    bool mailbox_mode;
     bool frame_timestamps_enabled;
     uint64_t refresh_duration;
 
@@ -221,7 +209,7 @@
         bool dequeued;
     } images[android::BufferQueue::NUM_BUFFER_SLOTS];
 
-    android::SortedVector<TimingInfo> timing;
+    android::Vector<TimingInfo> timing;
 };
 
 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain) {
@@ -293,73 +281,64 @@
 }
 
 uint32_t get_num_ready_timings(Swapchain& swapchain) {
-    uint32_t num_ready = 0;
-    uint32_t num_timings = static_cast<uint32_t>(swapchain.timing.size());
-    uint32_t frames_ago = num_timings;
-    for (uint32_t i = 0; i < num_timings; i++) {
-        TimingInfo* ti = &swapchain.timing.editItemAt(i);
-        if (ti) {
-            if (ti->ready()) {
-                // This TimingInfo is ready to be reported to the user.  Add it
-                // to the num_ready.
-                num_ready++;
-            } else {
-                // This TimingInfo is not yet ready to be reported to the user,
-                // and so we should look for any available timestamps that
-                // might make it ready.
-                int64_t desired_present_time = 0;
-                int64_t render_complete_time = 0;
-                int64_t composition_latch_time = 0;
-                int64_t actual_present_time = 0;
-                for (uint32_t f = MIN_NUM_FRAMES_AGO; f < frames_ago; f++) {
-                    // Obtain timestamps:
-                    int ret = native_window_get_frame_timestamps(
-                        swapchain.surface.window.get(), f,
-                        &desired_present_time, &render_complete_time,
-                        &composition_latch_time,
-                        NULL,  //&first_composition_start_time,
-                        NULL,  //&last_composition_start_time,
-                        NULL,  //&composition_finish_time,
-                        // TODO(ianelliott): Maybe ask if this one is
-                        // supported, at startup time (since it may not be
-                        // supported):
-                        &actual_present_time,
-                        NULL,  //&display_retire_time,
-                        NULL,  //&dequeue_ready_time,
-                        NULL /*&reads_done_time*/);
-                    if (ret) {
-                        break;
-                    } else if (!ret) {
-                        // We obtained at least one valid timestamp.  See if it
-                        // is for the present represented by this TimingInfo:
-                        if (static_cast<uint64_t>(desired_present_time) ==
-                            ti->vals_.desiredPresentTime) {
-                            // Record the timestamp(s) we received, and then
-                            // see if this TimingInfo is ready to be reported
-                            // to the user:
-                            ti->timestamp_desired_present_time_ =
-                                static_cast<uint64_t>(desired_present_time);
-                            ti->timestamp_actual_present_time_ =
-                                static_cast<uint64_t>(actual_present_time);
-                            ti->timestamp_render_complete_time_ =
-                                static_cast<uint64_t>(render_complete_time);
-                            ti->timestamp_composition_latch_time_ =
-                                static_cast<uint64_t>(composition_latch_time);
+    if (swapchain.timing.size() < MIN_NUM_FRAMES_AGO) {
+        return 0;
+    }
 
-                            if (ti->ready()) {
-                                // The TimingInfo has received enough
-                                // timestamps, and should now use those
-                                // timestamps to calculate the info that should
-                                // be reported to the user:
-                                //
-                                ti->calculate(swapchain.refresh_duration);
-                                num_ready++;
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
+    uint32_t num_ready = 0;
+    const size_t num_timings = swapchain.timing.size() - MIN_NUM_FRAMES_AGO + 1;
+    for (uint32_t i = 0; i < num_timings; i++) {
+        TimingInfo& ti = swapchain.timing.editItemAt(i);
+        if (ti.ready()) {
+            // This TimingInfo is ready to be reported to the user.  Add it
+            // to the num_ready.
+            num_ready++;
+            continue;
+        }
+        // This TimingInfo is not yet ready to be reported to the user,
+        // and so we should look for any available timestamps that
+        // might make it ready.
+        int64_t desired_present_time = 0;
+        int64_t render_complete_time = 0;
+        int64_t composition_latch_time = 0;
+        int64_t actual_present_time = 0;
+        // Obtain timestamps:
+        int ret = native_window_get_frame_timestamps(
+            swapchain.surface.window.get(), ti.native_frame_id_,
+            &desired_present_time, &render_complete_time,
+            &composition_latch_time,
+            NULL,  //&first_composition_start_time,
+            NULL,  //&last_composition_start_time,
+            NULL,  //&composition_finish_time,
+            // TODO(ianelliott): Maybe ask if this one is
+            // supported, at startup time (since it may not be
+            // supported):
+            &actual_present_time,
+            NULL,  //&display_retire_time,
+            NULL,  //&dequeue_ready_time,
+            NULL /*&reads_done_time*/);
+
+        if (ret != android::NO_ERROR) {
+            continue;
+        }
+
+        // Record the timestamp(s) we received, and then see if this TimingInfo
+        // is ready to be reported to the user:
+        ti.timestamp_desired_present_time_ =
+            static_cast<uint64_t>(desired_present_time);
+        ti.timestamp_actual_present_time_ =
+            static_cast<uint64_t>(actual_present_time);
+        ti.timestamp_render_complete_time_ =
+            static_cast<uint64_t>(render_complete_time);
+        ti.timestamp_composition_latch_time_ =
+               static_cast<uint64_t>(composition_latch_time);
+
+        if (ti.ready()) {
+            // The TimingInfo has received enough timestamps, and should now
+            // use those timestamps to calculate the info that should be
+            // reported to the user:
+            ti.calculate(swapchain.refresh_duration);
+            num_ready++;
         }
     }
     return num_ready;
@@ -369,29 +348,35 @@
 void copy_ready_timings(Swapchain& swapchain,
                         uint32_t* count,
                         VkPastPresentationTimingGOOGLE* timings) {
-    uint32_t num_copied = 0;
-    uint32_t num_timings = static_cast<uint32_t>(swapchain.timing.size());
-    if (*count < num_timings) {
-        num_timings = *count;
+    if (swapchain.timing.empty()) {
+        *count = 0;
+        return;
     }
-    for (uint32_t i = 0; i < num_timings; i++) {
-        TimingInfo* ti = &swapchain.timing.editItemAt(i);
-        if (ti && ti->ready()) {
-            ti->get_values(&timings[num_copied]);
-            num_copied++;
-            // We only report the values for a given present once, so remove
-            // them from swapchain.timing:
-            //
-            // TODO(ianelliott): SEE WHAT HAPPENS TO THE LOOP WHEN THE
-            // FOLLOWING IS DONE:
-            swapchain.timing.removeAt(i);
-            i--;
-            num_timings--;
-            if (*count == num_copied) {
-                break;
-            }
+
+    size_t last_ready = swapchain.timing.size() - 1;
+    while (!swapchain.timing[last_ready].ready()) {
+        if (last_ready == 0) {
+            *count = 0;
+            return;
         }
+        last_ready--;
     }
+
+    uint32_t num_copied = 0;
+    size_t num_to_remove = 0;
+    for (uint32_t i = 0; i <= last_ready && num_copied < *count; i++) {
+        const TimingInfo& ti = swapchain.timing[i];
+        if (ti.ready()) {
+            ti.get_values(&timings[num_copied]);
+            num_copied++;
+        }
+        num_to_remove++;
+    }
+
+    // Discard old frames that aren't ready if newer frames are ready.
+    // We don't expect to get the timing info for those old frames.
+    swapchain.timing.removeItemsAt(0, num_to_remove);
+
     *count = num_copied;
 }
 
@@ -812,13 +797,35 @@
 
     int gralloc_usage = 0;
     if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
-        result = dispatch.GetSwapchainGrallocUsage2ANDROID(
-            device, create_info->imageFormat, create_info->imageUsage,
-            swapchain_image_usage, &gralloc_usage);
+        uint64_t consumer_usage, producer_usage;
+        if (GetData(device).driver_version == 256587285) {
+            // HACK workaround for loader/driver mismatch during transition to
+            // vkGetSwapchainGrallocUsage2ANDROID.
+            typedef VkResult(VKAPI_PTR *
+                             PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK)(
+                VkDevice device, VkFormat format, VkImageUsageFlags imageUsage,
+                uint64_t * grallocConsumerUsage,
+                uint64_t * grallocProducerUsage);
+            auto get_swapchain_gralloc_usage =
+                reinterpret_cast<PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK>(
+                    dispatch.GetSwapchainGrallocUsage2ANDROID);
+            result = get_swapchain_gralloc_usage(
+                device, create_info->imageFormat, create_info->imageUsage,
+                &consumer_usage, &producer_usage);
+        } else {
+            result = dispatch.GetSwapchainGrallocUsage2ANDROID(
+                device, create_info->imageFormat, create_info->imageUsage,
+                swapchain_image_usage, &consumer_usage, &producer_usage);
+        }
         if (result != VK_SUCCESS) {
             ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
+        // TODO: This is the same translation done by Gralloc1On0Adapter.
+        // Remove it once ANativeWindow has been updated to take gralloc1-style
+        // usages.
+        gralloc_usage =
+            static_cast<int>(consumer_usage) | static_cast<int>(producer_usage);
     } else if (dispatch.GetSwapchainGrallocUsageANDROID) {
         result = dispatch.GetSwapchainGrallocUsageANDROID(
             device, create_info->imageFormat, create_info->imageUsage,
@@ -827,8 +834,6 @@
             ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
             return VK_ERROR_INITIALIZATION_FAILED;
         }
-    } else {
-        gralloc_usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
     }
     err = native_window_set_usage(surface.window.get(), gralloc_usage);
     if (err != 0) {
@@ -857,7 +862,8 @@
                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (!mem)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
-    Swapchain* swapchain = new (mem) Swapchain(surface, num_images);
+    Swapchain* swapchain =
+        new (mem) Swapchain(surface, num_images, create_info->presentMode);
 
     // -- Dequeue all buffers and create a VkImage for each --
     // Any failures during or after this must cancel the dequeued buffers.
@@ -918,6 +924,12 @@
         image_native_buffer.stride = img.buffer->stride;
         image_native_buffer.format = img.buffer->format;
         image_native_buffer.usage = img.buffer->usage;
+        // TODO: Adjust once ANativeWindowBuffer supports gralloc1-style usage.
+        // For now, this is the same translation Gralloc1On0Adapter does.
+        image_native_buffer.usage2.consumer =
+            static_cast<uint64_t>(img.buffer->usage);
+        image_native_buffer.usage2.producer =
+            static_cast<uint64_t>(img.buffer->usage);
 
         result =
             dispatch.CreateImage(device, &image_create, nullptr, &img.image);
@@ -1153,7 +1165,8 @@
             *SwapchainFromHandle(present_info->pSwapchains[sc]);
         uint32_t image_idx = present_info->pImageIndices[sc];
         Swapchain::Image& img = swapchain.images[image_idx];
-        const VkPresentRegionKHR* region = (regions) ? &regions[sc] : nullptr;
+        const VkPresentRegionKHR* region =
+            (regions && !swapchain.mailbox_mode) ? &regions[sc] : nullptr;
         const VkPresentTimeGOOGLE* time = (times) ? &times[sc] : nullptr;
         VkResult swapchain_result = VK_SUCCESS;
         VkResult result;
@@ -1219,13 +1232,20 @@
                         native_window_enable_frame_timestamps(window, true);
                         swapchain.frame_timestamps_enabled = true;
                     }
-                    // Record this presentID and desiredPresentTime so it can
-                    // be later correlated to this present.
-                    TimingInfo timing_record(time);
-                    swapchain.timing.add(timing_record);
-                    uint32_t num_timings =
-                        static_cast<uint32_t>(swapchain.timing.size());
-                    if (num_timings > MAX_TIMING_INFOS) {
+
+                    // Record the nativeFrameId so it can be later correlated to
+                    // this present.
+                    uint64_t nativeFrameId = 0;
+                    err = native_window_get_next_frame_id(
+                            window, &nativeFrameId);
+                    if (err != android::NO_ERROR) {
+                        ALOGE("Failed to get next native frame ID.");
+                    }
+
+                    // Add a new timing record with the user's presentID and
+                    // the nativeFrameId.
+                    swapchain.timing.push_back(TimingInfo(time, nativeFrameId));
+                    while (swapchain.timing.size() > MAX_TIMING_INFOS) {
                         swapchain.timing.removeAt(0);
                     }
                     if (time->desiredPresentTime) {
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 55f7f19..e03ee0a 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -906,9 +906,11 @@
                                           VkFormat,
                                           VkImageUsageFlags,
                                           VkSwapchainImageUsageFlagsANDROID,
-                                          int* grallocUsage) {
+                                          uint64_t* grallocConsumerUsage,
+                                          uint64_t* grallocProducerUsage) {
     // The null driver never reads or writes the gralloc buffer
-    *grallocUsage = 0;
+    *grallocConsumerUsage = 0;
+    *grallocProducerUsage = 0;
     return VK_SUCCESS;
 }
 
diff --git a/vulkan/nulldrv/null_driver_gen.h b/vulkan/nulldrv/null_driver_gen.h
index cfc14dd..d73bf14 100644
--- a/vulkan/nulldrv/null_driver_gen.h
+++ b/vulkan/nulldrv/null_driver_gen.h
@@ -165,8 +165,8 @@
 VKAPI_ATTR void CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents);
 VKAPI_ATTR void CmdEndRenderPass(VkCommandBuffer commandBuffer);
 VKAPI_ATTR void CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int32_t* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
 VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
 VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
 VKAPI_ATTR VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);