Merge "thermalservice: plumb up Thermal HAL 2.0 and add dump"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index cd0fbd4..16abc1e 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -4,6 +4,7 @@
 [Builtin Hooks Options]
 # Only turn on clang-format check for the following subfolders.
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+               libs/graphicsenv/
                libs/gui/
                libs/ui/
                libs/vr/
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index e4990b0..86ec8f8 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -77,7 +77,6 @@
 
 static constexpr const char* kCpPath = "/system/bin/cp";
 static constexpr const char* kXattrDefault = "user.default";
-static constexpr const char* kPropHasReserved = "vold.has_reserved";
 
 static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M
 
@@ -343,55 +342,6 @@
     return 0;
 }
 
-/**
- * Ensure that we have a hard-limit quota to protect against abusive apps;
- * they should never use more than 90% of blocks or 50% of inodes.
- */
-static int prepare_app_quota(const std::unique_ptr<std::string>& uuid ATTRIBUTE_UNUSED,
-        const std::string& device, uid_t uid) {
-    // Skip when reserved blocks are protecting us against abusive apps
-    if (android::base::GetBoolProperty(kPropHasReserved, false)) return 0;
-    // Skip when device no quotas present
-    if (device.empty()) return 0;
-
-    struct dqblk dq;
-    if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
-            reinterpret_cast<char*>(&dq)) != 0) {
-        PLOG(WARNING) << "Failed to find quota for " << uid;
-        return -1;
-    }
-
-#if APPLY_HARD_QUOTAS
-    if ((dq.dqb_bhardlimit == 0) || (dq.dqb_ihardlimit == 0)) {
-        auto path = create_data_path(uuid ? uuid->c_str() : nullptr);
-        struct statvfs stat;
-        if (statvfs(path.c_str(), &stat) != 0) {
-            PLOG(WARNING) << "Failed to statvfs " << path;
-            return -1;
-        }
-
-        dq.dqb_valid = QIF_LIMITS;
-        dq.dqb_bhardlimit =
-            (((static_cast<uint64_t>(stat.f_blocks) * stat.f_frsize) / 10) * 9) / QIF_DQBLKSIZE;
-        dq.dqb_ihardlimit = (stat.f_files / 2);
-        if (quotactl(QCMD(Q_SETQUOTA, USRQUOTA), device.c_str(), uid,
-                reinterpret_cast<char*>(&dq)) != 0) {
-            PLOG(WARNING) << "Failed to set hard quota for " << uid;
-            return -1;
-        } else {
-            LOG(DEBUG) << "Applied hard quotas for " << uid;
-            return 0;
-        }
-    } else {
-        // Hard quota already set; assume it's reasonable
-        return 0;
-    }
-#else
-    // Hard quotas disabled
-    return 0;
-#endif
-}
-
 static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) {
     if (!property_get_bool("dalvik.vm.usejitprofiles", false)) {
         return true;
@@ -506,10 +456,6 @@
             return error("Failed to restorecon " + path);
         }
 
-        if (prepare_app_quota(uuid, findQuotaDeviceForUuid(uuid), uid)) {
-            return error("Failed to set hard quota " + path);
-        }
-
         if (!prepare_app_profile_dir(packageName, appId, userId)) {
             return error("Failed to prepare profiles for " + packageName);
         }
@@ -988,13 +934,6 @@
         }
     }
 
-    // Data under /data/media doesn't have an app, but we still want
-    // to limit it to prevent abuse.
-    if (prepare_app_quota(uuid, findQuotaDeviceForUuid(uuid),
-            multiuser_get_uid(userId, AID_MEDIA_RW))) {
-        return error("Failed to set hard quota for media_rw");
-    }
-
     return ok();
 }
 
@@ -2644,21 +2583,6 @@
                     reinterpret_cast<char*>(&dq)) == 0) {
                 LOG(DEBUG) << "Found quota mount " << source << " at " << target;
                 mQuotaReverseMounts[target] = source;
-
-                // ext4 only enables DQUOT_USAGE_ENABLED by default, so we
-                // need to kick it again to enable DQUOT_LIMITS_ENABLED. We
-                // only need hard limits enabled when we're not being protected
-                // by reserved blocks.
-                if (!android::base::GetBoolProperty(kPropHasReserved, false)) {
-                    if (quotactl(QCMD(Q_QUOTAON, USRQUOTA), source.c_str(), QFMT_VFS_V1,
-                            nullptr) != 0 && errno != EBUSY) {
-                        PLOG(ERROR) << "Failed to enable USRQUOTA on " << source;
-                    }
-                    if (quotactl(QCMD(Q_QUOTAON, GRPQUOTA), source.c_str(), QFMT_VFS_V1,
-                            nullptr) != 0 && errno != EBUSY) {
-                        PLOG(ERROR) << "Failed to enable GRPQUOTA on " << source;
-                    }
-                }
             }
         }
 #endif
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 28c7658..b2e7047 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -322,21 +322,8 @@
             return false;
         }
         const char* isa = parameters_.instruction_set;
-
-        // Check whether the file exists where expected.
         std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE;
         std::string isa_path = dalvik_cache + "/" + isa;
-        std::string art_path = isa_path + "/system@framework@boot.art";
-        std::string oat_path = isa_path + "/system@framework@boot.oat";
-        bool cleared = false;
-        if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
-            // Files exist, assume everything is alright if not forced. Otherwise clean up.
-            if (!force) {
-                return true;
-            }
-            ClearDirectory(isa_path);
-            cleared = true;
-        }
 
         // Reset umask in otapreopt, so that we control the the access for the files we create.
         umask(0);
@@ -355,17 +342,34 @@
             }
         }
 
-        // Prepare to create.
+        // Check whether we have files in /data.
+        // TODO: check that the files are correct wrt/ jars.
+        std::string art_path = isa_path + "/system@framework@boot.art";
+        std::string oat_path = isa_path + "/system@framework@boot.oat";
+        bool cleared = false;
+        if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
+            // Files exist, assume everything is alright if not forced. Otherwise clean up.
+            if (!force) {
+                return true;
+            }
+            ClearDirectory(isa_path);
+            cleared = true;
+        }
+
+        // Check whether we have an image in /system.
+        // TODO: check that the files are correct wrt/ jars.
+        std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
+        if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
+            // Note: we ignore |force| here.
+            return true;
+        }
+
+
         if (!cleared) {
             ClearDirectory(isa_path);
         }
 
-        std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
-        if (access(preopted_boot_art_path.c_str(), F_OK) != 0) {
-          // No preopted boot image. Try to compile.
-          return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
-        }
-        return true;
+        return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
     }
 
     static bool CreatePath(const std::string& path) {
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index 5829c4f..d05724a 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -36,8 +36,6 @@
 #define BYPASS_QUOTA 0
 #define BYPASS_SDCARDFS 0
 
-#define APPLY_HARD_QUOTAS 0
-
 namespace android {
 namespace installd {
 
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index d776682..79cd6b5 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -274,6 +274,7 @@
     // Note that we ignore the strict_policy and don't propagate it
     // further (since we do no outbound RPCs anyway).
     strict_policy = bio_get_uint32(msg);
+    bio_get_uint32(msg);  // Ignore worksource header.
     s = bio_get_string16(msg, &len);
     if (s == NULL) {
         return -1;
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index 507ce53..0b89879 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -86,7 +86,7 @@
     virtual void* getBase() const;
     virtual size_t getSize() const;
     virtual uint32_t getFlags() const;
-    virtual uint32_t getOffset() const;
+    off_t getOffset() const override;
 
 private:
     friend class IMemory;
@@ -113,7 +113,7 @@
     mutable void*       mBase;
     mutable size_t      mSize;
     mutable uint32_t    mFlags;
-    mutable uint32_t    mOffset;
+    mutable off_t       mOffset;
     mutable bool        mRealHeap;
     mutable Mutex       mLock;
 };
@@ -187,13 +187,16 @@
         data.writeInterfaceToken(IMemory::getInterfaceDescriptor());
         if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) {
             sp<IBinder> heap = reply.readStrongBinder();
-            ssize_t o = reply.readInt32();
-            size_t s = reply.readInt32();
             if (heap != nullptr) {
                 mHeap = interface_cast<IMemoryHeap>(heap);
                 if (mHeap != nullptr) {
+                    const int64_t offset64 = reply.readInt64();
+                    const uint64_t size64 = reply.readUint64();
+                    const ssize_t o = (ssize_t)offset64;
+                    const size_t s = (size_t)size64;
                     size_t heapSize = mHeap->getSize();
-                    if (s <= heapSize
+                    if (s == size64 && o == offset64 // ILP32 bounds check
+                            && s <= heapSize
                             && o >= 0
                             && (static_cast<size_t>(o) <= heapSize - s)) {
                         mOffset = o;
@@ -233,8 +236,8 @@
             ssize_t offset;
             size_t size;
             reply->writeStrongBinder( IInterface::asBinder(getMemory(&offset, &size)) );
-            reply->writeInt32(offset);
-            reply->writeInt32(size);
+            reply->writeInt64(offset);
+            reply->writeUint64(size);
             return NO_ERROR;
         } break;
         default:
@@ -313,18 +316,23 @@
         data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
         status_t err = remote()->transact(HEAP_ID, data, &reply);
         int parcel_fd = reply.readFileDescriptor();
-        ssize_t size = reply.readInt32();
-        uint32_t flags = reply.readInt32();
-        uint32_t offset = reply.readInt32();
-
-        ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)",
-                IInterface::asBinder(this).get(),
-                parcel_fd, size, err, strerror(-err));
+        const uint64_t size64 = reply.readUint64();
+        const int64_t offset64 = reply.readInt64();
+        const uint32_t flags = reply.readUint32();
+        const size_t size = (size_t)size64;
+        const off_t offset = (off_t)offset64;
+        if (err != NO_ERROR || // failed transaction
+                size != size64 || offset != offset64) { // ILP32 size check
+            ALOGE("binder=%p transaction failed fd=%d, size=%zu, err=%d (%s)",
+                    IInterface::asBinder(this).get(),
+                    parcel_fd, size, err, strerror(-err));
+            return;
+        }
 
         Mutex::Autolock _l(mLock);
         if (mHeapId.load(memory_order_relaxed) == -1) {
             int fd = fcntl(parcel_fd, F_DUPFD_CLOEXEC, 0);
-            ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
+            ALOGE_IF(fd == -1, "cannot dup fd=%d, size=%zu, err=%d (%s)",
                     parcel_fd, size, err, strerror(errno));
 
             int access = PROT_READ;
@@ -334,7 +342,7 @@
             mRealHeap = true;
             mBase = mmap(nullptr, size, access, MAP_SHARED, fd, offset);
             if (mBase == MAP_FAILED) {
-                ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
+                ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zu, fd=%d (%s)",
                         IInterface::asBinder(this).get(), size, fd, strerror(errno));
                 close(fd);
             } else {
@@ -368,7 +376,7 @@
     return mFlags;
 }
 
-uint32_t BpMemoryHeap::getOffset() const {
+off_t BpMemoryHeap::getOffset() const {
     assertMapped();
     return mOffset;
 }
@@ -390,9 +398,9 @@
        case HEAP_ID: {
             CHECK_INTERFACE(IMemoryHeap, data, reply);
             reply->writeFileDescriptor(getHeapID());
-            reply->writeInt32(getSize());
-            reply->writeInt32(getFlags());
-            reply->writeInt32(getOffset());
+            reply->writeUint64(getSize());
+            reply->writeInt64(getOffset());
+            reply->writeUint32(getFlags());
             return NO_ERROR;
         } break;
         default:
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index f052bcb..7a47724 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -109,6 +109,10 @@
     "BC_DEAD_BINDER_DONE"
 };
 
+// The work source represents the UID of the process we should attribute the transaction to.
+// We use -1 to specify that the work source was not set using #setWorkSource.
+static const int kUnsetWorkSource = -1;
+
 static const char* getReturnString(uint32_t cmd)
 {
     size_t idx = cmd & 0xff;
@@ -383,6 +387,25 @@
     return mStrictModePolicy;
 }
 
+uid_t IPCThreadState::setWorkSource(uid_t uid)
+{
+    uid_t returnValue = mWorkSource;
+    mWorkSource = uid;
+    return returnValue;
+}
+
+uid_t IPCThreadState::getWorkSource() const
+{
+    return mWorkSource;
+}
+
+uid_t IPCThreadState::clearWorkSource()
+{
+    uid_t returnValue = mWorkSource;
+    mWorkSource = kUnsetWorkSource;
+    return returnValue;
+}
+
 void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
 {
     mLastTransactionBinderFlags = flags;
@@ -736,6 +759,7 @@
 
 IPCThreadState::IPCThreadState()
     : mProcess(ProcessState::self()),
+      mWorkSource(kUnsetWorkSource),
       mStrictModePolicy(0),
       mLastTransactionBinderFlags(0)
 {
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 9850ad9..4c300b4 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -76,7 +76,7 @@
     }
 }
 
-MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, uint32_t offset)
+MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, off_t offset)
     : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
       mDevice(nullptr), mNeedUnmap(false), mOffset(0)
 {
@@ -85,7 +85,7 @@
     mapfd(fcntl(fd, F_DUPFD_CLOEXEC, 0), size, offset);
 }
 
-status_t MemoryHeapBase::init(int fd, void *base, int size, int flags, const char* device)
+status_t MemoryHeapBase::init(int fd, void *base, size_t size, int flags, const char* device)
 {
     if (mFD != -1) {
         return INVALID_OPERATION;
@@ -98,13 +98,20 @@
     return NO_ERROR;
 }
 
-status_t MemoryHeapBase::mapfd(int fd, size_t size, uint32_t offset)
+status_t MemoryHeapBase::mapfd(int fd, size_t size, off_t offset)
 {
     if (size == 0) {
         // try to figure out the size automatically
         struct stat sb;
-        if (fstat(fd, &sb) == 0)
-            size = sb.st_size;
+        if (fstat(fd, &sb) == 0) {
+            size = (size_t)sb.st_size;
+            // sb.st_size is off_t which on ILP32 may be 64 bits while size_t is 32 bits.
+            if ((off_t)size != sb.st_size) {
+                ALOGE("%s: size of file %lld cannot fit in memory",
+                        __func__, (long long)sb.st_size);
+                return INVALID_OPERATION;
+            }
+        }
         // if it didn't work, let mmap() fail.
     }
 
@@ -112,12 +119,12 @@
         void* base = (uint8_t*)mmap(nullptr, size,
                 PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
         if (base == MAP_FAILED) {
-            ALOGE("mmap(fd=%d, size=%u) failed (%s)",
-                    fd, uint32_t(size), strerror(errno));
+            ALOGE("mmap(fd=%d, size=%zu) failed (%s)",
+                    fd, size, strerror(errno));
             close(fd);
             return -errno;
         }
-        //ALOGD("mmap(fd=%d, base=%p, size=%lu)", fd, base, size);
+        //ALOGD("mmap(fd=%d, base=%p, size=%zu)", fd, base, size);
         mBase = base;
         mNeedUnmap = true;
     } else  {
@@ -140,7 +147,7 @@
     int fd = android_atomic_or(-1, &mFD);
     if (fd >= 0) {
         if (mNeedUnmap) {
-            //ALOGD("munmap(fd=%d, base=%p, size=%lu)", fd, mBase, mSize);
+            //ALOGD("munmap(fd=%d, base=%p, size=%zu)", fd, mBase, mSize);
             munmap(mBase, mSize);
         }
         mBase = nullptr;
@@ -169,7 +176,7 @@
     return mDevice;
 }
 
-uint32_t MemoryHeapBase::getOffset() const {
+off_t MemoryHeapBase::getOffset() const {
     return mOffset;
 }
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 87c9842..bc1a71c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -601,6 +601,7 @@
 {
     writeInt32(IPCThreadState::self()->getStrictModePolicy() |
                STRICT_MODE_PENALTY_GATHER);
+    writeInt32(IPCThreadState::self()->getWorkSource());
     // currently the interface identification token is just its name as a string
     return writeString16(interface);
 }
@@ -613,6 +614,7 @@
 bool Parcel::enforceInterface(const String16& interface,
                               IPCThreadState* threadState) const
 {
+    // StrictModePolicy.
     int32_t strictPolicy = readInt32();
     if (threadState == nullptr) {
         threadState = IPCThreadState::self();
@@ -627,6 +629,10 @@
     } else {
       threadState->setStrictModePolicy(strictPolicy);
     }
+    // WorkSource.
+    int32_t workSource = readInt32();
+    threadState->setWorkSource(workSource);
+    // Interface descriptor.
     const String16 str(readString16());
     if (str == interface) {
         return true;
diff --git a/libs/binder/include/binder/IMemory.h b/libs/binder/include/binder/IMemory.h
index 3099bf5..11f7efa 100644
--- a/libs/binder/include/binder/IMemory.h
+++ b/libs/binder/include/binder/IMemory.h
@@ -43,7 +43,7 @@
     virtual void*       getBase() const = 0;
     virtual size_t      getSize() const = 0;
     virtual uint32_t    getFlags() const = 0;
-    virtual uint32_t    getOffset() const = 0;
+    virtual off_t       getOffset() const = 0;
 
     // these are there just for backward source compatibility
     int32_t heapID() const { return getHeapID(); }
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 40b51ad..5888e14 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -47,6 +47,13 @@
             void                setStrictModePolicy(int32_t policy);
             int32_t             getStrictModePolicy() const;
 
+            // See Binder#setThreadWorkSource in Binder.java.
+            uid_t               setWorkSource(uid_t uid);
+            // See Binder#getThreadWorkSource in Binder.java.
+            uid_t               getWorkSource() const;
+            // See Binder#clearThreadWorkSource in Binder.java.
+            uid_t               clearWorkSource();
+
             void                setLastTransactionBinderFlags(int32_t flags);
             int32_t             getLastTransactionBinderFlags() const;
 
@@ -155,6 +162,9 @@
             status_t            mLastError;
             pid_t               mCallingPid;
             uid_t               mCallingUid;
+            // The UID of the process who is responsible for this transaction.
+            // This is used for resource attribution.
+            int32_t             mWorkSource;
             int32_t             mStrictModePolicy;
             int32_t             mLastTransactionBinderFlags;
             IPCThreadStateBase  *mIPCThreadStateBase;
diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h
index 5e0a382..2f5039d 100644
--- a/libs/binder/include/binder/MemoryHeapBase.h
+++ b/libs/binder/include/binder/MemoryHeapBase.h
@@ -42,7 +42,7 @@
      * maps the memory referenced by fd. but DOESN'T take ownership
      * of the filedescriptor (it makes a copy with dup()
      */
-    MemoryHeapBase(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0);
+    MemoryHeapBase(int fd, size_t size, uint32_t flags = 0, off_t offset = 0);
 
     /*
      * maps memory from the given device
@@ -64,7 +64,7 @@
 
     virtual size_t      getSize() const;
     virtual uint32_t    getFlags() const;
-    virtual uint32_t    getOffset() const;
+            off_t       getOffset() const override;
 
     const char*         getDevice() const;
 
@@ -82,11 +82,11 @@
 protected:
             MemoryHeapBase();
     // init() takes ownership of fd
-    status_t init(int fd, void *base, int size,
+    status_t init(int fd, void *base, size_t size,
             int flags = 0, const char* device = nullptr);
 
 private:
-    status_t mapfd(int fd, size_t size, uint32_t offset = 0);
+    status_t mapfd(int fd, size_t size, off_t offset = 0);
 
     int         mFD;
     size_t      mSize;
@@ -94,7 +94,7 @@
     uint32_t    mFlags;
     const char* mDevice;
     bool        mNeedUnmap;
-    uint32_t    mOffset;
+    off_t       mOffset;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index faeb78f..bf0c956 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -76,34 +76,18 @@
     (*vec)[index] = value;
 }
 
-/**
- * Writes a vector to the next location in a non-null parcel.
- */
-template <typename T>
-static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<T>& vec);
-
-/**
- * Reads a vector to the next location in a non-null parcel.
- */
-template <typename T>
-static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<T>* vec);
-
 // @START
 /**
  * Writes a vector of int32_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<int32_t>(AParcel* parcel,
-                                                    const std::vector<int32_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int32_t>& vec) {
     return AParcel_writeInt32Array(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of int32_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<int32_t>(const AParcel* parcel,
-                                                   std::vector<int32_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int32_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readInt32Array(parcel, &vectorData, &AParcel_stdVectorReallocator<int32_t>,
                                   AParcel_stdVectorGetter<int32_t>);
@@ -112,18 +96,14 @@
 /**
  * Writes a vector of uint32_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<uint32_t>(AParcel* parcel,
-                                                     const std::vector<uint32_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint32_t>& vec) {
     return AParcel_writeUint32Array(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of uint32_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<uint32_t>(const AParcel* parcel,
-                                                    std::vector<uint32_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint32_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readUint32Array(parcel, &vectorData, &AParcel_stdVectorReallocator<uint32_t>,
                                    AParcel_stdVectorGetter<uint32_t>);
@@ -132,18 +112,14 @@
 /**
  * Writes a vector of int64_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<int64_t>(AParcel* parcel,
-                                                    const std::vector<int64_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int64_t>& vec) {
     return AParcel_writeInt64Array(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of int64_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<int64_t>(const AParcel* parcel,
-                                                   std::vector<int64_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int64_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readInt64Array(parcel, &vectorData, &AParcel_stdVectorReallocator<int64_t>,
                                   AParcel_stdVectorGetter<int64_t>);
@@ -152,18 +128,14 @@
 /**
  * Writes a vector of uint64_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<uint64_t>(AParcel* parcel,
-                                                     const std::vector<uint64_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint64_t>& vec) {
     return AParcel_writeUint64Array(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of uint64_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<uint64_t>(const AParcel* parcel,
-                                                    std::vector<uint64_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint64_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readUint64Array(parcel, &vectorData, &AParcel_stdVectorReallocator<uint64_t>,
                                    AParcel_stdVectorGetter<uint64_t>);
@@ -172,16 +144,14 @@
 /**
  * Writes a vector of float to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<float>(AParcel* parcel, const std::vector<float>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<float>& vec) {
     return AParcel_writeFloatArray(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of float from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<float>(const AParcel* parcel, std::vector<float>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<float>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readFloatArray(parcel, &vectorData, &AParcel_stdVectorReallocator<float>,
                                   AParcel_stdVectorGetter<float>);
@@ -190,17 +160,14 @@
 /**
  * Writes a vector of double to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<double>(AParcel* parcel,
-                                                   const std::vector<double>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<double>& vec) {
     return AParcel_writeDoubleArray(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of double from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<double>(const AParcel* parcel, std::vector<double>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<double>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readDoubleArray(parcel, &vectorData, &AParcel_stdVectorReallocator<double>,
                                    AParcel_stdVectorGetter<double>);
@@ -209,8 +176,7 @@
 /**
  * Writes a vector of bool to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<bool>(AParcel* parcel, const std::vector<bool>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<bool>& vec) {
     return AParcel_writeBoolArray(parcel, static_cast<const void*>(&vec),
                                   AParcel_stdVectorGetter<bool>, vec.size());
 }
@@ -218,8 +184,7 @@
 /**
  * Reads a vector of bool from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<bool>(const AParcel* parcel, std::vector<bool>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<bool>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readBoolArray(parcel, &vectorData, &AParcel_stdVectorReallocator<bool>,
                                  AParcel_stdVectorSetter<bool>);
@@ -228,18 +193,14 @@
 /**
  * Writes a vector of char16_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<char16_t>(AParcel* parcel,
-                                                     const std::vector<char16_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<char16_t>& vec) {
     return AParcel_writeCharArray(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of char16_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<char16_t>(const AParcel* parcel,
-                                                    std::vector<char16_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<char16_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readCharArray(parcel, &vectorData, &AParcel_stdVectorReallocator<char16_t>,
                                  AParcel_stdVectorGetter<char16_t>);
@@ -248,17 +209,14 @@
 /**
  * Writes a vector of int8_t to the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_writeVector<int8_t>(AParcel* parcel,
-                                                   const std::vector<int8_t>& vec) {
+inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int8_t>& vec) {
     return AParcel_writeByteArray(parcel, vec.data(), vec.size());
 }
 
 /**
  * Reads a vector of int8_t from the next location in a non-null parcel.
  */
-template <>
-inline binder_status_t AParcel_readVector<int8_t>(const AParcel* parcel, std::vector<int8_t>* vec) {
+inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) {
     void* vectorData = static_cast<void*>(vec);
     return AParcel_readByteArray(parcel, &vectorData, &AParcel_stdVectorReallocator<int8_t>,
                                  AParcel_stdVectorGetter<int8_t>);
diff --git a/libs/binder/ndk/scripts/gen_parcel_helper.py b/libs/binder/ndk/scripts/gen_parcel_helper.py
index 45f8d06..2cf10d3 100755
--- a/libs/binder/ndk/scripts/gen_parcel_helper.py
+++ b/libs/binder/ndk/scripts/gen_parcel_helper.py
@@ -152,8 +152,7 @@
         cpp_helper += "/**\n"
         cpp_helper += " * Writes a vector of " + cpp + " to the next location in a non-null parcel.\n"
         cpp_helper += " */\n"
-        cpp_helper += "template<>\n"
-        cpp_helper += "inline binder_status_t AParcel_writeVector<" + cpp + ">(AParcel* parcel, const std::vector<" + cpp + ">& vec) {\n"
+        cpp_helper += "inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<" + cpp + ">& vec) {\n"
         write_args = "vec.data()"
         if nca: write_args = "static_cast<const void*>(&vec), AParcel_stdVectorGetter<" + cpp + ">"
         cpp_helper += "    return AParcel_write" + pretty + "Array(parcel, " + write_args + ", vec.size());\n"
@@ -162,8 +161,7 @@
         cpp_helper += "/**\n"
         cpp_helper += " * Reads a vector of " + cpp + " from the next location in a non-null parcel.\n"
         cpp_helper += " */\n"
-        cpp_helper += "template<>\n"
-        cpp_helper += "inline binder_status_t AParcel_readVector<" + cpp + ">(const AParcel* parcel, std::vector<" + cpp + ">* vec) {\n"
+        cpp_helper += "inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<" + cpp + ">* vec) {\n"
         cpp_helper += "    void* vectorData = static_cast<void*>(vec);\n"
         read_args = []
         read_args += ["parcel"]
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 73c2eba..7bcfffd 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -71,6 +71,7 @@
     BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
     BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
     BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
+    BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
 };
 
 pid_t start_server_process(int arg2, bool usePoll = false)
@@ -938,6 +939,43 @@
     EXPECT_EQ(NO_ERROR, ret);
 }
 
+TEST_F(BinderLibTest, WorkSourceUnsetByDefault)
+{
+    status_t ret;
+    Parcel data, reply;
+    data.writeInterfaceToken(binderLibTestServiceName);
+    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+    EXPECT_EQ(-1, reply.readInt32());
+    EXPECT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(BinderLibTest, WorkSourceSet)
+{
+    status_t ret;
+    Parcel data, reply;
+    uid_t previousWorkSource = IPCThreadState::self()->setWorkSource(100);
+    data.writeInterfaceToken(binderLibTestServiceName);
+    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+    EXPECT_EQ(100, reply.readInt32());
+    EXPECT_EQ(-1, previousWorkSource);
+    EXPECT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(BinderLibTest, WorkSourceCleared)
+{
+    status_t ret;
+    Parcel data, reply;
+
+    IPCThreadState::self()->setWorkSource(100);
+    uid_t previousWorkSource = IPCThreadState::self()->clearWorkSource();
+    data.writeInterfaceToken(binderLibTestServiceName);
+    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+
+    EXPECT_EQ(-1, reply.readInt32());
+    EXPECT_EQ(100, previousWorkSource);
+    EXPECT_EQ(NO_ERROR, ret);
+}
+
 class BinderLibTestService : public BBinder
 {
     public:
@@ -1236,6 +1274,11 @@
                 }
                 return NO_ERROR;
             }
+            case BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION: {
+                data.enforceInterface(binderLibTestServiceName);
+                reply->writeInt32(IPCThreadState::self()->getWorkSource());
+                return NO_ERROR;
+            }
             default:
                 return UNKNOWN_TRANSACTION;
             };
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index e53f7fd..024d72b 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -167,7 +167,7 @@
         auto sphalNamespace = android_get_exported_namespace("sphal");
         if (!sphalNamespace) return;
         mDriverNamespace = android_create_namespace("gfx driver",
-                                                    nullptr,             // ld_library_path
+                                                    mDriverPath.c_str(), // ld_library_path
                                                     mDriverPath.c_str(), // default_library_path
                                                     ANDROID_NAMESPACE_TYPE_SHARED |
                                                             ANDROID_NAMESPACE_TYPE_ISOLATED,
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index f99bc53..cf9d4c5 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,11 +103,15 @@
     }
 
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
-                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   ISurfaceComposer::Rotation rotation) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
+        data.writeInt32(static_cast<int32_t>(reqDataspace));
+        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
         data.write(sourceCrop);
         data.writeUint32(reqWidth);
         data.writeUint32(reqHeight);
@@ -126,15 +130,19 @@
 
         *outBuffer = new GraphicBuffer();
         reply.read(**outBuffer);
+
         return result;
     }
 
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
-                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                    float frameScale, bool childrenOnly) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(layerHandleBinder);
+        data.writeInt32(static_cast<int32_t>(reqDataspace));
+        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
         data.write(sourceCrop);
         data.writeFloat(frameScale);
         data.writeBool(childrenOnly);
@@ -148,6 +156,7 @@
             ALOGE("captureLayers failed to readInt32: %d", result);
             return result;
         }
+
         *outBuffer = new GraphicBuffer();
         reply.read(**outBuffer);
 
@@ -645,6 +654,8 @@
         case CAPTURE_SCREEN: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> display = data.readStrongBinder();
+            ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32());
+            ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32());
             sp<GraphicBuffer> outBuffer;
             Rect sourceCrop(Rect::EMPTY_RECT);
             data.read(sourceCrop);
@@ -653,8 +664,8 @@
             bool useIdentityTransform = static_cast<bool>(data.readInt32());
             int32_t rotation = data.readInt32();
 
-            status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
-                                         useIdentityTransform,
+            status_t res = captureScreen(display, &outBuffer, reqDataspace, reqPixelFormat,
+                                         sourceCrop, reqWidth, reqHeight, useIdentityTransform,
                                          static_cast<ISurfaceComposer::Rotation>(rotation));
             reply->writeInt32(res);
             if (res == NO_ERROR) {
@@ -665,14 +676,16 @@
         case CAPTURE_LAYERS: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> layerHandleBinder = data.readStrongBinder();
+            ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32());
+            ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32());
             sp<GraphicBuffer> outBuffer;
             Rect sourceCrop(Rect::EMPTY_RECT);
             data.read(sourceCrop);
             float frameScale = data.readFloat();
             bool childrenOnly = data.readBool();
 
-            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale,
-                                         childrenOnly);
+            status_t res = captureLayers(layerHandleBinder, &outBuffer, reqDataspace,
+                                         reqPixelFormat, sourceCrop, frameScale, childrenOnly);
             reply->writeInt32(res);
             if (res == NO_ERROR) {
                 reply->write(*outBuffer);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 1ac9609..7498f36 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -887,13 +887,14 @@
 
 // ----------------------------------------------------------------------------
 
-status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                                   uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
-                                   sp<GraphicBuffer>* outBuffer) {
+status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   uint32_t rotation, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight,
-                                    useIdentityTransform,
+    status_t ret = s->captureScreen(display, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop,
+                                    reqWidth, reqHeight, useIdentityTransform,
                                     static_cast<ISurfaceComposer::Rotation>(rotation));
     if (ret != NO_ERROR) {
         return ret;
@@ -901,21 +902,25 @@
     return ret;
 }
 
-status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
+                                         const ui::Dataspace reqDataSpace,
+                                         const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                          float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
-                                    false /* childrenOnly */);
+    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
+                                    sourceCrop, frameScale, false /* childrenOnly */);
     return ret;
 }
 
-status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle,
+                                              const ui::Dataspace reqDataSpace,
+                                              const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                               float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
-                                    true /* childrenOnly */);
+    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
+                                    sourceCrop, frameScale, true /* childrenOnly */);
     return ret;
 }
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a55cfe0..781e062 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -180,6 +180,36 @@
      * The subregion can be optionally rotated.  It will also be scaled to
      * match the size of the output buffer.
      *
+     * reqDataspace and reqPixelFormat specify the data space and pixel format
+     * of the buffer. The caller should pick the data space and pixel format
+     * that it can consume.
+     *
+     * At the moment, sourceCrop is ignored and is always set to the visible
+     * region (projected display viewport) of the screen.
+     *
+     * reqWidth and reqHeight specifies the size of the buffer.  When either
+     * of them is 0, they are set to the size of the logical display viewport.
+     *
+     * When useIdentityTransform is true, layer transformations are disabled.
+     *
+     * rotation specifies the rotation of the source crop (and the pixels in
+     * it) around its center.
+     */
+    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   Rotation rotation = eRotateNone) = 0;
+    /**
+     * Capture the specified screen. This requires READ_FRAME_BUFFER
+     * permission.  This function will fail if there is a secure window on
+     * screen.
+     *
+     * This function can capture a subregion (the source crop) of the screen
+     * into an sRGB buffer with RGBA_8888 pixel format.
+     * The subregion can be optionally rotated.  It will also be scaled to
+     * match the size of the output buffer.
+     *
      * At the moment, sourceCrop is ignored and is always set to the visible
      * region (projected display viewport) of the screen.
      *
@@ -193,15 +223,34 @@
      */
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, Rotation rotation = eRotateNone) = 0;
+                                   bool useIdentityTransform, Rotation rotation = eRotateNone) {
+        return captureScreen(display, outBuffer, ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
+                             sourceCrop, reqWidth, reqHeight, useIdentityTransform, rotation);
+    }
 
     /**
      * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
+     *
+     * reqDataspace and reqPixelFormat specify the data space and pixel format
+     * of the buffer. The caller should pick the data space and pixel format
+     * that it can consume.
      */
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
-                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                    float frameScale = 1.0, bool childrenOnly = false) = 0;
 
+    /**
+     * Capture a subtree of the layer hierarchy into an sRGB buffer with RGBA_8888 pixel format,
+     * potentially ignoring the root node.
+     */
+    status_t captureLayers(const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
+                           const Rect& sourceCrop, float frameScale = 1.0,
+                           bool childrenOnly = false) {
+        return captureLayers(layerHandleBinder, outBuffer, ui::Dataspace::V0_SRGB,
+                             ui::PixelFormat::RGBA_8888, sourceCrop, frameScale, childrenOnly);
+    }
+
     /* Clears the frame statistics for animations.
      *
      * Requires the ACCESS_SURFACE_FLINGER permission.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 69a759f..1b4eda7 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -329,12 +329,16 @@
 public:
     // if cropping isn't required, callers may pass in a default Rect, e.g.:
     //   capture(display, producer, Rect(), reqWidth, ...);
-    static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                            uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
-                            sp<GraphicBuffer>* outBuffer);
-    static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
-                                  sp<GraphicBuffer>* outBuffer);
-    static status_t captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+    static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
+                            const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                            uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                            uint32_t rotation, sp<GraphicBuffer>* outBuffer);
+    static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
+                                  const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                  float frameScale, sp<GraphicBuffer>* outBuffer);
+    static status_t captureChildLayers(const sp<IBinder>& layerHandle,
+                                       const ui::Dataspace reqDataSpace,
+                                       const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                        float frameScale, sp<GraphicBuffer>* outBuffer);
 };
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index bc80899..500df05 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -134,8 +134,9 @@
     sp<IBinder> display(sf->getBuiltInDisplay(
             ISurfaceComposer::eDisplayIdMain));
     sp<GraphicBuffer> outBuffer;
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, false));
+    ASSERT_EQ(NO_ERROR,
+              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
+                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));
 
     ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
             NATIVE_WINDOW_API_CPU));
@@ -165,8 +166,9 @@
                 &buf));
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, false));
+    ASSERT_EQ(NO_ERROR,
+              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
+                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));
 }
 
 TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -596,14 +598,19 @@
     }
     status_t setActiveColorMode(const sp<IBinder>& /*display*/,
         ColorMode /*colorMode*/) override { return NO_ERROR; }
-    status_t captureScreen(const sp<IBinder>& /*display*/,
-            sp<GraphicBuffer>* /*outBuffer*/,
-            Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
-            bool /*useIdentityTransform*/,
-            Rotation /*rotation*/) override { return NO_ERROR; }
+    status_t captureScreen(const sp<IBinder>& /*display*/, sp<GraphicBuffer>* /*outBuffer*/,
+                           const ui::Dataspace /*reqDataspace*/,
+                           const ui::PixelFormat /*reqPixelFormat*/, Rect /*sourceCrop*/,
+                           uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
+                           bool /*useIdentityTransform*/, Rotation /*rotation*/) override {
+        return NO_ERROR;
+    }
     virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
-                                   sp<GraphicBuffer>* /*outBuffer*/, const Rect& /*sourceCrop*/,
-                                   float /*frameScale*/, bool /*childrenOnly*/) override {
+                                   sp<GraphicBuffer>* /*outBuffer*/,
+                                   const ui::Dataspace /*reqDataspace*/,
+                                   const ui::PixelFormat /*reqPixelFormat*/,
+                                   const Rect& /*sourceCrop*/, float /*frameScale*/,
+                                   bool /*childrenOnly*/) override {
         return NO_ERROR;
     }
     status_t clearAnimationFrameStats() override { return NO_ERROR; }
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index ba5cfcd..43ac79e 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -22,6 +22,7 @@
     "buffer_hub_base.cpp",
     "buffer_hub_rpc.cpp",
     "consumer_buffer.cpp",
+    "buffer_client_impl.cpp",
     "ion_buffer.cpp",
     "producer_buffer.cpp",
 ]
diff --git a/libs/vr/libbufferhub/buffer_client_impl.cpp b/libs/vr/libbufferhub/buffer_client_impl.cpp
new file mode 100644
index 0000000..6bef98a
--- /dev/null
+++ b/libs/vr/libbufferhub/buffer_client_impl.cpp
@@ -0,0 +1,55 @@
+#include <log/log.h>
+#include <private/dvr/IBufferClient.h>
+
+namespace android {
+namespace dvr {
+
+class BpBufferClient : public BpInterface<IBufferClient> {
+ public:
+  explicit BpBufferClient(const sp<IBinder>& impl)
+      : BpInterface<IBufferClient>(impl) {}
+
+  bool isValid() override;
+};
+
+IMPLEMENT_META_INTERFACE(BufferClient, "android.dvr.IBufferClient");
+
+// Transaction code
+enum {
+  IS_VALID = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+bool BpBufferClient::isValid() {
+  Parcel data, reply;
+  status_t ret =
+      data.writeInterfaceToken(IBufferClient::getInterfaceDescriptor());
+  if (ret != NO_ERROR) {
+    ALOGE("BpBufferClient::isValid: failed to write into parcel; errno=%d",
+          ret);
+    return false;
+  }
+
+  ret = remote()->transact(IS_VALID, data, &reply);
+  if (ret == NO_ERROR) {
+    return reply.readBool();
+  } else {
+    ALOGE("BpBufferClient::isValid: failed to transact; errno=%d", ret);
+    return false;
+  }
+}
+
+status_t BnBufferClient::onTransact(uint32_t code, const Parcel& data,
+                                    Parcel* reply, uint32_t flags) {
+  switch (code) {
+    case IS_VALID: {
+      CHECK_INTERFACE(IBufferClient, data, reply);
+      return reply->writeBool(isValid());
+    } break;
+    default:
+      // Should not reach except binder defined transactions such as dumpsys
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 8c6e7e2..8351efc 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -214,13 +214,12 @@
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
 
-  uint64_t context;
   LocalHandle fence;
 
   // The producer buffer starts in gained state.
 
   // Acquire, release, and gain in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
   EXPECT_EQ(-EALREADY, p->Gain(&fence));
 
@@ -233,10 +232,10 @@
   EXPECT_EQ(-EBUSY, p->Gain(&fence));
 
   // Acquire in posted state should succeed.
-  EXPECT_LE(0, c->Acquire(&fence, &context));
+  EXPECT_LE(0, c->Acquire(&fence));
 
   // Acquire, post, and gain in acquired state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
   EXPECT_EQ(-EBUSY, p->Gain(&fence));
 
@@ -246,14 +245,14 @@
 
   // Release, acquire, and post in released state should fail.
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
 
   // Gain in released state should succeed.
   EXPECT_EQ(0, p->Gain(&fence));
 
   // Acquire, release, and gain in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
   EXPECT_EQ(-EALREADY, p->Gain(&fence));
 }
@@ -329,6 +328,36 @@
   EXPECT_FALSE(invalid_fence.IsValid());
 }
 
+TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
+  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
+      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+  ASSERT_TRUE(p.get() != nullptr);
+
+  // The producer buffer starts in gained state. Post the buffer.
+  ASSERT_EQ(0, p->Post(LocalHandle()));
+
+  // Gain in posted state should only succeed with gain_posted_buffer = true.
+  LocalHandle invalid_fence;
+  EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
+  EXPECT_EQ(0, p->Gain(&invalid_fence, true));
+}
+
+TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
+  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
+      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+  ASSERT_TRUE(p.get() != nullptr);
+
+  // The producer buffer starts in gained state. Post the buffer.
+  ASSERT_EQ(0, p->Post(LocalHandle()));
+
+  // GainAsync in posted state should only succeed with gain_posted_buffer
+  // equals true.
+  DvrNativeBufferMetadata metadata;
+  LocalHandle invalid_fence;
+  EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
+  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
+}
+
 TEST_F(LibBufferHubTest, TestZeroConsumer) {
   std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
       kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
@@ -491,7 +520,7 @@
   EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   LocalHandle fence;
   Metadata m2 = {};
-  EXPECT_EQ(0, c->Acquire(&fence, &m2));
+  EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
   EXPECT_EQ(m.field1, m2.field1);
   EXPECT_EQ(m.field2, m2.field2);
   EXPECT_EQ(0, c->Release(LocalHandle()));
@@ -552,11 +581,11 @@
 
   // It is illegal to acquire metadata larger than originally requested during
   // buffer allocation.
-  EXPECT_NE(0, c->Acquire(&fence, &e));
+  EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
 
   // It is ok to acquire metadata smaller than originally requested during
   // buffer allocation.
-  EXPECT_EQ(0, c->Acquire(&fence, &sequence));
+  EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
   EXPECT_EQ(m.field1, sequence);
 }
 
diff --git a/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h b/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h
new file mode 100644
index 0000000..03f2d95
--- /dev/null
+++ b/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h
@@ -0,0 +1,29 @@
+#ifndef ANDROID_DVR_IBUFFERCLIENT_H
+#define ANDROID_DVR_IBUFFERCLIENT_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+namespace dvr {
+
+// Interface for acessing BufferHubBuffer remotely.
+class IBufferClient : public IInterface {
+ public:
+  DECLARE_META_INTERFACE(BufferClient);
+
+  // Checks if the buffer node is valid.
+  virtual bool isValid() = 0;
+};
+
+// BnInterface for IBufferClient. Should only be created in bufferhub service.
+class BnBufferClient : public BnInterface<IBufferClient> {
+ public:
+  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                              uint32_t flags = 0);
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_IBUFFERCLIENT_H
\ No newline at end of file
diff --git a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
index 2044c53..7349779 100644
--- a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
@@ -45,15 +45,6 @@
   // Returns zero on success, or a negative errno code otherwise.
   int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size);
 
-  // Attempt to retrieve a post event from buffer hub. If successful,
-  // |ready_fence| is set to a fence to wait on until the buffer is ready. This
-  // call will only succeed after the fd is signaled. This returns zero or a
-  // negative unix error code.
-  template <typename Meta>
-  int Acquire(LocalHandle* ready_fence, Meta* meta) {
-    return Acquire(ready_fence, meta, sizeof(*meta));
-  }
-
   // Asynchronously acquires a bufer.
   int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
 
diff --git a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
index d2d4d1e..2761416 100644
--- a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
@@ -52,11 +52,14 @@
 
   // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it
   // must be waited on before using the buffer. If it is not valid then the
-  // buffer is free for immediate use. This call will only succeed if the buffer
-  // is in the released state.
-  // This returns zero or a negative unix error code.
-  int Gain(LocalHandle* release_fence);
-  int GainAsync();
+  // buffer is free for immediate use. This call will succeed if the buffer
+  // is in the released state, or in posted state and gain_posted_buffer is
+  // true.
+  //
+  // @param release_fence output fence.
+  // @param gain_posted_buffer whether to gain posted buffer or not.
+  // @return This returns zero or a negative unix error code.
+  int Gain(LocalHandle* release_fence, bool gain_posted_buffer = false);
 
   // Asynchronously marks a released buffer as gained. This method is similar to
   // the synchronous version above, except that it does not wait for BufferHub
@@ -64,7 +67,13 @@
   // the underlying message, no error is returned if this method is called when
   // the buffer is in an incorrect state. Returns zero if sending the message
   // succeeded, or a negative errno code if local error check fails.
-  int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
+  // TODO(b/112007999): gain_posted_buffer true is only used to prevent
+  // libdvrtracking from starving when there are non-responding clients. This
+  // gain_posted_buffer param can be removed once libdvrtracking start to use
+  // the new AHardwareBuffer API.
+  int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
+                bool gain_posted_buffer = false);
+  int GainAsync();
 
   // Detaches a ProducerBuffer from an existing producer/consumer set. Can only
   // be called when a producer buffer has exclusive access to the buffer (i.e.
@@ -92,7 +101,8 @@
   explicit ProducerBuffer(LocalChannelHandle channel);
 
   // Local state transition helpers.
-  int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
+  int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
+                bool gain_posted_buffer = false);
   int LocalPost(const DvrNativeBufferMetadata* meta,
                 const LocalHandle& ready_fence);
 };
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index 7b6f77a..8f0e3e3 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -134,7 +134,7 @@
 }
 
 int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta,
-                              LocalHandle* out_fence) {
+                              LocalHandle* out_fence, bool gain_posted_buffer) {
   uint64_t buffer_state = buffer_state_->load();
   ALOGD_IF(TRACE, "ProducerBuffer::LocalGain: buffer=%d, state=%" PRIx64 ".",
            id(), buffer_state);
@@ -142,13 +142,14 @@
   if (!out_meta)
     return -EINVAL;
 
-  if (!BufferHubDefs::IsBufferReleased(buffer_state)) {
-    if (BufferHubDefs::IsBufferGained(buffer_state)) {
-      // We don't want to log error when gaining a newly allocated
-      // buffer.
-      ALOGI("ProducerBuffer::LocalGain: already gained id=%d.", id());
-      return -EALREADY;
-    }
+  if (BufferHubDefs::IsBufferGained(buffer_state)) {
+    // We don't want to log error when gaining a newly allocated
+    // buffer.
+    ALOGI("ProducerBuffer::LocalGain: already gained id=%d.", id());
+    return -EALREADY;
+  }
+  if (BufferHubDefs::IsBufferAcquired(buffer_state) ||
+      (BufferHubDefs::IsBufferPosted(buffer_state) && !gain_posted_buffer)) {
     ALOGE("ProducerBuffer::LocalGain: not released id=%d state=%" PRIx64 ".",
           id(), buffer_state);
     return -EBUSY;
@@ -180,11 +181,11 @@
   return 0;
 }
 
-int ProducerBuffer::Gain(LocalHandle* release_fence) {
+int ProducerBuffer::Gain(LocalHandle* release_fence, bool gain_posted_buffer) {
   ATRACE_NAME("ProducerBuffer::Gain");
 
   DvrNativeBufferMetadata meta;
-  if (const int error = LocalGain(&meta, release_fence))
+  if (const int error = LocalGain(&meta, release_fence, gain_posted_buffer))
     return error;
 
   auto status = InvokeRemoteMethod<BufferHubRPC::ProducerGain>();
@@ -194,10 +195,11 @@
 }
 
 int ProducerBuffer::GainAsync(DvrNativeBufferMetadata* out_meta,
-                              LocalHandle* release_fence) {
+                              LocalHandle* release_fence,
+                              bool gain_posted_buffer) {
   ATRACE_NAME("ProducerBuffer::GainAsync");
 
-  if (const int error = LocalGain(out_meta, release_fence))
+  if (const int error = LocalGain(out_meta, release_fence, gain_posted_buffer))
     return error;
 
   return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerGain::Opcode));
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 6f792ec..a7fea33 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -549,7 +549,14 @@
         char model[PROPERTY_VALUE_MAX];
         property_get("ro.product.manufacturer", manufacturer, "UNSET");
         property_get("ro.product.model", model, "UNSET");
-        so = load_angle_from_namespace("feature_support", ns);
+
+        // Check if ANGLE is enabled. Workaround for b/118375731
+        // We suspect that loading & unloading a library somehow corrupts
+        // the process.
+        property_get("debug.angle.enable", prop, "0");
+        if (atoi(prop)) {
+            so = load_angle_from_namespace("feature_support", ns);
+        }
         if (so) {
             ALOGV("Temporarily loaded ANGLE's opt-in/out logic from namespace");
             bool use_version0_API = false;
diff --git a/opengl/tools/glgen/stubs/egl/EGL15Header.java-if b/opengl/tools/glgen/stubs/egl/EGL15Header.java-if
index 7409d93..859380f 100644
--- a/opengl/tools/glgen/stubs/egl/EGL15Header.java-if
+++ b/opengl/tools/glgen/stubs/egl/EGL15Header.java-if
@@ -20,7 +20,9 @@
  * EGL 1.5
  *
  */
-public class EGL15 {
+public final class EGL15 {
+
+    private EGL15() {};
 
     public static final int EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT            = 0x00000001;
     public static final int EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT   = 0x00000002;
diff --git a/services/inputflinger/host/InputFlinger.cpp b/services/inputflinger/host/InputFlinger.cpp
index f1d3726..2da2a70 100644
--- a/services/inputflinger/host/InputFlinger.cpp
+++ b/services/inputflinger/host/InputFlinger.cpp
@@ -53,7 +53,7 @@
     if ((uid != AID_SHELL)
             && !PermissionCache::checkPermission(sDumpPermission, pid, uid)) {
         result.appendFormat("Permission Denial: "
-                "can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid);
+                "can't dump InputFlinger from pid=%d, uid=%d\n", pid, uid);
     } else {
         dumpInternal(result);
     }
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index ab677e1..440f1e2 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -70,6 +70,8 @@
               mName.string());
         destroyAllHwcLayers();
     }
+
+    mTimeStats.onDestroy(getSequence());
 }
 
 void BufferLayer::useSurfaceDamage() {
@@ -335,8 +337,8 @@
     nsecs_t desiredPresentTime = getDesiredPresentTime();
     mFrameTracker.setDesiredPresentTime(desiredPresentTime);
 
-    const std::string layerName(getName().c_str());
-    mTimeStats.setDesiredTime(layerName, mCurrentFrameNumber, desiredPresentTime);
+    const int32_t layerID = getSequence();
+    mTimeStats.setDesiredTime(layerID, mCurrentFrameNumber, desiredPresentTime);
 
     std::shared_ptr<FenceTime> frameReadyFence = getCurrentFenceTime();
     if (frameReadyFence->isValid()) {
@@ -348,14 +350,14 @@
     }
 
     if (presentFence->isValid()) {
-        mTimeStats.setPresentFence(layerName, mCurrentFrameNumber, presentFence);
+        mTimeStats.setPresentFence(layerID, mCurrentFrameNumber, presentFence);
         mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
     } else if (mFlinger->getHwComposer().isConnected(HWC_DISPLAY_PRIMARY)) {
         // The HWC doesn't support present fences, so use the refresh
         // timestamp instead.
         const nsecs_t actualPresentTime =
                 mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
-        mTimeStats.setPresentTime(layerName, mCurrentFrameNumber, actualPresentTime);
+        mTimeStats.setPresentTime(layerID, mCurrentFrameNumber, actualPresentTime);
         mFrameTracker.setActualPresentTime(actualPresentTime);
     }
 
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 6cbc4c4..e592a8b 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -227,6 +227,7 @@
     // BufferItem's that weren't actually queued. This can happen in shared
     // buffer mode.
     bool queuedBuffer = false;
+    const int32_t layerID = getSequence();
     LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
                     getTransformToDisplayInverse(), mFreezeGeometryUpdates);
@@ -247,7 +248,7 @@
         // and return early
         if (queuedBuffer) {
             Mutex::Autolock lock(mQueueItemLock);
-            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
+            mTimeStats.removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
             mQueuedFrames--;
         }
@@ -261,7 +262,7 @@
             Mutex::Autolock lock(mQueueItemLock);
             mQueueItems.clear();
             mQueuedFrames = 0;
-            mTimeStats.clearLayerRecord(getName().c_str());
+            mTimeStats.clearLayerRecord(layerID);
         }
 
         // Once we have hit this state, the shadow queue may no longer
@@ -282,14 +283,13 @@
         // Remove any stale buffers that have been dropped during
         // updateTexImage
         while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
-            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
+            mTimeStats.removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
             mQueueItems.removeAt(0);
             mQueuedFrames--;
         }
 
-        const std::string layerName(getName().c_str());
-        mTimeStats.setAcquireFence(layerName, currentFrameNumber, mQueueItems[0].mFenceTime);
-        mTimeStats.setLatchTime(layerName, currentFrameNumber, latchTime);
+        mTimeStats.setAcquireFence(layerID, currentFrameNumber, mQueueItems[0].mFenceTime);
+        mTimeStats.setLatchTime(layerID, currentFrameNumber, latchTime);
 
         mQueueItems.removeAt(0);
     }
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index e52b35a..5df8ade 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -377,6 +377,8 @@
         return NO_ERROR;
     }
 
+    const int32_t layerID = getSequence();
+
     // Reject if the layer is invalid
     uint32_t bufferWidth = s.buffer->width;
     uint32_t bufferHeight = s.buffer->height;
@@ -397,7 +399,7 @@
         ALOGE("[%s] rejecting buffer: "
               "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
               mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
-        mTimeStats.removeTimeRecord(getName().c_str(), getFrameNumber());
+        mTimeStats.removeTimeRecord(layerID, getFrameNumber());
         return BAD_VALUE;
     }
 
@@ -405,7 +407,7 @@
     if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
         // TODO(alecmouri): Fail somewhere upstream if the fence is invalid.
         if (!releaseFence->isValid()) {
-            mTimeStats.clearLayerRecord(getName().c_str());
+            mTimeStats.clearLayerRecord(layerID);
             return UNKNOWN_ERROR;
         }
 
@@ -415,7 +417,7 @@
         auto currentStatus = s.acquireFence->getStatus();
         if (currentStatus == Fence::Status::Invalid) {
             ALOGE("Existing fence has invalid state");
-            mTimeStats.clearLayerRecord(getName().c_str());
+            mTimeStats.clearLayerRecord(layerID);
             return BAD_VALUE;
         }
 
@@ -423,7 +425,7 @@
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
             mDrawingState.acquireFence = releaseFence;
-            mTimeStats.clearLayerRecord(getName().c_str());
+            mTimeStats.clearLayerRecord(layerID);
             return BAD_VALUE;
         }
 
@@ -439,7 +441,7 @@
                 // synchronization is broken, the best we can do is hope fences
                 // signal in order so the new fence will act like a union
                 mDrawingState.acquireFence = releaseFence;
-                mTimeStats.clearLayerRecord(getName().c_str());
+                mTimeStats.clearLayerRecord(layerID);
                 return BAD_VALUE;
             }
             mDrawingState.acquireFence = mergedFence;
@@ -462,16 +464,16 @@
         // a GL-composited layer) not at all.
         status_t err = bindTextureImage();
         if (err != NO_ERROR) {
-            mTimeStats.clearLayerRecord(getName().c_str());
+            mTimeStats.clearLayerRecord(layerID);
             return BAD_VALUE;
         }
     }
 
     // TODO(marissaw): properly support mTimeStats
-    const std::string layerName(getName().c_str());
-    mTimeStats.setPostTime(getName().c_str(), getFrameNumber(), latchTime);
-    mTimeStats.setAcquireFence(layerName, getFrameNumber(), getCurrentFenceTime());
-    mTimeStats.setLatchTime(layerName, getFrameNumber(), latchTime);
+    mTimeStats.setLayerName(layerID, getName().c_str());
+    mTimeStats.setPostTime(layerID, getFrameNumber(), latchTime);
+    mTimeStats.setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
+    mTimeStats.setLatchTime(layerID, getFrameNumber(), latchTime);
 
     return NO_ERROR;
 }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 38482c9..918f7de 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -349,10 +349,11 @@
     DisplayRenderArea(const sp<const DisplayDevice> device,
                       ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
           : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
-                              rotation) {}
+                              device->getCompositionDataSpace(), rotation) {}
     DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
-                      uint32_t reqHeight, ui::Transform::orientation_flags rotation)
-          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE,
+                      uint32_t reqHeight, ui::Dataspace reqDataSpace,
+                      ui::Transform::orientation_flags rotation)
+          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace,
                        getDisplayRotation(rotation, device->getInstallOrientation())),
             mDevice(device),
             mSourceCrop(sourceCrop) {}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 3a40648..393041d 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -184,7 +184,6 @@
 
         auto newDisplay = std::make_unique<Display>(
                 *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType);
-        newDisplay->setFrequencyScaleParameters(mFrequencyScaler);
         newDisplay->setConnected(true);
         mDisplays.emplace(displayId, std::move(newDisplay));
     } else if (connection == Connection::Disconnected) {
@@ -224,14 +223,6 @@
     return static_cast<Error>(mComposer->executeCommands());
 }
 
-void Device::setDisplayFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler) {
-    mFrequencyScaler = frequencyScaler;
-}
-
-Device::FrequencyScaler Device::getDisplayFrequencyScaleParameters() {
-    return mFrequencyScaler;
-}
-
 // Display methods
 
 Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor,
@@ -271,7 +262,6 @@
     mWidth(-1),
     mHeight(-1),
     mVsyncPeriod(-1),
-    mFrequencyScaler(display.mFrequencyScaler),
     mDpiX(-1),
     mDpiY(-1) {}
 
@@ -711,10 +701,6 @@
     mIsConnected = connected;
 }
 
-void Display::setFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler) {
-    mFrequencyScaler = frequencyScaler;
-}
-
 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
 {
     int32_t value = 0;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 363adb5..d274631 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -23,7 +23,6 @@
 #undef HWC2_INCLUDE_STRINGIFICATION
 #undef HWC2_USE_CPP11
 
-#include <cutils/properties.h>
 #include <gui/HdrMetadata.h>
 #include <math/mat4.h>
 #include <ui/GraphicTypes.h>
@@ -85,11 +84,6 @@
 public:
     explicit Device(std::unique_ptr<android::Hwc2::Composer> composer);
 
-    struct FrequencyScaler {
-        int32_t multiplier = 1;
-        int32_t divisor = 1;
-    };
-
     void registerCallback(ComposerCallback* callback, int32_t sequenceId);
 
     // Required by HWC2
@@ -121,9 +115,6 @@
     // This method provides an explicit way to flush state changes to HWC.
     Error flushCommands();
 
-    void setDisplayFrequencyScaleParameters(FrequencyScaler frequecyScaler);
-    FrequencyScaler getDisplayFrequencyScaleParameters();
-
 private:
     // Initialization methods
 
@@ -134,7 +125,6 @@
     std::unordered_set<Capability> mCapabilities;
     std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
     android::Hwc2::impl::PowerAdvisor mPowerAdvisor;
-    FrequencyScaler mFrequencyScaler;
     bool mRegisteredCallback = false;
 };
 
@@ -199,8 +189,7 @@
 
         int32_t getWidth() const { return mWidth; }
         int32_t getHeight() const { return mHeight; }
-        nsecs_t getVsyncPeriod() const {
-            return mVsyncPeriod * mFrequencyScaler.multiplier / mFrequencyScaler.divisor; }
+        nsecs_t getVsyncPeriod() const { return mVsyncPeriod; }
         float getDpiX() const { return mDpiX; }
         float getDpiY() const { return mDpiY; }
 
@@ -213,7 +202,6 @@
         int32_t mWidth;
         int32_t mHeight;
         nsecs_t mVsyncPeriod;
-        Device::FrequencyScaler mFrequencyScaler;
         float mDpiX;
         float mDpiY;
     };
@@ -281,7 +269,6 @@
     hwc2_display_t getId() const { return mId; }
     bool isConnected() const { return mIsConnected; }
     void setConnected(bool connected);  // For use by Device only
-    void setFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler);
 
 private:
     int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
@@ -306,7 +293,6 @@
     hwc2_display_t mId;
     bool mIsConnected;
     DisplayType mType;
-    Device::FrequencyScaler mFrequencyScaler;
     std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
     std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
 };
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6b56ca4..d827fd2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -814,15 +814,4 @@
     return mDisplayData[displayId].hwcDisplay->getId();
 }
 
-void HWComposer::setDisplayFrequencyScaleParameters(
-        HWC2::Device::FrequencyScaler frequencyScaler)
-{
-    mHwcDevice->setDisplayFrequencyScaleParameters(frequencyScaler);
-}
-
-HWC2::Device::FrequencyScaler HWComposer::getDisplayFrequencyScaleParameters()
-{
-    return mHwcDevice->getDisplayFrequencyScaleParameters();
-}
-
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cca1f3b..4777ca9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -186,14 +186,6 @@
     android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
 
     std::optional<hwc2_display_t> getHwcDisplayId(int32_t displayId) const;
-
-    // ------------------------------------------------------------------------
-    // These functions set and get the frequencyScaler.  The frequencyScaler holds
-    // a multiplier and divisor for virtually scaling the panel frequency in
-    // software.  This is used to simulate different panel frequencies when
-    // panel hardware is not available.
-    void setDisplayFrequencyScaleParameters(HWC2::Device::FrequencyScaler frequencyScaler);
-    HWC2::Device::FrequencyScaler getDisplayFrequencyScaleParameters();
 private:
     // For unit tests
     friend TestableSurfaceFlinger;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3a3f5eb..88c3c8a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1470,14 +1470,15 @@
 void Layer::onDisconnect() {
     Mutex::Autolock lock(mFrameEventHistoryMutex);
     mFrameEventHistory.onDisconnect();
-    mTimeStats.onDisconnect(getName().c_str());
+    mTimeStats.onDisconnect(getSequence());
 }
 
 void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
                                      FrameEventHistoryDelta* outDelta) {
     if (newTimestamps) {
-        mTimeStats.setPostTime(getName().c_str(), newTimestamps->frameNumber,
-                               newTimestamps->postedTime);
+        const int32_t layerID = getSequence();
+        mTimeStats.setLayerName(layerID, getName().c_str());
+        mTimeStats.setPostTime(layerID, newTimestamps->frameNumber, newTimestamps->postedTime);
     }
 
     Mutex::Autolock lock(mFrameEventHistoryMutex);
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 3c11e73..9bad6de 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <ui/GraphicTypes.h>
 #include <ui/Transform.h>
 
 #include <functional>
@@ -19,9 +20,11 @@
     static float getCaptureFillValue(CaptureFill captureFill);
 
     RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill,
+               ui::Dataspace reqDataSpace,
                ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
           : mReqWidth(reqWidth),
             mReqHeight(reqHeight),
+            mReqDataSpace(reqDataSpace),
             mCaptureFill(captureFill),
             mRotationFlags(rotation) {}
 
@@ -66,6 +69,9 @@
     int getReqWidth() const { return mReqWidth; };
     int getReqHeight() const { return mReqHeight; };
 
+    // Returns the composition data space of the render area.
+    ui::Dataspace getReqDataSpace() const { return mReqDataSpace; }
+
     // Returns the fill color of the physical render area.  Regions not
     // covered by any rendered layer should be filled with this color.
     CaptureFill getCaptureFill() const { return mCaptureFill; };
@@ -73,6 +79,7 @@
 private:
     const uint32_t mReqWidth;
     const uint32_t mReqHeight;
+    const ui::Dataspace mReqDataSpace;
     const CaptureFill mCaptureFill;
     const ui::Transform::orientation_flags mRotationFlags;
 };
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index cba9181..172c418 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -25,6 +25,7 @@
 #include <algorithm>
 
 #include <log/log.h>
+#include <cutils/properties.h>
 #include <utils/String8.h>
 #include <utils/Thread.h>
 #include <utils/Trace.h>
@@ -520,27 +521,12 @@
 
 void DispSync::setPeriod(nsecs_t period) {
     Mutex::Autolock lock(mMutex);
-    mPeriodBase = mPeriod = period;
+    mPeriod = period;
     mPhase = 0;
     mReferenceTime = 0;
     mThread->updateModel(mPeriod, mPhase, mReferenceTime);
 }
 
-void DispSync::scalePeriod(HWC2::Device::FrequencyScaler frequencyScaler) {
-    Mutex::Autolock lock(mMutex);
-
-    // if only 1 of the properties is updated, we will get to this
-    // point "attempting" to set the scale to 1 when it is already
-    // 1.  Check that special case so that we don't do a useless
-    // update of the model.
-    if ((frequencyScaler.multiplier == 1) &&
-            (frequencyScaler.divisor == 1) &&
-            (mPeriod == mPeriodBase)) return;
-
-    mPeriod = mPeriodBase * frequencyScaler.multiplier / frequencyScaler.divisor;
-    mThread->updateModel(mPeriod, mPhase, mReferenceTime);
-}
-
 nsecs_t DispSync::getPeriod() {
     // lock mutex as mPeriod changes multiple times in updateModelLocked
     Mutex::Autolock lock(mMutex);
@@ -565,7 +551,7 @@
 
         // Exclude the min and max from the average
         durationSum -= minDuration + maxDuration;
-        mPeriodBase = mPeriod = durationSum / (mNumResyncSamples - 3);
+        mPeriod = durationSum / (mNumResyncSamples - 3);
 
         ALOGV("[%s] mPeriod = %" PRId64, mName, ns2us(mPeriod));
 
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
index 5b511f4..5d19093 100644
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ b/services/surfaceflinger/Scheduler/DispSync.h
@@ -24,7 +24,6 @@
 #include <utils/Timers.h>
 
 #include <ui/FenceTime.h>
-#include <DisplayHardware/HWC2.h>
 
 #include <memory>
 
@@ -49,7 +48,6 @@
     virtual bool addResyncSample(nsecs_t timestamp) = 0;
     virtual void endResync() = 0;
     virtual void setPeriod(nsecs_t period) = 0;
-    virtual void scalePeriod(HWC2::Device::FrequencyScaler) = 0;
     virtual nsecs_t getPeriod() = 0;
     virtual void setRefreshSkipCount(int count) = 0;
     virtual status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) = 0;
@@ -120,12 +118,6 @@
     // turned on.  It should NOT be used after that.
     void setPeriod(nsecs_t period) override;
 
-    // The scalePeriod method applies the multiplier and divisor to
-    // scale the vsync event model's period.   The function is added
-    // for an experimental test mode and should not be used outside
-    // of that purpose.
-    void scalePeriod(HWC2::Device::FrequencyScaler frequencyScaler);
-
     // The getPeriod method returns the current vsync period.
     nsecs_t getPeriod() override;
 
@@ -188,7 +180,6 @@
     // mPeriod is the computed period of the modeled vsync events in
     // nanoseconds.
     nsecs_t mPeriod;
-    nsecs_t mPeriodBase;
 
     // mPhase is the phase offset of the modeled vsync events.  It is the
     // number of nanoseconds from time 0 to the first vsync event.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1a5a389..c5a4cac 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1905,6 +1905,8 @@
         mTimeStats.incrementClientCompositionFrames();
     }
 
+    mTimeStats.setPresentFenceGlobal(presentFenceTime);
+
     if (display && getHwComposer().isConnected(display->getId()) &&
         display->getPowerMode() == HWC_POWER_MODE_OFF) {
         return;
@@ -3980,6 +3982,10 @@
         getHwComposer().setPowerMode(type, mode);
     }
 
+    if (display->isPrimary()) {
+        mTimeStats.setPowerMode(mode);
+    }
+
     ALOGD("Finished setting power mode %d on display %d", mode, displayId);
 }
 
@@ -4772,9 +4778,9 @@
         code == IBinder::SYSPROPS_TRANSACTION) {
         return OK;
     }
-    // Numbers from 1000 to 1029 are currently use for backdoors. The code
+    // Numbers from 1000 to 1030 are currently use for backdoors. The code
     // in onTransact verifies that the user is root, and has access to use SF.
-    if (code >= 1000 && code <= 1029) {
+    if (code >= 1000 && code <= 1030) {
         ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
         return OK;
     }
@@ -4970,11 +4976,9 @@
                 repaintEverything();
                 return NO_ERROR;
             }
-            // TODO(b/111505327): Find out whether the usage of 1024 can switch to 1030,
-            // deprecate 1024 if they can.
-            case 1024: { // Does device have wide color gamut display?
-                reply->writeBool(hasWideColorDisplay);
-                return NO_ERROR;
+            // Deprecate, use 1030 to check whether the device is color managed.
+            case 1024: {
+                return NAME_NOT_FOUND;
             }
             case 1025: { // Set layer tracing
                 n = data.readInt32();
@@ -5025,54 +5029,6 @@
                 reply->writeBool(getBE().mHwc->isUsingVrComposer());
                 return NO_ERROR;
             }
-            case 1029: {
-                // Code 1029 is an experimental feature that allows applications to
-                // simulate a high frequency panel by setting a multiplier and divisor
-                // on the VSYNC-sf clock.  If either the multiplier or divisor are
-                // 0, then the code simply return the current multiplier and divisor.
-                HWC2::Device::FrequencyScaler frequencyScaler;
-                frequencyScaler.multiplier = data.readInt32();
-                frequencyScaler.divisor = data.readInt32();
-
-                if ((frequencyScaler.multiplier == 0) || (frequencyScaler.divisor == 0)) {
-                    frequencyScaler = getBE().mHwc->getDisplayFrequencyScaleParameters();
-                    reply->writeInt32(frequencyScaler.multiplier);
-                    reply->writeInt32(frequencyScaler.divisor);
-                    return NO_ERROR;
-                }
-
-                if ((frequencyScaler.multiplier == 1) && (frequencyScaler.divisor == 1)) {
-                    if (mUseScheduler) {
-                        mScheduler->enableHardwareVsync();
-                    } else {
-                        enableHardwareVsync();
-                    }
-                } else {
-                    if (mUseScheduler) {
-                        mScheduler->disableHardwareVsync(true);
-                    } else {
-                        disableHardwareVsync(true);
-                    }
-                }
-                mPrimaryDispSync->scalePeriod(frequencyScaler);
-                getBE().mHwc->setDisplayFrequencyScaleParameters(frequencyScaler);
-
-                ATRACE_INT("PeriodMultiplier", frequencyScaler.multiplier);
-                ATRACE_INT("PeriodDivisor", frequencyScaler.divisor);
-
-                const hwc2_display_t hwcDisplayId = getBE().mHwc->getActiveConfig(
-                        DisplayDevice::DISPLAY_PRIMARY)->getDisplayId();
-
-                onHotplugReceived(getBE().mComposerSequenceId,
-                        hwcDisplayId, HWC2::Connection::Disconnected);
-                onHotplugReceived(getBE().mComposerSequenceId,
-                        hwcDisplayId, HWC2::Connection::Connected);
-                frequencyScaler = getBE().mHwc->getDisplayFrequencyScaleParameters();
-                reply->writeInt32(frequencyScaler.multiplier);
-                reply->writeInt32(frequencyScaler.divisor);
-
-                return NO_ERROR;
-            }
             // Is device color managed?
             case 1030: {
                 reply->writeBool(useColorManagement);
@@ -5102,7 +5058,8 @@
 };
 
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
-                                       sp<GraphicBuffer>* outBuffer, Rect sourceCrop,
+                                       sp<GraphicBuffer>* outBuffer, const Dataspace reqDataspace,
+                                       const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                        uint32_t reqWidth, uint32_t reqHeight,
                                        bool useIdentityTransform,
                                        ISurfaceComposer::Rotation rotation) {
@@ -5131,23 +5088,27 @@
         }
     }
 
-    DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
+    DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace,
+                                 renderAreaRotation);
 
     auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
                                     display, std::placeholders::_1);
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform);
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat,
+                               useIdentityTransform);
 }
 
 status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
-                                       sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                       sp<GraphicBuffer>* outBuffer, const Dataspace reqDataspace,
+                                       const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                        float frameScale, bool childrenOnly) {
     ATRACE_CALL();
 
     class LayerRenderArea : public RenderArea {
     public:
         LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
-                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
-              : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR),
+                        int32_t reqWidth, int32_t reqHeight, Dataspace reqDataSpace,
+                        bool childrenOnly)
+              : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR, reqDataSpace),
                 mLayer(layer),
                 mCrop(crop),
                 mNeedsFiltering(false),
@@ -5254,7 +5215,7 @@
         reqHeight = 1;
     }
 
-    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
+    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, reqDataspace, childrenOnly);
 
     auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
         parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
@@ -5266,19 +5227,22 @@
             visitor(layer);
         });
     };
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, false);
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat, false);
 }
 
 status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
                                              TraverseLayersFunction traverseLayers,
                                              sp<GraphicBuffer>* outBuffer,
+                                             const ui::PixelFormat reqPixelFormat,
                                              bool useIdentityTransform) {
     ATRACE_CALL();
 
+    // TODO(b/116112787) Make buffer usage a parameter.
     const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
             GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
     *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
-                                   HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot");
+                                   static_cast<android_pixel_format>(reqPixelFormat), 1, usage,
+                                   "screenshot");
 
     // This mutex protects syncFd and captureResult for communication of the return values from the
     // main thread back to this Binder thread
@@ -5354,8 +5318,7 @@
     const auto sourceCrop = renderArea.getSourceCrop();
     const auto rotation = renderArea.getRotationFlags();
 
-    // assume ColorMode::SRGB / RenderIntent::COLORIMETRIC
-    engine.setOutputDataSpace(Dataspace::SRGB);
+    engine.setOutputDataSpace(renderArea.getReqDataSpace());
     engine.setDisplayMaxLuminance(DisplayDevice::sDefaultMaxLumiance);
 
     // make sure to clear all GL error flags
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 658f04e..8045246 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -433,10 +433,14 @@
     virtual sp<IDisplayEventConnection> createDisplayEventConnection(
             ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp);
     virtual status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer,
-                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   ISurfaceComposer::Rotation rotation);
     virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
-                                   const Rect& sourceCrop, float frameScale, bool childrenOnly);
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
+                                   float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats);
     virtual status_t getDisplayConfigs(const sp<IBinder>& displayToken,
                                        Vector<DisplayInfo>* configs);
@@ -586,7 +590,7 @@
     void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                 bool useIdentityTransform);
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
-                                 sp<GraphicBuffer>* outBuffer,
+                                 sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
                                  bool useIdentityTransform);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 2e1231b..43fa262 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -24,6 +24,7 @@
 #include <log/log.h>
 
 #include <utils/String8.h>
+#include <utils/Timers.h>
 #include <utils/Trace.h>
 
 #include <algorithm>
@@ -82,7 +83,7 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    timeStats.totalFrames++;
+    mTimeStats.totalFrames++;
 }
 
 void TimeStats::incrementMissedFrames() {
@@ -91,7 +92,7 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    timeStats.missedFrames++;
+    mTimeStats.missedFrames++;
 }
 
 void TimeStats::incrementClientCompositionFrames() {
@@ -100,12 +101,12 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    timeStats.clientCompositionFrames++;
+    mTimeStats.clientCompositionFrames++;
 }
 
-bool TimeStats::recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord) {
+bool TimeStats::recordReadyLocked(int32_t layerID, TimeRecord* timeRecord) {
     if (!timeRecord->ready) {
-        ALOGV("[%s]-[%" PRIu64 "]-presentFence is still not received", layerName.c_str(),
+        ALOGV("[%d]-[%" PRIu64 "]-presentFence is still not received", layerID,
               timeRecord->frameTime.frameNumber);
         return false;
     }
@@ -118,7 +119,7 @@
             timeRecord->frameTime.acquireTime = timeRecord->acquireFence->getSignalTime();
             timeRecord->acquireFence = nullptr;
         } else {
-            ALOGV("[%s]-[%" PRIu64 "]-acquireFence signal time is invalid", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-acquireFence signal time is invalid", layerID,
                   timeRecord->frameTime.frameNumber);
         }
     }
@@ -131,7 +132,7 @@
             timeRecord->frameTime.presentTime = timeRecord->presentFence->getSignalTime();
             timeRecord->presentFence = nullptr;
         } else {
-            ALOGV("[%s]-[%" PRIu64 "]-presentFence signal time invalid", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-presentFence signal time invalid", layerID,
                   timeRecord->frameTime.frameNumber);
         }
     }
@@ -161,60 +162,61 @@
     return "";
 }
 
-void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) {
+void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerID) {
     ATRACE_CALL();
 
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord;
     std::deque<TimeRecord>& timeRecords = layerRecord.timeRecords;
     while (!timeRecords.empty()) {
-        if (!recordReadyLocked(layerName, &timeRecords[0])) break;
-        ALOGV("[%s]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerName.c_str(),
+        if (!recordReadyLocked(layerID, &timeRecords[0])) break;
+        ALOGV("[%d]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerID,
               timeRecords[0].frameTime.frameNumber, timeRecords[0].frameTime.presentTime);
 
         if (prevTimeRecord.ready) {
-            if (!timeStats.stats.count(layerName)) {
-                timeStats.stats[layerName].layerName = layerName;
-                timeStats.stats[layerName].packageName = getPackageName(layerName);
+            const std::string& layerName = layerRecord.layerName;
+            if (!mTimeStats.stats.count(layerName)) {
+                mTimeStats.stats[layerName].layerName = layerName;
+                mTimeStats.stats[layerName].packageName = getPackageName(layerName);
             }
-            TimeStatsHelper::TimeStatsLayer& timeStatsLayer = timeStats.stats[layerName];
+            TimeStatsHelper::TimeStatsLayer& timeStatsLayer = mTimeStats.stats[layerName];
             timeStatsLayer.totalFrames++;
             timeStatsLayer.droppedFrames += layerRecord.droppedFrames;
             layerRecord.droppedFrames = 0;
 
             const int32_t postToAcquireMs = msBetween(timeRecords[0].frameTime.postTime,
                                                       timeRecords[0].frameTime.acquireTime);
-            ALOGV("[%s]-[%" PRIu64 "]-post2acquire[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-post2acquire[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, postToAcquireMs);
             timeStatsLayer.deltas["post2acquire"].insert(postToAcquireMs);
 
             const int32_t postToPresentMs = msBetween(timeRecords[0].frameTime.postTime,
                                                       timeRecords[0].frameTime.presentTime);
-            ALOGV("[%s]-[%" PRIu64 "]-post2present[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-post2present[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, postToPresentMs);
             timeStatsLayer.deltas["post2present"].insert(postToPresentMs);
 
             const int32_t acquireToPresentMs = msBetween(timeRecords[0].frameTime.acquireTime,
                                                          timeRecords[0].frameTime.presentTime);
-            ALOGV("[%s]-[%" PRIu64 "]-acquire2present[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-acquire2present[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, acquireToPresentMs);
             timeStatsLayer.deltas["acquire2present"].insert(acquireToPresentMs);
 
             const int32_t latchToPresentMs = msBetween(timeRecords[0].frameTime.latchTime,
                                                        timeRecords[0].frameTime.presentTime);
-            ALOGV("[%s]-[%" PRIu64 "]-latch2present[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-latch2present[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, latchToPresentMs);
             timeStatsLayer.deltas["latch2present"].insert(latchToPresentMs);
 
             const int32_t desiredToPresentMs = msBetween(timeRecords[0].frameTime.desiredTime,
                                                          timeRecords[0].frameTime.presentTime);
-            ALOGV("[%s]-[%" PRIu64 "]-desired2present[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-desired2present[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, desiredToPresentMs);
             timeStatsLayer.deltas["desired2present"].insert(desiredToPresentMs);
 
             const int32_t presentToPresentMs = msBetween(prevTimeRecord.frameTime.presentTime,
                                                          timeRecords[0].frameTime.presentTime);
-            ALOGV("[%s]-[%" PRIu64 "]-present2present[%d]", layerName.c_str(),
+            ALOGV("[%d]-[%" PRIu64 "]-present2present[%d]", layerID,
                   timeRecords[0].frameTime.frameNumber, presentToPresentMs);
             timeStatsLayer.deltas["present2present"].insert(presentToPresentMs);
         }
@@ -239,23 +241,33 @@
     return std::regex_match(layerName.begin(), layerName.end(), layerNameRegex);
 }
 
-void TimeStats::setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime) {
+void TimeStats::setLayerName(int32_t layerID, const std::string& layerName) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-PostTime[%" PRId64 "]", layerName.c_str(), frameNumber, postTime);
+    ALOGV("[%d]-[%s]", layerID, layerName.c_str());
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName) && !layerNameIsValid(layerName)) {
-        return;
+    if (!mTimeStatsTracker.count(layerID) && layerNameIsValid(layerName)) {
+        mTimeStatsTracker[layerID].layerName = layerName;
     }
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+}
+
+void TimeStats::setPostTime(int32_t layerID, uint64_t frameNumber, nsecs_t postTime) {
+    if (!mEnabled.load()) return;
+
+    ATRACE_CALL();
+    ALOGV("[%d]-[%" PRIu64 "]-PostTime[%" PRId64 "]", layerID, frameNumber, postTime);
+
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     if (layerRecord.timeRecords.size() == MAX_NUM_TIME_RECORDS) {
-        ALOGV("[%s]-timeRecords is already at its maximum size[%zu]", layerName.c_str(),
-              MAX_NUM_TIME_RECORDS);
-        // TODO(zzyiwei): if this happens, there must be a present fence missing
-        // or waitData is not in the correct position. Need to think out a
-        // reasonable way to recover from this state.
+        ALOGE("[%d]-[%s]-timeRecords is already at its maximum size[%zu]. Please file a bug.",
+              layerID, layerRecord.layerName.c_str(), MAX_NUM_TIME_RECORDS);
+        layerRecord.timeRecords.clear();
+        layerRecord.prevTimeRecord.ready = false;
+        layerRecord.waitData = -1;
         return;
     }
     // For most media content, the acquireFence is invalid because the buffer is
@@ -275,84 +287,77 @@
         layerRecord.waitData = layerRecord.timeRecords.size() - 1;
 }
 
-void TimeStats::setLatchTime(const std::string& layerName, uint64_t frameNumber,
-                             nsecs_t latchTime) {
+void TimeStats::setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerName.c_str(), frameNumber, latchTime);
+    ALOGV("[%d]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerID, frameNumber, latchTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.frameTime.latchTime = latchTime;
     }
 }
 
-void TimeStats::setDesiredTime(const std::string& layerName, uint64_t frameNumber,
-                               nsecs_t desiredTime) {
+void TimeStats::setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerName.c_str(), frameNumber,
-          desiredTime);
+    ALOGV("[%d]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerID, frameNumber, desiredTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.frameTime.desiredTime = desiredTime;
     }
 }
 
-void TimeStats::setAcquireTime(const std::string& layerName, uint64_t frameNumber,
-                               nsecs_t acquireTime) {
+void TimeStats::setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerName.c_str(), frameNumber,
-          acquireTime);
+    ALOGV("[%d]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerID, frameNumber, acquireTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.frameTime.acquireTime = acquireTime;
     }
 }
 
-void TimeStats::setAcquireFence(const std::string& layerName, uint64_t frameNumber,
+void TimeStats::setAcquireFence(int32_t layerID, uint64_t frameNumber,
                                 const std::shared_ptr<FenceTime>& acquireFence) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber,
+    ALOGV("[%d]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerID, frameNumber,
           acquireFence->getSignalTime());
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.acquireFence = acquireFence;
     }
 }
 
-void TimeStats::setPresentTime(const std::string& layerName, uint64_t frameNumber,
-                               nsecs_t presentTime) {
+void TimeStats::setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerName.c_str(), frameNumber,
-          presentTime);
+    ALOGV("[%d]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerID, frameNumber, presentTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.frameTime.presentTime = presentTime;
@@ -360,20 +365,20 @@
         layerRecord.waitData++;
     }
 
-    flushAvailableRecordsToStatsLocked(layerName);
+    flushAvailableRecordsToStatsLocked(layerID);
 }
 
-void TimeStats::setPresentFence(const std::string& layerName, uint64_t frameNumber,
+void TimeStats::setPresentFence(int32_t layerID, uint64_t frameNumber,
                                 const std::shared_ptr<FenceTime>& presentFence) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber,
+    ALOGV("[%d]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerID, frameNumber,
           presentFence->getSignalTime());
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
     if (timeRecord.frameTime.frameNumber == frameNumber) {
         timeRecord.presentFence = presentFence;
@@ -381,45 +386,57 @@
         layerRecord.waitData++;
     }
 
-    flushAvailableRecordsToStatsLocked(layerName);
+    flushAvailableRecordsToStatsLocked(layerID);
 }
 
-void TimeStats::onDisconnect(const std::string& layerName) {
+void TimeStats::onDisconnect(int32_t layerID) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-onDisconnect", layerName.c_str());
+    ALOGV("[%d]-onDisconnect", layerID);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    flushAvailableRecordsToStatsLocked(layerName);
-    timeStatsTracker.erase(layerName);
+    if (!mTimeStatsTracker.count(layerID)) return;
+    flushAvailableRecordsToStatsLocked(layerID);
+    mTimeStatsTracker.erase(layerID);
 }
 
-void TimeStats::clearLayerRecord(const std::string& layerName) {
+void TimeStats::onDestroy(int32_t layerID) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-clearLayerRecord", layerName.c_str());
+    ALOGV("[%d]-onDestroy", layerID);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    flushAvailableRecordsToStatsLocked(layerID);
+    mTimeStatsTracker.erase(layerID);
+}
+
+void TimeStats::clearLayerRecord(int32_t layerID) {
+    if (!mEnabled.load()) return;
+
+    ATRACE_CALL();
+    ALOGV("[%d]-clearLayerRecord", layerID);
+
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     layerRecord.timeRecords.clear();
     layerRecord.prevTimeRecord.ready = false;
     layerRecord.waitData = -1;
     layerRecord.droppedFrames = 0;
 }
 
-void TimeStats::removeTimeRecord(const std::string& layerName, uint64_t frameNumber) {
+void TimeStats::removeTimeRecord(int32_t layerID, uint64_t frameNumber) {
     if (!mEnabled.load()) return;
 
     ATRACE_CALL();
-    ALOGV("[%s]-[%" PRIu64 "]-removeTimeRecord", layerName.c_str(), frameNumber);
+    ALOGV("[%d]-[%" PRIu64 "]-removeTimeRecord", layerID, frameNumber);
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (!timeStatsTracker.count(layerName)) return;
-    LayerRecord& layerRecord = timeStatsTracker[layerName];
+    if (!mTimeStatsTracker.count(layerID)) return;
+    LayerRecord& layerRecord = mTimeStatsTracker[layerID];
     size_t removeAt = 0;
     for (const TimeRecord& record : layerRecord.timeRecords) {
         if (record.frameTime.frameNumber == frameNumber) break;
@@ -433,6 +450,87 @@
     layerRecord.droppedFrames++;
 }
 
+void TimeStats::flushPowerTimeLocked() {
+    nsecs_t curTime = systemTime();
+    // elapsedTime is in milliseconds.
+    int64_t elapsedTime = (curTime - mPowerTime.prevTime) / 1000000;
+
+    switch (mPowerTime.powerMode) {
+        case HWC_POWER_MODE_NORMAL:
+            mTimeStats.displayOnTime += elapsedTime;
+            break;
+        case HWC_POWER_MODE_OFF:
+        case HWC_POWER_MODE_DOZE:
+        case HWC_POWER_MODE_DOZE_SUSPEND:
+        default:
+            break;
+    }
+
+    mPowerTime.prevTime = curTime;
+}
+
+void TimeStats::setPowerMode(int32_t powerMode) {
+    if (!mEnabled.load()) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mPowerTime.powerMode = powerMode;
+        return;
+    }
+
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (powerMode == mPowerTime.powerMode) return;
+
+    flushPowerTimeLocked();
+    mPowerTime.powerMode = powerMode;
+}
+
+void TimeStats::flushAvailableGlobalRecordsToStatsLocked() {
+    ATRACE_CALL();
+
+    while (!mGlobalRecord.presentFences.empty()) {
+        const nsecs_t curPresentTime = mGlobalRecord.presentFences.front()->getSignalTime();
+        if (curPresentTime == Fence::SIGNAL_TIME_PENDING) break;
+
+        if (curPresentTime == Fence::SIGNAL_TIME_INVALID) {
+            ALOGE("GlobalPresentFence is invalid!");
+            mGlobalRecord.prevPresentTime = 0;
+            mGlobalRecord.presentFences.pop_front();
+            continue;
+        }
+
+        ALOGV("GlobalPresentFenceTime[%" PRId64 "]",
+              mGlobalRecord.presentFences.front()->getSignalTime());
+
+        const int32_t presentToPresentMs = msBetween(mGlobalRecord.prevPresentTime, curPresentTime);
+        ALOGV("Global present2present[%d]", presentToPresentMs);
+
+        mTimeStats.presentToPresent.insert(presentToPresentMs);
+        mGlobalRecord.prevPresentTime = curPresentTime;
+        mGlobalRecord.presentFences.pop_front();
+    }
+}
+
+void TimeStats::setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) {
+    if (!mEnabled.load()) return;
+
+    ATRACE_CALL();
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (presentFence == nullptr) {
+        mGlobalRecord.prevPresentTime = 0;
+        return;
+    }
+
+    if (mGlobalRecord.presentFences.size() == MAX_NUM_TIME_RECORDS) {
+        // The front presentFence must be trapped in pending status in this
+        // case. Try dequeuing the front one to recover.
+        ALOGE("GlobalPresentFences is already at its maximum size[%zu]", MAX_NUM_TIME_RECORDS);
+        mGlobalRecord.prevPresentTime = 0;
+        mGlobalRecord.presentFences.pop_front();
+    }
+
+    mGlobalRecord.presentFences.emplace_back(presentFence);
+    flushAvailableGlobalRecordsToStatsLocked();
+}
+
 void TimeStats::enable() {
     if (mEnabled.load()) return;
 
@@ -441,7 +539,8 @@
     std::lock_guard<std::mutex> lock(mMutex);
     ALOGD("Enabled");
     mEnabled.store(true);
-    timeStats.statsStart = static_cast<int64_t>(std::time(0));
+    mTimeStats.statsStart = static_cast<int64_t>(std::time(0));
+    mPowerTime.prevTime = systemTime();
 }
 
 void TimeStats::disable() {
@@ -452,7 +551,7 @@
     std::lock_guard<std::mutex> lock(mMutex);
     ALOGD("Disabled");
     mEnabled.store(false);
-    timeStats.statsEnd = static_cast<int64_t>(std::time(0));
+    mTimeStats.statsEnd = static_cast<int64_t>(std::time(0));
 }
 
 void TimeStats::clear() {
@@ -460,12 +559,15 @@
 
     std::lock_guard<std::mutex> lock(mMutex);
     ALOGD("Cleared");
-    timeStats.stats.clear();
-    timeStats.statsStart = (mEnabled.load() ? static_cast<int64_t>(std::time(0)) : 0);
-    timeStats.statsEnd = 0;
-    timeStats.totalFrames = 0;
-    timeStats.missedFrames = 0;
-    timeStats.clientCompositionFrames = 0;
+    mTimeStats.stats.clear();
+    mTimeStats.statsStart = (mEnabled.load() ? static_cast<int64_t>(std::time(0)) : 0);
+    mTimeStats.statsEnd = 0;
+    mTimeStats.totalFrames = 0;
+    mTimeStats.missedFrames = 0;
+    mTimeStats.clientCompositionFrames = 0;
+    mTimeStats.displayOnTime = 0;
+    mTimeStats.presentToPresent.hist.clear();
+    mPowerTime.prevTime = systemTime();
 }
 
 bool TimeStats::isEnabled() {
@@ -476,19 +578,21 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    if (timeStats.statsStart == 0) {
+    if (mTimeStats.statsStart == 0) {
         return;
     }
 
-    timeStats.statsEnd = static_cast<int64_t>(std::time(0));
+    mTimeStats.statsEnd = static_cast<int64_t>(std::time(0));
+
+    flushPowerTimeLocked();
 
     if (asProto) {
         ALOGD("Dumping TimeStats as proto");
-        SFTimeStatsGlobalProto timeStatsProto = timeStats.toProto(maxLayers);
+        SFTimeStatsGlobalProto timeStatsProto = mTimeStats.toProto(maxLayers);
         result.append(timeStatsProto.SerializeAsString().c_str(), timeStatsProto.ByteSize());
     } else {
         ALOGD("Dumping TimeStats as text");
-        result.append(timeStats.toString(maxLayers).c_str());
+        result.append(mTimeStats.toString(maxLayers).c_str());
         result.append("\n");
     }
 }
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 5ab3934..d1e554c 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -19,6 +19,8 @@
 #include <timestatsproto/TimeStatsHelper.h>
 #include <timestatsproto/TimeStatsProtoHeader.h>
 
+#include <hardware/hwcomposer_defs.h>
+
 #include <ui/FenceTime.h>
 
 #include <utils/String16.h>
@@ -57,6 +59,7 @@
     };
 
     struct LayerRecord {
+        std::string layerName;
         // This is the index in timeRecords, at which the timestamps for that
         // specific frame are still not fully received. This is not waiting for
         // fences to signal, but rather waiting to receive those fences/timestamps.
@@ -66,6 +69,16 @@
         std::deque<TimeRecord> timeRecords;
     };
 
+    struct PowerTime {
+        int32_t powerMode = HWC_POWER_MODE_OFF;
+        nsecs_t prevTime = 0;
+    };
+
+    struct GlobalRecord {
+        nsecs_t prevPresentTime = 0;
+        std::deque<std::shared_ptr<FenceTime>> presentFences;
+    };
+
 public:
     static TimeStats& getInstance();
     void parseArgs(bool asProto, const Vector<String16>& args, size_t& index, String8& result);
@@ -73,27 +86,35 @@
     void incrementMissedFrames();
     void incrementClientCompositionFrames();
 
-    void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime);
-    void setLatchTime(const std::string& layerName, uint64_t frameNumber, nsecs_t latchTime);
-    void setDesiredTime(const std::string& layerName, uint64_t frameNumber, nsecs_t desiredTime);
-    void setAcquireTime(const std::string& layerName, uint64_t frameNumber, nsecs_t acquireTime);
-    void setAcquireFence(const std::string& layerName, uint64_t frameNumber,
+    void setLayerName(int32_t layerID, const std::string& layerName);
+    void setPostTime(int32_t layerID, uint64_t frameNumber, nsecs_t postTime);
+    void setLatchTime(int32_t layerID, uint64_t frameNumber, nsecs_t latchTime);
+    void setDesiredTime(int32_t layerID, uint64_t frameNumber, nsecs_t desiredTime);
+    void setAcquireTime(int32_t layerID, uint64_t frameNumber, nsecs_t acquireTime);
+    void setAcquireFence(int32_t layerID, uint64_t frameNumber,
                          const std::shared_ptr<FenceTime>& acquireFence);
-    void setPresentTime(const std::string& layerName, uint64_t frameNumber, nsecs_t presentTime);
-    void setPresentFence(const std::string& layerName, uint64_t frameNumber,
+    void setPresentTime(int32_t layerID, uint64_t frameNumber, nsecs_t presentTime);
+    void setPresentFence(int32_t layerID, uint64_t frameNumber,
                          const std::shared_ptr<FenceTime>& presentFence);
     // On producer disconnect with BufferQueue.
-    void onDisconnect(const std::string& layerName);
+    void onDisconnect(int32_t layerID);
+    // On layer tear down.
+    void onDestroy(int32_t layerID);
     // When SF is cleaning up the queue, clear the LayerRecord as well.
-    void clearLayerRecord(const std::string& layerName);
+    void clearLayerRecord(int32_t layerID);
     // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
-    void removeTimeRecord(const std::string& layerName, uint64_t frameNumber);
+    void removeTimeRecord(int32_t layerID, uint64_t frameNumber);
+
+    void setPowerMode(int32_t powerMode);
+    void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence);
 
 private:
     TimeStats() = default;
 
-    bool recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord);
-    void flushAvailableRecordsToStatsLocked(const std::string& layerName);
+    bool recordReadyLocked(int32_t layerID, TimeRecord* timeRecord);
+    void flushAvailableRecordsToStatsLocked(int32_t layerID);
+    void flushPowerTimeLocked();
+    void flushAvailableGlobalRecordsToStatsLocked();
 
     void enable();
     void disable();
@@ -103,8 +124,11 @@
 
     std::atomic<bool> mEnabled = false;
     std::mutex mMutex;
-    TimeStatsHelper::TimeStatsGlobal timeStats;
-    std::unordered_map<std::string, LayerRecord> timeStatsTracker;
+    TimeStatsHelper::TimeStatsGlobal mTimeStats;
+    // Hashmap for LayerRecord with layerID as the hash key
+    std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
+    PowerTime mPowerTime;
+    GlobalRecord mGlobalRecord;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index b7b2778..c701224 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -49,7 +49,7 @@
 float TimeStatsHelper::Histogram::averageTime() const {
     int64_t ret = 0;
     int64_t count = 0;
-    for (auto& ele : hist) {
+    for (const auto& ele : hist) {
         count += ele.second;
         ret += ele.first * ele.second;
     }
@@ -73,13 +73,13 @@
     StringAppendF(&result, "packageName = %s\n", packageName.c_str());
     StringAppendF(&result, "totalFrames = %d\n", totalFrames);
     StringAppendF(&result, "droppedFrames = %d\n", droppedFrames);
-    auto iter = deltas.find("present2present");
+    const auto iter = deltas.find("present2present");
     if (iter != deltas.end()) {
         StringAppendF(&result, "averageFPS = %.3f\n", 1000.0 / iter->second.averageTime());
     }
-    for (auto& ele : deltas) {
+    for (const auto& ele : deltas) {
         StringAppendF(&result, "%s histogram is as below:\n", ele.first.c_str());
-        StringAppendF(&result, "%s", ele.second.toString().c_str());
+        result.append(ele.second.toString());
     }
 
     return result;
@@ -92,9 +92,12 @@
     StringAppendF(&result, "totalFrames = %d\n", totalFrames);
     StringAppendF(&result, "missedFrames = %d\n", missedFrames);
     StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames);
+    StringAppendF(&result, "displayOnTime = %lld ms\n", static_cast<long long int>(displayOnTime));
+    StringAppendF(&result, "presentToPresent histogram is as below:\n");
+    result.append(presentToPresent.toString());
     const auto dumpStats = generateDumpStats(maxLayers);
-    for (auto& ele : dumpStats) {
-        StringAppendF(&result, "%s", ele->toString().c_str());
+    for (const auto& ele : dumpStats) {
+        result.append(ele->toString());
     }
 
     return result;
@@ -106,10 +109,10 @@
     layerProto.set_package_name(packageName);
     layerProto.set_total_frames(totalFrames);
     layerProto.set_dropped_frames(droppedFrames);
-    for (auto& ele : deltas) {
+    for (const auto& ele : deltas) {
         SFTimeStatsDeltaProto* deltaProto = layerProto.add_deltas();
         deltaProto->set_delta_name(ele.first);
-        for (auto& histEle : ele.second.hist) {
+        for (const auto& histEle : ele.second.hist) {
             SFTimeStatsHistogramBucketProto* histProto = deltaProto->add_histograms();
             histProto->set_time_millis(histEle.first);
             histProto->set_frame_count(histEle.second);
@@ -126,8 +129,14 @@
     globalProto.set_total_frames(totalFrames);
     globalProto.set_missed_frames(missedFrames);
     globalProto.set_client_composition_frames(clientCompositionFrames);
+    globalProto.set_display_on_time(displayOnTime);
+    for (const auto& histEle : presentToPresent.hist) {
+        SFTimeStatsHistogramBucketProto* histProto = globalProto.add_present_to_present();
+        histProto->set_time_millis(histEle.first);
+        histProto->set_frame_count(histEle.second);
+    }
     const auto dumpStats = generateDumpStats(maxLayers);
-    for (auto& ele : dumpStats) {
+    for (const auto& ele : dumpStats) {
         SFTimeStatsLayerProto* layerProto = globalProto.add_stats();
         layerProto->CopyFrom(ele->toProto());
     }
@@ -137,7 +146,7 @@
 std::vector<TimeStatsHelper::TimeStatsLayer const*>
 TimeStatsHelper::TimeStatsGlobal::generateDumpStats(std::optional<uint32_t> maxLayers) const {
     std::vector<TimeStatsLayer const*> dumpStats;
-    for (auto& ele : stats) {
+    for (const auto& ele : stats) {
         dumpStats.push_back(&ele.second);
     }
 
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 99c891b..7d0fe79 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -57,6 +57,8 @@
         int32_t totalFrames = 0;
         int32_t missedFrames = 0;
         int32_t clientCompositionFrames = 0;
+        int64_t displayOnTime = 0;
+        Histogram presentToPresent;
         std::unordered_map<std::string, TimeStatsLayer> stats;
 
         std::string toString(std::optional<uint32_t> maxLayers) const;
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
index b8f38c2..377612a 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
+++ b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
@@ -20,13 +20,12 @@
 
 option optimize_for = LITE_RUNTIME;
 
-// //depot/google3/java/com/google/android/apps/graphics/stats/proto/
+// //depot/google3/wireless/android/graphics/surfaceflingerstats/proto/
 // timestats.proto is based on this proto. Please only make valid protobuf
-// changes to these messages, and keep the other file in sync per Android
-// release. Please also do not include "option optimize_for = LITE_RUNTIME;" at
-// google3 side.
+// changes to these messages, and keep google3 side proto messages in sync if
+// the end to end pipeline needs to be updated.
 
-// Next tag: 7
+// Next tag: 9
 message SFTimeStatsGlobalProto {
   // The stats start time in UTC as seconds since January 1, 1970
   optional int64 stats_start = 1;
@@ -38,6 +37,10 @@
   optional int32 missed_frames = 4;
   // Total frames fallback to client composition.
   optional int32 client_composition_frames = 5;
+  // Primary display on time in milliseconds.
+  optional int64 display_on_time = 7;
+  // Present to present histogram.
+  repeated SFTimeStatsHistogramBucketProto present_to_present = 8;
   // Stats per layer. Apps could have multiple layers.
   repeated SFTimeStatsLayerProto stats = 6;
 }
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 9e762f0..a73ec6c 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -267,8 +267,9 @@
     sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
     std::function<status_t()> condition = [=]() {
         sp<GraphicBuffer> outBuffer;
-        return ScreenshotClient::capture(display, Rect(), 0 /*reqWidth*/, 0 /*reqHeight*/, false,
-                                         ROTATION, &outBuffer);
+        return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB,
+                                         ui::PixelFormat::RGBA_8888, Rect(), 0 /*reqWidth*/,
+                                         0 /*reqHeight*/, false, ROTATION, &outBuffer);
     };
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
@@ -278,8 +279,9 @@
     sp<GraphicBuffer> outBuffer;
     std::function<status_t()> condition = [=]() {
         sp<GraphicBuffer> outBuffer;
-        return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(), Rect(), FRAME_SCALE,
-                                               &outBuffer);
+        return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(),
+                                               ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
+                                               Rect(), FRAME_SCALE, &outBuffer);
     };
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3719a3d..1352df5 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -190,7 +190,8 @@
     constexpr bool forSystem = true;
 
     DisplayRenderArea renderArea(mDisplay, sourceCrop, DEFAULT_DISPLAY_WIDTH,
-                                 DEFAULT_DISPLAY_HEIGHT, ui::Transform::ROT_0);
+                                 DEFAULT_DISPLAY_HEIGHT, ui::Dataspace::V0_SRGB,
+                                 ui::Transform::ROT_0);
 
     auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
         return mFlinger.traverseLayersInDisplay(mDisplay, visitor);
@@ -288,7 +289,7 @@
         EXPECT_CALL(*test->mRenderEngine, flush()).WillOnce(Return(ByMove(base::unique_fd())));
         EXPECT_CALL(*test->mRenderEngine, finish()).WillOnce(Return(true));
 
-        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(ui::Dataspace::SRGB)).Times(1);
+        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(_)).Times(1);
         EXPECT_CALL(*test->mRenderEngine, setDisplayMaxLuminance(DEFAULT_DISPLAY_MAX_LUMINANCE))
                 .Times(1);
         // This expectation retires on saturation as setViewportAndProjection is
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
index 495b3f2..34e71cb 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
@@ -35,7 +35,6 @@
     MOCK_METHOD1(addResyncSample, bool(nsecs_t));
     MOCK_METHOD0(endResync, void());
     MOCK_METHOD1(setPeriod, void(nsecs_t));
-    MOCK_METHOD1(scalePeriod, void(HWC2::Device::FrequencyScaler));
     MOCK_METHOD0(getPeriod, nsecs_t());
     MOCK_METHOD1(setRefreshSkipCount, void(int));
     MOCK_METHOD3(addEventListener, status_t(const char*, nsecs_t, Callback*));
diff --git a/services/vr/bufferhubd/IBufferHub.cpp b/services/vr/bufferhubd/IBufferHub.cpp
index 9d5b91a..2f39e41 100644
--- a/services/vr/bufferhubd/IBufferHub.cpp
+++ b/services/vr/bufferhubd/IBufferHub.cpp
@@ -4,14 +4,69 @@
 namespace android {
 namespace dvr {
 
+class BpBufferHub : public BpInterface<IBufferHub> {
+ public:
+  explicit BpBufferHub(const sp<IBinder>& impl)
+      : BpInterface<IBufferHub>(impl) {}
+
+  sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                 uint32_t layer_count, uint32_t format,
+                                 uint64_t usage,
+                                 uint64_t user_metadata_size) override;
+};
+
 IMPLEMENT_META_INTERFACE(BufferHub, "android.dvr.IBufferHub");
 
+// Transaction code
+enum {
+  CREATE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+sp<IBufferClient> BpBufferHub::createBuffer(uint32_t width, uint32_t height,
+                                            uint32_t layer_count,
+                                            uint32_t format, uint64_t usage,
+                                            uint64_t user_metadata_size) {
+  Parcel data, reply;
+  status_t ret = NO_ERROR;
+  ret |= data.writeInterfaceToken(IBufferHub::getInterfaceDescriptor());
+  ret |= data.writeUint32(width);
+  ret |= data.writeUint32(height);
+  ret |= data.writeUint32(layer_count);
+  ret |= data.writeUint32(format);
+  ret |= data.writeUint64(usage);
+  ret |= data.writeUint64(user_metadata_size);
+
+  if (ret != NO_ERROR) {
+    ALOGE("BpBufferHub::createBuffer: failed to write into parcel");
+    return nullptr;
+  }
+
+  ret = remote()->transact(CREATE_BUFFER, data, &reply);
+  if (ret == NO_ERROR) {
+    return interface_cast<IBufferClient>(reply.readStrongBinder());
+  } else {
+    ALOGE("BpBufferHub::createBuffer: failed to transact; errno=%d", ret);
+    return nullptr;
+  }
+}
+
 status_t BnBufferHub::onTransact(uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags) {
   switch (code) {
+    case CREATE_BUFFER: {
+      CHECK_INTERFACE(IBufferHub, data, reply);
+      uint32_t width = data.readUint32();
+      uint32_t height = data.readUint32();
+      uint32_t layer_count = data.readUint32();
+      uint32_t format = data.readUint32();
+      uint64_t usage = data.readUint64();
+      uint64_t user_metadata_size = data.readUint64();
+      sp<IBufferClient> ret = createBuffer(width, height, layer_count, format,
+                                           usage, user_metadata_size);
+      return reply->writeStrongBinder(IInterface::asBinder(ret));
+    } break;
     default:
-      // Should not reach
-      ALOGE("onTransact(): unknown code %u received!", code);
+      // Should not reach except binder defined transactions such as dumpsys
       return BBinder::onTransact(code, data, reply, flags);
   }
 }
diff --git a/services/vr/bufferhubd/buffer_hub_binder.cpp b/services/vr/bufferhubd/buffer_hub_binder.cpp
index de82c09..f8a9758 100644
--- a/services/vr/bufferhubd/buffer_hub_binder.cpp
+++ b/services/vr/bufferhubd/buffer_hub_binder.cpp
@@ -5,6 +5,7 @@
 #include <binder/ProcessState.h>
 #include <log/log.h>
 #include <private/dvr/buffer_hub_binder.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
@@ -45,8 +46,14 @@
             "Input arguments are ignored.\n");
   }
 
-  // TODO(b/116526156): output real data in this class once we have it
+  fprintf(out, "Binder service:\n");
+  // Active buffers
+  fprintf(out, "Active BufferClients: %zu\n", client_list_.size());
+  // TODO(b/117790952): print buffer information after BufferNode has it
+  // TODO(b/116526156): print more information once we have them
+
   if (pdx_service_) {
+    fprintf(out, "\nPDX service:\n");
     // BufferHubService::Dumpstate(size_t) is not actually using the param
     // So just using 0 as the length
     fprintf(out, "%s", pdx_service_->DumpState(0).c_str());
@@ -58,23 +65,17 @@
   return NO_ERROR;
 }
 
-sp<IBufferHub> BufferHubBinderService::getServiceProxy() {
-  sp<IServiceManager> sm = defaultServiceManager();
-  sp<IBinder> service = sm->checkService(String16(getServiceName()));
+sp<IBufferClient> BufferHubBinderService::createBuffer(
+    uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
+    uint64_t usage, uint64_t user_metadata_size) {
+  std::shared_ptr<BufferNode> node = std::make_shared<BufferNode>(
+      width, height, layer_count, format, usage, user_metadata_size);
 
-  if (service == nullptr) {
-    ALOGE("getServiceProxy(): %s binder service not found!", getServiceName());
-    return nullptr;
-  }
+  sp<BufferClient> client = new BufferClient(node);
+  // Add it to list for bookkeeping and dumpsys.
+  client_list_.push_back(client);
 
-  sp<IBufferHub> ret = interface_cast<IBufferHub>(service);
-  if (ret == nullptr) {
-    ALOGE("getServiceProxy(): %s binder service type casting error!",
-          getServiceName());
-    return nullptr;
-  }
-
-  return ret;
+  return client;
 }
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/include/private/dvr/IBufferHub.h b/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
index 266ae88..bd5f9cf 100644
--- a/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
+++ b/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
@@ -3,6 +3,7 @@
 
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <private/dvr/IBufferClient.h>
 
 namespace android {
 namespace dvr {
@@ -10,6 +11,12 @@
 class IBufferHub : public IInterface {
  public:
   DECLARE_META_INTERFACE(BufferHub);
+
+  static const char* getServiceName() { return "bufferhubd"; }
+  virtual sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                         uint32_t layer_count, uint32_t format,
+                                         uint64_t usage,
+                                         uint64_t user_metadata_size) = 0;
 };
 
 class BnBufferHub : public BnInterface<IBufferHub> {
@@ -18,13 +25,7 @@
                               uint32_t flags = 0);
 };
 
-class BpBufferHub : public BpInterface<IBufferHub> {
- public:
-  explicit BpBufferHub(const sp<IBinder>& impl)
-      : BpInterface<IBufferHub>(impl) {}
-};
-
 }  // namespace dvr
 }  // namespace android
 
-#endif
\ No newline at end of file
+#endif  // ANDROID_DVR_IBUFFERHUB_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_client.h b/services/vr/bufferhubd/include/private/dvr/buffer_client.h
new file mode 100644
index 0000000..20d51ee
--- /dev/null
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_client.h
@@ -0,0 +1,29 @@
+#ifndef ANDROID_DVR_BUFFERCLIENT_H
+#define ANDROID_DVR_BUFFERCLIENT_H
+
+#include <private/dvr/IBufferClient.h>
+#include <private/dvr/buffer_node.h>
+
+namespace android {
+namespace dvr {
+
+class BufferClient : public BnBufferClient {
+ public:
+  // Creates a server-side buffer client from an existing BufferNode. Note that
+  // this funciton takes ownership of the shared_ptr.
+  explicit BufferClient(std::shared_ptr<BufferNode> node)
+      : buffer_node_(std::move(node)){};
+
+  // Binder IPC functions
+  bool isValid() override {
+    return buffer_node_ ? buffer_node_->IsValid() : false;
+  };
+
+ private:
+  std::shared_ptr<BufferNode> buffer_node_;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_IBUFFERCLIENT_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
index e266ff8..9064d87 100644
--- a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
@@ -1,8 +1,11 @@
 #ifndef ANDROID_DVR_BUFFER_HUB_BINDER_H
 #define ANDROID_DVR_BUFFER_HUB_BINDER_H
 
+#include <vector>
+
 #include <binder/BinderService.h>
 #include <private/dvr/IBufferHub.h>
+#include <private/dvr/buffer_client.h>
 #include <private/dvr/buffer_hub.h>
 
 namespace android {
@@ -12,16 +15,20 @@
                                public BnBufferHub {
  public:
   static status_t start(const std::shared_ptr<BufferHubService>& pdx_service);
-  static const char* getServiceName() { return "bufferhubd"; }
   // Dump bufferhub related information to given fd (usually stdout)
   // usage: adb shell dumpsys bufferhubd
   virtual status_t dump(int fd, const Vector<String16>& args) override;
 
-  // Helper function to get the BpReference to this service
-  static sp<IBufferHub> getServiceProxy();
+  // Binder IPC functions
+  sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                 uint32_t layer_count, uint32_t format,
+                                 uint64_t usage,
+                                 uint64_t user_metadata_size) override;
 
  private:
   std::shared_ptr<BufferHubService> pdx_service_;
+
+  std::vector<sp<BufferClient>> client_list_;
 };
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
index 587e6db..7fa2226 100644
--- a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
+++ b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
@@ -1,23 +1,41 @@
+#include <binder/IServiceManager.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <private/dvr/buffer_hub_binder.h>
+#include <private/dvr/IBufferClient.h>
+#include <private/dvr/IBufferHub.h>
+#include <ui/PixelFormat.h>
 
 namespace android {
 namespace dvr {
 
 namespace {
 
-using testing::Ne;
+using testing::NotNull;
+
+const int kWidth = 640;
+const int kHeight = 480;
+const int kLayerCount = 1;
+const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+const int kUsage = 0;
+const size_t kUserMetadataSize = 0;
 
 class BufferHubBinderServiceTest : public ::testing::Test {
-  // Add setup and teardown if necessary
+ protected:
+  void SetUp() override {
+    status_t ret = getService<IBufferHub>(
+        String16(IBufferHub::getServiceName()), &service);
+    ASSERT_EQ(ret, OK);
+    ASSERT_THAT(service, NotNull());
+  }
+
+  sp<IBufferHub> service;
 };
 
-TEST_F(BufferHubBinderServiceTest, TestInitialize) {
-  // Create a new service will kill the current one.
-  // So just check if Binder service is running
-  sp<IBufferHub> service = BufferHubBinderService::getServiceProxy();
-  EXPECT_THAT(service, Ne(nullptr));
+TEST_F(BufferHubBinderServiceTest, TestCreateBuffer) {
+  sp<IBufferClient> bufferClient = service->createBuffer(
+      kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
+  ASSERT_THAT(bufferClient, NotNull());
+  EXPECT_TRUE(bufferClient->isValid());
 }
 
 }  // namespace