Merge "Fix the obsolete vkjson path in gpu services" into pi-dev
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index cb6d0c6..8421568 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -104,6 +104,12 @@
     chmod 0666 /sys/kernel/tracing/events/block/block_rq_complete/enable
     chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_complete/enable
 
+    # graphics
+    chmod 0666 /sys/kernel/tracing/events/sde/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/sde/enable
+    chmod 0666 /sys/kernel/tracing/events/mdss/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/mdss/enable
+
 # Tracing disabled by default
     write /sys/kernel/debug/tracing/tracing_on 0
     write /sys/kernel/tracing/tracing_on 0
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 19bf216..3f7f6e9 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -104,6 +104,7 @@
 #define RAFT_DIR "/data/misc/raft"
 #define RECOVERY_DIR "/cache/recovery"
 #define RECOVERY_DATA_DIR "/data/misc/recovery"
+#define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
 #define LOGPERSIST_DATA_DIR "/data/misc/logd"
 #define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
 #define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
@@ -1236,7 +1237,6 @@
 }
 
 static void DumpHals() {
-    using android::sp;
     using android::hidl::manager::V1_0::IServiceManager;
     using android::hardware::defaultServiceManager;
 
@@ -1432,19 +1432,40 @@
     printf("== Running Application Activities\n");
     printf("========================================================\n");
 
-    RunDumpsys("APP ACTIVITIES", {"activity", "-v", "all"});
+    // The following dumpsys internally collects output from running apps, so it can take a long
+    // time. So let's extend the timeout.
+
+    const CommandOptions DUMPSYS_COMPONENTS_OPTIONS = CommandOptions::WithTimeout(60).Build();
+
+    RunDumpsys("APP ACTIVITIES", {"activity", "-v", "all"}, DUMPSYS_COMPONENTS_OPTIONS);
 
     printf("========================================================\n");
-    printf("== Running Application Services\n");
+    printf("== Running Application Services (platform)\n");
     printf("========================================================\n");
 
-    RunDumpsys("APP SERVICES", {"activity", "service", "all"});
+    RunDumpsys("APP SERVICES PLATFORM", {"activity", "service", "all-platform"},
+            DUMPSYS_COMPONENTS_OPTIONS);
 
     printf("========================================================\n");
-    printf("== Running Application Providers\n");
+    printf("== Running Application Services (non-platform)\n");
     printf("========================================================\n");
 
-    RunDumpsys("APP PROVIDERS", {"activity", "provider", "all"});
+    RunDumpsys("APP SERVICES NON-PLATFORM", {"activity", "service", "all-non-platform"},
+            DUMPSYS_COMPONENTS_OPTIONS);
+
+    printf("========================================================\n");
+    printf("== Running Application Providers (platform)\n");
+    printf("========================================================\n");
+
+    RunDumpsys("APP PROVIDERS PLATFORM", {"activity", "provider", "all-platform"},
+            DUMPSYS_COMPONENTS_OPTIONS);
+
+    printf("========================================================\n");
+    printf("== Running Application Providers (non-platform)\n");
+    printf("========================================================\n");
+
+    RunDumpsys("APP PROVIDERS NON-PLATFORM", {"activity", "provider", "all-non-platform"},
+            DUMPSYS_COMPONENTS_OPTIONS);
 
     printf("========================================================\n");
     printf("== Dropbox crashes\n");
@@ -1560,69 +1581,80 @@
             paths[i])));
     }
 
+    sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
+    if (dumpstate_device == nullptr) {
+        MYLOGE("No IDumpstateDevice implementation\n");
+        return;
+    }
+
+    using ScopedNativeHandle =
+            std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
+    ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
+                              [](native_handle_t* handle) {
+                                  native_handle_close(handle);
+                                  native_handle_delete(handle);
+                              });
+    if (handle == nullptr) {
+        MYLOGE("Could not create native_handle\n");
+        return;
+    }
+
+    for (size_t i = 0; i < paths.size(); i++) {
+        MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());
+
+        android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+            open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+        if (fd < 0) {
+            MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
+            return;
+        }
+        handle.get()->data[i] = fd.release();
+    }
+
     // Given that bugreport is required to diagnose failures, it's better to
-    // drop the result of IDumpstateDevice than to block the rest of bugreport
-    // for an arbitrary amount of time.
-    std::packaged_task<std::unique_ptr<ssize_t[]>()>
-        dumpstate_task([paths]() -> std::unique_ptr<ssize_t[]> {
-            ::android::sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
-            if (dumpstate_device == nullptr) {
-                MYLOGE("No IDumpstateDevice implementation\n");
-                return nullptr;
-            }
-
-            using ScopedNativeHandle =
-                std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
-            ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
-                                      [](native_handle_t* handle) {
-                                          native_handle_close(handle);
-                                          native_handle_delete(handle);
-                                      });
-            if (handle == nullptr) {
-                MYLOGE("Could not create native_handle\n");
-                return nullptr;
-            }
-
-            for (size_t i = 0; i < paths.size(); i++) {
-                MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());
-
-                android::base::unique_fd fd(TEMP_FAILURE_RETRY(
-                    open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
-                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
-                if (fd < 0) {
-                    MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
-                    return nullptr;
-                }
-                handle.get()->data[i] = fd.release();
-            }
-
+    // set an arbitrary amount of timeout for IDumpstateDevice than to block the
+    // rest of bugreport. In the timeout case, we will kill dumpstate board HAL
+    // and grab whatever dumped
+    std::packaged_task<bool()>
+            dumpstate_task([paths, dumpstate_device, &handle]() -> bool {
             android::hardware::Return<void> status = dumpstate_device->dumpstateBoard(handle.get());
             if (!status.isOk()) {
                 MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
-                return nullptr;
+                return false;
             }
-            auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
-            for (size_t i = 0; i < paths.size(); i++) {
-                struct stat s;
-                if (fstat(handle.get()->data[i], &s) == -1) {
-                    MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
-                           strerror(errno));
-                    file_sizes[i] = -1;
-                    continue;
-                }
-                file_sizes[i] = s.st_size;
-            }
-            return file_sizes;
+            return true;
         });
+
     auto result = dumpstate_task.get_future();
     std::thread(std::move(dumpstate_task)).detach();
-    if (result.wait_for(30s) != std::future_status::ready) {
-        MYLOGE("dumpstateBoard timed out after 30s\n");
-        return;
+
+    constexpr size_t timeout_sec = 30;
+    if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
+        MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate vendor HAL\n", timeout_sec);
+        if (!android::base::SetProperty("ctl.interface_restart",
+                                        android::base::StringPrintf("%s/default",
+                                                                    IDumpstateDevice::descriptor))) {
+            MYLOGE("Couldn't restart dumpstate HAL\n");
+        }
     }
-    std::unique_ptr<ssize_t[]> file_sizes = result.get();
-    if (file_sizes == nullptr) {
-        return;
+    // Wait some time for init to kill dumpstate vendor HAL
+    constexpr size_t killing_timeout_sec = 10;
+    if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
+        MYLOGE("killing dumpstateBoard timed out after %zus, continue and "
+               "there might be racing in content\n", killing_timeout_sec);
+    }
+
+    auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
+    for (size_t i = 0; i < paths.size(); i++) {
+        struct stat s;
+        if (fstat(handle.get()->data[i], &s) == -1) {
+            MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
+                   strerror(errno));
+            file_sizes[i] = -1;
+            continue;
+        }
+        file_sizes[i] = s.st_size;
     }
 
     for (size_t i = 0; i < paths.size(); i++) {
@@ -2126,6 +2158,7 @@
 
         ds.AddDir(RECOVERY_DIR, true);
         ds.AddDir(RECOVERY_DATA_DIR, true);
+        ds.AddDir(UPDATE_ENGINE_LOG_DIR, true);
         ds.AddDir(LOGPERSIST_DATA_DIR, false);
         if (!PropertiesHelper::IsUserBuild()) {
             ds.AddDir(PROFILE_DATA_DIR_CUR, true);
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index c402c3c..3ae56db 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -114,14 +114,29 @@
         LOG(ERROR) << "Target slot suffix not legal: " << arg[2];
         exit(207);
     }
-    std::string vendor_partition = StringPrintf("/dev/block/bootdevice/by-name/vendor%s",
-                                                arg[2]);
-    int vendor_result = mount(vendor_partition.c_str(),
-                              "/postinstall/vendor",
-                              "ext4",
-                              MS_RDONLY,
-                              /* data */ nullptr);
-    UNUSED(vendor_result);
+    {
+      std::string vendor_partition = StringPrintf("/dev/block/bootdevice/by-name/vendor%s",
+                                                  arg[2]);
+      int vendor_result = mount(vendor_partition.c_str(),
+                                "/postinstall/vendor",
+                                "ext4",
+                                MS_RDONLY,
+                                /* data */ nullptr);
+      UNUSED(vendor_result);
+    }
+
+    // Try to mount the product partition. update_engine doesn't do this for us, but we
+    // want it for product APKs. Same notes as vendor above.
+    {
+      std::string product_partition = StringPrintf("/dev/block/bootdevice/by-name/product%s",
+                                                   arg[2]);
+      int product_result = mount(product_partition.c_str(),
+                                 "/postinstall/product",
+                                 "ext4",
+                                 MS_RDONLY,
+                                 /* data */ nullptr);
+      UNUSED(product_result);
+    }
 
     // Chdir into /postinstall.
     if (chdir("/postinstall") != 0) {
diff --git a/data/etc/android.hardware.strongbox_keystore.xml b/data/etc/android.hardware.strongbox_keystore.xml
new file mode 100644
index 0000000..2a0ec37
--- /dev/null
+++ b/data/etc/android.hardware.strongbox_keystore.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          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.
+-->
+
+<!-- Feature for devices with Keymaster in StrongBox. -->
+<permissions>
+    <feature name="android.hardware.strongbox_keystore" />
+</permissions>
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 6103188..7c1eaaf 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -75,6 +75,28 @@
         ":libbinder_aidl",
     ],
 
+    target: {
+        vendor: {
+            exclude_srcs: [
+                "ActivityManager.cpp",
+                "AppOpsManager.cpp",
+                "IActivityManager.cpp",
+                "IAppOpsCallback.cpp",
+                "IAppOpsService.cpp",
+                "IBatteryStats.cpp",
+                "IMediaResourceMonitor.cpp",
+                "IPermissionController.cpp",
+                "IProcessInfoService.cpp",
+                "IUidObserver.cpp",
+                "PermissionCache.cpp",
+                "PermissionController.cpp",
+                "ProcessInfoService.cpp",
+                "IpPrefix.cpp",
+                ":libbinder_aidl",
+            ],
+        },
+    },
+
     aidl: {
         export_aidl_headers: true,
     },
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index ef67ab8..89ebc6c 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -49,6 +49,19 @@
         return reply.readInt32() != 0;
     }
 
+    virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
+        data.writeString16(op);
+        data.writeInt32(uid);
+        data.writeString16(packageName);
+        remote()->transact(NOTE_OP_TRANSACTION, data, &reply);
+        // fail on exception
+        if (reply.readExceptionCode() != 0) return 2; // MODE_ERRORED
+        return reply.readInt32();
+    }
+
     virtual void getPackagesForUid(const uid_t uid, Vector<String16>& packages)
     {
         Parcel data, reply;
@@ -111,6 +124,17 @@
             return NO_ERROR;
         } break;
 
+        case NOTE_OP_TRANSACTION: {
+            CHECK_INTERFACE(IPermissionController, data, reply);
+            String16 op = data.readString16();
+            int32_t uid = data.readInt32();
+            String16 packageName = data.readString16();
+            int32_t res = noteOp(op, uid, packageName);
+            reply->writeNoException();
+            reply->writeInt32(res);
+            return NO_ERROR;
+        } break;
+
         case GET_PACKAGES_FOR_UID_TRANSACTION: {
             CHECK_INTERFACE(IPermissionController, data, reply);
             int32_t uid = data.readInt32();
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 70f5108..711143c 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -20,6 +20,9 @@
 
 #include <utils/Log.h>
 #include <binder/IPCThreadState.h>
+#ifndef __ANDROID_VNDK__
+#include <binder/IPermissionController.h>
+#endif
 #include <binder/Parcel.h>
 #include <utils/String8.h>
 #include <utils/SystemClock.h>
@@ -48,6 +51,9 @@
     return gDefaultServiceManager;
 }
 
+#ifndef __ANDROID_VNDK__
+// IPermissionController is not accessible to vendors
+
 bool checkCallingPermission(const String16& permission)
 {
     return checkCallingPermission(permission, NULL, NULL);
@@ -122,6 +128,8 @@
     }
 }
 
+#endif //__ANDROID_VNDK__
+
 // ----------------------------------------------------------------------
 
 class BpServiceManager : public BpInterface<IServiceManager>
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index cb542bf..2e7edd7 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1535,7 +1535,12 @@
             && len <= pad_size(len)) {
         if (mObjectsSize > 0) {
             status_t err = validateReadData(mDataPos + pad_size(len));
-            if(err != NO_ERROR) return err;
+            if(err != NO_ERROR) {
+                // Still increment the data position by the expected length
+                mDataPos += pad_size(len);
+                ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
+                return err;
+            }
         }
         memcpy(outData, mData+mDataPos, len);
         mDataPos += pad_size(len);
@@ -1557,7 +1562,12 @@
             && len <= pad_size(len)) {
         if (mObjectsSize > 0) {
             status_t err = validateReadData(mDataPos + pad_size(len));
-            if(err != NO_ERROR) return NULL;
+            if(err != NO_ERROR) {
+                // Still increment the data position by the expected length
+                mDataPos += pad_size(len);
+                ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
+                return NULL;
+            }
         }
 
         const void* data = mData+mDataPos;
@@ -1575,7 +1585,11 @@
     if ((mDataPos+sizeof(T)) <= mDataSize) {
         if (mObjectsSize > 0) {
             status_t err = validateReadData(mDataPos + sizeof(T));
-            if(err != NO_ERROR) return err;
+            if(err != NO_ERROR) {
+                // Still increment the data position by the expected length
+                mDataPos += sizeof(T);
+                return err;
+            }
         }
 
         const void* data = mData+mDataPos;
diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp
index 25748ca..96df33c 100644
--- a/libs/binder/PermissionController.cpp
+++ b/libs/binder/PermissionController.cpp
@@ -59,6 +59,12 @@
     return service != NULL ? service->checkPermission(permission, pid, uid) : false;
 }
 
+int32_t PermissionController::noteOp(const String16& op, int32_t uid, const String16& packageName)
+{
+    sp<IPermissionController> service = getService();
+    return service != NULL ? service->noteOp(op, uid, packageName) : MODE_ERRORED;
+}
+
 void PermissionController::getPackagesForUid(const uid_t uid, Vector<String16> &packages)
 {
     sp<IPermissionController> service = getService();
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index f0613d1..9899b65 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -94,6 +94,8 @@
 
 Mutex gDefaultServiceManagerLock;
 sp<IServiceManager> gDefaultServiceManager;
+#ifndef __ANDROID_VNDK__
 sp<IPermissionController> gPermissionController;
+#endif
 
 }   // namespace android
diff --git a/libs/binder/include/binder/ActivityManager.h b/libs/binder/include/binder/ActivityManager.h
index 3090cae..b8db091 100644
--- a/libs/binder/include/binder/ActivityManager.h
+++ b/libs/binder/include/binder/ActivityManager.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_ACTIVITY_MANAGER_H
 #define ANDROID_ACTIVITY_MANAGER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IActivityManager.h>
 
 #include <utils/threads.h>
@@ -64,4 +66,8 @@
 
 }; // namespace android
 // ---------------------------------------------------------------------------
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_ACTIVITY_MANAGER_H
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index a44d270..c5b57c7 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_APP_OPS_MANAGER_H
 #define ANDROID_APP_OPS_MANAGER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IAppOpsService.h>
 
 #include <utils/threads.h>
@@ -117,4 +119,8 @@
 
 }; // namespace android
 // ---------------------------------------------------------------------------
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_APP_OPS_MANAGER_H
diff --git a/libs/binder/include/binder/IActivityManager.h b/libs/binder/include/binder/IActivityManager.h
index 6607c0e..f34969b 100644
--- a/libs/binder/include/binder/IActivityManager.h
+++ b/libs/binder/include/binder/IActivityManager.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_IACTIVITY_MANAGER_H
 #define ANDROID_IACTIVITY_MANAGER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 #include <binder/IUidObserver.h>
 
@@ -49,4 +51,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IACTIVITY_MANAGER_H
diff --git a/libs/binder/include/binder/IAppOpsCallback.h b/libs/binder/include/binder/IAppOpsCallback.h
index b62e9e2..e5b12a9 100644
--- a/libs/binder/include/binder/IAppOpsCallback.h
+++ b/libs/binder/include/binder/IAppOpsCallback.h
@@ -18,6 +18,8 @@
 #ifndef ANDROID_IAPP_OPS_CALLBACK_H
 #define ANDROID_IAPP_OPS_CALLBACK_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 
 namespace android {
@@ -51,5 +53,9 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IAPP_OPS_CALLBACK_H
 
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/binder/include/binder/IAppOpsService.h
index ecba5d6..f0c5e17 100644
--- a/libs/binder/include/binder/IAppOpsService.h
+++ b/libs/binder/include/binder/IAppOpsService.h
@@ -18,6 +18,8 @@
 #ifndef ANDROID_IAPP_OPS_SERVICE_H
 #define ANDROID_IAPP_OPS_SERVICE_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IAppOpsCallback.h>
 #include <binder/IInterface.h>
 
@@ -75,4 +77,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IAPP_OPS_SERVICE_H
diff --git a/libs/binder/include/binder/IBatteryStats.h b/libs/binder/include/binder/IBatteryStats.h
index e15d6f0..59e806c 100644
--- a/libs/binder/include/binder/IBatteryStats.h
+++ b/libs/binder/include/binder/IBatteryStats.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_IBATTERYSTATS_H
 #define ANDROID_IBATTERYSTATS_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 
 namespace android {
@@ -76,4 +78,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IBATTERYSTATS_H
diff --git a/libs/binder/include/binder/IMediaResourceMonitor.h b/libs/binder/include/binder/IMediaResourceMonitor.h
index b21047f..213ee63 100644
--- a/libs/binder/include/binder/IMediaResourceMonitor.h
+++ b/libs/binder/include/binder/IMediaResourceMonitor.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_I_MEDIA_RESOURCE_MONITOR_H
 #define ANDROID_I_MEDIA_RESOURCE_MONITOR_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 
 namespace android {
@@ -52,4 +54,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_I_MEDIA_RESOURCE_MONITOR_H
diff --git a/libs/binder/include/binder/IPermissionController.h b/libs/binder/include/binder/IPermissionController.h
index 2f63677..3ec459f 100644
--- a/libs/binder/include/binder/IPermissionController.h
+++ b/libs/binder/include/binder/IPermissionController.h
@@ -18,6 +18,8 @@
 #ifndef ANDROID_IPERMISSION_CONTROLLER_H
 #define ANDROID_IPERMISSION_CONTROLLER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 #include <stdlib.h>
 
@@ -32,6 +34,8 @@
 
     virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0;
 
+    virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName) = 0;
+
     virtual void getPackagesForUid(const uid_t uid, Vector<String16> &packages) = 0;
 
     virtual bool isRuntimePermission(const String16& permission) = 0;
@@ -40,9 +44,10 @@
 
     enum {
         CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
-        GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
-        IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2,
-        GET_PACKAGE_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 3
+        NOTE_OP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
+        GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2,
+        IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 3,
+        GET_PACKAGE_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 4
     };
 };
 
@@ -61,5 +66,9 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IPERMISSION_CONTROLLER_H
 
diff --git a/libs/binder/include/binder/IProcessInfoService.h b/libs/binder/include/binder/IProcessInfoService.h
index 2669f91..033c145 100644
--- a/libs/binder/include/binder/IProcessInfoService.h
+++ b/libs/binder/include/binder/IProcessInfoService.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_I_PROCESS_INFO_SERVICE_H
 #define ANDROID_I_PROCESS_INFO_SERVICE_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 
 namespace android {
@@ -46,4 +48,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_I_PROCESS_INFO_SERVICE_H
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index cf4c08a..197026d 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -19,7 +19,6 @@
 #define ANDROID_ISERVICE_MANAGER_H
 
 #include <binder/IInterface.h>
-#include <binder/IPermissionController.h>
 #include <utils/Vector.h>
 #include <utils/String16.h>
 
diff --git a/libs/binder/include/binder/IUidObserver.h b/libs/binder/include/binder/IUidObserver.h
index fd4d8a6..d81789e 100644
--- a/libs/binder/include/binder/IUidObserver.h
+++ b/libs/binder/include/binder/IUidObserver.h
@@ -18,6 +18,8 @@
 #ifndef ANDROID_IUID_OBSERVER_H
 #define ANDROID_IUID_OBSERVER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IInterface.h>
 
 namespace android {
@@ -55,4 +57,8 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_IUID_OBSERVER_H
diff --git a/libs/binder/include/binder/IpPrefix.h b/libs/binder/include/binder/IpPrefix.h
index 96ebaac..dd5bc3a 100644
--- a/libs/binder/include/binder/IpPrefix.h
+++ b/libs/binder/include/binder/IpPrefix.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_IP_PREFIX_H
 #define ANDROID_IP_PREFIX_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <netinet/in.h>
 
 #include <binder/Parcelable.h>
@@ -85,4 +87,8 @@
 
 }  // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif  // ANDROID_IP_PREFIX_H
diff --git a/libs/binder/include/binder/PermissionCache.h b/libs/binder/include/binder/PermissionCache.h
index bcdf0c2..95eabff 100644
--- a/libs/binder/include/binder/PermissionCache.h
+++ b/libs/binder/include/binder/PermissionCache.h
@@ -17,6 +17,8 @@
 #ifndef BINDER_PERMISSION_H
 #define BINDER_PERMISSION_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <stdint.h>
 #include <unistd.h>
 
@@ -77,4 +79,8 @@
 // ---------------------------------------------------------------------------
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif /* BINDER_PERMISSION_H */
diff --git a/libs/binder/include/binder/PermissionController.h b/libs/binder/include/binder/PermissionController.h
index c4c98d0..d81f514 100644
--- a/libs/binder/include/binder/PermissionController.h
+++ b/libs/binder/include/binder/PermissionController.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_PERMISSION_CONTROLLER_H
 #define ANDROID_PERMISSION_CONTROLLER_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IPermissionController.h>
 
 #include <utils/threads.h>
@@ -35,9 +37,17 @@
         MATCH_INSTANT = 1<<23
     };
 
+    enum {
+        MODE_ALLOWED = 0,
+        MODE_IGNORED = 1,
+        MODE_ERRORED = 2,
+        MODE_DEFAULT = 3,
+    };
+
     PermissionController();
 
     bool checkPermission(const String16& permission, int32_t pid, int32_t uid);
+    int32_t noteOp(const String16& op, int32_t uid, const String16& packageName);
     void getPackagesForUid(const uid_t uid, Vector<String16>& packages);
     bool isRuntimePermission(const String16& permission);
     int getPackageUid(const String16& package, int flags);
@@ -52,4 +62,8 @@
 
 }; // namespace android
 // ---------------------------------------------------------------------------
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_PERMISSION_CONTROLLER_H
diff --git a/libs/binder/include/binder/ProcessInfoService.h b/libs/binder/include/binder/ProcessInfoService.h
index 0da61ee..a03aae9 100644
--- a/libs/binder/include/binder/ProcessInfoService.h
+++ b/libs/binder/include/binder/ProcessInfoService.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_PROCESS_INFO_SERVICE_H
 #define ANDROID_PROCESS_INFO_SERVICE_H
 
+#ifndef __ANDROID_VNDK__
+
 #include <binder/IProcessInfoService.h>
 #include <utils/Errors.h>
 #include <utils/Singleton.h>
@@ -78,5 +80,9 @@
 
 }; // namespace android
 
+#else // __ANDROID_VNDK__
+#error "This header is not visible to vendors"
+#endif // __ANDROID_VNDK__
+
 #endif // ANDROID_PROCESS_INFO_SERVICE_H
 
diff --git a/libs/binder/include/private/binder/Static.h b/libs/binder/include/private/binder/Static.h
index 3d10456..f04bcae 100644
--- a/libs/binder/include/private/binder/Static.h
+++ b/libs/binder/include/private/binder/Static.h
@@ -21,7 +21,9 @@
 
 #include <binder/IBinder.h>
 #include <binder/ProcessState.h>
+#ifndef __ANDROID_VNDK__
 #include <binder/IPermissionController.h>
+#endif
 #include <binder/IServiceManager.h>
 
 namespace android {
@@ -36,6 +38,8 @@
 // For IServiceManager.cpp
 extern Mutex gDefaultServiceManagerLock;
 extern sp<IServiceManager> gDefaultServiceManager;
+#ifndef __ANDROID_VNDK__
 extern sp<IPermissionController> gPermissionController;
+#endif
 
 }   // namespace android
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 835da20..8f6b1bd 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -47,6 +47,7 @@
         "android.hardware.drm@1.0::IDrmFactory",
         "android.hardware.graphics.composer@2.1::IComposer",
         "android.hardware.media.omx@1.0::IOmx",
+        "android.hardware.media.omx@1.0::IOmxStore",
         "android.hardware.sensors@1.0::ISensors",
         "android.hardware.vr@1.0::IVr",
         NULL,
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 17cf677..d70e142 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -35,7 +35,9 @@
 #include <gui/IProducerListener.h>
 
 #include <binder/IPCThreadState.h>
+#ifndef __ANDROID_VNDK__
 #include <binder/PermissionCache.h>
+#endif
 
 #include <system/window.h>
 
@@ -757,12 +759,18 @@
     }
 
     const IPCThreadState* ipc = IPCThreadState::self();
-    const pid_t pid = ipc->getCallingPid();
     const uid_t uid = ipc->getCallingUid();
+#ifndef __ANDROID_VNDK__
+    // permission check can't be done for vendors as vendors have no access to
+    // the PermissionController
+    const pid_t pid = ipc->getCallingPid();
     if ((uid != shellUid) &&
         !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
         outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer "
                 "from pid=%d, uid=%d\n", pid, uid);
+#else
+    if (uid != shellUid) {
+#endif
         android_errorWriteWithInfoLog(0x534e4554, "27046057",
                 static_cast<int32_t>(uid), NULL, 0);
         return PERMISSION_DENIED;
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index cc67aca..78cec41 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -214,7 +214,7 @@
  * Allocates a buffer that backs an AHardwareBuffer using the passed
  * AHardwareBuffer_Desc.
  *
- * \return NO_ERROR on success, or an error number of the allocation fails for
+ * \return 0 on success, or an error number of the allocation fails for
  * any reason. The returned buffer has a reference count of 1.
  */
 int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
@@ -267,7 +267,7 @@
  * may return an error or leave the buffer's content into an indeterminate
  * state.
  *
- * \return NO_ERROR on success, BAD_VALUE if \a buffer is NULL or if the usage
+ * \return 0 on success, -EINVAL if \a buffer is NULL or if the usage
  * flags are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or an error
  * number of the lock fails for any reason.
  */
@@ -281,7 +281,7 @@
  * completed. The caller is responsible for closing the fence when it is no
  * longer needed.
  *
- * \return NO_ERROR on success, BAD_VALUE if \a buffer is NULL, or an error
+ * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
  * number if the unlock fails for any reason.
  */
 int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence);
@@ -289,7 +289,7 @@
 /**
  * Send the AHardwareBuffer to an AF_UNIX socket.
  *
- * \return NO_ERROR on success, BAD_VALUE if \a buffer is NULL, or an error
+ * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
  * number if the operation fails for any reason.
  */
 int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd);
@@ -297,7 +297,7 @@
 /**
  * Receive the AHardwareBuffer from an AF_UNIX socket.
  *
- * \return NO_ERROR on success, BAD_VALUE if \a outBuffer is NULL, or an error
+ * \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
  * number if the operation fails for any reason.
  */
 int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer);
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 6fe72a1..b9ae524 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -27,6 +27,7 @@
 #include <utils/Singleton.h>
 
 #include <binder/IBinder.h>
+#include <binder/IPermissionController.h>
 #include <binder/IServiceManager.h>
 
 #include <sensor/ISensorServer.h>
diff --git a/libs/ui/HdrCapabilities.cpp b/libs/ui/HdrCapabilities.cpp
index 755e60c..50f9bf1 100644
--- a/libs/ui/HdrCapabilities.cpp
+++ b/libs/ui/HdrCapabilities.cpp
@@ -33,7 +33,7 @@
             sizeof(mMaxAverageLuminance) +
             sizeof(mMinLuminance) +
             sizeof(int32_t) +
-            mSupportedHdrTypes.size() * sizeof(int32_t);
+            mSupportedHdrTypes.size() * sizeof(ui::Hdr);
 }
 
 status_t HdrCapabilities::flatten(void* buffer, size_t size) const {
@@ -48,7 +48,7 @@
     reinterpret_cast<float&>(buf[2]) = mMinLuminance;
     buf[3] = static_cast<int32_t>(mSupportedHdrTypes.size());
     for (size_t i = 0, c = mSupportedHdrTypes.size(); i < c; ++i) {
-        buf[4 + i] = mSupportedHdrTypes[i];
+        buf[4 + i] = static_cast<int32_t>(mSupportedHdrTypes[i]);
     }
     return NO_ERROR;
 }
@@ -78,7 +78,7 @@
     if (itemCount) {
         mSupportedHdrTypes.resize(itemCount);
         for (size_t i = 0; i < itemCount; ++i) {
-            mSupportedHdrTypes[i] = buf[4 + i];
+            mSupportedHdrTypes[i] = static_cast<ui::Hdr>(buf[4 + i]);
         }
     }
     return NO_ERROR;
diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h
index bd5722f..0fa819d 100644
--- a/libs/ui/include/ui/GraphicTypes.h
+++ b/libs/ui/include/ui/GraphicTypes.h
@@ -24,6 +24,7 @@
 namespace android {
 namespace ui {
 
+using android::hardware::graphics::common::V1_0::Hdr;
 using android::hardware::graphics::common::V1_1::ColorMode;
 using android::hardware::graphics::common::V1_1::Dataspace;
 using android::hardware::graphics::common::V1_1::PixelFormat;
diff --git a/libs/ui/include/ui/HdrCapabilities.h b/libs/ui/include/ui/HdrCapabilities.h
index 925aa1b..4e98c28 100644
--- a/libs/ui/include/ui/HdrCapabilities.h
+++ b/libs/ui/include/ui/HdrCapabilities.h
@@ -21,6 +21,7 @@
 
 #include <vector>
 
+#include <ui/GraphicTypes.h>
 #include <utils/Flattenable.h>
 
 namespace android {
@@ -28,7 +29,7 @@
 class HdrCapabilities : public LightFlattenable<HdrCapabilities>
 {
 public:
-    HdrCapabilities(const std::vector<int32_t /*android_hdr_t*/>& types,
+    HdrCapabilities(const std::vector<ui::Hdr>& types,
             float maxLuminance, float maxAverageLuminance, float minLuminance)
       : mSupportedHdrTypes(types),
         mMaxLuminance(maxLuminance),
@@ -47,7 +48,7 @@
 
     ~HdrCapabilities();
 
-    const std::vector<int32_t /*android_hdr_t*/>& getSupportedHdrTypes() const {
+    const std::vector<ui::Hdr>& getSupportedHdrTypes() const {
         return mSupportedHdrTypes;
     }
     float getDesiredMaxLuminance() const { return mMaxLuminance; }
@@ -61,7 +62,7 @@
     status_t unflatten(void const* buffer, size_t size);
 
 private:
-    std::vector<int32_t /*android_hdr_t*/> mSupportedHdrTypes;
+    std::vector<ui::Hdr> mSupportedHdrTypes;
     float mMaxLuminance;
     float mMaxAverageLuminance;
     float mMinLuminance;
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index 7d4e2d1..d14f040 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -41,10 +41,19 @@
     }                                                          \
   } while (0)
 
+#define DVR_V1_API_ENTRY_DEPRECATED(name)                      \
+  do {                                                         \
+    if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
+        clamped_struct_size) {                                 \
+      dvr_api->name = nullptr;                                 \
+    }                                                          \
+  } while (0)
+
 #include "include/dvr/dvr_api_entries.h"
 
 // Undefine macro definitions to play nice with Google3 style rules.
 #undef DVR_V1_API_ENTRY
+#undef DVR_V1_API_ENTRY_DEPRECATED
 
     return 0;
   }
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
index 1a99234..baf1f2f 100644
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -38,17 +38,13 @@
 
 extern "C" {
 
-void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer) {
-  if (write_buffer)
-    *write_buffer = new DvrWriteBuffer;
-}
-
 void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
   if (write_buffer != nullptr) {
     ALOGW_IF(
         write_buffer->slot != -1,
         "dvrWriteBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks.");
+        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
+        dvrWriteBufferGetId(write_buffer));
     delete write_buffer;
   }
 }
@@ -57,14 +53,6 @@
   return write_buffer && write_buffer->write_buffer;
 }
 
-int dvrWriteBufferClear(DvrWriteBuffer* write_buffer) {
-  if (!write_buffer)
-    return -EINVAL;
-
-  write_buffer->write_buffer = nullptr;
-  return 0;
-}
-
 int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
   if (!write_buffer || !write_buffer->write_buffer)
     return -EINVAL;
@@ -81,44 +69,13 @@
       write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
-int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
-                       const void* meta, size_t meta_size_bytes) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  pdx::LocalHandle fence(ready_fence_fd);
-  int result = write_buffer->write_buffer->Post(fence, meta, meta_size_bytes);
-  return result;
-}
-
-int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd) {
-  if (!write_buffer || !write_buffer->write_buffer || !release_fence_fd)
-    return -EINVAL;
-
-  pdx::LocalHandle release_fence;
-  int result = write_buffer->write_buffer->Gain(&release_fence);
-  *release_fence_fd = release_fence.Release();
-  return result;
-}
-
-int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  return write_buffer->write_buffer->GainAsync();
-}
-
-void dvrReadBufferCreateEmpty(DvrReadBuffer** read_buffer) {
-  if (read_buffer)
-    *read_buffer = new DvrReadBuffer;
-}
-
 void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) {
   if (read_buffer != nullptr) {
     ALOGW_IF(
         read_buffer->slot != -1,
         "dvrReadBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks.");
+        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
+        dvrReadBufferGetId(read_buffer));
     delete read_buffer;
   }
 }
@@ -127,14 +84,6 @@
   return read_buffer && read_buffer->read_buffer;
 }
 
-int dvrReadBufferClear(DvrReadBuffer* read_buffer) {
-  if (!read_buffer)
-    return -EINVAL;
-
-  read_buffer->read_buffer = nullptr;
-  return 0;
-}
-
 int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
   if (!read_buffer || !read_buffer->read_buffer)
     return -EINVAL;
@@ -151,34 +100,6 @@
       read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
-int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
-                         void* meta, size_t meta_size_bytes) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  pdx::LocalHandle ready_fence;
-  int result =
-      read_buffer->read_buffer->Acquire(&ready_fence, meta, meta_size_bytes);
-  *ready_fence_fd = ready_fence.Release();
-  return result;
-}
-
-int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  pdx::LocalHandle fence(release_fence_fd);
-  int result = read_buffer->read_buffer->Release(fence);
-  return result;
-}
-
-int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  return read_buffer->read_buffer->ReleaseAsync();
-}
-
 void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
 
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
@@ -196,27 +117,4 @@
   return android::dvr::kSharedBufferLayoutVersion;
 }
 
-const struct native_handle* dvrWriteBufferGetNativeHandle(
-    DvrWriteBuffer* write_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return nullptr;
-
-  return write_buffer->write_buffer->native_handle();
-}
-
-const struct native_handle* dvrReadBufferGetNativeHandle(
-    DvrReadBuffer* read_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return nullptr;
-
-  return read_buffer->read_buffer->native_handle();
-}
-
-const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer) {
-  if (!buffer || !buffer->buffer)
-    return nullptr;
-
-  return buffer->buffer->handle();
-}
-
 }  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
index c36d190..74cee3f 100644
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ b/libs/vr/libdvr/dvr_buffer_queue.cpp
@@ -273,14 +273,6 @@
   return write_queue->id();
 }
 
-int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
-                                          ANativeWindow** out_window) {
-  ALOGW(
-      "dvrWriteBufferQueueGetExternalSurface: This API has been deprecated and "
-      "renamed to dvrWriteBufferQueueGetANativeWindow.");
-  return dvrWriteBufferQueueGetANativeWindow(write_queue, out_window);
-}
-
 int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
                                         ANativeWindow** out_window) {
   if (!write_queue || !out_window)
@@ -297,15 +289,6 @@
   return write_queue->CreateReadQueue(out_read_queue);
 }
 
-int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
-                               DvrWriteBuffer* write_buffer,
-                               int* out_fence_fd) {
-  if (!write_queue || !write_buffer || !out_fence_fd)
-    return -EINVAL;
-
-  return write_queue->Dequeue(timeout, write_buffer, out_fence_fd);
-}
-
 int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
                                   DvrWriteBuffer** out_write_buffer,
                                   DvrNativeBufferMetadata* out_meta,
@@ -355,34 +338,6 @@
   return 0;
 }
 
-int DvrReadBufferQueue::Dequeue(int timeout, DvrReadBuffer* read_buffer,
-                                int* out_fence_fd, void* out_meta,
-                                size_t meta_size_bytes) {
-  if (meta_size_bytes != consumer_queue_->metadata_size()) {
-    ALOGE(
-        "DvrReadBufferQueue::Dequeue: Invalid metadata size, expected (%zu), "
-        "but actual (%zu).",
-        consumer_queue_->metadata_size(), meta_size_bytes);
-    return -EINVAL;
-  }
-
-  size_t slot;
-  pdx::LocalHandle acquire_fence;
-  auto buffer_status = consumer_queue_->Dequeue(
-      timeout, &slot, out_meta, meta_size_bytes, &acquire_fence);
-  if (!buffer_status) {
-    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
-             "dvrReadBufferQueueDequeue: Failed to dequeue buffer: %s",
-             buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  read_buffer->read_buffer = buffer_status.take();
-  *out_fence_fd = acquire_fence.Release();
-
-  return 0;
-}
-
 int DvrReadBufferQueue::AcquireBuffer(int timeout,
                                       DvrReadBuffer** out_read_buffer,
                                       DvrNativeBufferMetadata* out_meta,
@@ -434,12 +389,22 @@
     return -EINVAL;
   }
   if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) {
-    ALOGE(
-        "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released does not "
-        "belong to this buffer queue. Releasing buffer: id=%d, buffer in "
-        "queue: id=%d",
-        read_buffer->read_buffer->id(), consumer_queue_->GetBufferId(slot));
-    return -EINVAL;
+    if (consumer_queue_->GetBufferId(slot) > 0) {
+      ALOGE(
+          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
+          "belong to this queue (queue_id=%d): attempting to release buffer "
+          "(buffer_id=%d) at slot %d which holds a different buffer "
+          "(buffer_id=%d).",
+          consumer_queue_->id(), read_buffer->read_buffer->id(),
+          static_cast<int>(slot), consumer_queue_->GetBufferId(slot));
+    } else {
+      ALOGI(
+          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
+          "belong to this queue (queue_id=%d): attempting to release buffer "
+          "(buffer_id=%d) at slot %d which is empty.",
+          consumer_queue_->id(), read_buffer->read_buffer->id(),
+          static_cast<int>(slot));
+    }
   }
 
   pdx::LocalHandle fence(release_fence_fd);
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index 499b7c1..80ffc82 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -443,11 +443,13 @@
 struct DvrApi_v1 {
 // Defines an API entry for V1 (no version suffix).
 #define DVR_V1_API_ENTRY(name) Dvr##name##Ptr name
+#define DVR_V1_API_ENTRY_DEPRECATED(name) Dvr##name##Ptr name
 
 #include "dvr_api_entries.h"
 
 // Undefine macro definitions to play nice with Google3 style rules.
 #undef DVR_V1_API_ENTRY
+#undef DVR_V1_API_ENTRY_DEPRECATED
 };
 
 int dvrGetApi(void* api, size_t struct_size, int version);
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
index cce8c7e..f0d8ec6 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
@@ -8,6 +8,10 @@
 #error Do not include this header directly.
 #endif
 
+#ifndef DVR_V1_API_ENTRY_DEPRECATED
+#error Do not include this header directly.
+#endif
+
 // Do not delete this line: BEGIN CODEGEN OUTPUT
 // Display manager client
 DVR_V1_API_ENTRY(DisplayManagerCreate);
@@ -32,42 +36,42 @@
 DVR_V1_API_ENTRY(SurfaceStateGetAttributes);
 
 // Write buffer
-DVR_V1_API_ENTRY(WriteBufferCreateEmpty);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferCreateEmpty);
 DVR_V1_API_ENTRY(WriteBufferDestroy);
 DVR_V1_API_ENTRY(WriteBufferIsValid);
-DVR_V1_API_ENTRY(WriteBufferClear);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferClear);
 DVR_V1_API_ENTRY(WriteBufferGetId);
 DVR_V1_API_ENTRY(WriteBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY(WriteBufferPost);
-DVR_V1_API_ENTRY(WriteBufferGain);
-DVR_V1_API_ENTRY(WriteBufferGainAsync);
-DVR_V1_API_ENTRY(WriteBufferGetNativeHandle);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferPost);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGain);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGainAsync);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGetNativeHandle);
 
 // Read buffer
-DVR_V1_API_ENTRY(ReadBufferCreateEmpty);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferCreateEmpty);
 DVR_V1_API_ENTRY(ReadBufferDestroy);
 DVR_V1_API_ENTRY(ReadBufferIsValid);
-DVR_V1_API_ENTRY(ReadBufferClear);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferClear);
 DVR_V1_API_ENTRY(ReadBufferGetId);
 DVR_V1_API_ENTRY(ReadBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY(ReadBufferAcquire);
-DVR_V1_API_ENTRY(ReadBufferRelease);
-DVR_V1_API_ENTRY(ReadBufferReleaseAsync);
-DVR_V1_API_ENTRY(ReadBufferGetNativeHandle);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferAcquire);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferRelease);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferReleaseAsync);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferGetNativeHandle);
 
 // Buffer
 DVR_V1_API_ENTRY(BufferDestroy);
 DVR_V1_API_ENTRY(BufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY(BufferGetNativeHandle);
+DVR_V1_API_ENTRY_DEPRECATED(BufferGetNativeHandle);
 DVR_V1_API_ENTRY(BufferGlobalLayoutVersionGet);
 
 // Write buffer queue
 DVR_V1_API_ENTRY(WriteBufferQueueDestroy);
 DVR_V1_API_ENTRY(WriteBufferQueueGetCapacity);
 DVR_V1_API_ENTRY(WriteBufferQueueGetId);
-DVR_V1_API_ENTRY(WriteBufferQueueGetExternalSurface);  // deprecated
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueGetExternalSurface);
 DVR_V1_API_ENTRY(WriteBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY(WriteBufferQueueDequeue);
+DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueDequeue);
 DVR_V1_API_ENTRY(WriteBufferQueueResizeBuffer);
 
 // Read buffer queue
@@ -75,7 +79,7 @@
 DVR_V1_API_ENTRY(ReadBufferQueueGetCapacity);
 DVR_V1_API_ENTRY(ReadBufferQueueGetId);
 DVR_V1_API_ENTRY(ReadBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY(ReadBufferQueueDequeue);
+DVR_V1_API_ENTRY_DEPRECATED(ReadBufferQueueDequeue);
 DVR_V1_API_ENTRY(ReadBufferQueueSetBufferAvailableCallback);
 DVR_V1_API_ENTRY(ReadBufferQueueSetBufferRemovedCallback);
 DVR_V1_API_ENTRY(ReadBufferQueueHandleEvents);
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
index 935a7b2..4234844 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -14,20 +14,12 @@
 typedef struct AHardwareBuffer AHardwareBuffer;
 struct native_handle;
 
-// Creates an empty write buffer that may be filled with an acutal buffer by
-// other functions.
-void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer);
-
 // Destroys the write buffer.
 void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
 
 // Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
 int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer);
 
-// Clears the contents of the buffer object. After a call to this function
-// dvrWriteBufferIsValid on the same buffer object returns 0.
-int dvrWriteBufferClear(DvrWriteBuffer* write_buffer);
-
 // Returns the global BufferHub id of this buffer.
 int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
 
@@ -36,34 +28,12 @@
 int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer);
 
-// Posts the buffer, notifying any connected read buffers. Takes ownership of
-// |ready_fence_fd|.
-int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
-                       const void* meta, size_t meta_size_bytes);
-
-// Gains a buffer that has been released by all connected read buffers.
-int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd);
-int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer);
-
-// TODO(eieio): Switch to return int and take an out parameter for the native
-// handle.
-const struct native_handle* dvrWriteBufferGetNativeHandle(
-    DvrWriteBuffer* write_buffer);
-
-// Creates an empty read buffer that may be filled with and actual buffer by
-// other functions.
-void dvrReadBufferCreateEmpty(DvrReadBuffer** read_buffer);
-
 // Destroys the read buffer.
 void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
 
 // Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
 int dvrReadBufferIsValid(DvrReadBuffer* read_buffer);
 
-// Clears the contents of the buffer object. After a call to this function
-// dvrReadBufferIsValid on the same buffer object returns 0.
-int dvrReadBufferClear(DvrReadBuffer* read_buffer);
-
 // Returns the global BufferHub id of this buffer.
 int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
 
@@ -72,21 +42,6 @@
 int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer);
 
-// Acquires the read buffer after it has been posted by the write buffer it is
-// connected to.
-int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
-                         void* meta, size_t meta_size_bytes);
-
-// Releases the read buffer, notifying the write buffer it is connected to.
-// Takes ownership of |release_fence_fd|.
-int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd);
-int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer);
-
-// TODO(eieio): Switch to return int and take an out parameter for the native
-// handle.
-const struct native_handle* dvrReadBufferGetNativeHandle(
-    DvrReadBuffer* read_buffer);
-
 // Destroys the buffer.
 void dvrBufferDestroy(DvrBuffer* buffer);
 
@@ -98,10 +53,6 @@
 // Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
 int dvrBufferGlobalLayoutVersionGet();
 
-// TODO(eieio): Switch to return int and take an out parameter for the native
-// handle.
-const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer);
-
 __END_DECLS
 
 #endif  // ANDROID_DVR_BUFFER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
index bf695c7..ac789da 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
@@ -76,10 +76,6 @@
 int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
                                         ANativeWindow** out_window);
 
-// @deprecated Please use dvrWriteBufferQueueGetANativeWindow instead.
-int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
-                                          ANativeWindow** out_window);
-
 // Create a read buffer queue from an existing write buffer queue.
 //
 // @param write_queue The DvrWriteBufferQueue of interest.
@@ -89,10 +85,6 @@
 int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
                                        DvrReadBufferQueue** out_read_queue);
 
-// @deprecated Please use dvrWriteBufferQueueGainBuffer instead.
-int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
-                               DvrWriteBuffer* out_buffer, int* out_fence_fd);
-
 // Gains a buffer to write into.
 //
 // @param write_queue The DvrWriteBufferQueue to gain buffer from.
@@ -176,11 +168,6 @@
 int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
                                       DvrReadBufferQueue** out_read_queue);
 
-// @deprecated Please use dvrReadBufferQueueAcquireBuffer instead.
-int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
-                              DvrReadBuffer* out_buffer, int* out_fence_fd,
-                              void* out_meta, size_t meta_size_bytes);
-
 // Dequeues a buffer to read from.
 //
 // @param read_queue The DvrReadBufferQueue to acquire buffer from.
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 5d9d8b5..2d5f004 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -525,4 +525,55 @@
   }
 }
 
+TEST_F(DvrBufferQueueTest, ConsumerReleaseAfterProducerDestroy) {
+  int ret = api_.WriteBufferQueueCreate(
+      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
+      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
+  ASSERT_EQ(ret, 0);
+
+  DvrReadBufferQueue* read_queue = nullptr;
+  DvrReadBuffer* rb = nullptr;
+  DvrWriteBuffer* wb = nullptr;
+  DvrNativeBufferMetadata meta1;
+  DvrNativeBufferMetadata meta2;
+  int fence_fd = -1;
+
+  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+  ASSERT_EQ(ret, 0);
+
+  api_.ReadBufferQueueSetBufferAvailableCallback(
+      read_queue, &BufferAvailableCallback, this);
+
+  // Gain buffer for writing.
+  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
+                                        &meta1, &fence_fd);
+  ASSERT_EQ(ret, 0);
+  close(fence_fd);
+
+  // Post buffer to the read_queue.
+  ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
+  ASSERT_EQ(ret, 0);
+  wb = nullptr;
+
+  // Acquire buffer for reading.
+  ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
+                                          &meta2, &fence_fd);
+  ASSERT_EQ(ret, 0);
+  close(fence_fd);
+
+  // Destroy the write buffer queue and make sure the reader queue is picking
+  // these events up.
+  api_.WriteBufferQueueDestroy(write_queue_);
+  ret = api_.ReadBufferQueueHandleEvents(read_queue);
+  ASSERT_EQ(0, ret);
+
+  // Release buffer to the write_queue.
+  ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
+                                          /*release_fence_fd=*/-1);
+  ASSERT_EQ(ret, 0);
+  rb = nullptr;
+
+  api_.ReadBufferQueueDestroy(read_queue);
+}
+
 }  // namespace
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
index f83b26e..c9a5c09 100644
--- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
@@ -845,10 +845,10 @@
   ASSERT_NE(nullptr, write_queue.get());
 
   DvrWriteBuffer* buffer = nullptr;
-  dvrWriteBufferCreateEmpty(&buffer);
+  DvrNativeBufferMetadata metadata;
   int fence_fd = -1;
-  int error =
-      dvrWriteBufferQueueDequeue(write_queue.get(), 1000, buffer, &fence_fd);
+  int error = dvrWriteBufferQueueGainBuffer(write_queue.get(), /*timeout=*/1000,
+                                            &buffer, &metadata, &fence_fd);
   ASSERT_EQ(0, error);
 
   AHardwareBuffer* hardware_buffer = nullptr;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index f3a9ad8..b022a20 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -80,6 +80,7 @@
 extern char const * const gExtensionString;
 
 // clang-format off
+// Extensions implemented by the EGL wrapper.
 char const * const gBuiltinExtensionString =
         "EGL_KHR_get_all_proc_addresses "
         "EGL_ANDROID_presentation_time "
@@ -91,10 +92,11 @@
         "EGL_EXT_surface_CTA861_3_metadata "
         ;
 
+// Whitelist of extensions exposed to applications if implemented in the vendor driver.
 char const * const gExtensionString  =
         "EGL_KHR_image "                        // mandatory
         "EGL_KHR_image_base "                   // mandatory
-        "EGL_KHR_image_gl_colorspace "
+        "EGL_EXT_image_gl_colorspace "
         "EGL_KHR_image_pixmap "
         "EGL_KHR_lock_surface "
         "EGL_KHR_gl_colorspace "
@@ -451,12 +453,8 @@
 // surfaces
 // ----------------------------------------------------------------------------
 
-// Turn linear formats into corresponding sRGB formats when colorspace is
-// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
-// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
-// the modification isn't possible, the original dataSpace is returned.
-static android_dataspace modifyBufferDataspace(android_dataspace dataSpace,
-                                               EGLint colorspace) {
+// Translates EGL color spaces to Android data spaces.
+static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
         return HAL_DATASPACE_SRGB_LINEAR;
     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
@@ -474,193 +472,135 @@
     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
         return HAL_DATASPACE_BT2020_PQ;
     }
-    return dataSpace;
+    return HAL_DATASPACE_UNKNOWN;
 }
 
-// stripAttributes is used by eglCreateWindowSurface, eglCreatePbufferSurface
-// and eglCreatePixmapSurface to clean up color space related Window parameters
-// that a driver does not advertise support for.
-// Return true if stripped_attrib_list has stripped contents.
+// Returns a list of color spaces understood by the vendor EGL driver.
+static std::vector<EGLint> getDriverColorSpaces(egl_display_ptr dp,
+                                                android_pixel_format format) {
+    std::vector<EGLint> colorSpaces;
+    if (!dp->hasColorSpaceSupport) return colorSpaces;
 
-static EGLBoolean stripAttributes(egl_display_ptr dp, const EGLint* attrib_list,
-                                  EGLint format,
-                                  std::vector<EGLint>& stripped_attrib_list) {
-    std::vector<EGLint> allowedColorSpaces;
-    bool haveColorSpaceSupport = dp->haveExtension("EGL_KHR_gl_colorspace");
-    switch (format) {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-            if (haveColorSpaceSupport) {
-                // Spec says:
-                //     [fn1] Only OpenGL and OpenGL ES contexts which support sRGB
-                //     rendering must respect requests for EGL_GL_COLORSPACE_SRGB_KHR, and
-                //     only to sRGB formats supported by the context (normally just SRGB8)
-                //     Older versions not supporting sRGB rendering will ignore this
-                //     surface attribute.
-                //
-                // We support sRGB and pixel format is SRGB8, so allow
-                // the EGL_GL_COLORSPACE_SRGB_KHR and
-                // EGL_GL_COLORSPACE_LINEAR_KHR
-                // colorspaces to be specified.
+    // OpenGL drivers only support sRGB encoding with 8-bit formats.
+    // RGB_888 is never returned by getNativePixelFormat, but is included for completeness.
+    const bool formatSupportsSRGBEncoding =
+        format == HAL_PIXEL_FORMAT_RGBA_8888 || format == HAL_PIXEL_FORMAT_RGBX_8888 ||
+        format == HAL_PIXEL_FORMAT_RGB_888;
+    const bool formatIsFloatingPoint = format == HAL_PIXEL_FORMAT_RGBA_FP16;
 
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
-            }
-            if (findExtension(dp->disp.queryString.extensions,
-                                  "EGL_EXT_gl_colorspace_display_p3_linear")) {
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
-            }
-            if (findExtension(dp->disp.queryString.extensions,
-                                  "EGL_EXT_gl_colorspace_display_p3")) {
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
-            }
-            if (findExtension(dp->disp.queryString.extensions,
-                                  "EGL_EXT_gl_colorspace_bt2020_linear")) {
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
-            }
-            if (findExtension(dp->disp.queryString.extensions,
-                                  "EGL_EXT_gl_colorspace_bt2020_pq")) {
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
-            }
-            if (findExtension(dp->disp.queryString.extensions,
-                                  "EGL_EXT_gl_colorspace_scrgb_linear")) {
-                allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
-            }
-            break;
-
-        case HAL_PIXEL_FORMAT_RGBA_FP16:
-        case HAL_PIXEL_FORMAT_RGBA_1010102:
-        case HAL_PIXEL_FORMAT_RGB_565:
-            // Future: if driver supports XXXX extension, we can pass down that colorspace
-        default:
-            break;
-    }
-
-    if (!attrib_list) return false;
-
-    bool stripped = false;
-    for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
-        switch (attr[0]) {
-            case EGL_GL_COLORSPACE_KHR: {
-                    EGLint colorSpace = attr[1];
-                    bool found = false;
-                    // Verify that color space is allowed
-                    for (auto it : allowedColorSpaces) {
-                        if (colorSpace == it) {
-                            found = true;
-                        }
-                    }
-                    if (found) {
-                        // Found supported attribute
-                        stripped_attrib_list.push_back(attr[0]);
-                        stripped_attrib_list.push_back(attr[1]);
-                    } else if (!haveColorSpaceSupport) {
-                        // Device does not support colorspace extension
-                        // pass on the attribute and let downstream
-                        // components validate like normal
-                        stripped_attrib_list.push_back(attr[0]);
-                        stripped_attrib_list.push_back(attr[1]);
-                    } else {
-                        // Found supported attribute that driver does not
-                        // support, strip it.
-                        stripped = true;
-                    }
-                }
-                break;
-            default:
-                stripped_attrib_list.push_back(attr[0]);
-                stripped_attrib_list.push_back(attr[1]);
-                break;
+    if (formatSupportsSRGBEncoding) {
+        // sRGB and linear are always supported when color space support is present.
+        colorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
+        colorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
+        // DCI-P3 uses the sRGB transfer function, so it's only relevant for 8-bit formats.
+        if (findExtension(dp->disp.queryString.extensions,
+                              "EGL_EXT_gl_colorspace_display_p3")) {
+            colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
         }
     }
 
-    // Make sure there is at least one attribute
-    if (stripped) {
-        stripped_attrib_list.push_back(EGL_NONE);
+    // According to the spec, scRGB is only supported for floating point formats.
+    // For non-linear scRGB, the application is responsible for applying the
+    // transfer function.
+    if (formatIsFloatingPoint) {
+        if (findExtension(dp->disp.queryString.extensions,
+                  "EGL_EXT_gl_colorspace_scrgb")) {
+            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_EXT);
+        }
+        if (findExtension(dp->disp.queryString.extensions,
+                  "EGL_EXT_gl_colorspace_scrgb_linear")) {
+            colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
+        }
     }
-    return stripped;
+
+    // BT2020 can be used with any pixel format. PQ encoding must be applied by the
+    // application and does not affect the behavior of OpenGL.
+    if (findExtension(dp->disp.queryString.extensions,
+                          "EGL_EXT_gl_colorspace_bt2020_linear")) {
+        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
+    }
+    if (findExtension(dp->disp.queryString.extensions,
+                          "EGL_EXT_gl_colorspace_bt2020_pq")) {
+        colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
+    }
+
+    // Linear DCI-P3 simply uses different primaries than standard RGB and thus
+    // can be used with any pixel format.
+    if (findExtension(dp->disp.queryString.extensions,
+                          "EGL_EXT_gl_colorspace_display_p3_linear")) {
+        colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
+    }
+    return colorSpaces;
 }
 
-static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, NativeWindowType window,
-                                         const EGLint* attrib_list, EGLint& colorSpace,
-                                         android_dataspace& dataSpace) {
-    colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
-    dataSpace = HAL_DATASPACE_UNKNOWN;
+// Cleans up color space related parameters that the driver does not understand.
+// If there is no color space attribute in attrib_list, colorSpace is left
+// unmodified.
+static EGLBoolean processAttributes(egl_display_ptr dp, NativeWindowType window,
+                                    android_pixel_format format, const EGLint* attrib_list,
+                                    EGLint* colorSpace,
+                                    std::vector<EGLint>* strippedAttribList) {
+    for (const EGLint* attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
+        bool copyAttribute = true;
+        if (attr[0] == EGL_GL_COLORSPACE_KHR) {
+            // Fail immediately if the driver doesn't have color space support at all.
+            if (!dp->hasColorSpaceSupport) return false;
+            *colorSpace = attr[1];
 
-    if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
-        for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
-            if (*attr == EGL_GL_COLORSPACE_KHR) {
-                colorSpace = attr[1];
-                bool found = false;
-                bool verify = true;
-                // Verify that color space is allowed
-                if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
-                    colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
-                    // SRGB and LINEAR are always supported when EGL_KHR_gl_colorspace
-                    // is available, so no need to verify.
-                    found = true;
-                    verify = false;
-                } else if (colorSpace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
-                    found = true;
-                } else if (colorSpace == EGL_GL_COLORSPACE_BT2020_PQ_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
-                    found = true;
-                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb")) {
-                    found = true;
-                } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
-                    found = true;
-                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
-                    found = true;
-                } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
-                           dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
-                    found = true;
+            // Strip the attribute if the driver doesn't understand it.
+            copyAttribute = false;
+            std::vector<EGLint> driverColorSpaces = getDriverColorSpaces(dp, format);
+            for (auto driverColorSpace : driverColorSpaces) {
+                if (attr[1] == driverColorSpace) {
+                    copyAttribute = true;
+                    break;
                 }
-                if (!found) {
-                    return false;
-                }
-                if (verify && window) {
-                    bool wide_color_support = true;
-                    // Ordinarily we'd put a call to native_window_get_wide_color_support
-                    // at the beginning of the function so that we'll have the
-                    // result when needed elsewhere in the function.
-                    // However, because eglCreateWindowSurface is called by SurfaceFlinger and
-                    // SurfaceFlinger is required to answer the call below we would
-                    // end up in a deadlock situation. By moving the call to only happen
-                    // if the application has specifically asked for wide-color we avoid
-                    // the deadlock with SurfaceFlinger since it will not ask for a
-                    // wide-color surface.
-                    int err = native_window_get_wide_color_support(window, &wide_color_support);
-
-                    if (err) {
-                        ALOGE("getColorSpaceAttribute: invalid window (win=%p) "
-                              "failed (%#x) (already connected to another API?)",
-                              window, err);
-                        return false;
-                    }
-                    if (!wide_color_support) {
-                        // Application has asked for a wide-color colorspace but
-                        // wide-color support isn't available on the display the window is on.
-                        return false;
-                    }
-                }
-                // Only change the dataSpace from default if the application
-                // has explicitly set the color space with a EGL_GL_COLORSPACE_KHR attribute.
-                dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
             }
         }
+        if (copyAttribute) {
+            strippedAttribList->push_back(attr[0]);
+            strippedAttribList->push_back(attr[1]);
+        }
+    }
+    // Terminate the attribute list.
+    strippedAttribList->push_back(EGL_NONE);
+
+    // If the passed color space has wide color gamut, check whether the target native window
+    // supports wide color.
+    const bool colorSpaceIsNarrow =
+        *colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
+        *colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR;
+    if (window && !colorSpaceIsNarrow) {
+        bool windowSupportsWideColor = true;
+        // Ordinarily we'd put a call to native_window_get_wide_color_support
+        // at the beginning of the function so that we'll have the
+        // result when needed elsewhere in the function.
+        // However, because eglCreateWindowSurface is called by SurfaceFlinger and
+        // SurfaceFlinger is required to answer the call below we would
+        // end up in a deadlock situation. By moving the call to only happen
+        // if the application has specifically asked for wide-color we avoid
+        // the deadlock with SurfaceFlinger since it will not ask for a
+        // wide-color surface.
+        int err = native_window_get_wide_color_support(window, &windowSupportsWideColor);
+
+        if (err) {
+            ALOGE("processAttributes: invalid window (win=%p) "
+                  "failed (%#x) (already connected to another API?)",
+                  window, err);
+            return false;
+        }
+        if (!windowSupportsWideColor) {
+            // Application has asked for a wide-color colorspace but
+            // wide-color support isn't available on the display the window is on.
+            return false;
+        }
     }
     return true;
 }
 
-static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
-                                         EGLint& colorSpace, android_dataspace& dataSpace) {
-    return getColorSpaceAttribute(dp, NULL, attrib_list, colorSpace, dataSpace);
-}
-
-void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config, EGLint& format) {
+// Gets the native pixel format corrsponding to the passed EGLConfig.
+void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
+                          android_pixel_format* format) {
     // Set the native window's buffers format to match what this config requests.
     // Whether to use sRGB gamma is not part of the EGLconfig, but is part
     // of our native format. So if sRGB gamma is requested, we have to
@@ -694,27 +634,27 @@
     // endif
     if (a == 0) {
         if (colorDepth <= 16) {
-            format = HAL_PIXEL_FORMAT_RGB_565;
+            *format = HAL_PIXEL_FORMAT_RGB_565;
         } else {
             if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
                 if (colorDepth > 24) {
-                    format = HAL_PIXEL_FORMAT_RGBA_1010102;
+                    *format = HAL_PIXEL_FORMAT_RGBA_1010102;
                 } else {
-                    format = HAL_PIXEL_FORMAT_RGBX_8888;
+                    *format = HAL_PIXEL_FORMAT_RGBX_8888;
                 }
             } else {
-                format = HAL_PIXEL_FORMAT_RGBA_FP16;
+                *format = HAL_PIXEL_FORMAT_RGBA_FP16;
             }
         }
     } else {
         if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
             if (colorDepth > 24) {
-                format = HAL_PIXEL_FORMAT_RGBA_1010102;
+                *format = HAL_PIXEL_FORMAT_RGBA_1010102;
             } else {
-                format = HAL_PIXEL_FORMAT_RGBA_8888;
+                *format = HAL_PIXEL_FORMAT_RGBA_8888;
             }
         } else {
-            format = HAL_PIXEL_FORMAT_RGBA_FP16;
+            *format = HAL_PIXEL_FORMAT_RGBA_FP16;
         }
     }
 }
@@ -755,8 +695,6 @@
     egl_connection_t* cnx = NULL;
     egl_display_ptr dp = validate_display_connection(dpy, cnx);
     if (dp) {
-        EGLDisplay iDpy = dp->disp.dpy;
-
         if (!window) {
             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
         }
@@ -775,39 +713,36 @@
             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
         }
 
-        EGLint format;
-        getNativePixelFormat(iDpy, cnx, config, format);
+        EGLDisplay iDpy = dp->disp.dpy;
+        android_pixel_format format;
+        getNativePixelFormat(iDpy, cnx, config, &format);
 
         // now select correct colorspace and dataspace based on user's attribute list
-        EGLint colorSpace;
-        android_dataspace dataSpace;
-        if (!getColorSpaceAttribute(dp, window, attrib_list, colorSpace, dataSpace)) {
+        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+        std::vector<EGLint> strippedAttribList;
+        if (!processAttributes(dp, window, format, attrib_list, &colorSpace,
+                               &strippedAttribList)) {
             ALOGE("error invalid colorspace: %d", colorSpace);
             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
         }
+        attrib_list = strippedAttribList.data();
 
-        std::vector<EGLint> strippedAttribList;
-        if (stripAttributes(dp, attrib_list, format, strippedAttribList)) {
-            // Had to modify the attribute list due to use of color space.
-            // Use modified list from here on.
-            attrib_list = strippedAttribList.data();
-        }
-
-        if (format != 0) {
+        {
             int err = native_window_set_buffers_format(window, format);
             if (err != 0) {
                 ALOGE("error setting native window pixel format: %s (%d)",
-                        strerror(-err), err);
+                      strerror(-err), err);
                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
             }
         }
 
-        if (dataSpace != 0) {
+        android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
+        if (dataSpace != HAL_DATASPACE_UNKNOWN) {
             int err = native_window_set_buffers_data_space(window, dataSpace);
             if (err != 0) {
                 ALOGE("error setting native window pixel dataSpace: %s (%d)",
-                        strerror(-err), err);
+                      strerror(-err), err);
                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
             }
@@ -841,14 +776,20 @@
 
     egl_connection_t* cnx = NULL;
     egl_display_ptr dp = validate_display_connection(dpy, cnx);
-    EGLint colorSpace;
-    android_dataspace dataSpace;
     if (dp) {
+        EGLDisplay iDpy = dp->disp.dpy;
+        android_pixel_format format;
+        getNativePixelFormat(iDpy, cnx, config, &format);
+
         // now select a corresponding sRGB format if needed
-        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+        std::vector<EGLint> strippedAttribList;
+        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
+                               &strippedAttribList)) {
             ALOGE("error invalid colorspace: %d", colorSpace);
             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
         }
+        attrib_list = strippedAttribList.data();
 
         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
                 dp->disp.dpy, config, pixmap, attrib_list);
@@ -869,26 +810,18 @@
     egl_display_ptr dp = validate_display_connection(dpy, cnx);
     if (dp) {
         EGLDisplay iDpy = dp->disp.dpy;
-        EGLint format;
-        getNativePixelFormat(iDpy, cnx, config, format);
+        android_pixel_format format;
+        getNativePixelFormat(iDpy, cnx, config, &format);
 
-        // now select correct colorspace and dataspace based on user's attribute list
-        EGLint colorSpace;
-        android_dataspace dataSpace;
-        if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+        // Select correct colorspace based on user's attribute list
+        EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+        std::vector<EGLint> strippedAttribList;
+        if (!processAttributes(dp, nullptr, format, attrib_list, &colorSpace,
+                               &strippedAttribList)) {
             ALOGE("error invalid colorspace: %d", colorSpace);
             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
         }
-
-        // Pbuffers are not displayed so we don't need to store the
-        // colorspace. We do need to filter out color spaces the
-        // driver doesn't know how to process.
-        std::vector<EGLint> strippedAttribList;
-        if (stripAttributes(dp, attrib_list, format, strippedAttribList)) {
-            // Had to modify the attribute list due to use of color space.
-            // Use modified list from here on.
-            attrib_list = strippedAttribList.data();
-        }
+        attrib_list = strippedAttribList.data();
 
         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
                 dp->disp.dpy, config, attrib_list);
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 74ddd1c..2aec249 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -206,12 +206,16 @@
 
         mExtensionString = gBuiltinExtensionString;
 
+        hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");
+
+        // Note: CDD requires that devices supporting wide color and/or HDR color also support
+        // the EGL_KHR_gl_colorspace extension.
         bool wideColorBoardConfig =
                 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(
                         false);
 
         // Add wide-color extensions if device can support wide-color
-        if (wideColorBoardConfig) {
+        if (wideColorBoardConfig && hasColorSpaceSupport) {
             mExtensionString.append(
                     "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
                     "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 ");
@@ -220,7 +224,7 @@
         bool hasHdrBoardConfig =
                 getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
 
-        if (hasHdrBoardConfig) {
+        if (hasHdrBoardConfig && hasColorSpaceSupport) {
             // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
             // Typically that means there is an HDR capable display attached, but could be
             // support for attaching an HDR display. In either case, advertise support for
@@ -236,6 +240,12 @@
             if (len) {
                 // NOTE: we could avoid the copy if we had strnstr.
                 const std::string ext(start, len);
+                // Temporary hack: Adreno 530 driver exposes this extension under the draft
+                // KHR name, but during Khronos review it was decided to demote it to EXT.
+                if (ext == "EGL_EXT_image_gl_colorspace" &&
+                    findExtension(disp.queryString.extensions, "EGL_KHR_image_gl_colorspace")) {
+                    mExtensionString.append("EGL_EXT_image_gl_colorspace ");
+                }
                 if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
                     mExtensionString.append(ext + " ");
                 }
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index ccd333d..79a9f08 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -113,6 +113,7 @@
     DisplayImpl     disp;
     bool    finishOnSwap;       // property: debug.egl.finish
     bool    traceGpuCompletion; // property: debug.egl.traceGpuCompletion
+    bool    hasColorSpaceSupport;
 
 private:
     friend class egl_display_ptr;
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 2aa4cd3..7fd9d01 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -515,7 +515,27 @@
         recomputeVisibleRegions = true;
     }
 
-    setDataSpace(mConsumer->getCurrentDataSpace());
+    // Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy
+    // data space, however since framework doesn't distinguish them out of
+    // legacy SRGB, we have to treat them as the same for now.
+    // UNKNOWN is treated as legacy SRGB when the connected api is EGL.
+    ui::Dataspace dataSpace = mConsumer->getCurrentDataSpace();
+    switch (dataSpace) {
+        case ui::Dataspace::V0_SRGB:
+            dataSpace = ui::Dataspace::SRGB;
+            break;
+        case ui::Dataspace::V0_SRGB_LINEAR:
+            dataSpace = ui::Dataspace::SRGB_LINEAR;
+            break;
+        case ui::Dataspace::UNKNOWN:
+            if (mConsumer->getCurrentApi() == NATIVE_WINDOW_API_EGL) {
+                dataSpace = ui::Dataspace::SRGB;
+            }
+            break;
+        default:
+            break;
+    }
+    setDataSpace(dataSpace);
 
     Rect crop(mConsumer->getCurrentCrop());
     const uint32_t transform(mConsumer->getCurrentTransform());
@@ -630,7 +650,7 @@
     }
 
     const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
-    error = hwcLayer->setHdrMetadata(metadata);
+    error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
     if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
         ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
               to_string(error).c_str(), static_cast<int32_t>(error));
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index c90024b..077469b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -65,9 +65,14 @@
     }
 }
 
-void Client::setParentLayer(const sp<Layer>& parentLayer) {
+void Client::updateParent(const sp<Layer>& parentLayer) {
     Mutex::Autolock _l(mLock);
-    mParentLayer = parentLayer;
+
+    // If we didn't ever have a parent, then we must instead be
+    // relying on permissions and we never need a parent.
+    if (mParentLayer != nullptr) {
+        mParentLayer = parentLayer;
+    }
 }
 
 sp<Layer> Client::getParentLayer(bool* outParentDied) const {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index c7df9f7..49437ed 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -51,7 +51,7 @@
 
     sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
 
-    void setParentLayer(const sp<Layer>& parentLayer);
+    void updateParent(const sp<Layer>& parentLayer);
 
 private:
     // ISurfaceComposerClient interface
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index d90ab1d..7c6302e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -55,6 +55,7 @@
 using namespace android::hardware::configstore;
 using namespace android::hardware::configstore::V1_0;
 using android::ui::ColorMode;
+using android::ui::Hdr;
 using android::ui::RenderIntent;
 
 /*
@@ -77,7 +78,8 @@
         int displayWidth,
         int displayHeight,
         bool hasWideColorGamut,
-        bool hasHdr10,
+        const HdrCapabilities& hdrCapabilities,
+        const int32_t supportedPerFrameMetadata,
         int initialPowerMode)
     : lastCompositionHadVisibleLayers(false),
       mFlinger(flinger),
@@ -100,9 +102,27 @@
       mActiveColorMode(ColorMode::NATIVE),
       mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY),
       mHasWideColorGamut(hasWideColorGamut),
-      mHasHdr10(hasHdr10)
+      mHasHdr10(false),
+      mHasHLG(false),
+      mHasDolbyVision(false),
+      mSupportedPerFrameMetadata(supportedPerFrameMetadata)
 {
     // clang-format on
+    for (Hdr hdrType : hdrCapabilities.getSupportedHdrTypes()) {
+        switch (hdrType) {
+            case Hdr::HDR10:
+                mHasHdr10 = true;
+                break;
+            case Hdr::HLG:
+                mHasHLG = true;
+                break;
+            case Hdr::DOLBY_VISION:
+                mHasDolbyVision = true;
+                break;
+            default:
+                ALOGE("UNKNOWN HDR capability: %d", static_cast<int32_t>(hdrType));
+        }
+    }
 
     // initialize the display orientation transform.
     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index b8a8906..df5d945 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -23,17 +23,16 @@
 
 #include <math/mat4.h>
 
-#include <ui/Region.h>
-
 #include <binder/IBinder.h>
+#include <gui/ISurfaceComposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <ui/GraphicTypes.h>
+#include <ui/Region.h>
 #include <utils/RefBase.h>
 #include <utils/Mutex.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
-#include <gui/ISurfaceComposer.h>
-#include <hardware/hwcomposer_defs.h>
-#include <ui/GraphicTypes.h>
 #include "RenderArea.h"
 #include "RenderEngine/Surface.h"
 
@@ -85,7 +84,8 @@
             int displayWidth,
             int displayHeight,
             bool hasWideColorGamut,
-            bool hasHdr10,
+            const HdrCapabilities& hdrCapabilities,
+            const int32_t supportedPerFrameMetadata,
             int initialPowerMode);
     // clang-format on
 
@@ -131,12 +131,16 @@
     int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
     const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }
 
+    int32_t getSupportedPerFrameMetadata() const { return mSupportedPerFrameMetadata; }
+
     // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
     // machine happy without actually queueing a buffer if nothing has changed
     status_t beginFrame(bool mustRecompose) const;
     status_t prepareFrame(HWComposer& hwc);
     bool hasWideColorGamut() const { return mHasWideColorGamut; }
-    bool hasHdr10() const { return mHasHdr10; }
+    bool hasHDR10Support() const { return mHasHdr10; }
+    bool hasHLGSupport() const { return mHasHLG; }
+    bool hasDolbyVisionSupport() const { return mHasDolbyVision; }
 
     void swapBuffers(HWComposer& hwc) const;
 
@@ -255,6 +259,10 @@
     // Fed to RenderEngine during composition.
     bool mHasWideColorGamut;
     bool mHasHdr10;
+    bool mHasHLG;
+    bool mHasDolbyVision;
+
+    const int32_t mSupportedPerFrameMetadata;
 };
 
 struct DisplayDeviceState {
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 5daa87e..37ba433 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -32,11 +32,6 @@
 using hardware::Return;
 using hardware::hidl_vec;
 using hardware::hidl_handle;
-using namespace hardware::graphics::common;
-using namespace hardware::graphics::composer;
-using PerFrameMetadata = hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadata;
-using PerFrameMetadataKey =
-        hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
 
 namespace Hwc2 {
 
@@ -126,7 +121,7 @@
 void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId)
 {
     constexpr uint16_t kSetLayerInfoLength = 2;
-    beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+    beginCommand(static_cast<V2_1::IComposerClient::Command>(
                          IVrComposerClient::VrCommand::SET_LAYER_INFO),
                  kSetLayerInfoLength);
     write(type);
@@ -138,7 +133,7 @@
         const IVrComposerClient::BufferMetadata& metadata)
 {
     constexpr uint16_t kSetClientTargetMetadataLength = 7;
-    beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+    beginCommand(static_cast<V2_1::IComposerClient::Command>(
                          IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
                  kSetClientTargetMetadataLength);
     writeBufferMetadata(metadata);
@@ -149,7 +144,7 @@
         const IVrComposerClient::BufferMetadata& metadata)
 {
     constexpr uint16_t kSetLayerBufferMetadataLength = 7;
-    beginCommand(static_cast<hardware::graphics::composer::V2_1::IComposerClient::Command>(
+    beginCommand(static_cast<V2_1::IComposerClient::Command>(
                          IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
                  kSetLayerBufferMetadataLength);
     writeBufferMetadata(metadata);
@@ -171,7 +166,7 @@
     : mWriter(kWriterInitialSize),
       mIsUsingVrComposer(serviceName == std::string("vr"))
 {
-    mComposer = IComposer::getService(serviceName);
+    mComposer = V2_1::IComposer::getService(serviceName);
 
     if (mComposer == nullptr) {
         LOG_ALWAYS_FATAL("failed to get hwcomposer service");
@@ -189,7 +184,7 @@
     }
 
     // 2.2 support is optional
-    sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer);
+    sp<IComposer> composer_2_2 = IComposer::castFrom(mComposer);
     if (composer_2_2 != nullptr) {
         mClient_2_2 = IComposerClient::castFrom(mClient);
         LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr, "IComposer 2.2 did not return IComposerClient 2.2");
@@ -271,7 +266,7 @@
                 });
     } else {
         mClient->createVirtualDisplay(width, height,
-                static_cast<V1_0::PixelFormat>(*format), bufferSlotCount,
+                static_cast<types::V1_0::PixelFormat>(*format), bufferSlotCount,
                 [&](const auto& tmpError, const auto& tmpDisplay,
                     const auto& tmpFormat) {
                     error = tmpError;
@@ -368,7 +363,7 @@
                     if (error != Error::NONE) {
                         return;
                     }
-                    for (V1_0::ColorMode colorMode : tmpModes) {
+                    for (types::V1_0::ColorMode colorMode : tmpModes) {
                         outModes->push_back(static_cast<ColorMode>(colorMode));
                     }
                 });
@@ -533,7 +528,7 @@
             .height = target->getHeight(),
             .stride = target->getStride(),
             .layerCount = target->getLayerCount(),
-            .format = static_cast<V1_0::PixelFormat>(target->getPixelFormat()),
+            .format = static_cast<types::V1_0::PixelFormat>(target->getPixelFormat()),
             .usage = target->getUsage(),
         };
         mWriter.setClientTargetMetadata(metadata);
@@ -556,7 +551,7 @@
         ret = mClient_2_2->setColorMode_2_2(display, mode, renderIntent);
     } else {
         ret = mClient->setColorMode(display,
-                static_cast<V1_0::ColorMode>(mode));
+                static_cast<types::V1_0::ColorMode>(mode));
     }
     return unwrapRet(ret);
 }
@@ -577,15 +572,12 @@
     return Error::NONE;
 }
 
-Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode)
-{
-    hardware::Return<Error> ret(Error::UNSUPPORTED);
+Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode) {
+    Return<Error> ret(Error::UNSUPPORTED);
     if (mClient_2_2) {
         ret = mClient_2_2->setPowerMode_2_2(display, mode);
     } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
-        ret = mClient->setPowerMode(display,
-                                    static_cast<hardware::graphics::composer::V2_1::
-                                                        IComposerClient::PowerMode>(mode));
+        ret = mClient->setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
     }
 
     return unwrapRet(ret);
@@ -663,7 +655,7 @@
             .height = buffer->getHeight(),
             .stride = buffer->getStride(),
             .layerCount = buffer->getLayerCount(),
-            .format = static_cast<V1_0::PixelFormat>(buffer->getPixelFormat()),
+            .format = static_cast<types::V1_0::PixelFormat>(buffer->getPixelFormat()),
             .usage = buffer->getUsage(),
         };
         mWriter.setLayerBufferMetadata(metadata);
@@ -723,47 +715,6 @@
     return Error::NONE;
 }
 
-Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) {
-    if (!mClient_2_2) {
-        return Error::UNSUPPORTED;
-    }
-
-    mWriter.selectDisplay(display);
-    mWriter.selectLayer(layer);
-
-    std::vector<PerFrameMetadata> composerMetadata;
-    if (metadata.validTypes & HdrMetadata::SMPTE2086) {
-        composerMetadata
-                .insert(composerMetadata.end(),
-                        {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryRed.x},
-                         {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryRed.y},
-                         {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryGreen.x},
-                         {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryGreen.y},
-                         {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryBlue.x},
-                         {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryBlue.y},
-                         {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x},
-                         {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y},
-                         {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance},
-                         {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}});
-    }
-    if (metadata.validTypes & HdrMetadata::CTA861_3) {
-        composerMetadata.insert(composerMetadata.end(),
-                                {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
-                                  metadata.cta8613.maxContentLightLevel},
-                                 {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
-                                  metadata.cta8613.maxFrameAverageLightLevel}});
-    }
-
-    mWriter.setLayerPerFrameMetadata(composerMetadata);
-    return Error::NONE;
-}
-
 Error Composer::setLayerDisplayFrame(Display display, Layer layer,
         const IComposerClient::Rect& frame)
 {
@@ -934,6 +885,18 @@
 
 // Composer HAL 2.2
 
+Error Composer::setLayerPerFrameMetadata(Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) {
+    if (!mClient_2_2) {
+        return Error::UNSUPPORTED;
+    }
+
+    mWriter.selectDisplay(display);
+    mWriter.selectLayer(layer);
+    mWriter.setLayerPerFrameMetadata(perFrameMetadatas);
+    return Error::NONE;
+}
+
 Error Composer::getPerFrameMetadataKeys(
         Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) {
     if (!mClient_2_2) {
@@ -1007,9 +970,7 @@
     uint16_t length = 0;
 
     while (!isEmpty()) {
-        auto command_2_1 =
-                reinterpret_cast<hardware::graphics::composer::V2_1::IComposerClient::Command*>(
-                        &command);
+        auto command_2_1 = reinterpret_cast<V2_1::IComposerClient::Command*>(&command);
         if (!beginCommand(command_2_1, &length)) {
             break;
         }
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 08901f6..beee539 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -37,32 +37,35 @@
 
 namespace Hwc2 {
 
-using android::frameworks::vr::composer::V1_0::IVrComposerClient;
+using frameworks::vr::composer::V1_0::IVrComposerClient;
 
-using android::hardware::graphics::common::V1_0::ColorTransform;
-using android::hardware::graphics::common::V1_0::Hdr;
-using android::hardware::graphics::common::V1_0::Transform;
-using android::hardware::graphics::common::V1_1::ColorMode;
-using android::hardware::graphics::common::V1_1::Dataspace;
-using android::hardware::graphics::common::V1_1::PixelFormat;
-using android::hardware::graphics::common::V1_1::RenderIntent;
+namespace types = hardware::graphics::common;
 
-using android::hardware::graphics::composer::V2_1::Config;
-using android::hardware::graphics::composer::V2_1::Display;
-using android::hardware::graphics::composer::V2_1::Error;
-using android::hardware::graphics::composer::V2_1::IComposer;
-using android::hardware::graphics::composer::V2_1::IComposerCallback;
-using android::hardware::graphics::composer::V2_1::Layer;
-using android::hardware::graphics::composer::V2_2::IComposerClient;
+namespace V2_1 = hardware::graphics::composer::V2_1;
+namespace V2_2 = hardware::graphics::composer::V2_2;
 
-using android::hardware::graphics::composer::V2_2::CommandReaderBase;
-using android::hardware::graphics::composer::V2_2::CommandWriterBase;
+using types::V1_0::ColorTransform;
+using types::V1_0::Hdr;
+using types::V1_0::Transform;
 
-using android::hardware::kSynchronizedReadWrite;
-using android::hardware::MessageQueue;
-using android::hardware::MQDescriptorSync;
-using android::hardware::hidl_vec;
-using android::hardware::hidl_handle;
+using types::V1_1::ColorMode;
+using types::V1_1::Dataspace;
+using types::V1_1::PixelFormat;
+using types::V1_1::RenderIntent;
+
+using V2_1::Config;
+using V2_1::Display;
+using V2_1::Error;
+using V2_1::IComposerCallback;
+using V2_1::Layer;
+
+using V2_2::CommandReaderBase;
+using V2_2::CommandWriterBase;
+using V2_2::IComposer;
+using V2_2::IComposerClient;
+
+using PerFrameMetadata = IComposerClient::PerFrameMetadata;
+using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;
 
 class Composer {
 public:
@@ -160,8 +163,6 @@
     virtual Error setLayerCompositionType(Display display, Layer layer,
                                           IComposerClient::Composition type) = 0;
     virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0;
-    virtual Error setLayerHdrMetadata(Display display, Layer layer,
-                                      const HdrMetadata& metadata) = 0;
     virtual Error setLayerDisplayFrame(Display display, Layer layer,
                                        const IComposerClient::Rect& frame) = 0;
     virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0;
@@ -176,6 +177,9 @@
     virtual Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) = 0;
 
     // Composer HAL 2.2
+    virtual Error setLayerPerFrameMetadata(
+            Display display, Layer layer,
+            const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) = 0;
     virtual Error getPerFrameMetadataKeys(
             Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
     virtual Error getRenderIntents(Display display, ColorMode colorMode,
@@ -353,7 +357,6 @@
     Error setLayerCompositionType(Display display, Layer layer,
                                   IComposerClient::Composition type) override;
     Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override;
-    Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override;
     Error setLayerDisplayFrame(Display display, Layer layer,
                                const IComposerClient::Rect& frame) override;
     Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
@@ -368,6 +371,9 @@
     Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) override;
 
     // Composer HAL 2.2
+    Error setLayerPerFrameMetadata(
+            Display display, Layer layer,
+            const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) override;
     Error getPerFrameMetadataKeys(
             Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override;
     Error getRenderIntents(Display display, ColorMode colorMode,
@@ -396,8 +402,9 @@
     // this function to execute the command queue.
     Error execute();
 
-    sp<IComposer> mComposer;
-    sp<hardware::graphics::composer::V2_1::IComposerClient> mClient;
+    sp<V2_1::IComposer> mComposer;
+
+    sp<V2_1::IComposerClient> mClient;
     sp<IComposerClient> mClient_2_2;
 
     // 64KiB minus a small space for metadata such as read/write pointers
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 5f94bb4..3947318 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -32,6 +32,7 @@
 
 #include <algorithm>
 #include <inttypes.h>
+#include <set>
 
 using android::Fence;
 using android::FloatRect;
@@ -54,6 +55,11 @@
 
 namespace {
 
+inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
+                           const Hwc2::PerFrameMetadataKey& key) {
+    return keys.find(key) != keys.end();
+}
+
 class ComposerCallbackBridge : public Hwc2::IComposerCallback {
 public:
     ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
@@ -370,6 +376,42 @@
     return static_cast<Error>(intError);
 }
 
+Error Display::getSupportedPerFrameMetadata(int32_t* outSupportedPerFrameMetadata) const
+{
+    *outSupportedPerFrameMetadata = 0;
+    std::vector<Hwc2::PerFrameMetadataKey> tmpKeys;
+    auto intError = mComposer.getPerFrameMetadataKeys(mId, &tmpKeys);
+    auto error = static_cast<Error>(intError);
+    if (error != Error::None) {
+        return error;
+    }
+
+    // Check whether a specific metadata type is supported. A metadata type is considered
+    // supported if and only if all required fields are supported.
+
+    // SMPTE2086
+    std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end());
+    if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) {
+        *outSupportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086;
+    }
+    // CTA861_3
+    if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) {
+        *outSupportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3;
+    }
+
+    return Error::None;
+}
+
 Error Display::getRenderIntents(ColorMode colorMode,
         std::vector<RenderIntent>* outRenderIntents) const
 {
@@ -448,26 +490,21 @@
     return Error::None;
 }
 
-Error Display::getHdrCapabilities(
-        std::unique_ptr<HdrCapabilities>* outCapabilities) const
+Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const
 {
     float maxLuminance = -1.0f;
     float maxAverageLuminance = -1.0f;
     float minLuminance = -1.0f;
-    std::vector<Hwc2::Hdr> intTypes;
-    auto intError = mComposer.getHdrCapabilities(mId, &intTypes,
+    std::vector<Hwc2::Hdr> types;
+    auto intError = mComposer.getHdrCapabilities(mId, &types,
             &maxLuminance, &maxAverageLuminance, &minLuminance);
     auto error = static_cast<HWC2::Error>(intError);
 
-    std::vector<int32_t> types;
-    for (auto type : intTypes) {
-        types.push_back(static_cast<int32_t>(type));
-    }
     if (error != Error::None) {
         return error;
     }
 
-    *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
+    *outCapabilities = HdrCapabilities(std::move(types),
             maxLuminance, maxAverageLuminance, minLuminance);
     return Error::None;
 }
@@ -789,13 +826,49 @@
     return static_cast<Error>(intError);
 }
 
-Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) {
+Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
+        const android::HdrMetadata& metadata)
+{
     if (metadata == mHdrMetadata) {
         return Error::None;
     }
 
     mHdrMetadata = metadata;
-    auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata);
+    int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata;
+    std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas;
+    if (validTypes & HdrMetadata::SMPTE2086) {
+        perFrameMetadatas.insert(perFrameMetadatas.end(),
+                                 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryRed.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryRed.y},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryGreen.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryGreen.y},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryBlue.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryBlue.y},
+                                   {Hwc2::PerFrameMetadataKey::WHITE_POINT_X,
+                                         mHdrMetadata.smpte2086.whitePoint.x},
+                                   {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y,
+                                         mHdrMetadata.smpte2086.whitePoint.y},
+                                   {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE,
+                                         mHdrMetadata.smpte2086.maxLuminance},
+                                   {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE,
+                                         mHdrMetadata.smpte2086.minLuminance}});
+    }
+
+    if (validTypes & HdrMetadata::CTA861_3) {
+        perFrameMetadatas.insert(perFrameMetadatas.end(),
+                                 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
+                                         mHdrMetadata.cta8613.maxContentLightLevel},
+                                   {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+                                         mHdrMetadata.cta8613.maxFrameAverageLightLevel}});
+    }
+
+    auto intError = mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas);
     return static_cast<Error>(intError);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index e5779d4..3ac06ec 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -27,7 +27,6 @@
 #include <math/mat4.h>
 #include <ui/GraphicTypes.h>
 #include <ui/HdrCapabilities.h>
-
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
@@ -212,6 +211,10 @@
             std::unordered_map<Layer*, Composition>* outTypes);
     [[clang::warn_unused_result]] Error getColorModes(
             std::vector<android::ui::ColorMode>* outModes) const;
+    // outSupportedPerFrameMetadata is an opaque bitmask to the callers
+    // but contains HdrMetadata::Type::*.
+    [[clang::warn_unused_result]] Error getSupportedPerFrameMetadata(
+            int32_t* outSupportedPerFrameMetadata) const;
     [[clang::warn_unused_result]] Error getRenderIntents(
             android::ui::ColorMode colorMode,
             std::vector<android::ui::RenderIntent>* outRenderIntents) const;
@@ -228,7 +231,7 @@
     [[clang::warn_unused_result]] Error getType(DisplayType* outType) const;
     [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const;
     [[clang::warn_unused_result]] Error getHdrCapabilities(
-            std::unique_ptr<android::HdrCapabilities>* outCapabilities) const;
+            android::HdrCapabilities* outCapabilities) const;
     [[clang::warn_unused_result]] Error getReleaseFences(
             std::unordered_map<Layer*,
                     android::sp<android::Fence>>* outFences) const;
@@ -318,7 +321,9 @@
     [[clang::warn_unused_result]] Error setCompositionType(Composition type);
     [[clang::warn_unused_result]] Error setDataspace(
             android::ui::Dataspace dataspace);
-    [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata);
+    [[clang::warn_unused_result]] Error setPerFrameMetadata(
+            const int32_t supportedPerFrameMetadata,
+            const android::HdrMetadata& metadata);
     [[clang::warn_unused_result]] Error setDisplayFrame(
             const android::Rect& frame);
     [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 8db8aa6..1bbf039 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -824,24 +824,41 @@
     mDisplayData[displayId].releaseFences.clear();
 }
 
-std::unique_ptr<HdrCapabilities> HWComposer::getHdrCapabilities(
-        int32_t displayId) {
+status_t HWComposer::getHdrCapabilities(
+        int32_t displayId, HdrCapabilities* outCapabilities) {
     if (!isValidDisplay(displayId)) {
         ALOGE("getHdrCapabilities: Display %d is not valid", displayId);
-        return nullptr;
+        return BAD_INDEX;
     }
 
     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
-    std::unique_ptr<HdrCapabilities> capabilities;
-    auto error = hwcDisplay->getHdrCapabilities(&capabilities);
+    auto error = hwcDisplay->getHdrCapabilities(outCapabilities);
     if (error != HWC2::Error::None) {
         ALOGE("getOutputCapabilities: Failed to get capabilities on display %d:"
-                " %s (%d)", displayId, to_string(error).c_str(),
-                static_cast<int32_t>(error));
-        return nullptr;
+              " %s (%d)", displayId, to_string(error).c_str(),
+              static_cast<int32_t>(error));
+        return UNKNOWN_ERROR;
+    }
+    return NO_ERROR;
+}
+
+int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const {
+    if (!isValidDisplay(displayId)) {
+        ALOGE("getPerFrameMetadataKeys: Attempted to access invalid display %d",
+                displayId);
+        return 0;
     }
 
-    return capabilities;
+    int32_t supportedMetadata;
+    auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata(
+            &supportedMetadata);
+    if (error != HWC2::Error::None) {
+        ALOGE("getPerFrameMetadataKeys failed for display %d: %s (%d)", displayId,
+              to_string(error).c_str(), static_cast<int32_t>(error));
+        return 0;
+    }
+
+    return supportedMetadata;
 }
 
 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId,
@@ -855,7 +872,7 @@
     std::vector<ui::RenderIntent> renderIntents;
     auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents);
     if (error != HWC2::Error::None) {
-        ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
+        ALOGE("getRenderIntents failed for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
         return std::vector<ui::RenderIntent>();
     }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index e86d621..d7f3b08 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -24,7 +24,6 @@
 
 #include <ui/Fence.h>
 #include <ui/GraphicTypes.h>
-
 #include <utils/BitSet.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
@@ -134,8 +133,10 @@
     // it can call this to clear the shared pointers in the release fence map
     void clearReleaseFences(int32_t displayId);
 
-    // Returns the HDR capabilities of the given display
-    std::unique_ptr<HdrCapabilities> getHdrCapabilities(int32_t displayId);
+    // Fetches the HDR capabilities of the given display
+    status_t getHdrCapabilities(int32_t displayId, HdrCapabilities* outCapabilities);
+
+    int32_t getSupportedPerFrameMetadata(int32_t displayId) const;
 
     // Returns the available RenderIntent of the given display.
     std::vector<ui::RenderIntent> getRenderIntents(int32_t displayId, ui::ColorMode colorMode) const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8c0050e..bbc974d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <algorithm>
 
 #include <cutils/compiler.h>
 #include <cutils/native_handle.h>
@@ -1588,7 +1589,7 @@
 
         sp<Client> client(child->mClientRef.promote());
         if (client != nullptr) {
-            client->setParentLayer(newParent);
+            client->updateParent(newParent);
         }
     }
     mCurrentChildren.clear();
@@ -1624,7 +1625,7 @@
     sp<Client> newParentClient(newParent->mClientRef.promote());
 
     if (client != newParentClient) {
-        client->setParentLayer(newParent);
+        client->updateParent(newParent);
     }
 
     return true;
@@ -1643,19 +1644,9 @@
     return true;
 }
 
-// Dataspace::UNKNOWN, Dataspace::SRGB, Dataspace::SRGB_LINEAR,
-// Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are considered legacy
-// SRGB data space for now.
-// Note that Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy
-// data space, however since framework doesn't distinguish them out of legacy
-// SRGB, we have to treat them as the same for now.
 bool Layer::isLegacySrgbDataSpace() const {
-    // TODO(lpy) b/77652630, need to figure out when UNKNOWN can be treated as SRGB.
-    return mDrawingState.dataSpace == ui::Dataspace::UNKNOWN ||
-        mDrawingState.dataSpace == ui::Dataspace::SRGB ||
-        mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR ||
-        mDrawingState.dataSpace == ui::Dataspace::V0_SRGB ||
-        mDrawingState.dataSpace == ui::Dataspace::V0_SRGB_LINEAR;
+    return mDrawingState.dataSpace == ui::Dataspace::SRGB ||
+        mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR;
 }
 
 void Layer::setParent(const sp<Layer>& layer) {
@@ -1787,29 +1778,81 @@
     }
 }
 
-/**
- * Traverse only children in z order, ignoring relative layers.
- */
-void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
-                                     const LayerVector::Visitor& visitor) {
+LayerVector Layer::makeChildrenTraversalList(LayerVector::StateSet stateSet,
+                                             const std::vector<Layer*>& layersInTree) {
+    LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
+                        "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
+
+    LayerVector traverse;
+    for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
+        sp<Layer> strongRelative = weakRelative.promote();
+        // Only add relative layers that are also descendents of the top most parent of the tree.
+        // If a relative layer is not a descendent, then it should be ignored.
+        if (std::binary_search(layersInTree.begin(), layersInTree.end(), strongRelative.get())) {
+            traverse.add(strongRelative);
+        }
+    }
+
+    for (const sp<Layer>& child : children) {
+        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
+        // descendent of the top most parent of the tree. If it's not a descendent, then just add
+        // the child here since it won't be added later as a relative.
+        if (std::binary_search(layersInTree.begin(), layersInTree.end(),
+                               childState.zOrderRelativeOf.promote().get())) {
+            continue;
+        }
+        traverse.add(child);
+    }
+
+    return traverse;
+}
+
+void Layer::traverseChildrenInZOrderInner(const std::vector<Layer*>& layersInTree,
+                                          LayerVector::StateSet stateSet,
+                                          const LayerVector::Visitor& visitor) {
+    const LayerVector list = makeChildrenTraversalList(stateSet, layersInTree);
 
     size_t i = 0;
-    for (; i < children.size(); i++) {
-        const auto& relative = children[i];
+    for (; i < list.size(); i++) {
+        const auto& relative = list[i];
         if (relative->getZ() >= 0) {
             break;
         }
-        relative->traverseChildrenInZOrder(stateSet, visitor);
+        relative->traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
     }
+
     visitor(this);
-    for (; i < children.size(); i++) {
-        const auto& relative = children[i];
-        relative->traverseChildrenInZOrder(stateSet, visitor);
+    for (; i < list.size(); i++) {
+        const auto& relative = list[i];
+        relative->traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
     }
 }
 
+std::vector<Layer*> Layer::getLayersInTree(LayerVector::StateSet stateSet) {
+    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
+    const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
+
+    std::vector<Layer*> layersInTree = {this};
+    for (size_t i = 0; i < children.size(); i++) {
+        const auto& child = children[i];
+        std::vector<Layer*> childLayers = child->getLayersInTree(stateSet);
+        layersInTree.insert(layersInTree.end(), childLayers.cbegin(), childLayers.cend());
+    }
+
+    return layersInTree;
+}
+
+void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
+                                     const LayerVector::Visitor& visitor) {
+    std::vector<Layer*> layersInTree = getLayersInTree(stateSet);
+    std::sort(layersInTree.begin(), layersInTree.end());
+    traverseChildrenInZOrderInner(layersInTree, stateSet, visitor);
+}
+
 Transform Layer::getTransform() const {
     Transform t;
     const auto& p = mDrawingParent.promote();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d382a1a..be3967b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -51,6 +51,7 @@
 #include "RenderEngine/Texture.h"
 
 #include <math/vec4.h>
+#include <vector>
 
 using namespace android::surfaceflinger;
 
@@ -564,6 +565,10 @@
                                  const LayerVector::Visitor& visitor);
     void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor);
 
+    /**
+     * Traverse only children in z order, ignoring relative layers that are not children of the
+     * parent.
+     */
     void traverseChildrenInZOrder(LayerVector::StateSet stateSet,
                                   const LayerVector::Visitor& visitor);
 
@@ -778,6 +783,22 @@
     wp<Layer> mDrawingParent;
 
     mutable LayerBE mBE;
+
+private:
+    /**
+     * Returns an unsorted vector of all layers that are part of this tree.
+     * That includes the current layer and all its descendants.
+     */
+    std::vector<Layer*> getLayersInTree(LayerVector::StateSet stateSet);
+    /**
+     * Traverses layers that are part of this tree in the correct z order.
+     * layersInTree must be sorted before calling this method.
+     */
+    void traverseChildrenInZOrderInner(const std::vector<Layer*>& layersInTree,
+                                       LayerVector::StateSet stateSet,
+                                       const LayerVector::Visitor& visitor);
+    LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet,
+                                          const std::vector<Layer*>& layersInTree);
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index 5e79e7a..323bdb2 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -73,8 +73,4 @@
     mOutputTransferFunction = transferFunction;
 }
 
-void Description::enableToneMapping(bool enable) {
-    mToneMappingEnabled = enable;
-}
-
 } /* namespace android */
diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h
index 75c1981..5854ba4 100644
--- a/services/surfaceflinger/RenderEngine/Description.h
+++ b/services/surfaceflinger/RenderEngine/Description.h
@@ -51,12 +51,11 @@
         LINEAR,
         SRGB,
         ST2084,
+        HLG,  // Hybrid Log-Gamma for HDR.
     };
     void setInputTransferFunction(TransferFunction transferFunction);
     void setOutputTransferFunction(TransferFunction transferFunction);
 
-    void enableToneMapping(bool enable);
-
 private:
     friend class Program;
     friend class ProgramCache;
@@ -84,9 +83,6 @@
     // transfer functions for the input/output
     TransferFunction mInputTransferFunction = TransferFunction::LINEAR;
     TransferFunction mOutputTransferFunction = TransferFunction::LINEAR;
-
-    // tone-map the color
-    bool mToneMappingEnabled = false;
 };
 
 } /* namespace android */
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 0fb3d28..6e0fa32 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -316,15 +316,26 @@
                 wideColorState.setColorMatrix(mState.getColorMatrix() * mBt2020ToDisplayP3);
                 wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084);
                 wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
-                wideColorState.enableToneMapping(true);
+                break;
+            case Dataspace::BT2020_HLG:
+            case Dataspace::BT2020_ITU_HLG:
+                wideColorState.setColorMatrix(mState.getColorMatrix() * mBt2020ToDisplayP3);
+                wideColorState.setInputTransferFunction(Description::TransferFunction::HLG);
+                wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
                 break;
             default:
                 // treat all other dataspaces as sRGB
                 wideColorState.setColorMatrix(mState.getColorMatrix() * mSrgbToDisplayP3);
-                if ((mDataSpace & Dataspace::TRANSFER_MASK) & Dataspace::TRANSFER_LINEAR) {
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR);
-                } else {
-                    wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB);
+                switch (static_cast<Dataspace>(mDataSpace & Dataspace::TRANSFER_MASK)) {
+                    case Dataspace::TRANSFER_LINEAR:
+                        wideColorState.setInputTransferFunction(
+                                Description::TransferFunction::LINEAR);
+                        break;
+                    default:
+                        // treat all other transfer functions as sRGB
+                        wideColorState.setInputTransferFunction(
+                                Description::TransferFunction::SRGB);
+                        break;
                 }
                 wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
                 ALOGV("drawMesh: gamut transform applied");
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 6a34981..d1887ee 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -143,6 +143,9 @@
             case Description::TransferFunction::ST2084:
                 needs.set(Key::INPUT_TF_MASK, Key::INPUT_TF_ST2084);
                 break;
+            case Description::TransferFunction::HLG:
+                needs.set(Key::INPUT_TF_MASK, Key::INPUT_TF_HLG);
+                break;
         }
 
         switch (description.mOutputTransferFunction) {
@@ -156,10 +159,10 @@
             case Description::TransferFunction::ST2084:
                 needs.set(Key::OUTPUT_TF_MASK, Key::OUTPUT_TF_ST2084);
                 break;
+            case Description::TransferFunction::HLG:
+                needs.set(Key::OUTPUT_TF_MASK, Key::OUTPUT_TF_HLG);
+                break;
         }
-
-        needs.set(Key::TONE_MAPPING_MASK,
-                  description.mToneMappingEnabled ? Key::TONE_MAPPING_ON : Key::TONE_MAPPING_OFF);
     }
 
     return needs;
@@ -220,6 +223,8 @@
     if (needs.hasColorMatrix()) {
         fs << "uniform mat4 colorMatrix;";
 
+        // Generate EOTF that converts signal values to relative display light,
+        // both normalized to [0, 1].
         switch (needs.getInputTF()) {
             case Key::INPUT_TF_LINEAR:
             default:
@@ -259,8 +264,123 @@
                     }
                     )__SHADER__";
                 break;
+          case Key::INPUT_TF_HLG:
+              fs << R"__SHADER__(
+                  highp float EOTF_channel(const highp float channel) {
+                      const highp float a = 0.17883277;
+                      const highp float b = 0.28466892;
+                      const highp float c = 0.55991073;
+                      return channel <= 0.5 ? channel * channel / 3.0 :
+                              (exp((channel - c) / a) + b) / 12.0;
+                  }
+
+                  vec3 EOTF(const highp vec3 color) {
+                      return vec3(EOTF_channel(color.r), EOTF_channel(color.g),
+                              EOTF_channel(color.b));
+                  }
+                  )__SHADER__";
+              break;
         }
 
+        fs << R"__SHADER__(
+            highp float CalculateY(const highp vec3 color) {
+                // BT2020 standard uses the unadjusted KR = 0.2627,
+                // KB = 0.0593 luminance interpretation for RGB conversion.
+                return color.r * 0.262700 + color.g * 0.677998 +
+                        color.b * 0.059302;
+            }
+        )__SHADER__";
+
+        // Generate OOTF that modifies the relative display light.
+        switch(needs.getInputTF()) {
+            case Key::INPUT_TF_ST2084:
+                fs << R"__SHADER__(
+                    highp vec3 OOTF(const highp vec3 color) {
+                        const float maxLumi = 10000.0;
+                        const float maxMasteringLumi = 1000.0;
+                        const float maxContentLumi = 1000.0;
+                        const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
+                        const float maxOutLumi = 500.0;
+
+                        // Calculate Y value in XYZ color space.
+                        float colorY = CalculateY(color);
+
+                        // convert to nits first
+                        float nits = colorY * maxLumi;
+
+                        // clamp to max input luminance
+                        nits = clamp(nits, 0.0, maxInLumi);
+
+                        // scale [0.0, maxInLumi] to [0.0, maxOutLumi]
+                        if (maxInLumi <= maxOutLumi) {
+                            nits *= maxOutLumi / maxInLumi;
+                        } else {
+                            // three control points
+                            const float x0 = 10.0;
+                            const float y0 = 17.0;
+                            const float x1 = maxOutLumi * 0.75;
+                            const float y1 = x1;
+                            const float x2 = x1 + (maxInLumi - x1) / 2.0;
+                            const float y2 = y1 + (maxOutLumi - y1) * 0.75;
+
+                            // horizontal distances between the last three control points
+                            const float h12 = x2 - x1;
+                            const float h23 = maxInLumi - x2;
+                            // tangents at the last three control points
+                            const float m1 = (y2 - y1) / h12;
+                            const float m3 = (maxOutLumi - y2) / h23;
+                            const float m2 = (m1 + m3) / 2.0;
+
+                            if (nits < x0) {
+                                // scale [0.0, x0] to [0.0, y0] linearly
+                                const float slope = y0 / x0;
+                                nits *= slope;
+                            } else if (nits < x1) {
+                                // scale [x0, x1] to [y0, y1] linearly
+                                const float slope = (y1 - y0) / (x1 - x0);
+                                nits = y0 + (nits - x0) * slope;
+                            } else if (nits < x2) {
+                                // scale [x1, x2] to [y1, y2] using Hermite interp
+                                float t = (nits - x1) / h12;
+                                nits = (y1 * (1.0 + 2.0 * t) + h12 * m1 * t) * (1.0 - t) * (1.0 - t) +
+                                       (y2 * (3.0 - 2.0 * t) + h12 * m2 * (t - 1.0)) * t * t;
+                            } else {
+                                // scale [x2, maxInLumi] to [y2, maxOutLumi] using Hermite interp
+                                float t = (nits - x2) / h23;
+                                nits = (y2 * (1.0 + 2.0 * t) + h23 * m2 * t) * (1.0 - t) * (1.0 - t) +
+                                       (maxOutLumi * (3.0 - 2.0 * t) + h23 * m3 * (t - 1.0)) * t * t;
+                            }
+                        }
+
+                        // convert back to [0.0, 1.0]
+                        float targetY = nits / maxOutLumi;
+                        return color * (targetY / max(1e-6, colorY));
+                    }
+                )__SHADER__";
+                break;
+            case Key::INPUT_TF_HLG:
+                fs << R"__SHADER__(
+                    highp vec3 OOTF(const highp vec3 color) {
+                        const float maxOutLumi = 500.0;
+                        const float gamma = 1.2 + 0.42 * log(maxOutLumi / 1000.0) / log(10.0);
+                        // The formula is:
+                        // alpha * pow(Y, gamma - 1.0) * color + beta;
+                        // where alpha is 1.0, beta is 0.0 as recommended in
+                        // Rec. ITU-R BT.2100-1 TABLE 5.
+                        return pow(CalculateY(color), gamma - 1.0) * color;
+                    }
+                )__SHADER__";
+                break;
+            default:
+                fs << R"__SHADER__(
+                    highp vec3 OOTF(const highp vec3 color) {
+                        return color;
+                    }
+                )__SHADER__";
+        }
+
+        // Generate OETF that converts relative display light to signal values,
+        // both normalized to [0, 1]
         switch (needs.getOutputTF()) {
             case Key::OUTPUT_TF_LINEAR:
             default:
@@ -301,84 +421,22 @@
                     }
                 )__SHADER__";
                 break;
-        }
-
-        if (needs.hasToneMapping()) {
-            fs << R"__SHADER__(
-                float CalculateY(const vec3 color) {
-                    // BT2020 standard uses the unadjusted KR = 0.2627,
-                    // KB = 0.0593 luminance interpretation for RGB conversion.
-                    return color.r * 0.262700 + color.g * 0.677998 +
-                            color.b * 0.059302;
-                }
-                vec3 ToneMap(const vec3 color) {
-                    const float maxLumi = 10000.0;
-                    const float maxMasteringLumi = 1000.0;
-                    const float maxContentLumi = 1000.0;
-                    const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
-                    const float maxOutLumi = 500.0;
-
-                    // Calculate Y value in XYZ color space.
-                    float colorY = CalculateY(color);
-
-                    // convert to nits first
-                    float nits = colorY * maxLumi;
-
-                    // clamp to max input luminance
-                    nits = clamp(nits, 0.0, maxInLumi);
-
-                    // scale [0.0, maxInLumi] to [0.0, maxOutLumi]
-                    if (maxInLumi <= maxOutLumi) {
-                        nits *= maxOutLumi / maxInLumi;
-                    } else {
-                        // three control points
-                        const float x0 = 10.0;
-                        const float y0 = 17.0;
-                        const float x1 = maxOutLumi * 0.75;
-                        const float y1 = x1;
-                        const float x2 = x1 + (maxInLumi - x1) / 2.0;
-                        const float y2 = y1 + (maxOutLumi - y1) * 0.75;
-
-                        // horizontal distances between the last three control points
-                        const float h12 = x2 - x1;
-                        const float h23 = maxInLumi - x2;
-                        // tangents at the last three control points
-                        const float m1 = (y2 - y1) / h12;
-                        const float m3 = (maxOutLumi - y2) / h23;
-                        const float m2 = (m1 + m3) / 2.0;
-
-                        if (nits < x0) {
-                            // scale [0.0, x0] to [0.0, y0] linearly
-                            const float slope = y0 / x0;
-                            nits *= slope;
-                        } else if (nits < x1) {
-                            // scale [x0, x1] to [y0, y1] linearly
-                            const float slope = (y1 - y0) / (x1 - x0);
-                            nits = y0 + (nits - x0) * slope;
-                        } else if (nits < x2) {
-                            // scale [x1, x2] to [y1, y2] using Hermite interp
-                            float t = (nits - x1) / h12;
-                            nits = (y1 * (1.0 + 2.0 * t) + h12 * m1 * t) * (1.0 - t) * (1.0 - t) +
-                                   (y2 * (3.0 - 2.0 * t) + h12 * m2 * (t - 1.0)) * t * t;
-                        } else {
-                            // scale [x2, maxInLumi] to [y2, maxOutLumi] using Hermite interp
-                            float t = (nits - x2) / h23;
-                            nits = (y2 * (1.0 + 2.0 * t) + h23 * m2 * t) * (1.0 - t) * (1.0 - t) +
-                                   (maxOutLumi * (3.0 - 2.0 * t) + h23 * m3 * (t - 1.0)) * t * t;
-                        }
+            case Key::OUTPUT_TF_HLG:
+                fs << R"__SHADER__(
+                    highp float OETF_channel(const highp float channel) {
+                        const highp float a = 0.17883277;
+                        const highp float b = 0.28466892;
+                        const highp float c = 0.55991073;
+                        return channel <= 1.0 / 12.0 ? sqrt(3.0 * channel) :
+                                a * log(12.0 * channel - b) + c;
                     }
 
-                    // convert back to [0.0, 1.0]
-                    float targetY = nits / maxOutLumi;
-                    return color * (targetY / max(1e-6, colorY));
-                }
-            )__SHADER__";
-        } else {
-            fs << R"__SHADER__(
-                vec3 ToneMap(const vec3 color) {
-                    return color;
-                }
-            )__SHADER__";
+                    vec3 OETF(const highp vec3 color) {
+                        return vec3(OETF_channel(color.r), OETF_channel(color.g),
+                                OETF_channel(color.b));
+                    }
+                )__SHADER__";
+                break;
         }
     }
 
@@ -411,7 +469,7 @@
             // avoid divide by 0 by adding 0.5/256 to the alpha channel
             fs << "gl_FragColor.rgb = gl_FragColor.rgb / (gl_FragColor.a + 0.0019);";
         }
-        fs << "vec4 transformed = colorMatrix * vec4(ToneMap(EOTF(gl_FragColor.rgb)), 1);";
+        fs << "vec4 transformed = colorMatrix * vec4(OOTF(EOTF(gl_FragColor.rgb)), 1);";
         // the transformation from a wider colorspace to a narrower one can
         // result in >1.0 or <0.0 pixel values
         fs << "transformed.rgb = clamp(transformed.rgb, 0.0, 1.0);";
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index dcc8cc6..f67e132 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -81,19 +81,16 @@
             INPUT_TF_LINEAR = 0 << INPUT_TF_SHIFT,
             INPUT_TF_SRGB = 1 << INPUT_TF_SHIFT,
             INPUT_TF_ST2084 = 2 << INPUT_TF_SHIFT,
+            INPUT_TF_HLG = 3 << INPUT_TF_SHIFT,
 
             OUTPUT_TF_SHIFT = 8,
             OUTPUT_TF_MASK = 3 << OUTPUT_TF_SHIFT,
             OUTPUT_TF_LINEAR = 0 << OUTPUT_TF_SHIFT,
             OUTPUT_TF_SRGB = 1 << OUTPUT_TF_SHIFT,
             OUTPUT_TF_ST2084 = 2 << OUTPUT_TF_SHIFT,
+            OUTPUT_TF_HLG = 3 << OUTPUT_TF_SHIFT,
 
-            TONE_MAPPING_SHIFT = 10,
-            TONE_MAPPING_MASK = 1 << TONE_MAPPING_SHIFT,
-            TONE_MAPPING_OFF = 0 << TONE_MAPPING_SHIFT,
-            TONE_MAPPING_ON = 1 << TONE_MAPPING_SHIFT,
-
-            Y410_BT2020_SHIFT = 11,
+            Y410_BT2020_SHIFT = 10,
             Y410_BT2020_MASK = 1 << Y410_BT2020_SHIFT,
             Y410_BT2020_OFF = 0 << Y410_BT2020_SHIFT,
             Y410_BT2020_ON = 1 << Y410_BT2020_SHIFT,
@@ -115,7 +112,6 @@
         inline bool hasColorMatrix() const { return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON; }
         inline int getInputTF() const { return (mKey & INPUT_TF_MASK); }
         inline int getOutputTF() const { return (mKey & OUTPUT_TF_MASK); }
-        inline bool hasToneMapping() const { return (mKey & TONE_MAPPING_MASK) == TONE_MAPPING_ON; }
         inline bool isY410BT2020() const { return (mKey & Y410_BT2020_MASK) == Y410_BT2020_ON; }
 
         // this is the definition of a friend function -- not a method of class Needs
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 57f729b..e661f03 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -106,6 +106,7 @@
 using namespace android::hardware::configstore::V1_0;
 using ui::ColorMode;
 using ui::Dataspace;
+using ui::Hdr;
 using ui::RenderIntent;
 
 namespace {
@@ -1118,21 +1119,23 @@
         return BAD_VALUE;
     }
 
-    std::unique_ptr<HdrCapabilities> capabilities =
-            getBE().mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId());
-    if (capabilities) {
-        if (displayDevice->hasWideColorGamut() && !displayDevice->hasHdr10()) {
+    HdrCapabilities capabilities;
+    int status = getBE().mHwc->getHdrCapabilities(
+        displayDevice->getHwcDisplayId(), &capabilities);
+    if (status == NO_ERROR) {
+        if (displayDevice->hasWideColorGamut() &&
+            !displayDevice->hasHDR10Support()) {
             // insert HDR10 as we will force client composition for HDR10
             // layers
-            std::vector<int32_t> types = capabilities->getSupportedHdrTypes();
-            types.push_back(HAL_HDR_HDR10);
+            std::vector<Hdr> types = capabilities.getSupportedHdrTypes();
+            types.push_back(Hdr::HDR10);
 
             *outCapabilities = HdrCapabilities(types,
-                    capabilities->getDesiredMaxLuminance(),
-                    capabilities->getDesiredMaxAverageLuminance(),
-                    capabilities->getDesiredMinLuminance());
+                    capabilities.getDesiredMaxLuminance(),
+                    capabilities.getDesiredMaxAverageLuminance(),
+                    capabilities.getDesiredMinLuminance());
         } else {
-            *outCapabilities = std::move(*capabilities);
+            *outCapabilities = std::move(capabilities);
         }
     } else {
         return BAD_VALUE;
@@ -1906,7 +1909,7 @@
                 // Historically, HDR dataspaces are ignored by SurfaceFlinger. But
                 // since SurfaceFlinger simulates HDR support now, it should honor
                 // them unless there is also native support.
-                if (!displayDevice->hasHdr10()) {
+                if (!displayDevice->hasHDR10Support()) {
                     return Dataspace::V0_SCRGB_LINEAR;
                 }
                 break;
@@ -2024,7 +2027,7 @@
         for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
             if ((layer->getDataSpace() == Dataspace::BT2020_PQ ||
                  layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) &&
-                    !displayDevice->hasHdr10()) {
+                    !displayDevice->hasHDR10Support()) {
                 layer->forceClientComposition(hwcId);
             }
 
@@ -2277,13 +2280,8 @@
         }
     }
 
-    bool hasHdr10 = false;
-    std::unique_ptr<HdrCapabilities> hdrCapabilities = getHwComposer().getHdrCapabilities(hwcId);
-    if (hdrCapabilities) {
-        const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes();
-        auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10);
-        hasHdr10 = iter != types.cend();
-    }
+    HdrCapabilities hdrCapabilities;
+    getHwComposer().getHdrCapabilities(hwcId, &hdrCapabilities);
 
     auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
     auto nativeWindow = nativeWindowSurface->getNativeWindow();
@@ -2316,7 +2314,9 @@
     sp<DisplayDevice> hw =
             new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
                               dispSurface, std::move(renderSurface), displayWidth, displayHeight,
-                              hasWideColorGamut, hasHdr10, initialPowerMode);
+                              hasWideColorGamut, hdrCapabilities,
+                              getHwComposer().getSupportedPerFrameMetadata(hwcId),
+                              initialPowerMode);
 
     if (maxFrameBufferAcquiredBuffers >= 3) {
         nativeWindowSurface->preallocateBuffers();
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index a0f12f1..5108279 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -2376,6 +2376,58 @@
     mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
 }
 
+TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
+    auto fgHandle = mFGSurfaceControl->getHandle();
+
+    sp<SurfaceControl> child =
+            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+                                           0, mFGSurfaceControl.get());
+    sp<SurfaceControl> relative = mComposerClient->createSurface(String8("Relative surface"), 10,
+                                                                 10, PIXEL_FORMAT_RGBA_8888, 0);
+    fillSurfaceRGBA8(child, 200, 200, 200);
+    fillSurfaceRGBA8(relative, 100, 100, 100);
+
+    SurfaceComposerClient::Transaction()
+            .show(child)
+            // Set relative layer above fg layer so should be shown above when computing all layers.
+            .setRelativeLayer(relative, fgHandle, 1)
+            .show(relative)
+            .apply(true);
+
+    // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
+    ScreenCapture::captureLayers(&mCapture, fgHandle);
+    mCapture->expectFGColor(10, 10);
+    mCapture->expectChildColor(0, 0);
+}
+
+TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
+    auto fgHandle = mFGSurfaceControl->getHandle();
+
+    sp<SurfaceControl> child =
+            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
+                                           0, mFGSurfaceControl.get());
+    sp<SurfaceControl> relative =
+            mComposerClient->createSurface(String8("Relative surface"), 10, 10,
+                                           PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
+    fillSurfaceRGBA8(child, 200, 200, 200);
+    fillSurfaceRGBA8(relative, 100, 100, 100);
+
+    SurfaceComposerClient::Transaction()
+            .show(child)
+            // Set relative layer below fg layer but relative to child layer so it should be shown
+            // above child layer.
+            .setLayer(relative, -1)
+            .setRelativeLayer(relative, child->getHandle(), 1)
+            .show(relative)
+            .apply(true);
+
+    // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
+    // relative value should be taken into account, placing it above child layer.
+    ScreenCapture::captureLayers(&mCapture, fgHandle);
+    mCapture->expectFGColor(10, 10);
+    // Relative layer is showing on top of child layer
+    mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
+}
 
 // In the following tests we verify successful skipping of a parent layer,
 // so we use the same verification logic and only change how we mutate
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
index 6c0e4ab..0957d6a 100644
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ b/services/surfaceflinger/tests/hwc2/Android.bp
@@ -41,7 +41,6 @@
         "libmath",
     ],
     shared_libs: [
-        "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.common@1.1",
         "libcutils",
         "libEGL",
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 8ffc5ad..bcabe0d 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -20,17 +20,17 @@
     srcs: [
         ":libsurfaceflinger_sources",
         "DisplayTransactionTest.cpp",
-        "MockComposer.cpp",
-        "MockDisplaySurface.cpp",
-        "MockEventControlThread.cpp",
-        "MockEventThread.cpp",
-        "MockGraphicBufferConsumer.cpp",
-        "MockGraphicBufferProducer.cpp",
-        "MockMessageQueue.cpp",
-        "MockNativeWindow.cpp",
-        "MockNativeWindowSurface.cpp",
-        "MockRenderEngine.cpp",
-        "MockSurfaceInterceptor.cpp",
+        "mock/DisplayHardware/MockComposer.cpp",
+        "mock/DisplayHardware/MockDisplaySurface.cpp",
+        "mock/gui/MockGraphicBufferConsumer.cpp",
+        "mock/gui/MockGraphicBufferProducer.cpp",
+        "mock/MockEventControlThread.cpp",
+        "mock/MockEventThread.cpp",
+        "mock/MockMessageQueue.cpp",
+        "mock/MockNativeWindowSurface.cpp",
+        "mock/MockSurfaceInterceptor.cpp",
+        "mock/RenderEngine/MockRenderEngine.cpp",
+        "mock/system/window/MockNativeWindow.cpp",
     ],
     static_libs: [
         "libgmock",
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 0705b5c..f39ca00 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -21,20 +21,19 @@
 #include <gtest/gtest.h>
 
 #include <log/log.h>
-#include "system/window.h"
 
-#include "MockComposer.h"
-#include "MockDisplaySurface.h"
-#include "MockEventControlThread.h"
-#include "MockEventThread.h"
-#include "MockGraphicBufferConsumer.h"
-#include "MockGraphicBufferProducer.h"
-#include "MockMessageQueue.h"
-#include "MockNativeWindow.h"
-#include "MockNativeWindowSurface.h"
-#include "MockRenderEngine.h"
-#include "MockSurfaceInterceptor.h"
 #include "TestableSurfaceFlinger.h"
+#include "mock/DisplayHardware/MockComposer.h"
+#include "mock/DisplayHardware/MockDisplaySurface.h"
+#include "mock/MockEventControlThread.h"
+#include "mock/MockEventThread.h"
+#include "mock/MockMessageQueue.h"
+#include "mock/MockNativeWindowSurface.h"
+#include "mock/MockSurfaceInterceptor.h"
+#include "mock/RenderEngine/MockRenderEngine.h"
+#include "mock/gui/MockGraphicBufferConsumer.h"
+#include "mock/gui/MockGraphicBufferProducer.h"
+#include "mock/system/window/MockNativeWindow.h"
 
 namespace android {
 namespace {
@@ -81,7 +80,7 @@
         sp<DisplayDevice> build() {
             return new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, false, mDisplayToken,
                                      mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
-                                     0, false, false, HWC_POWER_MODE_NORMAL);
+                                     0, false, {}, 0, HWC_POWER_MODE_NORMAL);
         }
 
         FakeDisplayDeviceFactory& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
diff --git a/services/surfaceflinger/tests/unittests/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
similarity index 94%
rename from services/surfaceflinger/tests/unittests/MockComposer.cpp
rename to services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 318519b..7ed57b9 100644
--- a/services/surfaceflinger/tests/unittests/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockComposer.h"
+#include "mock/DisplayHardware/MockComposer.h"
 
 namespace android {
 namespace Hwc2 {
diff --git a/services/surfaceflinger/tests/unittests/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
similarity index 97%
rename from services/surfaceflinger/tests/unittests/MockComposer.h
rename to services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 8be2779..267670a 100644
--- a/services/surfaceflinger/tests/unittests/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -99,7 +99,8 @@
     MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&));
     MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition));
     MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace));
-    MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&));
+    MOCK_METHOD3(setLayerPerFrameMetadata,
+                 Error(Display, Layer, const std::vector<IComposerClient::PerFrameMetadata>&));
     MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&));
     MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float));
     MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*));
diff --git a/services/surfaceflinger/tests/unittests/MockDisplaySurface.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplaySurface.cpp
similarity index 93%
rename from services/surfaceflinger/tests/unittests/MockDisplaySurface.cpp
rename to services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplaySurface.cpp
index 507626b..e6ac6bf 100644
--- a/services/surfaceflinger/tests/unittests/MockDisplaySurface.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplaySurface.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockDisplaySurface.h"
+#include "mock/DisplayHardware/MockDisplaySurface.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockDisplaySurface.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplaySurface.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockDisplaySurface.h
rename to services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplaySurface.h
diff --git a/services/surfaceflinger/tests/unittests/MockEventControlThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockEventControlThread.cpp
rename to services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp
index 398fd42..f9bacc8 100644
--- a/services/surfaceflinger/tests/unittests/MockEventControlThread.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockEventControlThread.h"
+#include "mock/MockEventControlThread.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockEventControlThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventControlThread.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockEventControlThread.h
rename to services/surfaceflinger/tests/unittests/mock/MockEventControlThread.h
diff --git a/services/surfaceflinger/tests/unittests/MockEventThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockEventThread.cpp
rename to services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
index 6b5ea4b..408cd35 100644
--- a/services/surfaceflinger/tests/unittests/MockEventThread.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockEventThread.h"
+#include "mock/MockEventThread.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockEventThread.h
rename to services/surfaceflinger/tests/unittests/mock/MockEventThread.h
diff --git a/services/surfaceflinger/tests/unittests/MockMessageQueue.cpp b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockMessageQueue.cpp
rename to services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
index 62f45ed..97a13e4 100644
--- a/services/surfaceflinger/tests/unittests/MockMessageQueue.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockMessageQueue.h"
+#include "mock/MockMessageQueue.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockMessageQueue.h
rename to services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp
rename to services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
index 0314568..25ff39b 100644
--- a/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockNativeWindowSurface.h"
+#include "mock/MockNativeWindowSurface.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.h b/services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockNativeWindowSurface.h
rename to services/surfaceflinger/tests/unittests/mock/MockNativeWindowSurface.h
diff --git a/services/surfaceflinger/tests/unittests/MockSurfaceInterceptor.cpp b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockSurfaceInterceptor.cpp
rename to services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
index b2ec721..4129328 100644
--- a/services/surfaceflinger/tests/unittests/MockSurfaceInterceptor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockSurfaceInterceptor.h"
+#include "mock/MockSurfaceInterceptor.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockSurfaceInterceptor.h b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockSurfaceInterceptor.h
rename to services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
diff --git a/services/surfaceflinger/tests/unittests/MockRenderEngine.cpp b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
similarity index 95%
rename from services/surfaceflinger/tests/unittests/MockRenderEngine.cpp
rename to services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
index e69f4cf..a98bece 100644
--- a/services/surfaceflinger/tests/unittests/MockRenderEngine.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockRenderEngine.h"
+#include "mock/RenderEngine/MockRenderEngine.h"
 
 namespace android {
 namespace RE {
diff --git a/services/surfaceflinger/tests/unittests/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockRenderEngine.h
rename to services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferConsumer.cpp
similarity index 94%
rename from services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp
rename to services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferConsumer.cpp
index 4b27e75..a17b73f 100644
--- a/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferConsumer.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockGraphicBufferConsumer.h"
+#include "mock/gui/MockGraphicBufferConsumer.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.h b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferConsumer.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.h
rename to services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferConsumer.h
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferProducer.cpp
similarity index 94%
rename from services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp
rename to services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferProducer.cpp
index e6f0c63..a7fd667 100644
--- a/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferProducer.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockGraphicBufferProducer.h"
+#include "mock/gui/MockGraphicBufferProducer.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.h b/services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferProducer.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.h
rename to services/surfaceflinger/tests/unittests/mock/gui/MockGraphicBufferProducer.h
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindow.cpp b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.cpp
similarity index 98%
rename from services/surfaceflinger/tests/unittests/MockNativeWindow.cpp
rename to services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.cpp
index 61038f4..a490b92 100644
--- a/services/surfaceflinger/tests/unittests/MockNativeWindow.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "MockNativeWindow.h"
+#include "mock/system/window/MockNativeWindow.h"
 
 namespace android {
 namespace mock {
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindow.h b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
similarity index 100%
rename from services/surfaceflinger/tests/unittests/MockNativeWindow.h
rename to services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 84644a9..1f4df1e 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -983,6 +983,7 @@
     {{else if eq $.Name "vkDestroyImage"}}true
 
     {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
+    {{else if eq $.Name "vkGetPhysicalDeviceProperties2"}}true
     {{else if eq $.Name "vkGetPhysicalDeviceProperties2KHR"}}true
     {{end}}
 
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 741fbb8..56bc35e 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -848,7 +848,8 @@
     const InstanceData& data = GetData(physicalDevice);
 
     // GPDP2 must be present and enabled on the instance.
-    if (!data.driver.GetPhysicalDeviceProperties2KHR)
+    if (!data.driver.GetPhysicalDeviceProperties2KHR &&
+        !data.driver.GetPhysicalDeviceProperties2)
         return false;
 
     // Request the android-specific presentation properties via GPDP2
@@ -866,8 +867,12 @@
     presentation_properties->pNext = nullptr;
     presentation_properties->sharedImage = VK_FALSE;
 
-    data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
-                                                &properties);
+    if (data.driver.GetPhysicalDeviceProperties2KHR) {
+        data.driver.GetPhysicalDeviceProperties2KHR(physicalDevice,
+                                                    &properties);
+    } else {
+        data.driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
+    }
 
     return true;
 }
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index 51e3abf..ec98b9f 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -494,6 +494,7 @@
     INIT_PROC(true, instance, CreateDevice);
     INIT_PROC(true, instance, EnumerateDeviceExtensionProperties);
     INIT_PROC(false, instance, EnumeratePhysicalDeviceGroups);
+    INIT_PROC(false, instance, GetPhysicalDeviceProperties2);
     INIT_PROC_EXT(EXT_debug_report, true, instance, CreateDebugReportCallbackEXT);
     INIT_PROC_EXT(EXT_debug_report, true, instance, DestroyDebugReportCallbackEXT);
     INIT_PROC_EXT(EXT_debug_report, true, instance, DebugReportMessageEXT);
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 99dc889..14c3aba 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -69,6 +69,7 @@
     PFN_vkCreateDevice CreateDevice;
     PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
     PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups;
+    PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2;
     PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
     PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
     PFN_vkDebugReportMessageEXT DebugReportMessageEXT;