Merge "SF: Adding Idle Timer, to detect when devices are idle."
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 2c93832..516e3d8 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2054,6 +2054,7 @@
 }
 
 static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options) {
+    options->extra_options = ModeToString(mode);
     switch (mode) {
         case Dumpstate::BugreportMode::BUGREPORT_FULL:
             options->do_broadcast = true;
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 9bfd710..4811927 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -389,7 +389,7 @@
         auto time_left_ms = [end]() {
             auto now = std::chrono::steady_clock::now();
             auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
-            return std::max(diff.count(), 0ll);
+            return std::max(diff.count(), 0LL);
         };
 
         int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 2e9701f..854244f 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -139,7 +139,16 @@
     srcs: ["otapreopt_chroot.cpp"],
     shared_libs: [
         "libbase",
+        "libjsoncpp",
         "liblog",
+        "libselinux",
+        "libziparchive",
+    ],
+    static_libs: [
+        "libapex",
+        "libapexd",
+        "libavb",
+        "libdm",
     ],
 }
 
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index e90cf3b..a3dfa2d 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 #include <linux/unistd.h>
 #include <sys/mount.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 
 #include <sstream>
@@ -24,6 +25,9 @@
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
+#include <selinux/android.h>
+
+#include <apexd.h>
 
 #include "installd_constants.h"
 #include "otapreopt_utils.h"
@@ -138,6 +142,32 @@
       UNUSED(product_result);
     }
 
+    // Setup APEX mount point and its security context.
+    // The logic here is similar to the one in system/core/rootdir/init.rc:
+    //
+    //   mount tmpfs tmpfs /apex nodev noexec nosuid
+    //   chmod 0755 /apex
+    //   chown root root /apex
+    //   restorecon /apex
+    //
+    if (mount("tmpfs", "/postinstall/apex", "tmpfs", MS_NODEV | MS_NOEXEC | MS_NOSUID, nullptr)
+        != 0) {
+      PLOG(ERROR) << "Failed to mount tmpfs in /postinstall/apex";
+      exit(209);
+    }
+    if (chmod("/postinstall/apex", 0755) != 0) {
+      PLOG(ERROR) << "Failed to chmod /postinstall/apex to 0755";
+      exit(210);
+    }
+    if (chown("/postinstall/apex", 0, 0) != 0) {
+      PLOG(ERROR) << "Failed to chown /postinstall/apex to root:root";
+      exit(211);
+    }
+    if (selinux_android_restorecon("/postinstall/apex", 0) < 0) {
+      PLOG(ERROR) << "Failed to restorecon /postinstall/apex";
+      exit(212);
+    }
+
     // Chdir into /postinstall.
     if (chdir("/postinstall") != 0) {
         PLOG(ERROR) << "Unable to chdir into /postinstall.";
@@ -155,6 +185,18 @@
         exit(205);
     }
 
+    // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
+    // the Android Runtime APEX, as it is required by otapreopt to run dex2oat.
+    {
+      // The logic here is (partially) copied and adapted from
+      // system/apex/apexd/apexd_main.cpp.
+
+      // Only scan the APEX directory under /system (within the chroot dir).
+      // Note that this leaves around the loop devices created and used by
+      // libapexd's code, but this is fine, as we expect to reboot soon after.
+      apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
+    }
+
     // Now go on and run otapreopt.
 
     // Incoming:  cmd + status-fd + target-slot + cmd... + null      | Incoming | = argc + 1
diff --git a/cmds/rss_hwm_reset/Android.bp b/cmds/rss_hwm_reset/Android.bp
new file mode 100644
index 0000000..15f10ef
--- /dev/null
+++ b/cmds/rss_hwm_reset/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_binary {
+    name: "rss_hwm_reset",
+
+    srcs: [
+        "rss_hwm_reset.cc",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+
+    init_rc: ["rss_hwm_reset.rc"],
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.cc b/cmds/rss_hwm_reset/rss_hwm_reset.cc
new file mode 100644
index 0000000..1626e7e
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+  * rss_hwm_reset clears the RSS high-water mark counters for all currently
+  * running processes. It writes "5" to /proc/PID/clear_refs for every PID.
+  *
+  * It runs in its own process becuase dac_override capability is required
+  * in order to write to other processes' clear_refs.
+  *
+  * It is invoked from a system service by flipping sys.rss_hwm_reset.on
+  * property to "1".
+  */
+
+#define LOG_TAG "rss_hwm_reset"
+
+#include <dirent.h>
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+
+namespace {
+// Resets RSS HWM counter for the selected process by writing 5 to
+// /proc/PID/clear_refs.
+void reset_rss_hwm(const char* pid) {
+    std::string clear_refs_path =
+            ::android::base::StringPrintf("/proc/%s/clear_refs", pid);
+    ::android::base::WriteStringToFile("5", clear_refs_path);
+}
+}
+
+// Clears RSS HWM counters for all currently running processes.
+int main(int /* argc */, char** /* argv[] */) {
+    DIR* dirp = opendir("/proc");
+    if (dirp == nullptr) {
+        ALOGE("unable to read /proc");
+        return 1;
+    }
+    struct dirent* entry;
+    while ((entry = readdir(dirp)) != nullptr) {
+        // Skip entries that are not directories.
+        if (entry->d_type != DT_DIR) continue;
+        // Skip entries that do not contain only numbers.
+        const char* pid = entry->d_name;
+        while (*pid) {
+            if (*pid < '0' || *pid > '9') break;
+            pid++;
+        }
+        if (*pid != 0) continue;
+
+        pid = entry->d_name;
+        reset_rss_hwm(pid);
+    }
+    closedir(dirp);
+    return 0;
+}
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.rc b/cmds/rss_hwm_reset/rss_hwm_reset.rc
new file mode 100644
index 0000000..fbbc820
--- /dev/null
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.rc
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+service rss_hwm_reset /system/bin/rss_hwm_reset
+    class late_start
+    disabled
+    oneshot
+    user nobody
+    group nobody readproc
+    writepid /dev/cpuset/system-background/tasks
+    capabilities DAC_OVERRIDE
+
+on property:sys.rss_hwm_reset.on=1
+    start rss_hwm_reset
+    setprop sys.rss_hwm_reset.on 0
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 4d24680..ed9531e 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -110,6 +110,47 @@
 
 #endif /* __ANDROID_API__ >= 23 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated
+ * with Domain Name |dname| on the given |network|.
+ * The typical value for |ns_class| is ns_c_in, while |type| can be any
+ * record type (for instance, ns_t_aaaa or ns_t_txt).
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nquery(net_handle_t network,
+        const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29);
+
+/**
+ * Issue the query |msg| on the given |network|.
+ *
+ * Returns a file descriptor to watch for read events, or a negative
+ * POSIX error code (see errno.h) if an immediate error occurs.
+ */
+int android_res_nsend(net_handle_t network,
+        const unsigned char *msg, int msglen) __INTRODUCED_IN(29);
+
+/**
+ * Read a result for the query associated with the |fd| descriptor.
+ *
+ * Returns:
+ *     < 0: negative POSIX error code (see errno.h for possible values). |rcode| is not set.
+ *     >= 0: length of |answer|. |rcode| is the resolver return code (e.g., ns_r_nxdomain)
+ */
+int android_res_nresult(int fd,
+        int *rcode, unsigned char *answer, int anslen) __INTRODUCED_IN(29);
+
+/**
+ * Attempts to cancel the in-progress query associated with the |nsend_fd|
+ * descriptor.
+ */
+void android_res_cancel(int nsend_fd) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif  // ANDROID_MULTINETWORK_H
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index ab94719..d285030 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -878,6 +878,16 @@
     return writeNullableTypedVector(val, &Parcel::writeInt64);
 }
 
+status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
+{
+    return writeTypedVector(val, &Parcel::writeUint64);
+}
+
+status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
+{
+    return writeNullableTypedVector(val, &Parcel::writeUint64);
+}
+
 status_t Parcel::writeFloatVector(const std::vector<float>& val)
 {
     return writeTypedVector(val, &Parcel::writeFloat);
@@ -1739,6 +1749,14 @@
     return readTypedVector(val, &Parcel::readInt64);
 }
 
+status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
+    return readNullableTypedVector(val, &Parcel::readUint64);
+}
+
+status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
+    return readTypedVector(val, &Parcel::readUint64);
+}
+
 status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
     return readNullableTypedVector(val, &Parcel::readFloat);
 }
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index c9c273a..cd151ee 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -139,6 +139,8 @@
     status_t            writeInt32Vector(const std::vector<int32_t>& val);
     status_t            writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
     status_t            writeInt64Vector(const std::vector<int64_t>& val);
+    status_t            writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val);
+    status_t            writeUint64Vector(const std::vector<uint64_t>& val);
     status_t            writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
     status_t            writeFloatVector(const std::vector<float>& val);
     status_t            writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
@@ -313,6 +315,8 @@
     status_t            readInt32Vector(std::vector<int32_t>* val) const;
     status_t            readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
     status_t            readInt64Vector(std::vector<int64_t>* val) const;
+    status_t            readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const;
+    status_t            readUint64Vector(std::vector<uint64_t>* val) const;
     status_t            readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
     status_t            readFloatVector(std::vector<float>* val) const;
     status_t            readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index d799c5f..1b69dfd 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -23,6 +23,8 @@
         "include_apex",
     ],
 
+    cflags: ["-Wall", "-Wextra", "-Werror"],
+
     srcs: [
         "ibinder.cpp",
         "ibinder_jni.cpp",
@@ -40,6 +42,10 @@
     ],
 
     version_script: "libbinder_ndk.map.txt",
+    stubs: {
+        symbol_file: "libbinder_ndk.map.txt",
+        versions: ["29"],
+    },
 }
 
 ndk_headers {
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 866af70..2258210 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -149,7 +149,49 @@
  * not required to be null-terminated. If the object at index is null, then this should be null.
  */
 typedef const char* (*AParcel_stringArrayElementGetter)(const void* arrayData, size_t index,
-                                                        size_t* outLength);
+                                                        int32_t* outLength);
+
+/**
+ * This is called to allocate an array of size 'length'. If length is -1, then a 'null' array (or
+ * equivalent) should be created.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param arrayData some external representation of an array
+ * \param length the length to allocate this array to
+ *
+ * \return true if allocation succeeded. If length is -1, a true return here means that a 'null'
+ * value (or equivalent) was successfully stored.
+ */
+typedef bool (*AParcel_parcelableArrayAllocator)(void* arrayData, int32_t length);
+
+/**
+ * This is called to parcel the underlying data from an arrayData object at index.
+ *
+ * See also AParcel_writeParcelableArray
+ *
+ * \param parcel parcel to write the parcelable to
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be retrieved.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_writeParcelableElement)(AParcel* parcel, const void* arrayData,
+                                                          size_t index);
+
+/**
+ * This is called to set an underlying value in an arrayData object at index.
+ *
+ * See also AParcel_readParcelableArray
+ *
+ * \param parcel parcel to read the parcelable from
+ * \param arrayData some external representation of an array of parcelables (a user-defined type).
+ * \param index the index of the value to be set.
+ *
+ * \return status (usually returned from other parceling functions). STATUS_OK for success.
+ */
+typedef binder_status_t (*AParcel_readParcelableElement)(const AParcel* parcel, void* arrayData,
+                                                         size_t index);
 
 // @START-PRIMITIVE-VECTOR-GETTERS
 /**
@@ -497,6 +539,40 @@
                                         AParcel_stringArrayElementAllocator elementAllocator)
         __INTRODUCED_IN(29);
 
+/**
+ * Writes an array of parcelables (user-defined types) to the next location in a non-null parcel.
+ *
+ * \param parcel the parcel to write to.
+ * \param arrayData an array of size 'length' (or null if length is -1, may be null if length is 0).
+ * \param length the length of arrayData or -1 if this represents a null array.
+ * \param elementWriter function to be called for every array index to write the user-defined type
+ * at that location.
+ *
+ * \return STATUS_OK on successful write.
+ */
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+                                             AParcel_writeParcelableElement elementWriter)
+        __INTRODUCED_IN(29);
+
+/**
+ * Reads an array of parcelables (user-defined types) from the next location in a non-null parcel.
+ *
+ * First, allocator will be called with the length of the array. If the allocation succeeds and the
+ * length is greater than zero, elementReader will be called for every index to read the
+ * corresponding parcelable.
+ *
+ * \param parcel the parcel to read from.
+ * \param arrayData some external representation of an array.
+ * \param allocator the callback that will be called to allocate the array.
+ * \param elementReader the callback that will be called to fill out individual elements.
+ *
+ * \return STATUS_OK on successful read.
+ */
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+                                            AParcel_parcelableArrayAllocator allocator,
+                                            AParcel_readParcelableElement elementReader)
+        __INTRODUCED_IN(29);
+
 // @START-PRIMITIVE-READ-WRITE
 /**
  * Writes int32_t value to the next location in a non-null parcel.
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 f99c3a9..fcdf7af 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -299,7 +299,7 @@
  * index.
  */
 static inline const char* AParcel_stdVectorStringElementGetter(const void* vectorData, size_t index,
-                                                               size_t* outLength) {
+                                                               int32_t* outLength) {
     const std::vector<std::string>* vec = static_cast<const std::vector<std::string>*>(vectorData);
     const std::string& element = vec->at(index);
 
@@ -327,7 +327,7 @@
  */
 static inline const char* AParcel_nullableStdVectorStringElementGetter(const void* vectorData,
                                                                        size_t index,
-                                                                       size_t* outLength) {
+                                                                       int32_t* outLength) {
     const std::optional<std::vector<std::optional<std::string>>>* vec =
             static_cast<const std::optional<std::vector<std::optional<std::string>>>*>(vectorData);
     const std::optional<std::string>& element = vec->value().at(index);
@@ -420,6 +420,46 @@
             AParcel_nullableStdVectorStringElementAllocator);
 }
 
+/**
+ * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_writeStdVectorParcelableElement(AParcel* parcel, const void* vectorData,
+                                                        size_t index) {
+    const std::vector<P>* vector = static_cast<const std::vector<P>*>(vectorData);
+    return vector->at(index).writeToParcel(parcel);
+}
+
+/**
+ * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_readStdVectorParcelableElement(const AParcel* parcel, void* vectorData,
+                                                       size_t index) {
+    std::vector<P>* vector = static_cast<std::vector<P>*>(vectorData);
+    return vector->at(index).readFromParcel(parcel);
+}
+
+/**
+ * Convenience API for writing a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<P>& vec) {
+    const void* vectorData = static_cast<const void*>(&vec);
+    return AParcel_writeParcelableArray(parcel, vectorData, vec.size(),
+                                        AParcel_writeStdVectorParcelableElement<P>);
+}
+
+/**
+ * Convenience API for reading a std::vector<P>
+ */
+template <typename P>
+static inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<P>* vec) {
+    void* vectorData = static_cast<void*>(vec);
+    return AParcel_readParcelableArray(parcel, vectorData, AParcel_stdVectorExternalAllocator<P>,
+                                       AParcel_readStdVectorParcelableElement<P>);
+}
+
 // @START
 /**
  * Writes a vector of int32_t to the next location in a non-null parcel.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 4328b6e..ee7132f 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -40,6 +40,7 @@
     AParcel_readInt32Array;
     AParcel_readInt64;
     AParcel_readInt64Array;
+    AParcel_readParcelableArray;
     AParcel_readParcelFileDescriptor;
     AParcel_readStatusHeader;
     AParcel_readString;
@@ -64,6 +65,7 @@
     AParcel_writeInt32Array;
     AParcel_writeInt64;
     AParcel_writeInt64Array;
+    AParcel_writeParcelableArray;
     AParcel_writeParcelFileDescriptor;
     AParcel_writeStatusHeader;
     AParcel_writeString;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 2d68559..ae2276e 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -173,7 +173,7 @@
 
     Parcel* rawParcel = parcel->get();
 
-    for (size_t i = 0; i < length; i++) {
+    for (int32_t i = 0; i < length; i++) {
         status = (rawParcel->*write)(getter(arrayData, i));
 
         if (status != STATUS_OK) return PruneStatusT(status);
@@ -197,7 +197,7 @@
 
     if (length <= 0) return STATUS_OK;
 
-    for (size_t i = 0; i < length; i++) {
+    for (int32_t i = 0; i < length; i++) {
         T readTarget;
         status = (rawParcel->*read)(&readTarget);
         if (status != STATUS_OK) return PruneStatusT(status);
@@ -376,12 +376,12 @@
     if (status != STATUS_OK) return status;
     if (length <= 0) return STATUS_OK;
 
-    for (size_t i = 0; i < length; i++) {
-        size_t length = 0;
-        const char* str = getter(arrayData, i, &length);
-        if (str == nullptr && length != -1) return STATUS_BAD_VALUE;
+    for (int32_t i = 0; i < length; i++) {
+        int32_t elementLength = 0;
+        const char* str = getter(arrayData, i, &elementLength);
+        if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
 
-        binder_status_t status = AParcel_writeString(parcel, str, length);
+        binder_status_t status = AParcel_writeString(parcel, str, elementLength);
         if (status != STATUS_OK) return status;
     }
 
@@ -392,7 +392,7 @@
 // allocator.
 struct StringArrayElementAllocationAdapter {
     void* arrayData;  // stringData from the NDK
-    size_t index;     // index into the string array
+    int32_t index;    // index into the string array
     AParcel_stringArrayElementAllocator elementAllocator;
 
     static bool Allocator(void* stringData, int32_t length, char** buffer) {
@@ -433,6 +433,45 @@
     return STATUS_OK;
 }
 
+binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
+                                             AParcel_writeParcelableElement elementWriter) {
+    // we have no clue if arrayData represents a null object or not, we can only infer from length
+    bool arrayIsNull = length < 0;
+    binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
+    if (status != STATUS_OK) return status;
+    if (length <= 0) return STATUS_OK;
+
+    for (int32_t i = 0; i < length; i++) {
+        binder_status_t status = elementWriter(parcel, arrayData, i);
+        if (status != STATUS_OK) return status;
+    }
+
+    return STATUS_OK;
+}
+
+binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
+                                            AParcel_parcelableArrayAllocator allocator,
+                                            AParcel_readParcelableElement elementReader) {
+    const Parcel* rawParcel = parcel->get();
+
+    int32_t length;
+    status_t status = rawParcel->readInt32(&length);
+
+    if (status != STATUS_OK) return PruneStatusT(status);
+    if (length < -1) return STATUS_BAD_VALUE;
+
+    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
+
+    if (length == -1) return STATUS_OK;  // null array
+
+    for (int32_t i = 0; i < length; i++) {
+        binder_status_t status = elementReader(parcel, arrayData, i);
+        if (status != STATUS_OK) return status;
+    }
+
+    return STATUS_OK;
+}
+
 // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
 // libbinder and this library.
 // @START
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index cd37d49..f23ed5d 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -72,6 +72,7 @@
     BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
     BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
     BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
+    BINDER_LIB_TEST_ECHO_VECTOR,
 };
 
 pid_t start_server_process(int arg2, bool usePoll = false)
@@ -1060,6 +1061,21 @@
     EXPECT_EQ(NO_ERROR, ret2);
 }
 
+TEST_F(BinderLibTest, VectorSent) {
+    Parcel data, reply;
+    sp<IBinder> server = addServer();
+    ASSERT_TRUE(server != nullptr);
+
+    std::vector<uint64_t> const testValue = { std::numeric_limits<uint64_t>::max(), 0, 200 };
+    data.writeUint64Vector(testValue);
+
+    status_t ret = server->transact(BINDER_LIB_TEST_ECHO_VECTOR, data, &reply);
+    EXPECT_EQ(NO_ERROR, ret);
+    std::vector<uint64_t> readValue;
+    ret = reply.readUint64Vector(&readValue);
+    EXPECT_EQ(readValue, testValue);
+}
+
 class BinderLibTestService : public BBinder
 {
     public:
@@ -1363,6 +1379,14 @@
                 reply->writeInt32(IPCThreadState::self()->getCallingWorkSourceUid());
                 return NO_ERROR;
             }
+            case BINDER_LIB_TEST_ECHO_VECTOR: {
+                std::vector<uint64_t> vector;
+                auto err = data.readUint64Vector(&vector);
+                if (err != NO_ERROR)
+                    return err;
+                reply->writeUint64Vector(vector);
+                return NO_ERROR;
+            }
             default:
                 return UNKNOWN_TRANSACTION;
             };
diff --git a/libs/binder/tests/binderValueTypeTest.cpp b/libs/binder/tests/binderValueTypeTest.cpp
index 15949d4..f8922b0 100644
--- a/libs/binder/tests/binderValueTypeTest.cpp
+++ b/libs/binder/tests/binderValueTypeTest.cpp
@@ -75,13 +75,13 @@
 
 VALUE_TYPE_TEST(bool, Boolean, true)
 VALUE_TYPE_TEST(int32_t, Int, 31337)
-VALUE_TYPE_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_TEST(int64_t, Long, 13370133701337L)
 VALUE_TYPE_TEST(double, Double, 3.14159265358979323846)
 VALUE_TYPE_TEST(String16, String, String16("Lovely"))
 
 VALUE_TYPE_VECTOR_TEST(bool, Boolean, true)
 VALUE_TYPE_VECTOR_TEST(int32_t, Int, 31337)
-VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337l)
+VALUE_TYPE_VECTOR_TEST(int64_t, Long, 13370133701337L)
 VALUE_TYPE_VECTOR_TEST(double, Double, 3.14159265358979323846)
 VALUE_TYPE_VECTOR_TEST(String16, String, String16("Lovely"))
 
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
index ed773e0..16952a6 100644
--- a/libs/gui/BufferHubProducer.cpp
+++ b/libs/gui/BufferHubProducer.cpp
@@ -520,7 +520,7 @@
     }
 
     auto buffer_producer = buffers_[slot].mBufferProducer;
-    queue_->Enqueue(buffer_producer, size_t(slot), 0ULL);
+    queue_->Enqueue(buffer_producer, size_t(slot), 0U);
     buffers_[slot].mBufferState.cancel();
     buffers_[slot].mFence = fence;
     ALOGV("cancelBuffer: slot %d", slot);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index f1fefcc..2d6be26 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -675,23 +675,19 @@
             return result;
         }
 
-        result = reply.readInt64Vector(
-                reinterpret_cast<std::vector<int64_t>*>(&outStats->component_0_sample));
+        result = reply.readUint64Vector(&outStats->component_0_sample);
         if (result != NO_ERROR) {
             return result;
         }
-        result = reply.readInt64Vector(
-                reinterpret_cast<std::vector<int64_t>*>(&outStats->component_1_sample));
+        result = reply.readUint64Vector(&outStats->component_1_sample);
         if (result != NO_ERROR) {
             return result;
         }
-        result = reply.readInt64Vector(
-                reinterpret_cast<std::vector<int64_t>*>(&outStats->component_2_sample));
+        result = reply.readUint64Vector(&outStats->component_2_sample);
         if (result != NO_ERROR) {
             return result;
         }
-        result = reply.readInt64Vector(
-                reinterpret_cast<std::vector<int64_t>*>(&outStats->component_3_sample));
+        result = reply.readUint64Vector(&outStats->component_3_sample);
         return result;
     }
 };
@@ -1033,7 +1029,7 @@
                 reply->writeInt32(static_cast<int32_t>(defaultDataspace));
                 reply->writeInt32(static_cast<int32_t>(defaultPixelFormat));
                 reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace));
-                reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace));
+                reply->writeInt32(static_cast<int32_t>(wideColorGamutPixelFormat));
             }
             return NO_ERROR;
         }
@@ -1121,14 +1117,10 @@
             result = getDisplayedContentSample(display, maxFrames, timestamp, &stats);
             if (result == NO_ERROR) {
                 reply->writeUint64(stats.numFrames);
-                reply->writeInt64Vector(
-                        *reinterpret_cast<std::vector<int64_t>*>(&stats.component_0_sample));
-                reply->writeInt64Vector(
-                        *reinterpret_cast<std::vector<int64_t>*>(&stats.component_1_sample));
-                reply->writeInt64Vector(
-                        *reinterpret_cast<std::vector<int64_t>*>(&stats.component_2_sample));
-                reply->writeInt64Vector(
-                        *reinterpret_cast<std::vector<int64_t>*>(&stats.component_3_sample));
+                reply->writeUint64Vector(stats.component_0_sample);
+                reply->writeUint64Vector(stats.component_1_sample);
+                reply->writeUint64Vector(stats.component_2_sample);
+                reply->writeUint64Vector(stats.component_3_sample);
             }
             return result;
         }
diff --git a/libs/sensorprivacy/Android.bp b/libs/sensorprivacy/Android.bp
new file mode 100644
index 0000000..e0e3469
--- /dev/null
+++ b/libs/sensorprivacy/Android.bp
@@ -0,0 +1,47 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_shared {
+    name: "libsensorprivacy",
+
+    aidl: {
+        export_aidl_headers: true,
+        local_include_dirs: ["aidl"],
+    },
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wzero-as-null-pointer-constant",
+    ],
+
+    srcs: [
+        "aidl/android/hardware/ISensorPrivacyListener.aidl",
+        "aidl/android/hardware/ISensorPrivacyManager.aidl",
+        "SensorPrivacyManager.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "libutils",
+        "liblog",
+        "libhardware",
+    ],
+
+    export_include_dirs: ["include"],
+
+    export_shared_lib_headers: ["libbinder"],
+}
diff --git a/libs/sensorprivacy/SensorPrivacyManager.cpp b/libs/sensorprivacy/SensorPrivacyManager.cpp
new file mode 100644
index 0000000..1da79a0
--- /dev/null
+++ b/libs/sensorprivacy/SensorPrivacyManager.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mutex>
+#include <unistd.h>
+
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
+
+#include <utils/SystemClock.h>
+
+namespace android {
+
+SensorPrivacyManager::SensorPrivacyManager()
+{
+}
+
+sp<hardware::ISensorPrivacyManager> SensorPrivacyManager::getService()
+{
+    std::lock_guard<Mutex> scoped_lock(mLock);
+    int64_t startTime = 0;
+    sp<hardware::ISensorPrivacyManager> service = mService;
+    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
+        sp<IBinder> binder = defaultServiceManager()->checkService(String16("sensor_privacy"));
+        if (binder == nullptr) {
+            // Wait for the sensor privacy service to come back...
+            if (startTime == 0) {
+                startTime = uptimeMillis();
+                ALOGI("Waiting for sensor privacy service");
+            } else if ((uptimeMillis() - startTime) > 1000000) {
+                ALOGW("Waiting too long for sensor privacy service, giving up");
+                service = nullptr;
+                break;
+            }
+            usleep(25000);
+        } else {
+            service = interface_cast<hardware::ISensorPrivacyManager>(binder);
+            mService = service;
+        }
+    }
+    return service;
+}
+
+void SensorPrivacyManager::addSensorPrivacyListener(
+        const sp<hardware::ISensorPrivacyListener>& listener)
+{
+    sp<hardware::ISensorPrivacyManager> service = getService();
+    if (service != nullptr) {
+        service->addSensorPrivacyListener(listener);
+    }
+}
+
+void SensorPrivacyManager::removeSensorPrivacyListener(
+        const sp<hardware::ISensorPrivacyListener>& listener)
+{
+    sp<hardware::ISensorPrivacyManager> service = getService();
+    if (service != nullptr) {
+        service->removeSensorPrivacyListener(listener);
+    }
+}
+
+bool SensorPrivacyManager::isSensorPrivacyEnabled()
+{
+    sp<hardware::ISensorPrivacyManager> service = getService();
+    if (service != nullptr) {
+        bool result;
+        service->isSensorPrivacyEnabled(&result);
+        return result;
+    }
+    // if the SensorPrivacyManager is not available then assume sensor privacy is disabled
+    return false;
+}
+
+}; // namespace android
diff --git a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl
new file mode 100644
index 0000000..58177d8
--- /dev/null
+++ b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyListener.aidl
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+/**
+ * @hide
+ */
+oneway interface ISensorPrivacyListener {
+    void onSensorPrivacyChanged(boolean enabled);
+}
diff --git a/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl
new file mode 100644
index 0000000..4c2d5db
--- /dev/null
+++ b/libs/sensorprivacy/aidl/android/hardware/ISensorPrivacyManager.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.hardware.ISensorPrivacyListener;
+
+/** @hide */
+interface ISensorPrivacyManager {
+    void addSensorPrivacyListener(in ISensorPrivacyListener listener);
+
+    void removeSensorPrivacyListener(in ISensorPrivacyListener listener);
+
+    boolean isSensorPrivacyEnabled();
+
+    void setSensorPrivacy(boolean enable);
+}
diff --git a/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
new file mode 100644
index 0000000..8826595
--- /dev/null
+++ b/libs/sensorprivacy/include/sensorprivacy/SensorPrivacyManager.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSOR_PRIVACY_MANAGER_H
+#define ANDROID_SENSOR_PRIVACY_MANAGER_H
+
+#include "android/hardware/ISensorPrivacyListener.h"
+#include "android/hardware/ISensorPrivacyManager.h"
+
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class SensorPrivacyManager
+{
+public:
+    SensorPrivacyManager();
+
+    void addSensorPrivacyListener(const sp<hardware::ISensorPrivacyListener>& listener);
+    void removeSensorPrivacyListener(const sp<hardware::ISensorPrivacyListener>& listener);
+    bool isSensorPrivacyEnabled();
+
+private:
+    Mutex mLock;
+    sp<hardware::ISensorPrivacyManager> mService;
+    sp<hardware::ISensorPrivacyManager> getService();
+};
+
+
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SENSOR_PRIVACY_MANAGER_H
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 3816c1b..5bc113f 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -40,6 +40,7 @@
 
 #include <android-base/unique_fd.h>
 #include <ui/BufferHubBuffer.h>
+#include <ui/BufferHubDefs.h>
 
 using android::base::unique_fd;
 using android::dvr::BufferTraits;
@@ -61,15 +62,14 @@
 // to use Binder.
 static constexpr char kBufferHubClientPath[] = "system/buffer_hub/client";
 
-using dvr::BufferHubDefs::AnyClientAcquired;
-using dvr::BufferHubDefs::AnyClientGained;
-using dvr::BufferHubDefs::AnyClientPosted;
-using dvr::BufferHubDefs::IsClientAcquired;
-using dvr::BufferHubDefs::IsClientGained;
-using dvr::BufferHubDefs::IsClientPosted;
-using dvr::BufferHubDefs::IsClientReleased;
-using dvr::BufferHubDefs::kHighBitsMask;
-using dvr::BufferHubDefs::kMetadataHeaderSize;
+using BufferHubDefs::AnyClientAcquired;
+using BufferHubDefs::AnyClientGained;
+using BufferHubDefs::AnyClientPosted;
+using BufferHubDefs::IsClientAcquired;
+using BufferHubDefs::IsClientGained;
+using BufferHubDefs::IsClientPosted;
+using BufferHubDefs::IsClientReleased;
+using BufferHubDefs::kHighBitsMask;
 
 } // namespace
 
@@ -161,7 +161,7 @@
     }
 
     size_t metadataSize = static_cast<size_t>(bufferTraits.metadata_size());
-    if (metadataSize < kMetadataHeaderSize) {
+    if (metadataSize < BufferHubDefs::kMetadataHeaderSize) {
         ALOGE("BufferHubBuffer::ImportGraphicBuffer: metadata too small: %zu", metadataSize);
         return -EINVAL;
     }
@@ -191,22 +191,22 @@
     mClientStateMask = bufferTraits.client_state_mask();
 
     // TODO(b/112012161) Set up shared fences.
-    ALOGD("BufferHubBuffer::ImportGraphicBuffer: id=%d, buffer_state=%" PRIx64 ".", id(),
+    ALOGD("BufferHubBuffer::ImportGraphicBuffer: id=%d, buffer_state=%" PRIx32 ".", id(),
           buffer_state_->load(std::memory_order_acquire));
     return 0;
 }
 
 int BufferHubBuffer::Gain() {
-    uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
     if (IsClientGained(current_buffer_state, mClientStateMask)) {
-        ALOGV("%s: Buffer is already gained by this client %" PRIx64 ".", __FUNCTION__,
+        ALOGV("%s: Buffer is already gained by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
     do {
         if (AnyClientGained(current_buffer_state & (~mClientStateMask)) ||
             AnyClientAcquired(current_buffer_state)) {
-            ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+            ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
                   __FUNCTION__, mId, mClientStateMask, current_buffer_state);
             return -EBUSY;
         }
@@ -220,13 +220,13 @@
 }
 
 int BufferHubBuffer::Post() {
-    uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    uint64_t current_active_clients_bit_mask = 0ULL;
-    uint64_t updated_buffer_state = 0ULL;
+    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+    uint32_t current_active_clients_bit_mask = 0U;
+    uint32_t updated_buffer_state = 0U;
     do {
         if (!IsClientGained(current_buffer_state, mClientStateMask)) {
             ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
-                  "mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+                  "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
                   __FUNCTION__, mId, mClientStateMask, current_buffer_state);
             return -EBUSY;
         }
@@ -242,17 +242,17 @@
 }
 
 int BufferHubBuffer::Acquire() {
-    uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
     if (IsClientAcquired(current_buffer_state, mClientStateMask)) {
-        ALOGV("%s: Buffer is already acquired by this client %" PRIx64 ".", __FUNCTION__,
+        ALOGV("%s: Buffer is already acquired by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
-    uint64_t updated_buffer_state = 0ULL;
+    uint32_t updated_buffer_state = 0U;
     do {
         if (!IsClientPosted(current_buffer_state, mClientStateMask)) {
             ALOGE("%s: Cannot acquire a buffer that is not in posted state. buffer_id=%d "
-                  "mClientStateMask=%" PRIx64 " state=%" PRIx64 ".",
+                  "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
                   __FUNCTION__, mId, mClientStateMask, current_buffer_state);
             return -EBUSY;
         }
@@ -266,13 +266,13 @@
 }
 
 int BufferHubBuffer::Release() {
-    uint64_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
+    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
     if (IsClientReleased(current_buffer_state, mClientStateMask)) {
-        ALOGV("%s: Buffer is already released by this client %" PRIx64 ".", __FUNCTION__,
+        ALOGV("%s: Buffer is already released by this client %" PRIx32 ".", __FUNCTION__,
               mClientStateMask);
         return 0;
     }
-    uint64_t updated_buffer_state = 0ULL;
+    uint32_t updated_buffer_state = 0U;
     do {
         updated_buffer_state = current_buffer_state & (~mClientStateMask);
     } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
diff --git a/libs/ui/BufferHubMetadata.cpp b/libs/ui/BufferHubMetadata.cpp
index 18d9a2c..816707d 100644
--- a/libs/ui/BufferHubMetadata.cpp
+++ b/libs/ui/BufferHubMetadata.cpp
@@ -16,6 +16,7 @@
 
 #include <errno.h>
 #include <sys/mman.h>
+#include <limits>
 
 #include <cutils/ashmem.h>
 #include <log/log.h>
@@ -29,8 +30,8 @@
 
 } // namespace
 
-using dvr::BufferHubDefs::kMetadataHeaderSize;
-using dvr::BufferHubDefs::MetadataHeader;
+using BufferHubDefs::kMetadataHeaderSize;
+using BufferHubDefs::MetadataHeader;
 
 /* static */
 BufferHubMetadata BufferHubMetadata::Create(size_t userMetadataSize) {
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index e606e26..f408fcb 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -104,6 +104,7 @@
                                 buffer->desc().width, buffer->desc().height,
                                 static_cast<PixelFormat>(buffer->desc().format),
                                 buffer->desc().layers, buffer->desc().usage, buffer->desc().stride);
+    mBufferId = buffer->id();
     mBufferHubBuffer = std::move(buffer);
 }
 #endif // LIBUI_IN_VNDK
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 03d10e7..90dd391 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -34,11 +34,11 @@
 #pragma clang diagnostic ignored "-Wunused-template"
 #pragma clang diagnostic ignored "-Wweak-vtables"
 #include <pdx/client.h>
-#include <private/dvr/buffer_hub_defs.h>
 #include <private/dvr/native_handle_wrapper.h>
 #pragma clang diagnostic pop
 
 #include <android/hardware_buffer.h>
+#include <ui/BufferHubDefs.h>
 #include <ui/BufferHubMetadata.h>
 
 namespace android {
@@ -86,13 +86,13 @@
     const native_handle_t* DuplicateHandle() { return mBufferHandle.DuplicateHandle(); }
 
     // Returns the current value of MetadataHeader::buffer_state.
-    uint64_t buffer_state() {
+    uint32_t buffer_state() {
         return mMetadata.metadata_header()->buffer_state.load(std::memory_order_acquire);
     }
 
     // A state mask which is unique to a buffer hub client among all its siblings sharing the same
     // concrete graphic buffer.
-    uint64_t client_state_mask() const { return mClientStateMask; }
+    uint32_t client_state_mask() const { return mClientStateMask; }
 
     size_t user_metadata_size() const { return mMetadata.user_metadata_size(); }
 
@@ -154,7 +154,7 @@
 
     // Client state mask of this BufferHubBuffer object. It is unique amoung all
     // clients/users of the buffer.
-    uint64_t mClientStateMask = 0;
+    uint32_t mClientStateMask = 0U;
 
     // Stores ground truth of the buffer.
     AHardwareBuffer_Desc mBufferDesc;
@@ -166,9 +166,9 @@
     // bufferhubd daemon and all buffer clients.
     BufferHubMetadata mMetadata;
     // Shortcuts to the atomics inside the header of mMetadata.
-    std::atomic<uint64_t>* buffer_state_{nullptr};
-    std::atomic<uint64_t>* fence_state_{nullptr};
-    std::atomic<uint64_t>* active_clients_bit_mask_{nullptr};
+    std::atomic<uint32_t>* buffer_state_ = nullptr;
+    std::atomic<uint32_t>* fence_state_ = nullptr;
+    std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
 
     // PDX backend.
     BufferHubClient mClient;
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
new file mode 100644
index 0000000..d259fef
--- /dev/null
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BUFFER_HUB_DEFS_H_
+#define ANDROID_BUFFER_HUB_DEFS_H_
+
+#include <atomic>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpacked"
+// TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr
+#include <dvr/dvr_api.h>
+#pragma clang diagnostic pop
+
+namespace android {
+
+namespace BufferHubDefs {
+
+// Single buffer clients (up to 16) ownership signal.
+// 32-bit atomic unsigned int.
+// Each client takes 2 bits. The first bit locates in the first 16 bits of
+// buffer_state; the second bit locates in the last 16 bits of buffer_state.
+// Client states:
+// Gained state 11. Exclusive write state.
+// Posted state 10.
+// Acquired state 01. Shared read state.
+// Released state 00.
+//
+//  MSB                        LSB
+//   |                          |
+//   v                          v
+// [C15|...|C1|C0|C15| ... |C1|C0]
+
+// Maximum number of clients a buffer can have.
+static constexpr int kMaxNumberOfClients = 16;
+
+// Definition of bit masks.
+//  MSB                            LSB
+//   | kHighBitsMask | kLowbitsMask |
+//   v               v              v
+// [b31|   ...   |b16|b15|   ...  |b0]
+
+// The location of lower 16 bits in the 32-bit buffer state.
+static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U;
+
+// The location of higher 16 bits in the 32-bit buffer state.
+static constexpr uint32_t kHighBitsMask = ~kLowbitsMask;
+
+// The client bit mask of the first client.
+static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
+
+// Returns true if any of the client is in gained state.
+static inline bool AnyClientGained(uint32_t state) {
+    uint32_t high_bits = state >> kMaxNumberOfClients;
+    uint32_t low_bits = state & kLowbitsMask;
+    return high_bits == low_bits && low_bits != 0U;
+}
+
+// Returns true if the input client is in gained state.
+static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
+    return state == client_bit_mask;
+}
+
+// Returns true if any of the client is in posted state.
+static inline bool AnyClientPosted(uint32_t state) {
+    uint32_t high_bits = state >> kMaxNumberOfClients;
+    uint32_t low_bits = state & kLowbitsMask;
+    uint32_t posted_or_acquired = high_bits ^ low_bits;
+    return posted_or_acquired & high_bits;
+}
+
+// Returns true if the input client is in posted state.
+static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
+    uint32_t client_bits = state & client_bit_mask;
+    if (client_bits == 0U) return false;
+    uint32_t low_bits = client_bits & kLowbitsMask;
+    return low_bits == 0U;
+}
+
+// Return true if any of the client is in acquired state.
+static inline bool AnyClientAcquired(uint32_t state) {
+    uint32_t high_bits = state >> kMaxNumberOfClients;
+    uint32_t low_bits = state & kLowbitsMask;
+    uint32_t posted_or_acquired = high_bits ^ low_bits;
+    return posted_or_acquired & low_bits;
+}
+
+// Return true if the input client is in acquired state.
+static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
+    uint32_t client_bits = state & client_bit_mask;
+    if (client_bits == 0U) return false;
+    uint32_t high_bits = client_bits & kHighBitsMask;
+    return high_bits == 0U;
+}
+
+// Returns true if all clients are in released state.
+static inline bool IsBufferReleased(uint32_t state) {
+    return state == 0U;
+}
+
+// Returns true if the input client is in released state.
+static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
+    return (state & client_bit_mask) == 0U;
+}
+
+// Returns the next available buffer client's client_state_masks.
+// @params union_bits. Union of all existing clients' client_state_masks.
+static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
+    uint32_t low_union = union_bits & kLowbitsMask;
+    if (low_union == kLowbitsMask) return 0U;
+    uint32_t incremented = low_union + 1U;
+    uint32_t difference = incremented ^ low_union;
+    uint32_t new_low_bit = (difference + 1U) >> 1;
+    return new_low_bit + (new_low_bit << kMaxNumberOfClients);
+}
+
+struct __attribute__((aligned(8))) MetadataHeader {
+    // Internal data format, which can be updated as long as the size, padding and field alignment
+    // of the struct is consistent within the same ABI. As this part is subject for future updates,
+    // it's not stable cross Android version, so don't have it visible from outside of the Android
+    // platform (include Apps and vendor HAL).
+
+    // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
+    // buffer_state.
+    std::atomic<uint32_t> buffer_state;
+
+    // Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32
+    // bits are there for easier manipulation, but the value should be ignored.
+    std::atomic<uint32_t> fence_state;
+
+    // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
+    // active_clients_bit_mask.
+    std::atomic<uint32_t> active_clients_bit_mask;
+
+    // Explicit padding 4 bytes.
+    uint32_t padding;
+
+    // The index of the buffer queue where the buffer belongs to.
+    uint64_t queue_index;
+
+    // Public data format, which should be updated with caution. See more details in dvr_api.h
+    DvrNativeBufferMetadata metadata;
+};
+
+static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
+static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
+
+} // namespace BufferHubDefs
+
+} // namespace android
+
+#endif // ANDROID_BUFFER_HUB_DEFS_H_
diff --git a/libs/ui/include/ui/BufferHubMetadata.h b/libs/ui/include/ui/BufferHubMetadata.h
index 4261971..2121894 100644
--- a/libs/ui/include/ui/BufferHubMetadata.h
+++ b/libs/ui/include/ui/BufferHubMetadata.h
@@ -17,26 +17,8 @@
 #ifndef ANDROID_BUFFER_HUB_METADATA_H_
 #define ANDROID_BUFFER_HUB_METADATA_H_
 
-// We would eliminate the clang warnings introduced by libdpx.
-// TODO(b/112338294): Remove those once BufferHub moved to use Binder
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-#pragma clang diagnostic ignored "-Wdouble-promotion"
-#pragma clang diagnostic ignored "-Wgnu-case-range"
-#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
-#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
-#pragma clang diagnostic ignored "-Wnested-anon-types"
-#pragma clang diagnostic ignored "-Wpacked"
-#pragma clang diagnostic ignored "-Wshadow"
-#pragma clang diagnostic ignored "-Wsign-conversion"
-#pragma clang diagnostic ignored "-Wswitch-enum"
-#pragma clang diagnostic ignored "-Wundefined-func-template"
-#pragma clang diagnostic ignored "-Wunused-template"
-#pragma clang diagnostic ignored "-Wweak-vtables"
-#include <private/dvr/buffer_hub_defs.h>
-#pragma clang diagnostic pop
-
 #include <android-base/unique_fd.h>
+#include <ui/BufferHubDefs.h>
 
 namespace android {
 
@@ -84,23 +66,21 @@
     bool IsValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; }
 
     size_t user_metadata_size() const { return mUserMetadataSize; }
-    size_t metadata_size() const {
-        return mUserMetadataSize + dvr::BufferHubDefs::kMetadataHeaderSize;
-    }
+    size_t metadata_size() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; }
 
     const unique_fd& ashmem_fd() const { return mAshmemFd; }
-    dvr::BufferHubDefs::MetadataHeader* metadata_header() { return mMetadataHeader; }
+    BufferHubDefs::MetadataHeader* metadata_header() { return mMetadataHeader; }
 
 private:
     BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd,
-                      dvr::BufferHubDefs::MetadataHeader* metadataHeader);
+                      BufferHubDefs::MetadataHeader* metadataHeader);
 
     BufferHubMetadata(const BufferHubMetadata&) = delete;
     void operator=(const BufferHubMetadata&) = delete;
 
     size_t mUserMetadataSize = 0;
     unique_fd mAshmemFd;
-    dvr::BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr;
+    BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr;
 };
 
 } // namespace android
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index 81f6cd9..b73ca2b 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -153,6 +153,7 @@
     uint32_t getLayerCount() const      { return static_cast<uint32_t>(layerCount); }
     Rect getBounds() const              { return Rect(width, height); }
     uint64_t getId() const              { return mId; }
+    int32_t getBufferId() const { return mBufferId; }
 
     uint32_t getGenerationNumber() const { return mGenerationNumber; }
     void setGenerationNumber(uint32_t generation) {
@@ -247,6 +248,12 @@
 
     uint64_t mId;
 
+    // System unique buffer ID. Note that this is different from mId, which is process unique. For
+    // GraphicBuffer backed by BufferHub, the mBufferId is a system unique identifier that stays the
+    // same cross process for the same chunck of underlying memory. Also note that this only applies
+    // to GraphicBuffers that are backed by BufferHub.
+    int32_t mBufferId = -1;
+
     // Stores the generation number of this buffer. If this number does not
     // match the BufferQueue's internal generation number (set through
     // IGBP::setGenerationNumber), attempts to attach the buffer will fail.
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 18bbb3e..a670b3c 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -45,7 +45,7 @@
 }
 
 cc_test {
-    name: "BufferHubBuffer_test",
+    name: "BufferHub_test",
     header_libs: [
         "libbufferhub_headers",
         "libdvr_headers",
@@ -67,19 +67,7 @@
     srcs: [
         "BufferHubBuffer_test.cpp",
         "BufferHubEventFd_test.cpp",
+        "BufferHubMetadata_test.cpp",
     ],
     cflags: ["-Wall", "-Werror"],
 }
-
-cc_test {
-    name: "BufferHubMetadata_test",
-    header_libs: ["libbufferhub_headers", "libdvr_headers"],
-    shared_libs: [
-        "libbase",
-        "libpdx_default_transport",
-        "libui",
-        "libutils",
-    ],
-    srcs: ["BufferHubMetadata_test.cpp"],
-    cflags: ["-Wall", "-Werror"],
-}
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index e33acf6..a894f20 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -36,16 +36,16 @@
 const int kUsage = 0;
 const size_t kUserMetadataSize = 0;
 
-using dvr::BufferHubDefs::AnyClientAcquired;
-using dvr::BufferHubDefs::AnyClientGained;
-using dvr::BufferHubDefs::AnyClientPosted;
-using dvr::BufferHubDefs::IsBufferReleased;
-using dvr::BufferHubDefs::IsClientAcquired;
-using dvr::BufferHubDefs::IsClientGained;
-using dvr::BufferHubDefs::IsClientPosted;
-using dvr::BufferHubDefs::IsClientReleased;
-using dvr::BufferHubDefs::kFirstClientBitMask;
-using dvr::BufferHubDefs::kMetadataHeaderSize;
+using BufferHubDefs::AnyClientAcquired;
+using BufferHubDefs::AnyClientGained;
+using BufferHubDefs::AnyClientPosted;
+using BufferHubDefs::IsBufferReleased;
+using BufferHubDefs::IsClientAcquired;
+using BufferHubDefs::IsClientGained;
+using BufferHubDefs::IsClientPosted;
+using BufferHubDefs::IsClientReleased;
+using BufferHubDefs::kFirstClientBitMask;
+using BufferHubDefs::kMetadataHeaderSize;
 using frameworks::bufferhub::V1_0::BufferHubStatus;
 using frameworks::bufferhub::V1_0::IBufferClient;
 using frameworks::bufferhub::V1_0::IBufferHub;
@@ -67,9 +67,9 @@
     }
 
     std::unique_ptr<BufferHubBuffer> b1;
-    uint64_t b1ClientMask = 0ULL;
+    uint64_t b1ClientMask = 0U;
     std::unique_ptr<BufferHubBuffer> b2;
-    uint64_t b2ClientMask = 0ULL;
+    uint64_t b2ClientMask = 0U;
 
 private:
     // Creates b1 and b2 as the clients of the same buffer for testing.
@@ -79,13 +79,13 @@
 void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() {
     b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
     b1ClientMask = b1->client_state_mask();
-    ASSERT_NE(b1ClientMask, 0ULL);
+    ASSERT_NE(b1ClientMask, 0U);
     auto statusOrHandle = b1->Duplicate();
     ASSERT_TRUE(statusOrHandle);
     LocalChannelHandle h2 = statusOrHandle.take();
     b2 = BufferHubBuffer::Import(std::move(h2));
     b2ClientMask = b2->client_state_mask();
-    ASSERT_NE(b2ClientMask, 0ULL);
+    ASSERT_NE(b2ClientMask, 0U);
     ASSERT_NE(b2ClientMask, b1ClientMask);
 }
 
@@ -126,7 +126,7 @@
                                       kUserMetadataSize);
     int id1 = b1->id();
     uint64_t bufferStateMask1 = b1->client_state_mask();
-    EXPECT_NE(bufferStateMask1, 0ULL);
+    EXPECT_NE(bufferStateMask1, 0U);
     EXPECT_TRUE(b1->IsValid());
     EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
 
@@ -149,7 +149,7 @@
 
     int id2 = b2->id();
     uint64_t bufferStateMask2 = b2->client_state_mask();
-    EXPECT_NE(bufferStateMask2, 0ULL);
+    EXPECT_NE(bufferStateMask2, 0U);
 
     // These two buffer instances are based on the same physical buffer under the
     // hood, so they should share the same id.
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
index 14422bf..11f8e57 100644
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ b/libs/ui/tests/BufferHubMetadata_test.cpp
@@ -17,7 +17,7 @@
 #include <gtest/gtest.h>
 #include <ui/BufferHubMetadata.h>
 
-using android::dvr::BufferHubDefs::IsBufferReleased;
+using android::BufferHubDefs::IsBufferReleased;
 
 namespace android {
 namespace dvr {
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
index 95ca2c1..81ab3ac 100644
--- a/libs/ui/tests/GraphicBuffer_test.cpp
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -39,6 +39,7 @@
     std::unique_ptr<BufferHubBuffer> b1 =
             BufferHubBuffer::Create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
                                     kTestUsage, /*userMetadataSize=*/0);
+    EXPECT_NE(b1, nullptr);
     EXPECT_TRUE(b1->IsValid());
 
     sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
@@ -51,4 +52,26 @@
     EXPECT_EQ(gb->getLayerCount(), kTestLayerCount);
 }
 
+TEST_F(GraphicBufferTest, InvalidBufferIdForNoneBufferHubBuffer) {
+    sp<GraphicBuffer> gb(
+            new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount, kTestUsage));
+    EXPECT_FALSE(gb->isBufferHubBuffer());
+    EXPECT_EQ(gb->getBufferId(), -1);
+}
+
+TEST_F(GraphicBufferTest, BufferIdMatchesBufferHubBufferId) {
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::Create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+                                    kTestUsage, /*userMetadataSize=*/0);
+    EXPECT_NE(b1, nullptr);
+    EXPECT_TRUE(b1->IsValid());
+
+    int b1_id = b1->id();
+    EXPECT_GE(b1_id, 0);
+
+    sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
+    EXPECT_TRUE(gb->isBufferHubBuffer());
+    EXPECT_EQ(gb->getBufferId(), b1_id);
+}
+
 } // namespace android
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 9bcfaa1..6cb6541 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -5,6 +5,7 @@
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #include <ui/BufferHubBuffer.h>
+#include <ui/BufferHubDefs.h>
 
 #include <mutex>
 #include <thread>
@@ -21,17 +22,17 @@
 using android::BufferHubBuffer;
 using android::GraphicBuffer;
 using android::sp;
+using android::BufferHubDefs::AnyClientAcquired;
+using android::BufferHubDefs::AnyClientGained;
+using android::BufferHubDefs::AnyClientPosted;
+using android::BufferHubDefs::IsBufferReleased;
+using android::BufferHubDefs::IsClientAcquired;
+using android::BufferHubDefs::IsClientPosted;
+using android::BufferHubDefs::IsClientReleased;
+using android::BufferHubDefs::kFirstClientBitMask;
+using android::BufferHubDefs::kMetadataHeaderSize;
 using android::dvr::ConsumerBuffer;
 using android::dvr::ProducerBuffer;
-using android::dvr::BufferHubDefs::AnyClientAcquired;
-using android::dvr::BufferHubDefs::AnyClientGained;
-using android::dvr::BufferHubDefs::AnyClientPosted;
-using android::dvr::BufferHubDefs::IsBufferReleased;
-using android::dvr::BufferHubDefs::IsClientAcquired;
-using android::dvr::BufferHubDefs::IsClientPosted;
-using android::dvr::BufferHubDefs::IsClientReleased;
-using android::dvr::BufferHubDefs::kFirstClientBitMask;
-using android::dvr::BufferHubDefs::kMetadataHeaderSize;
 using android::pdx::LocalChannelHandle;
 using android::pdx::LocalHandle;
 using android::pdx::Status;
@@ -45,7 +46,7 @@
 // Maximum number of consumers for the buffer that only has one producer in the
 // test.
 const size_t kMaxConsumerCount =
-    android::dvr::BufferHubDefs::kMaxNumberOfClients - 1;
+    android::BufferHubDefs::kMaxNumberOfClients - 1;
 const int kPollTimeoutMs = 100;
 
 using LibBufferHubTest = ::testing::Test;
@@ -174,7 +175,7 @@
   ASSERT_TRUE(p.get() != nullptr);
 
   // It's ok to create up to kMaxConsumerCount consumer buffers.
-  uint64_t client_state_masks = p->client_state_mask();
+  uint32_t client_state_masks = p->client_state_mask();
   std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
   for (size_t i = 0; i < kMaxConsumerCount; i++) {
     cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
@@ -183,7 +184,7 @@
     EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
     client_state_masks |= cs[i]->client_state_mask();
   }
-  EXPECT_EQ(client_state_masks, ~0ULL);
+  EXPECT_EQ(client_state_masks, ~0U);
 
   // The 64th creation will fail with out-of-memory error.
   auto state = p->CreateConsumer();
@@ -372,7 +373,7 @@
   std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
       kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
   ASSERT_TRUE(p.get() != nullptr);
-  uint64_t producer_state_mask = p->client_state_mask();
+  uint32_t producer_state_mask = p->client_state_mask();
 
   std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
   for (size_t i = 0; i < kMaxConsumerCount; ++i) {
@@ -718,7 +719,7 @@
   std::unique_ptr<ConsumerBuffer> c1 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c1.get() != nullptr);
-  const uint64_t client_state_mask1 = c1->client_state_mask();
+  const uint32_t client_state_mask1 = c1->client_state_mask();
 
   EXPECT_EQ(0, p->GainAsync());
   DvrNativeBufferMetadata meta;
@@ -738,7 +739,7 @@
   std::unique_ptr<ConsumerBuffer> c2 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c2.get() != nullptr);
-  const uint64_t client_state_mask2 = c2->client_state_mask();
+  const uint32_t client_state_mask2 = c2->client_state_mask();
   EXPECT_NE(client_state_mask1, client_state_mask2);
   EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
   EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
@@ -754,7 +755,7 @@
   std::unique_ptr<ConsumerBuffer> c1 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c1.get() != nullptr);
-  const uint64_t client_state_mask1 = c1->client_state_mask();
+  const uint32_t client_state_mask1 = c1->client_state_mask();
 
   EXPECT_EQ(0, p->GainAsync());
   DvrNativeBufferMetadata meta;
@@ -766,7 +767,7 @@
   std::unique_ptr<ConsumerBuffer> c2 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c2.get() != nullptr);
-  const uint64_t client_state_mask2 = c2->client_state_mask();
+  const uint32_t client_state_mask2 = c2->client_state_mask();
   EXPECT_NE(client_state_mask1, client_state_mask2);
   EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
   LocalHandle invalid_fence;
@@ -780,7 +781,7 @@
   std::unique_ptr<ConsumerBuffer> c3 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c3.get() != nullptr);
-  const uint64_t client_state_mask3 = c3->client_state_mask();
+  const uint32_t client_state_mask3 = c3->client_state_mask();
   EXPECT_NE(client_state_mask1, client_state_mask3);
   EXPECT_NE(client_state_mask2, client_state_mask3);
   EXPECT_LT(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
@@ -801,7 +802,7 @@
   std::unique_ptr<ConsumerBuffer> c4 =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c4.get() != nullptr);
-  const uint64_t client_state_mask4 = c4->client_state_mask();
+  const uint32_t client_state_mask4 = c4->client_state_mask();
   EXPECT_NE(client_state_mask3, client_state_mask4);
   EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
   EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
@@ -951,7 +952,7 @@
   int b1_id = b1->id();
   EXPECT_TRUE(b1->IsValid());
   EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
-  EXPECT_NE(b1->client_state_mask(), 0ULL);
+  EXPECT_NE(b1->client_state_mask(), 0U);
 
   auto status_or_handle = b1->Duplicate();
   EXPECT_TRUE(status_or_handle);
@@ -969,7 +970,7 @@
   ASSERT_TRUE(b2 != nullptr);
   EXPECT_TRUE(b2->IsValid());
   EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
-  EXPECT_NE(b2->client_state_mask(), 0ULL);
+  EXPECT_NE(b2->client_state_mask(), 0U);
 
   int b2_id = b2->id();
 
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
index 2dc427a..8497f3e 100644
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_base.cpp
@@ -124,16 +124,16 @@
   // memory region will be preserved.
   buffer_state_ = &metadata_header_->buffer_state;
   ALOGD_IF(TRACE,
-           "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx64 ".",
+           "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
            id(), buffer_state_->load(std::memory_order_acquire));
   fence_state_ = &metadata_header_->fence_state;
   ALOGD_IF(TRACE,
-           "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx64 ".", id(),
+           "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
            fence_state_->load(std::memory_order_acquire));
   active_clients_bit_mask_ = &metadata_header_->active_clients_bit_mask;
   ALOGD_IF(
       TRACE,
-      "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx64
+      "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
       ".",
       id(), active_clients_bit_mask_->load(std::memory_order_acquire));
 
@@ -171,7 +171,7 @@
       // If ready fence is valid, we put that into the epoll set.
       epoll_event event;
       event.events = EPOLLIN;
-      event.data.u64 = client_state_mask();
+      event.data.u32 = client_state_mask();
       pending_fence_fd_ = new_fence.Duplicate();
       if (epoll_ctl(shared_fence.Get(), EPOLL_CTL_ADD, pending_fence_fd_.Get(),
                     &event) < 0) {
diff --git a/libs/vr/libbufferhub/consumer_buffer.cpp b/libs/vr/libbufferhub/consumer_buffer.cpp
index 62fb5fd..b6ca64e 100644
--- a/libs/vr/libbufferhub/consumer_buffer.cpp
+++ b/libs/vr/libbufferhub/consumer_buffer.cpp
@@ -36,33 +36,33 @@
     return -EINVAL;
 
   // The buffer can be acquired iff the buffer state for this client is posted.
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (!BufferHubDefs::IsClientPosted(current_buffer_state,
                                      client_state_mask())) {
     ALOGE(
         "%s: Failed to acquire the buffer. The buffer is not posted, id=%d "
-        "state=%" PRIx64 " client_state_mask=%" PRIx64 ".",
+        "state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
         __FUNCTION__, id(), current_buffer_state, client_state_mask());
     return -EBUSY;
   }
 
   // Change the buffer state for this consumer from posted to acquired.
-  uint64_t updated_buffer_state = current_buffer_state ^ client_state_mask();
+  uint32_t updated_buffer_state = current_buffer_state ^ client_state_mask();
   while (!buffer_state_->compare_exchange_weak(
       current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
       std::memory_order_acquire)) {
     ALOGD(
         "%s Failed to acquire the buffer. Current buffer state was changed to "
-        "%" PRIx64
+        "%" PRIx32
         " when trying to acquire the buffer and modify the buffer state to "
-        "%" PRIx64 ". About to try again if the buffer is still posted.",
+        "%" PRIx32 ". About to try again if the buffer is still posted.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
     if (!BufferHubDefs::IsClientPosted(current_buffer_state,
                                        client_state_mask())) {
       ALOGE(
           "%s: Failed to acquire the buffer. The buffer is no longer posted, "
-          "id=%d state=%" PRIx64 " client_state_mask=%" PRIx64 ".",
+          "id=%d state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
           __FUNCTION__, id(), current_buffer_state, client_state_mask());
       return -EBUSY;
     }
@@ -81,7 +81,7 @@
     out_meta->user_metadata_ptr = 0;
   }
 
-  uint64_t fence_state = fence_state_->load(std::memory_order_acquire);
+  uint32_t fence_state = fence_state_->load(std::memory_order_acquire);
   // If there is an acquire fence from producer, we need to return it.
   // The producer state bit mask is kFirstClientBitMask for now.
   if (fence_state & BufferHubDefs::kFirstClientBitMask) {
@@ -142,21 +142,21 @@
 
   // Set the buffer state of this client to released if it is not already in
   // released state.
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (BufferHubDefs::IsClientReleased(current_buffer_state,
                                       client_state_mask())) {
     return 0;
   }
-  uint64_t updated_buffer_state = current_buffer_state & (~client_state_mask());
+  uint32_t updated_buffer_state = current_buffer_state & (~client_state_mask());
   while (!buffer_state_->compare_exchange_weak(
       current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
       std::memory_order_acquire)) {
     ALOGD(
         "%s: Failed to release the buffer. Current buffer state was changed to "
-        "%" PRIx64
+        "%" PRIx32
         " when trying to release the buffer and modify the buffer state to "
-        "%" PRIx64 ". About to try again.",
+        "%" PRIx32 ". About to try again.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
     // The failure of compare_exchange_weak updates current_buffer_state.
     updated_buffer_state = current_buffer_state & (~client_state_mask());
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index 09feb73..440a59d 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -90,13 +90,13 @@
   int cid() const { return cid_; }
 
   // Returns the buffer buffer state.
-  uint64_t buffer_state() {
+  uint32_t buffer_state() {
     return buffer_state_->load(std::memory_order_acquire);
   };
 
   // A state mask which is unique to a buffer hub client among all its siblings
   // sharing the same concrete graphic buffer.
-  uint64_t client_state_mask() const { return client_state_mask_; }
+  uint32_t client_state_mask() const { return client_state_mask_; }
 
   // The following methods return settings of the first buffer. Currently,
   // it is only possible to create multi-buffer BufferHubBases with the same
@@ -132,11 +132,11 @@
   // IonBuffer that is shared between bufferhubd, producer, and consumers.
   size_t metadata_buf_size_{0};
   size_t user_metadata_size_{0};
-  BufferHubDefs::MetadataHeader* metadata_header_{nullptr};
-  void* user_metadata_ptr_{nullptr};
-  std::atomic<uint64_t>* buffer_state_{nullptr};
-  std::atomic<uint64_t>* fence_state_{nullptr};
-  std::atomic<uint64_t>* active_clients_bit_mask_{nullptr};
+  BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
+  void* user_metadata_ptr_ = nullptr;
+  std::atomic<uint32_t>* buffer_state_ = nullptr;
+  std::atomic<uint32_t>* fence_state_ = nullptr;
+  std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
 
   LocalHandle shared_acquire_fence_;
   LocalHandle shared_release_fence_;
@@ -159,7 +159,7 @@
 
   // Client bit mask which indicates the locations of this client object in the
   // buffer_state_.
-  uint64_t client_state_mask_{0ULL};
+  uint32_t client_state_mask_{0U};
   IonBuffer buffer_;
   IonBuffer metadata_buffer_;
 };
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
index 400def7..f2c40fe 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
@@ -8,8 +8,7 @@
 #include <pdx/rpc/remote_method.h>
 #include <pdx/rpc/serializable.h>
 #include <private/dvr/native_handle_wrapper.h>
-
-#include <atomic>
+#include <ui/BufferHubDefs.h>
 
 namespace android {
 namespace dvr {
@@ -20,136 +19,55 @@
 static constexpr uint32_t kMetadataUsage =
     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
 
-// Single buffer clients (up to 32) ownership signal.
-// 64-bit atomic unsigned int.
-// Each client takes 2 bits. The first bit locates in the first 32 bits of
-// buffer_state; the second bit locates in the last 32 bits of buffer_state.
-// Client states:
-// Gained state 11. Exclusive write state.
-// Posted state 10.
-// Acquired state 01. Shared read state.
-// Released state 00.
-//
-//  MSB                        LSB
-//   |                          |
-//   v                          v
-// [C31|...|C1|C0|C31| ... |C1|C0]
+// See more details in libs/ui/include/ui/BufferHubDefs.h
+static constexpr int kMaxNumberOfClients =
+    android::BufferHubDefs::kMaxNumberOfClients;
+static constexpr uint32_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask;
+static constexpr uint32_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask;
+static constexpr uint32_t kFirstClientBitMask =
+    android::BufferHubDefs::kFirstClientBitMask;
 
-// Maximum number of clients a buffer can have.
-static constexpr int kMaxNumberOfClients = 32;
-
-// Definition of bit masks.
-//  MSB                            LSB
-//   | kHighBitsMask | kLowbitsMask |
-//   v               v              v
-// [b63|   ...   |b32|b31|   ...  |b0]
-
-// The location of lower 32 bits in the 64-bit buffer state.
-static constexpr uint64_t kLowbitsMask = (1ULL << kMaxNumberOfClients) - 1ULL;
-
-// The location of higher 32 bits in the 64-bit buffer state.
-static constexpr uint64_t kHighBitsMask = ~kLowbitsMask;
-
-// The client bit mask of the first client.
-static constexpr uint64_t kFirstClientBitMask =
-    (1ULL << kMaxNumberOfClients) + 1ULL;
-
-// Returns true if any of the client is in gained state.
-static inline bool AnyClientGained(uint64_t state) {
-  uint64_t high_bits = state >> kMaxNumberOfClients;
-  uint64_t low_bits = state & kLowbitsMask;
-  return high_bits == low_bits && low_bits != 0ULL;
+static inline bool AnyClientGained(uint32_t state) {
+  return android::BufferHubDefs::AnyClientGained(state);
 }
 
-// Returns true if the input client is in gained state.
-static inline bool IsClientGained(uint64_t state, uint64_t client_bit_mask) {
-  return state == client_bit_mask;
+static inline bool IsClientGained(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::IsClientGained(state, client_bit_mask);
 }
 
-// Returns true if any of the client is in posted state.
-static inline bool AnyClientPosted(uint64_t state) {
-  uint64_t high_bits = state >> kMaxNumberOfClients;
-  uint64_t low_bits = state & kLowbitsMask;
-  uint64_t posted_or_acquired = high_bits ^ low_bits;
-  return posted_or_acquired & high_bits;
+static inline bool AnyClientPosted(uint32_t state) {
+  return android::BufferHubDefs::AnyClientPosted(state);
 }
 
-// Returns true if the input client is in posted state.
-static inline bool IsClientPosted(uint64_t state, uint64_t client_bit_mask) {
-  uint64_t client_bits = state & client_bit_mask;
-  if (client_bits == 0ULL)
-    return false;
-  uint64_t low_bits = client_bits & kLowbitsMask;
-  return low_bits == 0ULL;
+static inline bool IsClientPosted(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::IsClientPosted(state, client_bit_mask);
 }
 
-// Return true if any of the client is in acquired state.
-static inline bool AnyClientAcquired(uint64_t state) {
-  uint64_t high_bits = state >> kMaxNumberOfClients;
-  uint64_t low_bits = state & kLowbitsMask;
-  uint64_t posted_or_acquired = high_bits ^ low_bits;
-  return posted_or_acquired & low_bits;
+static inline bool AnyClientAcquired(uint32_t state) {
+  return android::BufferHubDefs::AnyClientAcquired(state);
 }
 
-// Return true if the input client is in acquired state.
-static inline bool IsClientAcquired(uint64_t state, uint64_t client_bit_mask) {
-  uint64_t client_bits = state & client_bit_mask;
-  if (client_bits == 0ULL)
-    return false;
-  uint64_t high_bits = client_bits & kHighBitsMask;
-  return high_bits == 0ULL;
+static inline bool IsClientAcquired(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::IsClientAcquired(state, client_bit_mask);
 }
 
-// Returns true if all clients are in released state.
-static inline bool IsBufferReleased(uint64_t state) { return state == 0ULL; }
+static inline bool IsBufferReleased(uint32_t state) {
+  return android::BufferHubDefs::IsBufferReleased(state);
+}
 
-// Returns true if the input client is in released state.
-static inline bool IsClientReleased(uint64_t state, uint64_t client_bit_mask) {
-  return (state & client_bit_mask) == 0ULL;
+static inline bool IsClientReleased(uint32_t state, uint32_t client_bit_mask) {
+  return android::BufferHubDefs::IsClientReleased(state, client_bit_mask);
 }
 
 // Returns the next available buffer client's client_state_masks.
 // @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint64_t FindNextAvailableClientStateMask(uint64_t union_bits) {
-  uint64_t low_union = union_bits & kLowbitsMask;
-  if (low_union == kLowbitsMask)
-    return 0ULL;
-  uint64_t incremented = low_union + 1ULL;
-  uint64_t difference = incremented ^ low_union;
-  uint64_t new_low_bit = (difference + 1ULL) >> 1;
-  return new_low_bit + (new_low_bit << kMaxNumberOfClients);
+static inline uint32_t FindNextAvailableClientStateMask(uint32_t union_bits) {
+  return android::BufferHubDefs::FindNextAvailableClientStateMask(union_bits);
 }
 
-struct __attribute__((packed, aligned(8))) MetadataHeader {
-  // Internal data format, which can be updated as long as the size, padding and
-  // field alignment of the struct is consistent within the same ABI. As this
-  // part is subject for future updates, it's not stable cross Android version,
-  // so don't have it visible from outside of the Android platform (include Apps
-  // and vendor HAL).
-
-  // Every client takes up one bit from the higher 32 bits and one bit from the
-  // lower 32 bits in buffer_state.
-  std::atomic<uint64_t> buffer_state;
-
-  // Every client takes up one bit in fence_state. Only the lower 32 bits are
-  // valid. The upper 32 bits are there for easier manipulation, but the value
-  // should be ignored.
-  std::atomic<uint64_t> fence_state;
-
-  // Every client takes up one bit from the higher 32 bits and one bit from the
-  // lower 32 bits in active_clients_bit_mask.
-  std::atomic<uint64_t> active_clients_bit_mask;
-
-  // The index of the buffer queue where the buffer belongs to.
-  uint64_t queue_index;
-
-  // Public data format, which should be updated with caution. See more details
-  // in dvr_api.h
-  DvrNativeBufferMetadata metadata;
-};
-
-static_assert(sizeof(MetadataHeader) == 136, "Unexpected MetadataHeader size");
-static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
+using MetadataHeader = android::BufferHubDefs::MetadataHeader;
+static constexpr size_t kMetadataHeaderSize =
+    android::BufferHubDefs::kMetadataHeaderSize;
 
 }  // namespace BufferHubDefs
 
@@ -159,7 +77,7 @@
   BufferTraits() = default;
   BufferTraits(const native_handle_t* buffer_handle,
                const FileHandleType& metadata_handle, int id,
-               uint64_t client_state_mask, uint64_t metadata_size,
+               uint32_t client_state_mask, uint64_t metadata_size,
                uint32_t width, uint32_t height, uint32_t layer_count,
                uint32_t format, uint64_t usage, uint32_t stride,
                const FileHandleType& acquire_fence_fd,
@@ -189,7 +107,7 @@
   // same buffer channel has uniqued state bit among its siblings. For a
   // producer buffer the bit must be kFirstClientBitMask; for a consumer the bit
   // must be one of the kConsumerStateMask.
-  uint64_t client_state_mask() const { return client_state_mask_; }
+  uint32_t client_state_mask() const { return client_state_mask_; }
   uint64_t metadata_size() const { return metadata_size_; }
 
   uint32_t width() { return width_; }
@@ -213,7 +131,7 @@
  private:
   // BufferHub specific traits.
   int id_ = -1;
-  uint64_t client_state_mask_;
+  uint32_t client_state_mask_;
   uint64_t metadata_size_;
 
   // Traits for a GraphicBuffer.
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index 5ff4e00..f1cd0b4 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -99,7 +99,7 @@
  public:
   BufferDescription() = default;
   BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
-                    int buffer_cid, uint64_t client_state_mask,
+                    int buffer_cid, uint32_t client_state_mask,
                     const FileHandleType& acquire_fence_fd,
                     const FileHandleType& release_fence_fd)
       : id_(id),
@@ -123,7 +123,7 @@
 
   // State mask of the buffer client. Each BufferHub client backed by the
   // same buffer channel has uniqued state bit among its siblings.
-  uint64_t client_state_mask() const { return client_state_mask_; }
+  uint32_t client_state_mask() const { return client_state_mask_; }
   FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
   FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
 
@@ -133,7 +133,7 @@
  private:
   int id_{-1};
   int buffer_cid_{-1};
-  uint64_t client_state_mask_{0};
+  uint32_t client_state_mask_{0U};
   // Two IonBuffers: one for the graphic buffer and one for metadata.
   NativeBufferHandle<FileHandleType> buffer_;
   NativeBufferHandle<FileHandleType> metadata_;
diff --git a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h b/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
index ae70b77..a5c6ca2 100644
--- a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
+++ b/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
@@ -2,6 +2,8 @@
 #define ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
 
 #include <cutils/native_handle.h>
+#include <log/log.h>
+#include <pdx/rpc/serializable.h>
 
 #include <vector>
 
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index cd92b62..5274bf2 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -80,20 +80,20 @@
     return error;
 
   // The buffer can be posted iff the buffer state for this client is gained.
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (!BufferHubDefs::IsClientGained(current_buffer_state,
                                      client_state_mask())) {
-    ALOGE("%s: not gained, id=%d state=%" PRIx64 ".", __FUNCTION__, id(),
+    ALOGE("%s: not gained, id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
           current_buffer_state);
     return -EBUSY;
   }
 
   // Set the producer client buffer state to released, other clients' buffer
   // state to posted.
-  uint64_t current_active_clients_bit_mask =
+  uint32_t current_active_clients_bit_mask =
       active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint64_t updated_buffer_state = current_active_clients_bit_mask &
+  uint32_t updated_buffer_state = current_active_clients_bit_mask &
                                   (~client_state_mask()) &
                                   BufferHubDefs::kHighBitsMask;
   while (!buffer_state_->compare_exchange_weak(
@@ -101,16 +101,16 @@
       std::memory_order_acquire)) {
     ALOGD(
         "%s: Failed to post the buffer. Current buffer state was changed to "
-        "%" PRIx64
+        "%" PRIx32
         " when trying to post the buffer and modify the buffer state to "
-        "%" PRIx64
+        "%" PRIx32
         ". About to try again if the buffer is still gained by this client.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
     if (!BufferHubDefs::IsClientGained(current_buffer_state,
                                        client_state_mask())) {
       ALOGE(
           "%s: Failed to post the buffer. The buffer is no longer gained, "
-          "id=%d state=%" PRIx64 ".",
+          "id=%d state=%" PRIx32 ".",
           __FUNCTION__, id(), current_buffer_state);
       return -EBUSY;
     }
@@ -164,9 +164,9 @@
   if (!out_meta)
     return -EINVAL;
 
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
-  ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx64 ".", __FUNCTION__, id(),
+  ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx32 ".", __FUNCTION__, id(),
            current_buffer_state);
 
   if (BufferHubDefs::IsClientGained(current_buffer_state,
@@ -178,20 +178,20 @@
       BufferHubDefs::AnyClientGained(current_buffer_state) ||
       (BufferHubDefs::AnyClientPosted(current_buffer_state) &&
        !gain_posted_buffer)) {
-    ALOGE("%s: not released id=%d state=%" PRIx64 ".", __FUNCTION__, id(),
+    ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
           current_buffer_state);
     return -EBUSY;
   }
   // Change the buffer state to gained state.
-  uint64_t updated_buffer_state = client_state_mask();
+  uint32_t updated_buffer_state = client_state_mask();
   while (!buffer_state_->compare_exchange_weak(
       current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
       std::memory_order_acquire)) {
     ALOGD(
         "%s: Failed to gain the buffer. Current buffer state was changed to "
-        "%" PRIx64
+        "%" PRIx32
         " when trying to gain the buffer and modify the buffer state to "
-        "%" PRIx64
+        "%" PRIx32
         ". About to try again if the buffer is still not read by other "
         "clients.",
         __FUNCTION__, current_buffer_state, updated_buffer_state);
@@ -202,7 +202,7 @@
          !gain_posted_buffer)) {
       ALOGE(
           "%s: Failed to gain the buffer. The buffer is no longer released. "
-          "id=%d state=%" PRIx64 ".",
+          "id=%d state=%" PRIx32 ".",
           __FUNCTION__, id(), current_buffer_state);
       return -EBUSY;
     }
@@ -221,8 +221,8 @@
     out_meta->user_metadata_ptr = 0;
   }
 
-  uint64_t current_fence_state = fence_state_->load(std::memory_order_acquire);
-  uint64_t current_active_clients_bit_mask =
+  uint32_t current_fence_state = fence_state_->load(std::memory_order_acquire);
+  uint32_t current_active_clients_bit_mask =
       active_clients_bit_mask_->load(std::memory_order_acquire);
   // If there are release fence(s) from consumer(s), we need to return it to the
   // consumer(s).
@@ -289,11 +289,11 @@
 
   // TODO(b/112338294) Keep here for reference. Remove it after new logic is
   // written.
-  /* uint64_t buffer_state = buffer_state_->load(std::memory_order_acquire);
+  /* uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
   if (!BufferHubDefs::IsClientGained(
       buffer_state, BufferHubDefs::kFirstClientStateMask)) {
     // Can only detach a ProducerBuffer when it's in gained state.
-    ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx64
+    ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx32
           ") is not in gained state.",
           id(), buffer_state);
     return {};
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index fef8512..e383bb2 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -412,6 +412,7 @@
 // existing data members. If new fields need to be added, please take extra care
 // to make sure that new data field is padded properly the size of the struct
 // stays same.
+// TODO(b/118893702): move the definition to libnativewindow or libui
 struct ALIGNED_DVR_STRUCT(8) DvrNativeBufferMetadata {
 #ifdef __cplusplus
   DvrNativeBufferMetadata()
@@ -465,11 +466,11 @@
 
   // Only applicable for metadata retrieved from GainAsync. This indicates which
   // consumer has pending fence that producer should epoll on.
-  uint64_t release_fence_mask;
+  uint32_t release_fence_mask;
 
   // Reserved bytes for so that the struct is forward compatible and padding to
   // 104 bytes so the size is a multiple of 8.
-  int32_t reserved[8];
+  int32_t reserved[9];
 };
 
 #ifdef __cplusplus
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 2d5f004..df06097 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -62,7 +62,7 @@
              buffer_removed_count_);
   }
 
-  DvrWriteBufferQueue* write_queue_{nullptr};
+  DvrWriteBufferQueue* write_queue_ = nullptr;
   int buffer_available_count_{0};
   int buffer_removed_count_{0};
 };
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
index fa0adf0..f72dabc 100644
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
@@ -66,7 +66,7 @@
   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);
 }
 
-constexpr uint64_t kNanosPerSecond = 1000000000llu;
+constexpr uint64_t kNanosPerSecond = 1000000000LLU;
 
 uint64_t GetClockNs() {
   timespec t;
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
index f9aaa20..72d210c 100644
--- a/services/bufferhub/Android.bp
+++ b/services/bufferhub/Android.bp
@@ -29,10 +29,8 @@
         "BufferNode.cpp",
     ],
     header_libs: [
-        "libbufferhub_headers",
         "libdvr_headers",
         "libnativewindow_headers",
-        "libpdx_headers",
     ],
     shared_libs: [
         "android.frameworks.bufferhub@1.0",
@@ -56,10 +54,8 @@
         "main_bufferhub.cpp"
     ],
     header_libs: [
-        "libbufferhub_headers",
         "libdvr_headers",
         "libnativewindow_headers",
-        "libpdx_headers",
     ],
     shared_libs: [
         "android.frameworks.bufferhub@1.0",
diff --git a/services/bufferhub/BufferClient.cpp b/services/bufferhub/BufferClient.cpp
index 7459517..e312011 100644
--- a/services/bufferhub/BufferClient.cpp
+++ b/services/bufferhub/BufferClient.cpp
@@ -17,6 +17,7 @@
 #include <bufferhub/BufferClient.h>
 #include <bufferhub/BufferHubService.h>
 #include <hidl/HidlSupport.h>
+#include <log/log.h>
 
 namespace android {
 namespace frameworks {
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index ec84849..cc87e15 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -2,7 +2,6 @@
 
 #include <bufferhub/BufferHubService.h>
 #include <bufferhub/BufferNode.h>
-#include <private/dvr/buffer_hub_defs.h>
 #include <ui/GraphicBufferAllocator.h>
 
 namespace android {
@@ -14,11 +13,11 @@
 void BufferNode::InitializeMetadata() {
     // Using placement new here to reuse shared memory instead of new allocation
     // Initialize the atomic variables to zero.
-    dvr::BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
-    buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint64_t>(0);
-    fence_state_ = new (&metadata_header->fence_state) std::atomic<uint64_t>(0);
+    BufferHubDefs::MetadataHeader* metadata_header = metadata_.metadata_header();
+    buffer_state_ = new (&metadata_header->buffer_state) std::atomic<uint32_t>(0);
+    fence_state_ = new (&metadata_header->fence_state) std::atomic<uint32_t>(0);
     active_clients_bit_mask_ =
-            new (&metadata_header->active_clients_bit_mask) std::atomic<uint64_t>(0);
+            new (&metadata_header->active_clients_bit_mask) std::atomic<uint32_t>(0);
 }
 
 // Allocates a new BufferNode.
@@ -75,21 +74,22 @@
     }
 }
 
-uint64_t BufferNode::GetActiveClientsBitMask() const {
+uint32_t BufferNode::GetActiveClientsBitMask() const {
     return active_clients_bit_mask_->load(std::memory_order_acquire);
 }
 
-uint64_t BufferNode::AddNewActiveClientsBitToMask() {
-    uint64_t current_active_clients_bit_mask = GetActiveClientsBitMask();
-    uint64_t client_state_mask = 0ULL;
-    uint64_t updated_active_clients_bit_mask = 0ULL;
+uint32_t BufferNode::AddNewActiveClientsBitToMask() {
+    uint32_t current_active_clients_bit_mask = GetActiveClientsBitMask();
+    uint32_t client_state_mask = 0U;
+    uint32_t updated_active_clients_bit_mask = 0U;
     do {
-        client_state_mask = dvr::BufferHubDefs::FindNextAvailableClientStateMask(
-                current_active_clients_bit_mask);
-        if (client_state_mask == 0ULL) {
-            ALOGE("%s: reached the maximum number of channels per buffer node: 32.", __FUNCTION__);
+        client_state_mask =
+                BufferHubDefs::FindNextAvailableClientStateMask(current_active_clients_bit_mask);
+        if (client_state_mask == 0U) {
+            ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__,
+                  BufferHubDefs::kMaxNumberOfClients);
             errno = E2BIG;
-            return 0ULL;
+            return 0U;
         }
         updated_active_clients_bit_mask = current_active_clients_bit_mask | client_state_mask;
     } while (!(active_clients_bit_mask_->compare_exchange_weak(current_active_clients_bit_mask,
@@ -99,7 +99,7 @@
     return client_state_mask;
 }
 
-void BufferNode::RemoveClientsBitFromMask(const uint64_t& value) {
+void BufferNode::RemoveClientsBitFromMask(const uint32_t& value) {
     active_clients_bit_mask_->fetch_and(~value);
 }
 
diff --git a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
index c5b2cde..b51fcda 100644
--- a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
+++ b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
@@ -32,7 +32,7 @@
 class BufferHubIdGenerator {
 public:
     // 0 is considered invalid
-    static constexpr uint32_t kInvalidId = 0UL;
+    static constexpr uint32_t kInvalidId = 0U;
 
     // Get the singleton instance of this class
     static BufferHubIdGenerator& getInstance();
diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h
index 94ef505..cf56c33 100644
--- a/services/bufferhub/include/bufferhub/BufferNode.h
+++ b/services/bufferhub/include/bufferhub/BufferNode.h
@@ -3,6 +3,7 @@
 
 #include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubIdGenerator.h>
+#include <cutils/native_handle.h>
 #include <ui/BufferHubMetadata.h>
 
 namespace android {
@@ -37,19 +38,19 @@
     // Gets the current value of active_clients_bit_mask in metadata_ with
     // std::memory_order_acquire, so that all previous releases of
     // active_clients_bit_mask from all threads will be returned here.
-    uint64_t GetActiveClientsBitMask() const;
+    uint32_t GetActiveClientsBitMask() const;
 
     // Find and add a new client_state_mask to active_clients_bit_mask in
     // metadata_.
     // Return the new client_state_mask that is added to active_clients_bit_mask.
-    // Return 0ULL if there are already 32 bp clients of the buffer.
-    uint64_t AddNewActiveClientsBitToMask();
+    // Return 0U if there are already 16 clients of the buffer.
+    uint32_t AddNewActiveClientsBitToMask();
 
     // Removes the value from active_clients_bit_mask in metadata_ with
     // std::memory_order_release, so that the change will be visible to any
     // acquire of active_clients_bit_mask_ in any threads after the succeed of
     // this operation.
-    void RemoveClientsBitFromMask(const uint64_t& value);
+    void RemoveClientsBitFromMask(const uint32_t& value);
 
 private:
     // Helper method for constructors to initialize atomic metadata header
@@ -74,14 +75,14 @@
 
     // buffer_state_ tracks the state of the buffer. Buffer can be in one of these
     // four states: gained, posted, acquired, released.
-    std::atomic<uint64_t>* buffer_state_ = nullptr;
+    std::atomic<uint32_t>* buffer_state_ = nullptr;
 
     // TODO(b/112012161): add comments to fence_state_.
-    std::atomic<uint64_t>* fence_state_ = nullptr;
+    std::atomic<uint32_t>* fence_state_ = nullptr;
 
     // active_clients_bit_mask_ tracks all the bp clients of the buffer. It is the
     // union of all client_state_mask of all bp clients.
-    std::atomic<uint64_t>* active_clients_bit_mask_ = nullptr;
+    std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
 };
 
 } // namespace implementation
diff --git a/services/bufferhub/tests/Android.bp b/services/bufferhub/tests/Android.bp
index 3967886..e565374 100644
--- a/services/bufferhub/tests/Android.bp
+++ b/services/bufferhub/tests/Android.bp
@@ -1,16 +1,17 @@
 cc_test {
-    name: "BufferNode_test",
-    srcs: ["BufferNode_test.cpp"],
+    name: "BufferHubServer_test",
+    srcs: [
+        "BufferNode_test.cpp",
+        "BufferHubIdGenerator_test.cpp",
+    ],
     cflags: [
-        "-DLOG_TAG=\"BufferNode_test\"",
+        "-DLOG_TAG=\"BufferHubServer_test\"",
         "-DTRACE=0",
         "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
     ],
     header_libs: [
-        "libbufferhub_headers",
         "libdvr_headers",
         "libnativewindow_headers",
-        "libpdx_headers",
     ],
     shared_libs: [
         "libbufferhubservice",
@@ -19,22 +20,4 @@
     static_libs: [
         "libgmock",
     ],
-    // TODO(b/117568153): Temporarily opt out using libcrt.
-    no_libcrt: true,
 }
-
-cc_test {
-    name: "BufferHubIdGenerator_test",
-    srcs: ["BufferHubIdGenerator_test.cpp"],
-    cflags: [
-        "-DLOG_TAG=\"BufferHubIdGenerator_test\"",
-        "-DTRACE=0",
-        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
-    ],
-    shared_libs: [
-        "libbufferhubservice",
-    ],
-    static_libs: [
-        "libgmock",
-    ],
-}
\ No newline at end of file
diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp
index df31d78..dbf10e8 100644
--- a/services/bufferhub/tests/BufferNode_test.cpp
+++ b/services/bufferhub/tests/BufferNode_test.cpp
@@ -1,7 +1,9 @@
-#include <bufferhub/BufferNode.h>
 #include <errno.h>
+
+#include <bufferhub/BufferNode.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <ui/BufferHubDefs.h>
 #include <ui/GraphicBufferMapper.h>
 
 namespace android {
@@ -20,7 +22,6 @@
 const uint32_t kFormat = 1;
 const uint64_t kUsage = 0;
 const size_t kUserMetadataSize = 0;
-const size_t kMaxClientsCount = dvr::BufferHubDefs::kMaxNumberOfClients;
 
 class BufferNodeTest : public ::testing::Test {
 protected:
@@ -55,23 +56,23 @@
 }
 
 TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_twoNewClients) {
-    uint64_t new_client_state_mask_1 = buffer_node->AddNewActiveClientsBitToMask();
+    uint32_t new_client_state_mask_1 = buffer_node->AddNewActiveClientsBitToMask();
     EXPECT_EQ(buffer_node->GetActiveClientsBitMask(), new_client_state_mask_1);
 
     // Request and add a new client_state_mask again.
     // Active clients bit mask should be the union of the two new
     // client_state_masks.
-    uint64_t new_client_state_mask_2 = buffer_node->AddNewActiveClientsBitToMask();
+    uint32_t new_client_state_mask_2 = buffer_node->AddNewActiveClientsBitToMask();
     EXPECT_EQ(buffer_node->GetActiveClientsBitMask(),
               new_client_state_mask_1 | new_client_state_mask_2);
 }
 
 TEST_F(BufferNodeTest, TestAddNewActiveClientsBitToMask_32NewClients) {
-    uint64_t new_client_state_mask = 0ULL;
-    uint64_t current_mask = 0ULL;
-    uint64_t expected_mask = 0ULL;
+    uint32_t new_client_state_mask = 0U;
+    uint32_t current_mask = 0U;
+    uint32_t expected_mask = 0U;
 
-    for (int i = 0; i < kMaxClientsCount; ++i) {
+    for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) {
         new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
         EXPECT_NE(new_client_state_mask, 0);
         EXPECT_FALSE(new_client_state_mask & current_mask);
@@ -82,14 +83,14 @@
 
     // Method should fail upon requesting for more than maximum allowable clients.
     new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
-    EXPECT_EQ(new_client_state_mask, 0ULL);
+    EXPECT_EQ(new_client_state_mask, 0U);
     EXPECT_EQ(errno, E2BIG);
 }
 
 TEST_F(BufferNodeTest, TestRemoveActiveClientsBitFromMask) {
     buffer_node->AddNewActiveClientsBitToMask();
-    uint64_t current_mask = buffer_node->GetActiveClientsBitMask();
-    uint64_t new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
+    uint32_t current_mask = buffer_node->GetActiveClientsBitMask();
+    uint32_t new_client_state_mask = buffer_node->AddNewActiveClientsBitToMask();
     EXPECT_NE(buffer_node->GetActiveClientsBitMask(), current_mask);
 
     buffer_node->RemoveClientsBitFromMask(new_client_state_mask);
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index f87fcdc..33a2747 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -41,6 +41,7 @@
         "liblog",
         "libbinder",
         "libsensor",
+        "libsensorprivacy",
         "libcrypto",
         "libbase",
         "libhidlbase",
@@ -53,8 +54,8 @@
 
     static_libs: ["android.hardware.sensors@1.0-convert"],
 
-    // our public headers depend on libsensor
-    export_shared_lib_headers: ["libsensor"],
+    // our public headers depend on libsensor and libsensorprivacy
+    export_shared_lib_headers: ["libsensor", "libsensorprivacy"],
 }
 
 cc_binary {
@@ -64,6 +65,7 @@
 
     shared_libs: [
         "libsensorservice",
+        "libsensorprivacy",
         "libbinder",
         "libutils",
     ],
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 776efab..b66cbcf 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -279,7 +279,7 @@
                     }
                 } else {
                     // Regular sensor event, just copy it to the scratch buffer.
-                    if (mHasSensorAccess) {
+                    if (hasSensorAccess()) {
                         scratch[count++] = buffer[i];
                     }
                 }
@@ -290,7 +290,7 @@
                                         buffer[i].meta_data.sensor == sensor_handle)));
         }
     } else {
-        if (mHasSensorAccess) {
+        if (hasSensorAccess()) {
             scratch = const_cast<sensors_event_t *>(buffer);
             count = numEvents;
         } else {
@@ -321,7 +321,7 @@
     }
 
     int index_wake_up_event = -1;
-    if (mHasSensorAccess) {
+    if (hasSensorAccess()) {
         index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
         if (index_wake_up_event >= 0) {
             scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
@@ -375,6 +375,10 @@
     mHasSensorAccess = hasAccess;
 }
 
+bool SensorService::SensorEventConnection::hasSensorAccess() {
+    return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
+}
+
 void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
                                                                  int count) {
     sensors_event_t *eventCache_new;
@@ -491,7 +495,7 @@
     for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
         const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
         int index_wake_up_event = -1;
-        if (mHasSensorAccess) {
+        if (hasSensorAccess()) {
             index_wake_up_event =
                       findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
             if (index_wake_up_event >= 0) {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 061809f..7077880 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -130,6 +130,10 @@
     void updateLooperRegistration(const sp<Looper>& looper); void
             updateLooperRegistrationLocked(const sp<Looper>& looper);
 
+    // Returns whether sensor access is available based on both the uid being active and sensor
+    // privacy not being enabled.
+    bool hasSensorAccess();
+
     sp<SensorService> const mService;
     sp<BitTube> mChannel;
     uid_t mUid;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 85450f8..9a37ff1 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -29,6 +29,7 @@
 #include <openssl/hmac.h>
 #include <openssl/rand.h>
 #include <sensor/SensorEventQueue.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
 #include <utils/SystemClock.h>
 
 #include "BatteryService.h"
@@ -88,6 +89,7 @@
     : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
       mWakeLockAcquired(false) {
     mUidPolicy = new UidPolicy(this);
+    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
 }
 
 bool SensorService::initializeHmacKey() {
@@ -286,6 +288,9 @@
 
             // Start watching UID changes to apply policy.
             mUidPolicy->registerSelf();
+
+            // Start watching sensor privacy changes
+            mSensorPrivacyPolicy->registerSelf();
         }
     }
 }
@@ -338,6 +343,7 @@
         delete entry.second;
     }
     mUidPolicy->unregisterSelf();
+    mSensorPrivacyPolicy->unregisterSelf();
 }
 
 status_t SensorService::dump(int fd, const Vector<String16>& args) {
@@ -364,35 +370,16 @@
             }
 
             mCurrentOperatingMode = RESTRICTED;
-            // temporarily stop all sensor direct report
-            for (auto &i : mDirectConnections) {
-                sp<SensorDirectConnection> connection(i.promote());
-                if (connection != nullptr) {
-                    connection->stopAll(true /* backupRecord */);
-                }
-            }
-
-            dev.disableAllSensors();
-            // Clear all pending flush connections for all active sensors. If one of the active
-            // connections has called flush() and the underlying sensor has been disabled before a
-            // flush complete event is returned, we need to remove the connection from this queue.
-            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
-                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
-            }
+            // temporarily stop all sensor direct report and disable sensors
+            disableAllSensorsLocked();
             mWhiteListedPackage.setTo(String8(args[1]));
             return status_t(NO_ERROR);
         } else if (args.size() == 1 && args[0] == String16("enable")) {
             // If currently in restricted mode, reset back to NORMAL mode else ignore.
             if (mCurrentOperatingMode == RESTRICTED) {
                 mCurrentOperatingMode = NORMAL;
-                dev.enableAllSensors();
-                // recover all sensor direct report
-                for (auto &i : mDirectConnections) {
-                    sp<SensorDirectConnection> connection(i.promote());
-                    if (connection != nullptr) {
-                        connection->recoverAll();
-                    }
-                }
+                // enable sensors and recover all sensor direct report
+                enableAllSensorsLocked();
             }
             if (mCurrentOperatingMode == DATA_INJECTION) {
                resetToNormalModeLocked();
@@ -477,6 +464,8 @@
                case DATA_INJECTION:
                    result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
             }
+            result.appendFormat("Sensor Privacy: %s\n",
+                    mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
 
             result.appendFormat("%zd active connections\n", mActiveConnections.size());
             for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
@@ -519,6 +508,52 @@
     return NO_ERROR;
 }
 
+void SensorService::disableAllSensors() {
+    Mutex::Autolock _l(mLock);
+    disableAllSensorsLocked();
+}
+
+void SensorService::disableAllSensorsLocked() {
+    SensorDevice& dev(SensorDevice::getInstance());
+    for (auto &i : mDirectConnections) {
+        sp<SensorDirectConnection> connection(i.promote());
+        if (connection != nullptr) {
+            connection->stopAll(true /* backupRecord */);
+        }
+    }
+    dev.disableAllSensors();
+    // Clear all pending flush connections for all active sensors. If one of the active
+    // connections has called flush() and the underlying sensor has been disabled before a
+    // flush complete event is returned, we need to remove the connection from this queue.
+    for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
+        mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
+    }
+}
+
+void SensorService::enableAllSensors() {
+    Mutex::Autolock _l(mLock);
+    enableAllSensorsLocked();
+}
+
+void SensorService::enableAllSensorsLocked() {
+    // sensors should only be enabled if the operating state is not restricted and sensor
+    // privacy is not enabled.
+    if (mCurrentOperatingMode == RESTRICTED || mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+        ALOGW("Sensors cannot be enabled: mCurrentOperatingMode = %d, sensor privacy = %s",
+              mCurrentOperatingMode,
+              mSensorPrivacyPolicy->isSensorPrivacyEnabled() ? "enabled" : "disabled");
+        return;
+    }
+    SensorDevice& dev(SensorDevice::getInstance());
+    dev.enableAllSensors();
+    for (auto &i : mDirectConnections) {
+        sp<SensorDirectConnection> connection(i.promote());
+        if (connection != nullptr) {
+            connection->recoverAll();
+        }
+    }
+}
+
 // NOTE: This is a remote API - make sure all args are validated
 status_t SensorService::shellCommand(int in, int out, int err, Vector<String16>& args) {
     if (!checkCallingPermission(sManageSensorsPermission, nullptr, nullptr)) {
@@ -1076,6 +1111,12 @@
         const native_handle *resource) {
     Mutex::Autolock _l(mLock);
 
+    // No new direct connections are allowed when sensor privacy is enabled
+    if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+        ALOGE("Cannot create new direct connections when sensor privacy is enabled");
+        return nullptr;
+    }
+
     struct sensors_direct_mem_t mem = {
         .type = type,
         .format = format,
@@ -1753,4 +1794,31 @@
     return mActiveUids.find(uid) != mActiveUids.end();
 }
 
+void SensorService::SensorPrivacyPolicy::registerSelf() {
+    SensorPrivacyManager spm;
+    mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+    spm.addSensorPrivacyListener(this);
+}
+
+void SensorService::SensorPrivacyPolicy::unregisterSelf() {
+    SensorPrivacyManager spm;
+    spm.removeSensorPrivacyListener(this);
+}
+
+bool SensorService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+    return mSensorPrivacyEnabled;
+}
+
+binder::Status SensorService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+    mSensorPrivacyEnabled = enabled;
+    sp<SensorService> service = mService.promote();
+    if (service != nullptr) {
+        if (enabled) {
+            service->disableAllSensors();
+        } else {
+            service->enableAllSensors();
+        }
+    }
+    return binder::Status::ok();
+}
 }; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 24b0dd7..136ee27 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -26,6 +26,7 @@
 #include <sensor/ISensorServer.h>
 #include <sensor/ISensorEventConnection.h>
 #include <sensor/Sensor.h>
+#include "android/hardware/BnSensorPrivacyListener.h"
 
 #include <utils/AndroidThreads.h>
 #include <utils/KeyedVector.h>
@@ -132,6 +133,30 @@
             std::unordered_map<uid_t, bool> mOverrideUids;
     };
 
+    // Sensor privacy allows a user to disable access to all sensors on the device. When
+    // enabled sensor privacy will prevent all apps, including active apps, from accessing
+    // sensors, they will not receive trigger nor on-change events, flush event behavior
+    // does not change, and recurring events are the same as the first one delivered when
+    // sensor privacy was enabled. All sensor direct connections will be stopped as well
+    // and new direct connections will not be allowed while sensor privacy is enabled.
+    // Once sensor privacy is disabled access to sensors will be restored for active
+    // apps, previously stopped direct connections will be restarted, and new direct
+    // connections will be allowed again.
+    class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+        public:
+            explicit SensorPrivacyPolicy(wp<SensorService> service) : mService(service) {}
+            void registerSelf();
+            void unregisterSelf();
+
+            bool isSensorPrivacyEnabled();
+
+            binder::Status onSensorPrivacyChanged(bool enabled);
+
+        private:
+            wp<SensorService> mService;
+            std::atomic_bool mSensorPrivacyEnabled;
+    };
+
     enum Mode {
        // The regular operating mode where any application can register/unregister/call flush on
        // sensors.
@@ -275,6 +300,13 @@
     // Prints the shell command help
     status_t printHelp(int out);
 
+    // temporarily stops all active direct connections and disables all sensors
+    void disableAllSensors();
+    void disableAllSensorsLocked();
+    // restarts the previously stopped direct connections and enables all sensors
+    void enableAllSensors();
+    void enableAllSensorsLocked();
+
     static uint8_t sHmacGlobalKey[128];
     static bool sHmacGlobalKeyIsValid;
 
@@ -309,6 +341,7 @@
     Vector<SensorRegistrationInfo> mLastNSensorRegistrations;
 
     sp<UidPolicy> mUidPolicy;
+    sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 4e4d7dd..0a3be71 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -396,6 +396,7 @@
     }
 
     // Capture the old state of the layer for comparisons later
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     const bool oldOpacity = isOpaque(s);
     sp<GraphicBuffer> oldBuffer = mActiveBuffer;
@@ -502,7 +503,7 @@
 
     // FIXME: postedRegion should be dirty & bounds
     // transform the dirty region to window-manager space
-    return getTransform().transform(Region(getBufferSize(s)));
+    return getTransformLocked().transform(Region(getBufferSize(s)));
 }
 
 // transaction
@@ -550,7 +551,7 @@
 
 // h/w composer set-up
 bool BufferLayer::allTransactionsSignaled() {
-    auto headFrameNumber = getHeadFrameNumber();
+    auto headFrameNumber = getHeadFrameNumberLocked();
     bool matchingFramesFound = false;
     bool allTransactionsApplied = true;
     Mutex::Autolock lock(mLocalSyncPointMutex);
@@ -603,6 +604,7 @@
 
 void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
     ATRACE_CALL();
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
 
     computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
@@ -621,9 +623,9 @@
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
-    const Rect bounds{computeBounds()}; // Rounds from FloatRect
+    const Rect bounds{computeBoundsLocked()}; // Rounds from FloatRect
 
-    ui::Transform t = getTransform();
+    ui::Transform t = getTransformLocked();
     Rect win = bounds;
     const int bufferWidth = getBufferSize(s).getWidth();
     const int bufferHeight = getBufferSize(s).getHeight();
@@ -642,7 +644,7 @@
     texCoords[2] = vec2(right, 1.0f - bottom);
     texCoords[3] = vec2(right, 1.0f - top);
 
-    const auto roundedCornerState = getRoundedCornerState();
+    const auto roundedCornerState = getRoundedCornerStateLocked();
     const auto cropRect = roundedCornerState.cropRect;
     setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -664,7 +666,12 @@
 }
 
 uint64_t BufferLayer::getHeadFrameNumber() const {
-    if (hasFrameUpdate()) {
+    Mutex::Autolock lock(mStateMutex);
+    return getHeadFrameNumberLocked();
+}
+
+uint64_t BufferLayer::getHeadFrameNumberLocked() const {
+    if (hasFrameUpdateLocked()) {
         return getFrameNumber();
     } else {
         return mCurrentFrameNumber;
@@ -691,7 +698,7 @@
         std::swap(bufWidth, bufHeight);
     }
 
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
         if (invTransform & ui::Transform::ROT_90) {
             std::swap(bufWidth, bufHeight);
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 690a4e5..55d68f6 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -69,7 +69,7 @@
     bool isOpaque(const Layer::State& s) const override;
 
     // isVisible - true if this layer is visible, false otherwise
-    bool isVisible() const override;
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     // isFixedSize - true if content has a fixed size
     bool isFixedSize() const override;
@@ -87,7 +87,7 @@
     bool onPostComposition(const std::optional<DisplayId>& displayId,
                            const std::shared_ptr<FenceTime>& glDoneFence,
                            const std::shared_ptr<FenceTime>& presentFence,
-                           const CompositorTiming& compositorTiming) override;
+                           const CompositorTiming& compositorTiming) override EXCLUDES(mStateMutex);
 
     // latchBuffer - called each time the screen is redrawn and returns whether
     // the visible regions need to be recomputed (this is a fairly heavy
@@ -97,13 +97,13 @@
     // releaseFence will be populated with a native fence that fires when
     // composition has completed.
     Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                       const sp<Fence>& releaseFence) override;
+                       const sp<Fence>& releaseFence) override EXCLUDES(mStateMutex);
 
     bool isBufferLatched() const override { return mRefreshPending; }
 
     void notifyAvailableFrames() override;
 
-    bool hasReadyFrame() const override;
+    bool hasReadyFrame() const override EXCLUDES(mStateMutex);
 
     // Returns the current scaling mode, unless mOverrideScalingMode
     // is set, in which case, it returns mOverrideScalingMode
@@ -114,19 +114,24 @@
     // Functions that must be implemented by derived classes
     // -----------------------------------------------------------------------
 private:
-    virtual bool fenceHasSignaled() const = 0;
+    virtual bool fenceHasSignaled() const EXCLUDES(mStateMutex) = 0;
 
     virtual nsecs_t getDesiredPresentTime() = 0;
-    virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getCurrentFenceTimeLocked();
+    }
+
+    virtual std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const REQUIRES(mStateMutex) = 0;
 
     virtual void getDrawingTransformMatrix(float *matrix) = 0;
-    virtual uint32_t getDrawingTransform() const = 0;
-    virtual ui::Dataspace getDrawingDataSpace() const = 0;
-    virtual Rect getDrawingCrop() const = 0;
+    virtual uint32_t getDrawingTransform() const REQUIRES(mStateMutex) = 0;
+    virtual ui::Dataspace getDrawingDataSpace() const REQUIRES(mStateMutex) = 0;
+    virtual Rect getDrawingCrop() const REQUIRES(mStateMutex) = 0;
     virtual uint32_t getDrawingScalingMode() const = 0;
-    virtual Region getDrawingSurfaceDamage() const = 0;
-    virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
-    virtual int getDrawingApi() const = 0;
+    virtual Region getDrawingSurfaceDamage() const EXCLUDES(mStateMutex) = 0;
+    virtual const HdrMetadata& getDrawingHdrMetadata() const EXCLUDES(mStateMutex) = 0;
+    virtual int getDrawingApi() const EXCLUDES(mStateMutex) = 0;
     virtual PixelFormat getPixelFormat() const = 0;
 
     virtual uint64_t getFrameNumber() const = 0;
@@ -134,20 +139,21 @@
     virtual bool getAutoRefresh() const = 0;
     virtual bool getSidebandStreamChanged() const = 0;
 
-    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0;
+    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions)
+            EXCLUDES(mStateMutex) = 0;
 
-    virtual bool hasFrameUpdate() const = 0;
+    virtual bool hasFrameUpdateLocked() const REQUIRES(mStateMutex) = 0;
 
     virtual void setFilteringEnabled(bool enabled) = 0;
 
-    virtual status_t bindTextureImage() = 0;
+    virtual status_t bindTextureImage() EXCLUDES(mStateMutex) = 0;
     virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                                    const sp<Fence>& flushFence) = 0;
+                                    const sp<Fence>& flushFence) REQUIRES(mStateMutex) = 0;
 
-    virtual status_t updateActiveBuffer() = 0;
+    virtual status_t updateActiveBuffer() REQUIRES(mStateMutex) = 0;
     virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
 
-    virtual void setHwcLayerBuffer(DisplayId displayId) = 0;
+    virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0;
 
     // -----------------------------------------------------------------------
 
@@ -163,10 +169,15 @@
     // Check all of the local sync points to ensure that all transactions
     // which need to have been applied prior to the frame which is about to
     // be latched have signaled
-    bool allTransactionsSignaled();
+    bool allTransactionsSignaled() REQUIRES(mStateMutex);
 
     static bool getOpacityForFormat(uint32_t format);
 
+    bool hasFrameUpdate() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return hasFrameUpdateLocked();
+    }
+
     // from GLES
     const uint32_t mTextureName;
 
@@ -175,9 +186,12 @@
     bool needsFiltering(const RenderArea& renderArea) const;
 
     // drawing
-    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
+    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const
+            EXCLUDES(mStateMutex);
 
-    uint64_t getHeadFrameNumber() const;
+    uint64_t getHeadFrameNumber() const EXCLUDES(mStateMutex);
+
+    uint64_t getHeadFrameNumberLocked() const REQUIRES(mStateMutex);
 
     uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
@@ -189,7 +203,7 @@
 
     bool mRefreshPending{false};
 
-    Rect getBufferSize(const State& s) const override;
+    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index b784d11..70d52f1 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -51,7 +51,7 @@
     return history;
 }
 
-bool BufferQueueLayer::getTransformToDisplayInverse() const {
+bool BufferQueueLayer::getTransformToDisplayInverseLocked() const {
     return mConsumer->getTransformToDisplayInverse();
 }
 
@@ -131,7 +131,7 @@
     return mConsumer->getTimestamp();
 }
 
-std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
+std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTimeLocked() const {
     return mConsumer->getCurrentFenceTime();
 }
 
@@ -192,6 +192,7 @@
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     bool sidebandStreamChanged = true;
+    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
@@ -200,15 +201,15 @@
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
-        recomputeVisibleRegions = true;
 
+        recomputeVisibleRegions = true;
         const State& s(getDrawingState());
-        return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
+        return getTransformLocked().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
     }
     return {};
 }
 
-bool BufferQueueLayer::hasFrameUpdate() const {
+bool BufferQueueLayer::hasFrameUpdateLocked() const {
     return mQueuedFrames > 0;
 }
 
@@ -228,16 +229,18 @@
     // buffer mode.
     bool queuedBuffer = false;
     const int32_t layerID = getSequence();
-    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
+    status_t updateResult;
+    LayerRejecter r(mState.drawing, getCurrentState(), recomputeVisibleRegions,
                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
-                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);
+                    getTransformToDisplayInverseLocked(), mFreezeGeometryUpdates);
 
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
-    status_t updateResult =
-            mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                      mLastFrameNumberReceived, releaseFence);
+
+    updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
+                                             mLastFrameNumberReceived, releaseFence);
+
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index ae0b705..f9da044 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -44,7 +44,7 @@
 
     std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
 
-    bool getTransformToDisplayInverse() const override;
+    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -64,12 +64,12 @@
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
+    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override;
-    ui::Dataspace getDrawingDataSpace() const override;
-    Rect getDrawingCrop() const override;
+    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
+    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
+    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
     uint32_t getDrawingScalingMode() const override;
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
@@ -81,17 +81,18 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
+            EXCLUDES(mStateMutex);
 
-    bool hasFrameUpdate() const override;
+    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
 
     void setFilteringEnabled(bool enabled) override;
 
     status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override;
+                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
 
-    status_t updateActiveBuffer() override;
+    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
     void setHwcLayerBuffer(DisplayId displayId) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index efc2c9f..8091b94 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -70,30 +70,31 @@
 }
 
 bool BufferStateLayer::willPresentCurrentTransaction() const {
+    Mutex::Autolock lock(mStateMutex);
     // Returns true if the most recent Transaction applied to CurrentState will be presented.
     return getSidebandStreamChanged() || getAutoRefresh() ||
-            (mCurrentState.modified && mCurrentState.buffer != nullptr);
+            (mState.current.modified && mState.current.buffer != nullptr);
 }
 
-bool BufferStateLayer::getTransformToDisplayInverse() const {
-    return mCurrentState.transformToDisplayInverse;
+bool BufferStateLayer::getTransformToDisplayInverseLocked() const {
+    return mState.current.transformToDisplayInverse;
 }
 
-void BufferStateLayer::pushPendingState() {
-    if (!mCurrentState.modified) {
+void BufferStateLayer::pushPendingStateLocked() {
+    if (!mState.current.modified) {
         return;
     }
-    mPendingStates.push_back(mCurrentState);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.push_back(mState.current);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
-    const bool stateUpdateAvailable = !mPendingStates.empty();
-    while (!mPendingStates.empty()) {
+    const bool stateUpdateAvailable = !mState.pending.empty();
+    while (!mState.pending.empty()) {
         popPendingState(stateToCommit);
     }
-    mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
-    mCurrentState.modified = false;
+    mCurrentStateModified = stateUpdateAvailable && mState.current.modified;
+    mState.current.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -103,28 +104,31 @@
 }
 
 bool BufferStateLayer::setTransform(uint32_t transform) {
-    if (mCurrentState.transform == transform) return false;
-    mCurrentState.sequence++;
-    mCurrentState.transform = transform;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.transform == transform) return false;
+    mState.current.sequence++;
+    mState.current.transform = transform;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
-    if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
-    mCurrentState.sequence++;
-    mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false;
+    mState.current.sequence++;
+    mState.current.transformToDisplayInverse = transformToDisplayInverse;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setCrop(const Rect& crop) {
-    if (mCurrentState.crop == crop) return false;
-    mCurrentState.sequence++;
-    mCurrentState.crop = crop;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.crop == crop) return false;
+    mState.current.sequence++;
+    mState.current.crop = crop;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -135,86 +139,94 @@
     int w = frame.getWidth();
     int h = frame.getHeight();
 
-    if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
-        mCurrentState.active.w == w && mCurrentState.active.h == h) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y &&
+        mState.current.active.w == w && mState.current.active.h == h) {
         return false;
     }
 
     if (!frame.isValid()) {
         x = y = w = h = 0;
     }
-    mCurrentState.active.transform.set(x, y);
-    mCurrentState.active.w = w;
-    mCurrentState.active.h = h;
+    mState.current.active.transform.set(x, y);
+    mState.current.active.w = w;
+    mState.current.active.h = h;
 
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
-    if (mCurrentState.buffer) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.buffer) {
         mReleasePreviousBuffer = true;
     }
 
-    mCurrentState.sequence++;
-    mCurrentState.buffer = buffer;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.buffer = buffer;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
+    Mutex::Autolock lock(mStateMutex);
     // The acquire fences of BufferStateLayers have already signaled before they are set
     mCallbackHandleAcquireTime = fence->getSignalTime();
 
-    mCurrentState.acquireFence = fence;
-    mCurrentState.modified = true;
+    mState.current.acquireFence = fence;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
-    if (mCurrentState.dataspace == dataspace) return false;
-    mCurrentState.sequence++;
-    mCurrentState.dataspace = dataspace;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.dataspace == dataspace) return false;
+    mState.current.sequence++;
+    mState.current.dataspace = dataspace;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
-    if (mCurrentState.hdrMetadata == hdrMetadata) return false;
-    mCurrentState.sequence++;
-    mCurrentState.hdrMetadata = hdrMetadata;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.hdrMetadata == hdrMetadata) return false;
+    mState.current.sequence++;
+    mState.current.hdrMetadata = hdrMetadata;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
-    mCurrentState.sequence++;
-    mCurrentState.surfaceDamageRegion = surfaceDamage;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.sequence++;
+    mState.current.surfaceDamageRegion = surfaceDamage;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setApi(int32_t api) {
-    if (mCurrentState.api == api) return false;
-    mCurrentState.sequence++;
-    mCurrentState.api = api;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.api == api) return false;
+    mState.current.sequence++;
+    mState.current.api = api;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
-    if (mCurrentState.sidebandStream == sidebandStream) return false;
-    mCurrentState.sequence++;
-    mCurrentState.sidebandStream = sidebandStream;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.sidebandStream == sidebandStream) return false;
+    mState.current.sequence++;
+    mState.current.sidebandStream = sidebandStream;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     if (!mSidebandStreamChanged.exchange(true)) {
@@ -248,7 +260,10 @@
             mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
 
             // Store so latched time and release fence can be set
-            mCurrentState.callbackHandles.push_back(handle);
+            {
+                Mutex::Autolock lock(mStateMutex);
+                mState.current.callbackHandles.push_back(handle);
+            }
 
         } else { // If this layer will NOT need to be relatched and presented this frame
             // Notify the transaction completed thread this handle is done
@@ -263,8 +278,9 @@
 }
 
 bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.transparentRegionHint = transparent;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.transparentRegionHint = transparent;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -300,6 +316,7 @@
         return true;
     }
 
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
 }
 
@@ -308,7 +325,7 @@
     return 0;
 }
 
-std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
+std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const {
     return std::make_shared<FenceTime>(getDrawingState().acquireFence);
 }
 
@@ -339,14 +356,17 @@
 }
 
 Region BufferStateLayer::getDrawingSurfaceDamage() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().surfaceDamageRegion;
 }
 
 const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().hdrMetadata;
 }
 
 int BufferStateLayer::getDrawingApi() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().api;
 }
 
@@ -371,6 +391,7 @@
 }
 
 std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
+    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
@@ -382,12 +403,12 @@
         }
         recomputeVisibleRegions = true;
 
-        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
+        return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h)));
     }
     return {};
 }
 
-bool BufferStateLayer::hasFrameUpdate() const {
+bool BufferStateLayer::hasFrameUpdateLocked() const {
     return mCurrentStateModified && getCurrentState().buffer != nullptr;
 }
 
@@ -397,6 +418,10 @@
 }
 
 status_t BufferStateLayer::bindTextureImage() {
+    Mutex::Autolock lock(mStateMutex);
+    return bindTextureImageLocked();
+}
+status_t BufferStateLayer::bindTextureImageLocked() {
     const State& s(getDrawingState());
     auto& engine(mFlinger->getRenderEngine());
 
@@ -501,7 +526,7 @@
         auto incomingStatus = releaseFence->getStatus();
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
-            mDrawingState.acquireFence = releaseFence;
+            mState.drawing.acquireFence = releaseFence;
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
         }
@@ -512,16 +537,16 @@
             char fenceName[32] = {};
             snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
             sp<Fence> mergedFence =
-                    Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
+                    Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence);
             if (!mergedFence.get()) {
                 ALOGE("failed to merge release fences");
                 // 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;
+                mState.drawing.acquireFence = releaseFence;
                 mFlinger->mTimeStats->onDestroy(layerID);
                 return BAD_VALUE;
             }
-            mDrawingState.acquireFence = mergedFence;
+            mState.drawing.acquireFence = mergedFence;
         } else if (incomingStatus == Fence::Status::Unsignaled) {
             // If one fence has signaled and the other hasn't, the unsignaled
             // fence will approximately correspond with the correct timestamp.
@@ -530,7 +555,7 @@
             // by this point, they will have both signaled and only the timestamp
             // will be slightly off; any dependencies after this point will
             // already have been met.
-            mDrawingState.acquireFence = releaseFence;
+            mState.drawing.acquireFence = releaseFence;
         }
     } else {
         // Bind the new buffer to the GL texture.
@@ -539,7 +564,7 @@
         // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
         // devices will either call this in Layer::onDraw, or (if it's not
         // a GL-composited layer) not at all.
-        status_t err = bindTextureImage();
+        status_t err = bindTextureImageLocked();
         if (err != NO_ERROR) {
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
@@ -548,7 +573,7 @@
 
     // TODO(marissaw): properly support mTimeStats
     mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
-    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
+    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked());
     mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
 
     return NO_ERROR;
@@ -575,6 +600,7 @@
 }
 
 void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
+    Mutex::Autolock lock(mStateMutex);
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
 
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3f891d3..655353c 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -41,13 +41,14 @@
 
     bool shouldPresentNow(nsecs_t expectedPresentTime) const override;
 
-    bool getTransformToDisplayInverse() const override;
+    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
 
     uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
         return flags;
     }
-    void pushPendingState() override;
-    bool applyPendingStates(Layer::State* stateToCommit) override;
+
+    void pushPendingStateLocked() override REQUIRES(mStateMutex);
+    bool applyPendingStates(Layer::State* stateToCommit) override REQUIRES(mStateMutex);
 
     uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; }
     uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; }
@@ -59,18 +60,20 @@
     }
     Rect getCrop(const Layer::State& s) const;
 
-    bool setTransform(uint32_t transform) override;
-    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
-    bool setCrop(const Rect& crop) override;
-    bool setFrame(const Rect& frame) override;
-    bool setBuffer(const sp<GraphicBuffer>& buffer) override;
-    bool setAcquireFence(const sp<Fence>& fence) override;
-    bool setDataspace(ui::Dataspace dataspace) override;
-    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
-    bool setSurfaceDamageRegion(const Region& surfaceDamage) override;
-    bool setApi(int32_t api) override;
-    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override;
-    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override;
+    bool setTransform(uint32_t transform) override EXCLUDES(mStateMutex);
+    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override
+            EXCLUDES(mStateMutex);
+    bool setCrop(const Rect& crop) override EXCLUDES(mStateMutex);
+    bool setFrame(const Rect& frame) override EXCLUDES(mStateMutex);
+    bool setBuffer(const sp<GraphicBuffer>& buffer) override EXCLUDES(mStateMutex);
+    bool setAcquireFence(const sp<Fence>& fence) override EXCLUDES(mStateMutex);
+    bool setDataspace(ui::Dataspace dataspace) override EXCLUDES(mStateMutex);
+    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override EXCLUDES(mStateMutex);
+    bool setSurfaceDamageRegion(const Region& surfaceDamage) override EXCLUDES(mStateMutex);
+    bool setApi(int32_t api) override EXCLUDES(mStateMutex);
+    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override EXCLUDES(mStateMutex);
+    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override
+            EXCLUDES(mStateMutex);
 
     // Override to ignore legacy layer state properties that are not used by BufferStateLayer
     bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; }
@@ -87,26 +90,26 @@
     void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
                                       uint64_t /*frameNumber*/) override {}
 
-    Rect getBufferSize(const State& s) const override;
+    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
     // -----------------------------------------------------------------------
 
     // -----------------------------------------------------------------------
     // Interface implementation for BufferLayer
     // -----------------------------------------------------------------------
-    bool fenceHasSignaled() const override;
+    bool fenceHasSignaled() const override EXCLUDES(mStateMutex);
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
+    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override;
-    ui::Dataspace getDrawingDataSpace() const override;
-    Rect getDrawingCrop() const override;
+    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
+    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
+    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
     uint32_t getDrawingScalingMode() const override;
-    Region getDrawingSurfaceDamage() const override;
-    const HdrMetadata& getDrawingHdrMetadata() const override;
-    int getDrawingApi() const override;
+    Region getDrawingSurfaceDamage() const override EXCLUDES(mStateMutex);
+    const HdrMetadata& getDrawingHdrMetadata() const override EXCLUDES(mStateMutex);
+    int getDrawingApi() const override EXCLUDES(mStateMutex);
     PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
@@ -114,24 +117,26 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
+            EXCLUDES(mStateMutex);
 
-    bool hasFrameUpdate() const override;
+    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
 
     void setFilteringEnabled(bool enabled) override;
 
-    status_t bindTextureImage() override;
+    status_t bindTextureImage() override EXCLUDES(mStateMutex);
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override;
+                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
 
-    status_t updateActiveBuffer() override;
+    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void setHwcLayerBuffer(DisplayId displayId) override;
+    void setHwcLayerBuffer(DisplayId displayId) override EXCLUDES(mStateMutex);
 
 private:
     void onFirstRef() override;
     bool willPresentCurrentTransaction() const;
+    status_t bindTextureImageLocked() REQUIRES(mStateMutex);
 
     static const std::array<float, 16> IDENTITY_MATRIX;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index f27f6aa..cb7642e 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -40,15 +40,16 @@
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) {
+    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     if (color.a > 0) {
         renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2);
         computeGeometry(renderArea, mesh, useIdentityTransform);
         auto& engine(mFlinger->getRenderEngine());
 
-        Rect win{computeBounds()};
+        Rect win{computeBoundsLocked()};
 
-        const auto roundedCornerState = getRoundedCornerState();
+        const auto roundedCornerState = getRoundedCornerStateLocked();
         const auto cropRect = roundedCornerState.cropRect;
         setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -91,6 +92,7 @@
     }
     getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
 
+    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                                 static_cast<uint8_t>(std::round(255.0f * color.g)),
@@ -111,12 +113,12 @@
     }
     getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
 
-    error = hwcLayer->setColorTransform(getColorTransform());
+    error = hwcLayer->setColorTransform(getColorTransformLocked());
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
-    getBE().compositionInfo.hwc.colorTransform = getColorTransform();
+    getBE().compositionInfo.hwc.colorTransform = getColorTransformLocked();
 
     error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
     if (error != HWC2::Error::None) {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index d1b1697..5850a2e 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -29,12 +29,12 @@
     ~ColorLayer() override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform);
-    bool isVisible() const override;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
+            EXCLUDES(mStateMutex);
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
-                         int32_t supportedPerFrameMetadata) override;
+                         int32_t supportedPerFrameMetadata) override EXCLUDES(mStateMutex);
 
     bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
 
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 413844b..6c4f7c8 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,7 +31,7 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    bool isVisible() const override;
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                          int32_t supportedPerFrameMetadata) override;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 2963a97..3ad07ae 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -222,6 +222,7 @@
       : lastCompositionHadVisibleLayers(false),
         mFlinger(args.flinger),
         mDisplayToken(args.displayToken),
+        mSequenceId(args.sequenceId),
         mId(args.displayId),
         mNativeWindow(args.nativeWindow),
         mGraphicBuffer(nullptr),
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 8357228..ba85432 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -112,6 +112,7 @@
 
     const std::optional<DisplayId>& getId() const { return mId; }
     const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
+    int32_t getSequenceId() const { return mSequenceId; }
 
     int32_t getSupportedPerFrameMetadata() const { return mSupportedPerFrameMetadata; }
 
@@ -205,6 +206,7 @@
 private:
     const sp<SurfaceFlinger> mFlinger;
     const wp<IBinder> mDisplayToken;
+    const int32_t mSequenceId;
 
     std::optional<DisplayId> mId;
 
@@ -332,6 +334,7 @@
     const wp<IBinder> displayToken;
     const std::optional<DisplayId> displayId;
 
+    int32_t sequenceId{0};
     bool isVirtual{false};
     bool isSecure{false};
     sp<ANativeWindow> nativeWindow;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6d0fdad..f4b3cdd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,35 +83,35 @@
 
     mTransactionName = String8("TX - ") + mName;
 
-    mCurrentState.active_legacy.w = args.w;
-    mCurrentState.active_legacy.h = args.h;
-    mCurrentState.flags = layerFlags;
-    mCurrentState.active_legacy.transform.set(0, 0);
-    mCurrentState.crop_legacy.makeInvalid();
-    mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
-    mCurrentState.z = 0;
-    mCurrentState.color.a = 1.0f;
-    mCurrentState.layerStack = 0;
-    mCurrentState.sequence = 0;
-    mCurrentState.requested_legacy = mCurrentState.active_legacy;
-    mCurrentState.appId = 0;
-    mCurrentState.type = 0;
-    mCurrentState.active.w = UINT32_MAX;
-    mCurrentState.active.h = UINT32_MAX;
-    mCurrentState.active.transform.set(0, 0);
-    mCurrentState.transform = 0;
-    mCurrentState.transformToDisplayInverse = false;
-    mCurrentState.crop.makeInvalid();
-    mCurrentState.acquireFence = new Fence(-1);
-    mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
-    mCurrentState.hdrMetadata.validTypes = 0;
-    mCurrentState.surfaceDamageRegion.clear();
-    mCurrentState.cornerRadius = 0.0f;
-    mCurrentState.api = -1;
-    mCurrentState.hasColorTransform = false;
+    mState.current.active_legacy.w = args.w;
+    mState.current.active_legacy.h = args.h;
+    mState.current.flags = layerFlags;
+    mState.current.active_legacy.transform.set(0, 0);
+    mState.current.crop_legacy.makeInvalid();
+    mState.current.requestedCrop_legacy = mState.current.crop_legacy;
+    mState.current.z = 0;
+    mState.current.color.a = 1.0f;
+    mState.current.layerStack = 0;
+    mState.current.sequence = 0;
+    mState.current.requested_legacy = mState.current.active_legacy;
+    mState.current.appId = 0;
+    mState.current.type = 0;
+    mState.current.active.w = UINT32_MAX;
+    mState.current.active.h = UINT32_MAX;
+    mState.current.active.transform.set(0, 0);
+    mState.current.transform = 0;
+    mState.current.transformToDisplayInverse = false;
+    mState.current.crop.makeInvalid();
+    mState.current.acquireFence = new Fence(-1);
+    mState.current.dataspace = ui::Dataspace::UNKNOWN;
+    mState.current.hdrMetadata.validTypes = 0;
+    mState.current.surfaceDamageRegion.clear();
+    mState.current.cornerRadius = 0.0f;
+    mState.current.api = -1;
+    mState.current.hasColorTransform = false;
 
     // drawing state & current state are identical
-    mDrawingState = mCurrentState;
+    mState.drawing = mState.current;
 
     CompositorTiming compositorTiming;
     args.flinger->getCompositorTiming(&compositorTiming);
@@ -148,14 +148,17 @@
 void Layer::onRemovedFromCurrentState() {
     mRemovedFromCurrentState = true;
 
-    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
-        if (strongRelative != nullptr) {
-            strongRelative->removeZOrderRelative(this);
-            mFlinger->setTransactionFlags(eTraversalNeeded);
+    {
+        Mutex::Autolock lock(mStateMutex);
+        // the layer is removed from SF mState.current to mLayersPendingRemoval
+        if (mState.current.zOrderRelativeOf != nullptr) {
+            sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
+            if (strongRelative != nullptr) {
+                strongRelative->removeZOrderRelative(this);
+                mFlinger->setTransactionFlags(eTraversalNeeded);
+            }
+            mState.current.zOrderRelativeOf = nullptr;
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
     }
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
@@ -294,21 +297,32 @@
 }
 
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
-    FloatRect bounds = computeBounds(transparentRegion);
-    ui::Transform t = getTransform();
+    FloatRect bounds = computeBoundsLocked(transparentRegion);
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     bounds = t.transform(bounds);
     return Rect{bounds};
 }
 
 FloatRect Layer::computeBounds() const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked();
+}
+
+FloatRect Layer::computeBoundsLocked() const {
     const State& s(getDrawingState());
-    return computeBounds(getActiveTransparentRegion(s));
+    return computeBoundsLocked(getActiveTransparentRegion(s));
 }
 
 FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked(activeTransparentRegion);
+}
+
+FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const {
     const State& s(getDrawingState());
     Rect bounds = getCroppedBufferSize(s);
     FloatRect floatBounds = bounds.toFloatRect();
@@ -361,6 +375,7 @@
         // child bounds as well.
         ui::Transform t = s.active_legacy.transform;
         croppedBounds = t.transform(croppedBounds);
+        Mutex::Autolock lock(p->mStateMutex);
         croppedBounds = p->cropChildBounds(croppedBounds);
         croppedBounds = t.inverse().transform(croppedBounds);
     }
@@ -388,8 +403,8 @@
     // if there are no window scaling involved, this operation will map to full
     // pixels in the buffer.
 
-    FloatRect activeCropFloat = computeBounds();
-    ui::Transform t = getTransform();
+    FloatRect activeCropFloat = computeBoundsLocked();
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     activeCropFloat = t.transform(activeCropFloat);
     activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
@@ -439,7 +454,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -490,6 +505,7 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     RETURN_IF_NO_HWC_LAYER(*displayId);
@@ -498,7 +514,7 @@
     // enable this layer
     hwcInfo.forceClientComposition = false;
 
-    if (isSecure() && !display->isSecure()) {
+    if (isSecureLocked() && !display->isSecure()) {
         hwcInfo.forceClientComposition = true;
     }
 
@@ -508,7 +524,7 @@
     const State& s(getDrawingState());
     const Rect bufferSize = getBufferSize(s);
     auto blendMode = HWC2::BlendMode::None;
-    if (!isOpaque(s) || getAlpha() != 1.0f) {
+    if (!isOpaque(s) || getAlphaLocked() != 1.0f) {
         blendMode =
                 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
@@ -523,7 +539,7 @@
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
     Region activeTransparentRegion(getActiveTransparentRegion(s));
-    ui::Transform t = getTransform();
+    ui::Transform t = getTransformLocked();
     Rect activeCrop = getCrop(s);
     if (!activeCrop.isEmpty() && bufferSize.isValid()) {
         activeCrop = t.transform(activeCrop);
@@ -551,7 +567,7 @@
 
     // computeBounds returns a FloatRect to provide more accuracy during the
     // transformation. We then round upon constructing 'frame'.
-    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
+    Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))};
     if (!frame.intersect(display->getViewport(), &frame)) {
         frame.clear();
     }
@@ -579,7 +595,7 @@
     }
     getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
-    float alpha = static_cast<float>(getAlpha());
+    float alpha = static_cast<float>(getAlphaLocked());
     error = hwcLayer->setPlaneAlpha(alpha);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set plane alpha %.3f: "
@@ -596,6 +612,7 @@
     int appId = s.appId;
     sp<Layer> parent = mDrawingParent.promote();
     if (parent.get()) {
+        Mutex::Autolock lock(parent->mStateMutex);
         auto& parentState = parent->getDrawingState();
         if (parentState.type >= 0 || parentState.appId >= 0) {
             type = parentState.type;
@@ -621,7 +638,7 @@
     const ui::Transform bufferOrientation(mCurrentTransform);
     ui::Transform transform(tr * t * bufferOrientation);
 
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -671,6 +688,7 @@
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
@@ -685,7 +703,7 @@
     Rect win = getCroppedBufferSize(s);
     // Subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, getActiveTransparentRegion(s));
-    Rect frame(getTransform().transform(bounds));
+    Rect frame(getTransformLocked().transform(bounds));
     frame.intersect(display->getViewport(), &frame);
     auto& displayTransform = display->getTransform();
     auto position = displayTransform.transform(frame);
@@ -715,6 +733,7 @@
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
                             float alpha) const {
     auto& engine(mFlinger->getRenderEngine());
+    Mutex::Autolock lock(mStateMutex);
     computeGeometry(renderArea, getBE().mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(getBE().mMesh);
@@ -799,14 +818,14 @@
                             renderengine::Mesh& mesh,
                             bool useIdentityTransform) const {
     const ui::Transform renderAreaTransform(renderArea.getTransform());
-    FloatRect win = computeBounds();
+    FloatRect win = computeBoundsLocked();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
     vec2 rb = vec2(win.right, win.bottom);
     vec2 rt = vec2(win.right, win.top);
 
-    ui::Transform layerTransform = getTransform();
+    ui::Transform layerTransform = getTransformLocked();
     if (!useIdentityTransform) {
         lt = layerTransform.transform(lt);
         lb = layerTransform.transform(lb);
@@ -822,7 +841,12 @@
 }
 
 bool Layer::isSecure() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    return isSecureLocked();
+}
+
+bool Layer::isSecureLocked() const {
+    const State& s(mState.drawing);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
@@ -850,9 +874,13 @@
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
-
 void Layer::pushPendingState() {
-    if (!mCurrentState.modified) {
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
+}
+
+void Layer::pushPendingStateLocked() {
+    if (!mState.current.modified) {
         return;
     }
 
@@ -860,22 +888,22 @@
     // point and send it to the remote layer.
     // We don't allow installing sync points after we are removed from the current state
     // as we won't be able to signal our end.
-    if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
-        sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote();
+    if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
+        sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote();
         if (barrierLayer == nullptr) {
             ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mCurrentState.barrierLayer_legacy = nullptr;
+            mState.current.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mCurrentState.barrierLayer_legacy = nullptr;
+                mState.current.barrierLayer_legacy = nullptr;
             }
         }
 
@@ -883,21 +911,21 @@
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
-    mPendingStates.push_back(mCurrentState);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.push_back(mState.current);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 void Layer::popPendingState(State* stateToCommit) {
-    *stateToCommit = mPendingStates[0];
+    *stateToCommit = mState.pending[0];
 
-    mPendingStates.removeAt(0);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.removeAt(0);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
-    while (!mPendingStates.empty()) {
-        if (mPendingStates[0].barrierLayer_legacy != nullptr) {
+    while (!mState.pending.empty()) {
+        if (mState.pending[0].barrierLayer_legacy != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -909,7 +937,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mPendingStates[0].frameNumber_legacy) {
+                mState.pending[0].frameNumber_legacy) {
                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
@@ -937,12 +965,12 @@
 
     // If we still have pending updates, wake SurfaceFlinger back up and point
     // it at this layer so we can process them
-    if (!mPendingStates.empty()) {
+    if (!mState.pending.empty()) {
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
 
-    mCurrentState.modified = false;
+    mState.current.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -1039,7 +1067,8 @@
         return 0;
     }
 
-    pushPendingState();
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
         return 0;
@@ -1071,49 +1100,60 @@
         clearSyncPoints();
     }
 
-    if (mCurrentState.inputInfoChanged) {
+    if (mState.current.inputInfoChanged) {
         flags |= eInputInfoChanged;
-        mCurrentState.inputInfoChanged = false;
+        mState.current.inputInfoChanged = false;
     }
 
     // Commit the transaction
     commitTransaction(c);
-    mCurrentState.callbackHandles = {};
+    mState.current.callbackHandles = {};
     return flags;
 }
 
 void Layer::commitTransaction(const State& stateToCommit) {
-    mDrawingState = stateToCommit;
+    mState.drawing = stateToCommit;
+}
+
+uint32_t Layer::getTransactionFlags() const {
+    Mutex::Autolock lock(mStateMutex);
+    return mState.transactionFlags;
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_and(~flags) & flags;
+    Mutex::Autolock lock(mStateMutex);
+    uint32_t and_flags = mState.transactionFlags & flags;
+    mState.transactionFlags &= ~flags;
+    return and_flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_or(flags);
+    uint32_t old_flags = mState.transactionFlags;
+    mState.transactionFlags |= flags;
+    return old_flags;
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
-    if (mCurrentState.requested_legacy.transform.tx() == x &&
-        mCurrentState.requested_legacy.transform.ty() == y)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.transform.tx() == x &&
+        mState.current.requested_legacy.transform.ty() == y)
         return false;
-    mCurrentState.sequence++;
+    mState.current.sequence++;
 
     // We update the requested and active position simultaneously because
     // we want to apply the position portion of the transform matrix immediately,
     // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
-    mCurrentState.requested_legacy.transform.set(x, y);
+    mState.current.requested_legacy.transform.set(x, y);
     if (immediate && !mFreezeGeometryUpdates) {
         // Here we directly update the active state
         // unlike other setters, because we store it within
         // the transform, but use different latching rules.
         // b/38182305
-        mCurrentState.active_legacy.transform.set(x, y);
+        mState.current.active_legacy.transform.set(x, y);
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1146,38 +1186,44 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
-    mCurrentState.sequence++;
-    mCurrentState.z = z;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current))
+        return false;
+
+    mState.current.sequence++;
+    mState.current.z = z;
+    mState.current.modified = true;
 
     // Discard all relative layering.
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+    if (mState.current.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
             strongRelative->removeZOrderRelative(this);
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
+        mState.current.zOrderRelativeOf = nullptr;
     }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::removeZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.remove(relative);
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.remove(relative);
+    mState.current.sequence++;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::addZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.add(relative);
-    mCurrentState.modified = true;
-    mCurrentState.sequence++;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.add(relative);
+    mState.current.modified = true;
+    mState.current.sequence++;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
+    Mutex::Autolock lock(mStateMutex);
     sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
     if (handle == nullptr) {
         return false;
@@ -1187,20 +1233,20 @@
         return false;
     }
 
-    if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
-            mCurrentState.zOrderRelativeOf == relative) {
+    if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) &&
+        mState.current.zOrderRelativeOf == relative) {
         return false;
     }
 
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
-    mCurrentState.z = relativeZ;
+    mState.current.sequence++;
+    mState.current.modified = true;
+    mState.current.z = relativeZ;
 
-    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
+    auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote();
     if (oldZOrderRelativeOf != nullptr) {
         oldZOrderRelativeOf->removeZOrderRelative(this);
     }
-    mCurrentState.zOrderRelativeOf = relative;
+    mState.current.zOrderRelativeOf = relative;
     relative->addZOrderRelative(this);
 
     setTransactionFlags(eTransactionNeeded);
@@ -1209,48 +1255,51 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h)
         return false;
-    mCurrentState.requested_legacy.w = w;
-    mCurrentState.requested_legacy.h = h;
-    mCurrentState.modified = true;
+    mState.current.requested_legacy.w = w;
+    mState.current.requested_legacy.h = h;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     // record the new size, from this point on, when the client request
     // a buffer, it'll get the new size.
-    setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
+    setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h);
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    if (mCurrentState.color.a == alpha) return false;
-    mCurrentState.sequence++;
-    mCurrentState.color.a = alpha;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.color.a == alpha) return false;
+    mState.current.sequence++;
+    mState.current.color.a = alpha;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setColor(const half3& color) {
-    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
-        color.b == mCurrentState.color.b)
+    Mutex::Autolock lock(mStateMutex);
+    if (color.r == mState.current.color.r && color.g == mState.current.color.g &&
+        color.b == mState.current.color.b)
         return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.color.r = color.r;
-    mCurrentState.color.g = color.g;
-    mCurrentState.color.b = color.b;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.color.r = color.r;
+    mState.current.color.g = color.g;
+    mState.current.color.b = color.b;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCornerRadius(float cornerRadius) {
-    if (mCurrentState.cornerRadius == cornerRadius)
-        return false;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.cornerRadius == cornerRadius) return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.cornerRadius = cornerRadius;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.cornerRadius = cornerRadius;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1264,45 +1313,50 @@
         ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored");
         return false;
     }
-    mCurrentState.sequence++;
-    mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
-                                                 matrix.dsdy);
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.sequence++;
+    mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
+                                                  matrix.dsdy);
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.requestedTransparentRegion_legacy = transparent;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.requestedTransparentRegion_legacy = transparent;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
-    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags) return false;
-    mCurrentState.sequence++;
-    mCurrentState.flags = newFlags;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask);
+    if (mState.current.flags == newFlags) return false;
+    mState.current.sequence++;
+    mState.current.flags = newFlags;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
-    if (mCurrentState.requestedCrop_legacy == crop) return false;
-    mCurrentState.sequence++;
-    mCurrentState.requestedCrop_legacy = crop;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requestedCrop_legacy == crop) return false;
+    mState.current.sequence++;
+    mState.current.requestedCrop_legacy = crop;
     if (immediate && !mFreezeGeometryUpdates) {
-        mCurrentState.crop_legacy = crop;
+        mState.current.crop_legacy = crop;
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
+    Mutex::Autolock lock(mStateMutex);
     if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
@@ -1310,22 +1364,29 @@
 }
 
 void Layer::setInfo(int32_t type, int32_t appId) {
-    mCurrentState.appId = appId;
-    mCurrentState.type = type;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.appId = appId;
+    mState.current.type = type;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    if (mCurrentState.layerStack == layerStack) return false;
-    mCurrentState.sequence++;
-    mCurrentState.layerStack = layerStack;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.layerStack == layerStack) return false;
+    mState.current.sequence++;
+    mState.current.layerStack = layerStack;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 uint32_t Layer::getLayerStack() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getLayerStackLocked();
+}
+
+uint32_t Layer::getLayerStackLocked() const {
     auto p = mDrawingParent.promote();
     if (p == nullptr) {
         return getDrawingState().layerStack;
@@ -1334,15 +1395,16 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
-    mCurrentState.barrierLayer_legacy = barrierLayer;
-    mCurrentState.frameNumber_legacy = frameNumber;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.barrierLayer_legacy = barrierLayer;
+    mState.current.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
-    mCurrentState.modified = true;
-    pushPendingState();
-    mCurrentState.barrierLayer_legacy = nullptr;
-    mCurrentState.frameNumber_legacy = 0;
-    mCurrentState.modified = false;
+    mState.current.modified = true;
+    pushPendingStateLocked();
+    mState.current.barrierLayer_legacy = nullptr;
+    mState.current.frameNumber_legacy = 0;
+    mState.current.modified = false;
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
@@ -1355,7 +1417,8 @@
 // ----------------------------------------------------------------------------
 
 bool Layer::isHiddenByPolicy() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    const State& s(mState.drawing);
     const auto& parent = mDrawingParent.promote();
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
@@ -1400,6 +1463,7 @@
 
 // TODO(marissaw): add new layer state info to layer debugging
 LayerDebugInfo Layer::getLayerDebugInfo() const {
+    Mutex::Autolock lock(mStateMutex);
     LayerDebugInfo info;
     const State& ds = getDrawingState();
     info.mName = getName();
@@ -1409,7 +1473,7 @@
     info.mTransparentRegion = ds.activeTransparentRegion_legacy;
     info.mVisibleRegion = visibleRegion;
     info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStack();
+    info.mLayerStack = getLayerStackLocked();
     info.mX = ds.active_legacy.transform.tx();
     info.mY = ds.active_legacy.transform.ty();
     info.mZ = ds.z;
@@ -1445,6 +1509,13 @@
     return info;
 }
 
+std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+
+    return {state.layerStack, state.z};
+}
+
 void Layer::miniDumpHeader(std::string& result) {
     result.append("-------------------------------");
     result.append("-------------------------------");
@@ -1461,6 +1532,7 @@
 }
 
 void Layer::miniDump(std::string& result, DisplayId displayId) const {
+    Mutex::Autolock lock(mStateMutex);
     if (!hasHwcLayer(displayId)) {
         return;
     }
@@ -1589,6 +1661,7 @@
     }
 
     if (attachChildren()) {
+        Mutex::Autolock lock(mStateMutex);
         setTransactionFlags(eTransactionNeeded);
     }
     for (const sp<Layer>& child : mCurrentChildren) {
@@ -1639,6 +1712,7 @@
         client->updateParent(newParent);
     }
 
+    Mutex::Autolock lock(mStateMutex);
     if (mLayerDetached) {
         mLayerDetached = false;
         setTransactionFlags(eTransactionNeeded);
@@ -1682,18 +1756,24 @@
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
-    if (mCurrentState.colorTransform == matrix) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.colorTransform == matrix) {
         return false;
     }
-    ++mCurrentState.sequence;
-    mCurrentState.colorTransform = matrix;
-    mCurrentState.hasColorTransform = matrix != identityMatrix;
-    mCurrentState.modified = true;
+    ++mState.current.sequence;
+    mState.current.colorTransform = matrix;
+    mState.current.hasColorTransform = matrix != identityMatrix;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 mat4 Layer::getColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getColorTransformLocked();
+}
+
+mat4 Layer::getColorTransformLocked() const {
     mat4 colorTransform = mat4(getDrawingState().colorTransform);
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         colorTransform = parent->getColorTransform() * colorTransform;
@@ -1702,6 +1782,7 @@
 }
 
 bool Layer::hasColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
     bool hasColorTransform = getDrawingState().hasColorTransform;
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         hasColorTransform = hasColorTransform || parent->hasColorTransform();
@@ -1732,12 +1813,18 @@
 }
 
 int32_t Layer::getZ() const {
-    return mDrawingState.z;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    return usingRelativeZLocked(stateSet);
+}
+
+bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
     return state.zOrderRelativeOf != nullptr;
 }
 
@@ -1747,7 +1834,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     if (state.zOrderRelatives.size() == 0) {
         *outSkipRelativeZUsers = true;
@@ -1763,7 +1850,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         if (childState.zOrderRelativeOf != nullptr) {
             continue;
         }
@@ -1802,7 +1889,6 @@
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
-
         if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
             continue;
         }
@@ -1850,7 +1936,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     LayerVector traverse(stateSet);
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1863,7 +1949,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
         // descendent of the top most parent of the tree. If it's not a descendent, then just add
         // the child here since it won't be added later as a relative.
@@ -1920,10 +2006,16 @@
 }
 
 ui::Transform Layer::getTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getTransformLocked();
+}
+
+ui::Transform Layer::getTransformLocked() const {
     ui::Transform t;
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        t = p->getTransform();
+        Mutex::Autolock lock(p->mStateMutex);
+        t = p->getTransformLocked();
 
         // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
         // it isFixedSize) then there may be additional scaling not accounted
@@ -1951,18 +2043,27 @@
 }
 
 half Layer::getAlpha() const {
-    const auto& p = mDrawingParent.promote();
+    Mutex::Autolock lock(mStateMutex);
+    return getAlphaLocked();
+}
 
+half Layer::getAlphaLocked() const {
+    const auto& p = mDrawingParent.promote();
     half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
     return parentAlpha * getDrawingState().color.a;
 }
 
 half4 Layer::getColor() const {
     const half4 color(getDrawingState().color);
-    return half4(color.r, color.g, color.b, getAlpha());
+    return half4(color.r, color.g, color.b, getAlphaLocked());
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getRoundedCornerStateLocked();
+}
+
+Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
         RoundedCornerState parentState = p->getRoundedCornerState();
@@ -1979,7 +2080,7 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
+    return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -1992,19 +2093,21 @@
 }
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
-    mCurrentState.inputInfo = info;
-    mCurrentState.modified = true;
-    mCurrentState.inputInfoChanged = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.inputInfo = info;
+    mState.current.modified = true;
+    mState.current.inputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     ui::Transform requestedTransform = state.active_legacy.transform;
-    ui::Transform transform = getTransform();
+    ui::Transform transform = getTransformLocked();
 
     layerInfo->set_id(sequence);
     layerInfo->set_name(getName().c_str());
@@ -2026,7 +2129,7 @@
     LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
     LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
 
-    layerInfo->set_layer_stack(getLayerStack());
+    layerInfo->set_layer_stack(getLayerStackLocked());
     layerInfo->set_z(state.z);
 
     PositionProto* position = layerInfo->mutable_position();
@@ -2042,7 +2145,7 @@
     size->set_h(state.active_legacy.h);
 
     LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
-    layerInfo->set_corner_radius(getRoundedCornerState().radius);
+    layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius);
 
     layerInfo->set_is_opaque(isOpaque(state));
     layerInfo->set_invalidate(contentDirty);
@@ -2083,7 +2186,7 @@
     layerInfo->set_curr_frame(mCurrentFrameNumber);
     layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    for (const auto& pendingState : mPendingStates) {
+    for (const auto& pendingState : mState.pending) {
         auto barrierLayer = pendingState.barrierLayer_legacy.promote();
         if (barrierLayer != nullptr) {
             BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
@@ -2127,19 +2230,25 @@
 }
 
 InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
-    InputWindowInfo info = mDrawingState.inputInfo;
+    InputWindowInfo info;
+    ui::Transform t;
+    Rect layerBounds;
+    {
+        Mutex::Autolock lock(mStateMutex);
+        info = mState.drawing.inputInfo;
+        t = getTransformLocked();
+        const float xScale = t.sx();
+        const float yScale = t.sy();
+        if (xScale != 1.0f || yScale != 1.0f) {
+            info.windowXScale *= 1.0f / xScale;
+            info.windowYScale *= 1.0f / yScale;
+            info.touchableRegion.scaleSelf(xScale, yScale);
+        }
 
-    ui::Transform t = getTransform();
-    const float xScale = t.sx();
-    const float yScale = t.sy();
-    if (xScale != 1.0f || yScale != 1.0f) {
-        info.windowXScale *= 1.0f / xScale;
-        info.windowYScale *= 1.0f / yScale;
-        info.touchableRegion.scaleSelf(xScale, yScale);
+        // Transform layer size to screen space and inset it by surface insets.
+        layerBounds = getCroppedBufferSize(getDrawingState());
     }
 
-    // Transform layer size to screen space and inset it by surface insets.
-    Rect layerBounds = getCroppedBufferSize(getDrawingState());
     layerBounds = t.transform(layerBounds);
     layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
 
@@ -2162,7 +2271,8 @@
 }
 
 bool Layer::hasInput() const {
-    return mDrawingState.inputInfo.token != nullptr;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.inputInfo.token != nullptr;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7b6709e..57ef65a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -55,6 +55,7 @@
 #include "RenderArea.h"
 
 using namespace android::surfaceflinger;
+using StateSet = android::LayerVector::StateSet;
 
 namespace android {
 
@@ -239,7 +240,7 @@
     // also the rendered size of the layer prior to any transformations. Parent
     // or local matrix transformations will not affect the size of the buffer,
     // but may affect it's on-screen size or clipping.
-    virtual bool setSize(uint32_t w, uint32_t h);
+    virtual bool setSize(uint32_t w, uint32_t h) EXCLUDES(mStateMutex);
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
@@ -254,58 +255,76 @@
 
     // setPosition operates in parent buffer space (pre parent-transform) or display
     // space for top-level layers.
-    virtual bool setPosition(float x, float y, bool immediate);
+    virtual bool setPosition(float x, float y, bool immediate) EXCLUDES(mStateMutex);
     // Buffer space
-    virtual bool setCrop_legacy(const Rect& crop, bool immediate);
+    virtual bool setCrop_legacy(const Rect& crop, bool immediate) EXCLUDES(mStateMutex);
 
     // TODO(b/38182121): Could we eliminate the various latching modes by
     // using the layer hierarchy?
     // -----------------------------------------------------------------------
-    virtual bool setLayer(int32_t z);
-    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
+    virtual bool setLayer(int32_t z) EXCLUDES(mStateMutex);
+    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ)
+            EXCLUDES(mStateMutex);
 
-    virtual bool setAlpha(float alpha);
-    virtual bool setColor(const half3& color);
+    virtual bool setAlpha(float alpha) EXCLUDES(mStateMutex);
+    virtual bool setColor(const half3& color) EXCLUDES(mStateMutex);
 
     // Set rounded corner radius for this layer and its children.
     //
     // We only support 1 radius per layer in the hierarchy, where parent layers have precedence.
     // The shape of the rounded corner rectangle is specified by the crop rectangle of the layer
     // from which we inferred the rounded corner radius.
-    virtual bool setCornerRadius(float cornerRadius);
-    virtual bool setTransparentRegionHint(const Region& transparent);
-    virtual bool setFlags(uint8_t flags, uint8_t mask);
-    virtual bool setLayerStack(uint32_t layerStack);
-    virtual uint32_t getLayerStack() const;
+    virtual bool setCornerRadius(float cornerRadius) EXCLUDES(mStateMutex);
+    virtual bool setTransparentRegionHint(const Region& transparent) EXCLUDES(mStateMutex);
+    virtual bool setFlags(uint8_t flags, uint8_t mask) EXCLUDES(mStateMutex);
+    virtual bool setLayerStack(uint32_t layerStack) EXCLUDES(mStateMutex);
+    virtual uint32_t getLayerStack() const EXCLUDES(mStateMutex);
     virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle,
                                               uint64_t frameNumber);
-    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber);
-    virtual bool setOverrideScalingMode(int32_t overrideScalingMode);
-    virtual void setInfo(int32_t type, int32_t appId);
-    virtual bool reparentChildren(const sp<IBinder>& layer);
+    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber)
+            EXCLUDES(mStateMutex);
+    virtual bool setOverrideScalingMode(int32_t overrideScalingMode) EXCLUDES(mStateMutex);
+    virtual void setInfo(int32_t type, int32_t appId) EXCLUDES(mStateMutex);
+    virtual bool reparentChildren(const sp<IBinder>& layer) EXCLUDES(mStateMutex);
     virtual void setChildrenDrawingParent(const sp<Layer>& layer);
-    virtual bool reparent(const sp<IBinder>& newParentHandle);
+    virtual bool reparent(const sp<IBinder>& newParentHandle) EXCLUDES(mStateMutex);
     virtual bool detachChildren();
     bool attachChildren();
     bool isLayerDetached() const { return mLayerDetached; }
-    virtual bool setColorTransform(const mat4& matrix);
-    virtual mat4 getColorTransform() const;
-    virtual bool hasColorTransform() const;
+    virtual bool setColorTransform(const mat4& matrix) EXCLUDES(mStateMutex);
+    mat4 getColorTransform() const EXCLUDES(mStateMutex);
+    virtual mat4 getColorTransformLocked() const REQUIRES(mStateMutex);
+    virtual bool hasColorTransform() const EXCLUDES(mStateMutex);
+    ;
 
     // Used only to set BufferStateLayer state
-    virtual bool setTransform(uint32_t /*transform*/) { return false; };
-    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
-    virtual bool setCrop(const Rect& /*crop*/) { return false; };
-    virtual bool setFrame(const Rect& /*frame*/) { return false; };
-    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) { return false; };
-    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
-    virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; };
-    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; };
-    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; };
-    virtual bool setApi(int32_t /*api*/) { return false; };
-    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
+    virtual bool setTransform(uint32_t /*transform*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/)
+            EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setCrop(const Rect& /*crop*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setFrame(const Rect& /*frame*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setDataspace(ui::Dataspace /*dataspace*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setApi(int32_t /*api*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/)
+            EXCLUDES(mStateMutex) {
+        return false;
+    };
     virtual bool setTransactionCompletedListeners(
-            const std::vector<sp<CallbackHandle>>& /*handles*/) {
+            const std::vector<sp<CallbackHandle>>& /*handles*/) EXCLUDES(mStateMutex) {
         return false;
     };
 
@@ -324,18 +343,21 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
-    uint32_t getTransactionFlags() const { return mTransactionFlags; }
-    uint32_t getTransactionFlags(uint32_t flags);
-    uint32_t setTransactionFlags(uint32_t flags);
+    uint32_t getTransactionFlags() const EXCLUDES(mStateMutex);
+    uint32_t getTransactionFlags(uint32_t flags) EXCLUDES(mStateMutex);
+    uint32_t setTransactionFlags(uint32_t flags) REQUIRES(mStateMutex);
 
-    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
+    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const EXCLUDES(mStateMutex) {
         return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
     }
 
     void computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh,
-                         bool useIdentityTransform) const;
-    FloatRect computeBounds(const Region& activeTransparentRegion) const;
-    FloatRect computeBounds() const;
+                         bool useIdentityTransform) const REQUIRES(mStateMutex);
+    FloatRect computeBounds(const Region& activeTransparentRegion) const EXCLUDES(mStateMutex);
+    FloatRect computeBoundsLocked(const Region& activeTransparentRegion) const
+            REQUIRES(mStateMutex);
+    FloatRect computeBounds() const EXCLUDES(mStateMutex);
+    FloatRect computeBoundsLocked() const REQUIRES(mStateMutex);
 
     int32_t getSequence() const { return sequence; }
 
@@ -352,16 +374,21 @@
      */
     virtual bool isOpaque(const Layer::State&) const { return false; }
 
+    virtual bool isDrawingOpaque() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return isOpaque(mState.drawing);
+    }
+
     /*
      * isSecure - true if this surface is secure, that is if it prevents
      * screenshots or VNC servers.
      */
-    bool isSecure() const;
+    bool isSecure() const EXCLUDES(mStateMutex);
 
     /*
      * isVisible - true if this layer is visible, false otherwise
      */
-    virtual bool isVisible() const = 0;
+    virtual bool isVisible() const EXCLUDES(mStateMutex) = 0;
 
     /*
      * isHiddenByPolicy - true if this layer has been forced invisible.
@@ -369,7 +396,7 @@
      * For example if this layer has no active buffer, it may not be hidden by
      * policy, but it still can not be visible.
      */
-    bool isHiddenByPolicy() const;
+    bool isHiddenByPolicy() const EXCLUDES(mStateMutex);
 
     /*
      * isFixedSize - true if content has a fixed size
@@ -384,7 +411,8 @@
     bool isRemovedFromCurrentState() const;
 
     void writeToProto(LayerProto* layerInfo,
-                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
+                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing)
+            EXCLUDES(mStateMutex);
 
     void writeToProto(LayerProto* layerInfo, DisplayId displayId);
 
@@ -397,25 +425,32 @@
     virtual Region getActiveTransparentRegion(const Layer::State& s) const {
         return s.activeTransparentRegion_legacy;
     }
+
+    virtual Region getDrawingActiveTransparentRegion() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getActiveTransparentRegion(mState.drawing);
+    }
+
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
 
 protected:
     /*
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform) = 0;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
+            EXCLUDES(mStateMutex) = 0;
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
 
     virtual bool isHdrY410() const { return false; }
 
-    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z);
+    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z) EXCLUDES(mStateMutex);
     void forceClientComposition(DisplayId displayId);
     bool getForceClientComposition(DisplayId displayId);
     virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform,
-                                 const Rect& viewport, int32_t supportedPerFrameMetadata) = 0;
+                                 const Rect& viewport, int32_t supportedPerFrameMetadata)
+            EXCLUDES(mStateMutex) = 0;
 
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
@@ -423,7 +458,7 @@
     HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const;
     void setClearClientTarget(DisplayId displayId, bool clear);
     bool getClearClientTarget(DisplayId displayId) const;
-    void updateCursorPosition(const sp<const DisplayDevice>& display);
+    void updateCursorPosition(const sp<const DisplayDevice>& display) EXCLUDES(mStateMutex);
 
     /*
      * called after page-flip
@@ -446,7 +481,8 @@
     virtual bool onPostComposition(const std::optional<DisplayId>& /*displayId*/,
                                    const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                    const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                   const CompositorTiming& /*compositorTiming*/) {
+                                   const CompositorTiming& /*compositorTiming*/)
+            EXCLUDES(mStateMutex) {
         return false;
     }
 
@@ -458,14 +494,14 @@
      * draw - performs some global clipping optimizations
      * and calls onDraw().
      */
-    void draw(const RenderArea& renderArea, const Region& clip);
-    void draw(const RenderArea& renderArea, bool useIdentityTransform);
+    void draw(const RenderArea& renderArea, const Region& clip) EXCLUDES(mStateMutex);
+    void draw(const RenderArea& renderArea, bool useIdentityTransform) EXCLUDES(mStateMutex);
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
-    uint32_t doTransaction(uint32_t transactionFlags);
+    uint32_t doTransaction(uint32_t transactionFlags) EXCLUDES(mStateMutex);
 
     /*
      * setVisibleRegion - called to set the new visible region. This gives
@@ -498,17 +534,17 @@
      * to figure out if the content or size of a surface has changed.
      */
     virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
-                               const sp<Fence>& /*releaseFence*/) {
+                               const sp<Fence>& /*releaseFence*/) EXCLUDES(mStateMutex) {
         return {};
     }
 
     virtual bool isBufferLatched() const { return false; }
 
     /*
-     * called with the state lock from a binder thread when the layer is
+     * called with SurfaceFlinger mStateLock a binder thread when the layer is
      * removed from the current list to the pending removal list
      */
-    void onRemovedFromCurrentState();
+    void onRemovedFromCurrentState() EXCLUDES(mStateMutex);
 
     /*
      * Called when the layer is added back to the current state list.
@@ -528,7 +564,7 @@
     /*
      * Returns if a frame is ready
      */
-    virtual bool hasReadyFrame() const { return false; }
+    virtual bool hasReadyFrame() const EXCLUDES(mStateMutex) { return false; }
 
     virtual int32_t getQueuedFrameCount() const { return 0; }
 
@@ -557,17 +593,32 @@
     }
 
     // -----------------------------------------------------------------------
-    void clearWithOpenGL(const RenderArea& renderArea) const;
+    void clearWithOpenGL(const RenderArea& renderArea) const EXCLUDES(mStateMutex);
 
-    inline const State& getDrawingState() const { return mDrawingState; }
-    inline const State& getCurrentState() const { return mCurrentState; }
-    inline State& getCurrentState() { return mCurrentState; }
+    inline const State& getDrawingState() const REQUIRES(mStateMutex) { return mState.drawing; }
 
-    LayerDebugInfo getLayerDebugInfo() const;
+    inline const State& getCurrentState() const REQUIRES(mStateMutex) { return mState.current; }
+
+    inline State& getCurrentState() REQUIRES(mStateMutex) { return mState.current; }
+
+    std::tuple<uint32_t, int32_t> getLayerStackAndZ(StateSet stateSet) EXCLUDES(mStateMutex);
+    wp<Layer> getZOrderRelativeOf(StateSet stateSet) EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+
+        return state.zOrderRelativeOf;
+    }
+
+    uint8_t getCurrentFlags() EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return mState.current.flags;
+    }
+
+    LayerDebugInfo getLayerDebugInfo() const EXCLUDES(mStateMutex);
 
     /* always call base class first */
     static void miniDumpHeader(std::string& result);
-    void miniDump(std::string& result, DisplayId displayId) const;
+    void miniDump(std::string& result, DisplayId displayId) const EXCLUDES(mStateMutex);
     void dumpFrameStats(std::string& result) const;
     void dumpFrameEvents(std::string& result);
     void clearFrameStats();
@@ -582,22 +633,29 @@
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
                                   FrameEventHistoryDelta* outDelta);
 
-    virtual bool getTransformToDisplayInverse() const { return false; }
+    bool getTransformToDisplayInverse() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getTransformToDisplayInverseLocked();
+    }
 
-    ui::Transform getTransform() const;
+    virtual bool getTransformToDisplayInverseLocked() const REQUIRES(mStateMutex) { return false; }
+
+    ui::Transform getTransform() const EXCLUDES(mStateMutex);
+    ui::Transform getTransformLocked() const REQUIRES(mStateMutex);
 
     // Returns the Alpha of the Surface, accounting for the Alpha
     // of parent Surfaces in the hierarchy (alpha's will be multiplied
     // down the hierarchy).
-    half getAlpha() const;
-    half4 getColor() const;
+    half getAlpha() const EXCLUDES(mStateMutex);
+    half4 getColor() const REQUIRES(mStateMutex);
 
     // Returns how rounded corners should be drawn for this layer.
     // This will traverse the hierarchy until it reaches its root, finding topmost rounded
     // corner definition and converting it into current layer's coordinates.
     // As of now, only 1 corner radius per display list is supported. Subsequent ones will be
     // ignored.
-    RoundedCornerState getRoundedCornerState() const;
+    RoundedCornerState getRoundedCornerState() const EXCLUDES(mStateMutex);
+    RoundedCornerState getRoundedCornerStateLocked() const REQUIRES(mStateMutex);
 
     void traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                  const LayerVector::Visitor& visitor);
@@ -617,7 +675,7 @@
     ssize_t removeChild(const sp<Layer>& layer);
     sp<Layer> getParent() const { return mCurrentParent.promote(); }
     bool hasParent() const { return getParent() != nullptr; }
-    Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
+    Rect computeScreenBounds(bool reduceTransparentRegion = true) const EXCLUDES(mStateMutex);
     bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
     bool setChildRelativeLayer(const sp<Layer>& childLayer,
             const sp<IBinder>& relativeToHandle, int32_t relativeZ);
@@ -625,14 +683,23 @@
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-    int32_t getZ() const;
-    virtual void pushPendingState();
+    int32_t getZ() const EXCLUDES(mStateMutex);
+    void pushPendingState() EXCLUDES(mStateMutex);
+    virtual void pushPendingStateLocked() REQUIRES(mStateMutex);
 
     /**
      * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
      * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
      */
-    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
+    virtual Rect getBufferSize(const Layer::State&) const REQUIRES(mStateMutex) {
+        return Rect::INVALID_RECT;
+    }
+
+    virtual Rect getBufferSize(StateSet stateSet) const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+        return getBufferSize(state);
+    }
 
 protected:
     // constant
@@ -661,16 +728,17 @@
     // For unit tests
     friend class TestableSurfaceFlinger;
 
-    void commitTransaction(const State& stateToCommit);
+    void commitTransaction(const State& stateToCommit) REQUIRES(mStateMutex);
 
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
-    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
+    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const
+            REQUIRES(mStateMutex);
     // Compute the initial crop as specified by parent layers and the
     // SurfaceControl for this layer. Does not include buffer crop from the
     // IGraphicBufferProducer client, as that should not affect child clipping.
     // Returns in screen space.
-    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
+    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const REQUIRES(mStateMutex);
     /**
      * Setup rounded corners coordinates of this layer, taking into account the layer bounds and
      * crop coordinates, transforming them into layer space.
@@ -678,13 +746,13 @@
     void setupRoundedCornersCropCoordinates(Rect win, const FloatRect& roundedCornersCrop) const;
 
     // drawing
-    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
-                         float alpha) const;
+    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, float alpha) const
+            EXCLUDES(mStateMutex);
     void setParent(const sp<Layer>& layer);
 
     LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
-    void addZOrderRelative(const wp<Layer>& relative);
-    void removeZOrderRelative(const wp<Layer>& relative);
+    void addZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
+    void removeZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
 
     class SyncPoint {
     public:
@@ -720,9 +788,10 @@
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
-    void popPendingState(State* stateToCommit);
-    virtual bool applyPendingStates(State* stateToCommit);
-    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit);
+    void popPendingState(State* stateToCommit) REQUIRES(mStateMutex);
+    virtual bool applyPendingStates(State* stateToCommit) REQUIRES(mStateMutex);
+    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit)
+            REQUIRES(mStateMutex);
 
     void clearSyncPoints();
 
@@ -755,14 +824,15 @@
     bool getPremultipledAlpha() const;
 
     bool mPendingHWCDestroy{false};
-    void setInputInfo(const InputWindowInfo& info);
+    void setInputInfo(const InputWindowInfo& info) EXCLUDES(mStateMutex);
 
-    InputWindowInfo fillInputInfo(const Rect& screenBounds);
-    bool hasInput() const;
+    InputWindowInfo fillInputInfo(const Rect& screenBounds) EXCLUDES(mStateMutex);
+    bool hasInput() const EXCLUDES(mStateMutex);
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet);
+    bool usingRelativeZ(LayerVector::StateSet stateSet) EXCLUDES(mStateMutex);
+    bool usingRelativeZLocked(LayerVector::StateSet stateSet) REQUIRES(mStateMutex);
 
     bool mPremultipliedAlpha{true};
     String8 mName;
@@ -770,14 +840,14 @@
 
     bool mPrimaryDisplayOnly = false;
 
-    // these are protected by an external lock
-    State mCurrentState;
-    State mDrawingState;
-    std::atomic<uint32_t> mTransactionFlags{0};
-
     // Accessed from main thread and binder threads
-    Mutex mPendingStateMutex;
-    Vector<State> mPendingStates;
+    mutable Mutex mStateMutex;
+    struct {
+        State current;
+        State drawing;
+        uint32_t transactionFlags{0};
+        Vector<State> pending;
+    } mState GUARDED_BY(mStateMutex);
 
     // Timestamp history for UIAutomation. Thread safe.
     FrameTracker mFrameTracker;
@@ -850,7 +920,7 @@
      * The cropped bounds must be transformed back from parent layer space to child layer space by
      * applying the inverse of the child's transformation.
      */
-    FloatRect cropChildBounds(const FloatRect& childBounds) const;
+    FloatRect cropChildBounds(const FloatRect& childBounds) const REQUIRES(mStateMutex);
 
     /**
      * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return
@@ -858,7 +928,12 @@
      * A layer with an invalid buffer size and no crop is considered to be boundless. The layer
      * bounds are constrained by its parent bounds.
      */
-    Rect getCroppedBufferSize(const Layer::State& s) const;
+    Rect getCroppedBufferSize(const Layer::State& s) const REQUIRES(mStateMutex);
+
+    // locked version of public methods
+    bool isSecureLocked() const REQUIRES(mStateMutex);
+    virtual uint32_t getLayerStackLocked() const REQUIRES(mStateMutex);
+    half getAlphaLocked() const REQUIRES(mStateMutex);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index 8494524..a7db23e 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -38,18 +38,12 @@
     const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
     const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
 
-    const auto& lState =
-            (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
-    const auto& rState =
-            (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
+    const auto& [ls, lz] = l->getLayerStackAndZ(mStateSet);
+    const auto& [rs, rz] = r->getLayerStackAndZ(mStateSet);
 
-    uint32_t ls = lState.layerStack;
-    uint32_t rs = rState.layerStack;
     if (ls != rs)
         return (ls > rs) ? 1 : -1;
 
-    int32_t lz = lState.z;
-    int32_t rz = rState.z;
     if (lz != rz)
         return (lz > rz) ? 1 : -1;
 
@@ -62,9 +56,8 @@
 void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (size_t i = 0; i < size(); i++) {
         const auto& layer = (*this)[i];
-        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
-                                                      : layer->getDrawingState();
-        if (state.zOrderRelativeOf != nullptr) {
+        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
+        if (zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInZOrder(stateSet, visitor);
@@ -74,9 +67,8 @@
 void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
         const auto& layer = (*this)[i];
-        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
-                                                      : layer->getDrawingState();
-        if (state.zOrderRelativeOf != nullptr) {
+        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
+        if (zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInReverseZOrder(stateSet, visitor);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a14ca2d..e6a43c5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1494,7 +1494,7 @@
     // Re-enable default display.
     display = getDefaultDisplayDeviceLocked();
     LOG_ALWAYS_FATAL_IF(!display);
-    setPowerModeInternal(display, currentDisplayPowerMode, /*stateLockHeld*/ true);
+    setPowerModeInternal(display, currentDisplayPowerMode);
 
     // Reset the timing values to account for the period of the swapped in HWC
     const auto activeConfig = getHwComposer().getActiveConfig(*display->getId());
@@ -2358,6 +2358,7 @@
         const DisplayDeviceState& state, const sp<DisplaySurface>& dispSurface,
         const sp<IGraphicBufferProducer>& producer) {
     DisplayDeviceCreationArgs creationArgs(this, displayToken, displayId);
+    creationArgs.sequenceId = state.sequenceId;
     creationArgs.isVirtual = state.isVirtual();
     creationArgs.isSecure = state.isSecure;
     creationArgs.displaySurface = dispSurface;
@@ -2832,9 +2833,6 @@
     outDirtyRegion.clear();
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
-        // start with the whole surface at its current location
-        const Layer::State& s(layer->getDrawingState());
-
         // only consider the layers on the given layer stack
         if (!layer->belongsToDisplay(display->getLayerStack(), display->isPrimary())) {
             return;
@@ -2872,7 +2870,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque(s);
+            const bool translucent = !layer->isDrawingOpaque();
             Rect bounds(layer->computeScreenBounds());
 
             visibleRegion.set(bounds);
@@ -2882,7 +2880,8 @@
                 if (translucent) {
                     if (tr.preserveRects()) {
                         // transform the transparent region
-                        transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
+                        transparentRegion =
+                                tr.transform(layer->getDrawingActiveTransparentRegion());
                     } else {
                         // transformation too complex, can't do the
                         // transparent region optimization.
@@ -3170,9 +3169,8 @@
                 case HWC2::Composition::Sideband:
                 case HWC2::Composition::SolidColor: {
                     LOG_ALWAYS_FATAL_IF(!displayId);
-                    const Layer::State& state(layer->getDrawingState());
                     if (layer->getClearClientTarget(*displayId) && !firstLayer &&
-                        layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
+                        layer->isDrawingOpaque() && (layer->getAlpha() == 1.0f) &&
                         layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
@@ -3935,7 +3933,7 @@
     const auto display = getDisplayDevice(displayToken);
     if (!display) return;
 
-    setPowerModeInternal(display, HWC_POWER_MODE_NORMAL, /*stateLockHeld*/ false);
+    setPowerModeInternal(display, HWC_POWER_MODE_NORMAL);
 
     const auto activeConfig = getHwComposer().getActiveConfig(*display->getId());
     const nsecs_t period = activeConfig->getVsyncPeriod();
@@ -3952,8 +3950,7 @@
     postMessageAsync(new LambdaMessage([this] { onInitializeDisplays(); }));
 }
 
-void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int mode,
-                                          bool stateLockHeld) {
+void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int mode) {
     if (display->isVirtual()) {
         ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
         return;
@@ -3972,13 +3969,7 @@
     display->setPowerMode(mode);
 
     if (mInterceptor->isEnabled()) {
-        ConditionalLock lock(mStateLock, !stateLockHeld);
-        ssize_t idx = mCurrentState.displays.indexOfKey(display->getDisplayToken());
-        if (idx < 0) {
-            ALOGW("Surface Interceptor SavePowerMode: invalid display token");
-            return;
-        }
-        mInterceptor->savePowerModeUpdate(mCurrentState.displays.valueAt(idx).sequenceId, mode);
+        mInterceptor->savePowerModeUpdate(display->getSequenceId(), mode);
     }
 
     if (currentMode == HWC_POWER_MODE_OFF) {
@@ -4073,7 +4064,7 @@
         } else if (display->isVirtual()) {
             ALOGW("Attempt to set power mode %d for virtual display", mode);
         } else {
-            setPowerModeInternal(display, mode, /*stateLockHeld*/ false);
+            setPowerModeInternal(display, mode);
         }
     }));
 }
@@ -5203,15 +5194,12 @@
                 mFlinger(flinger),
                 mChildrenOnly(childrenOnly) {}
         const ui::Transform& getTransform() const override { return mTransform; }
-        Rect getBounds() const override {
-            const Layer::State& layerState(mLayer->getDrawingState());
-            return mLayer->getBufferSize(layerState);
-        }
+        Rect getBounds() const override { return mLayer->getBufferSize(StateSet::Drawing); }
         int getHeight() const override {
-            return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
+            return mLayer->getBufferSize(StateSet::Drawing).getHeight();
         }
         int getWidth() const override {
-            return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
+            return mLayer->getBufferSize(StateSet::Drawing).getWidth();
         }
         bool isSecure() const override { return false; }
         bool needsFiltering() const override { return mNeedsFiltering; }
@@ -5278,7 +5266,7 @@
 
     const int uid = IPCThreadState::self()->getCallingUid();
     const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
-    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
+    if (!forSystem && parent->getCurrentFlags() & layer_state_t::eLayerSecure) {
         ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
@@ -5286,12 +5274,12 @@
     Rect crop(sourceCrop);
     if (sourceCrop.width() <= 0) {
         crop.left = 0;
-        crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
+        crop.right = parent->getBufferSize(StateSet::Current).getWidth();
     }
 
     if (sourceCrop.height() <= 0) {
         crop.top = 0;
-        crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
+        crop.bottom = parent->getBufferSize(StateSet::Current).getHeight();
     }
 
     int32_t reqWidth = crop.width() * frameScale;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4977ca0..d3f0ece 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -524,7 +524,7 @@
     // called on the main thread in response to setActiveConfig()
     void setActiveConfigInternal(const sp<DisplayDevice>& display, int mode);
     // called on the main thread in response to setPowerMode()
-    void setPowerModeInternal(const sp<DisplayDevice>& display, int mode, bool stateLockHeld);
+    void setPowerModeInternal(const sp<DisplayDevice>& display, int mode);
 
     // Called on the main thread in response to setActiveColorMode()
     void setActiveColorModeInternal(const sp<DisplayDevice>& display, ui::ColorMode colorMode,
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 7bfe033..a6dcb7e 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -101,22 +101,23 @@
     transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
-    addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
-                      layer->mCurrentState.active_legacy.transform.ty());
-    addDepthLocked(transaction, layerId, layer->mCurrentState.z);
-    addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
+    Mutex::Autolock lock(layer->mStateMutex);
+    addPositionLocked(transaction, layerId, layer->mState.current.active_legacy.transform.tx(),
+                      layer->mState.current.active_legacy.transform.ty());
+    addDepthLocked(transaction, layerId, layer->mState.current.z);
+    addAlphaLocked(transaction, layerId, layer->mState.current.color.a);
     addTransparentRegionLocked(transaction, layerId,
-                               layer->mCurrentState.activeTransparentRegion_legacy);
-    addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
-    addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy);
-    addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
-    if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
+                               layer->mState.current.activeTransparentRegion_legacy);
+    addLayerStackLocked(transaction, layerId, layer->mState.current.layerStack);
+    addCropLocked(transaction, layerId, layer->mState.current.crop_legacy);
+    addCornerRadiusLocked(transaction, layerId, layer->mState.current.cornerRadius);
+    if (layer->mState.current.barrierLayer_legacy != nullptr) {
         addDeferTransactionLocked(transaction, layerId,
-                                  layer->mCurrentState.barrierLayer_legacy.promote(),
-                                  layer->mCurrentState.frameNumber_legacy);
+                                  layer->mState.current.barrierLayer_legacy.promote(),
+                                  layer->mState.current.frameNumber_legacy);
     }
     addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode());
-    addFlagsLocked(transaction, layerId, layer->mCurrentState.flags);
+    addFlagsLocked(transaction, layerId, layer->mState.current.flags);
 }
 
 void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -426,8 +427,9 @@
     SurfaceCreation* creation(increment->mutable_surface_creation());
     creation->set_id(getLayerId(layer));
     creation->set_name(getLayerName(layer));
-    creation->set_w(layer->mCurrentState.active_legacy.w);
-    creation->set_h(layer->mCurrentState.active_legacy.h);
+    Mutex::Autolock lock(layer->mStateMutex);
+    creation->set_w(layer->mState.current.active_legacy.w);
+    creation->set_h(layer->mState.current.active_legacy.h);
 }
 
 void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment,
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 6d4f7ef..4da08b8 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -178,11 +178,12 @@
 
     using HotplugEvent = SurfaceFlinger::HotplugEvent;
 
-    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; }
-    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; }
+    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mState.current; }
+    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mState.drawing; }
 
     void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
-        layer->mDrawingState.sidebandStream = sidebandStream;
+        Mutex::Autolock lock(layer->mStateMutex);
+        layer->mState.drawing.sidebandStream = sidebandStream;
         layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
     }
 
@@ -226,9 +227,8 @@
 
     auto onInitializeDisplays() { return mFlinger->onInitializeDisplays(); }
 
-    auto setPowerModeInternal(const sp<DisplayDevice>& display, int mode,
-                              bool stateLockHeld = false) {
-        return mFlinger->setPowerModeInternal(display, mode, stateLockHeld);
+    auto setPowerModeInternal(const sp<DisplayDevice>& display, int mode) {
+        return mFlinger->setPowerModeInternal(display, mode);
     }
 
     auto onMessageReceived(int32_t what) { return mFlinger->onMessageReceived(what); }
diff --git a/services/vr/bufferhubd/buffer_channel.cpp b/services/vr/bufferhubd/buffer_channel.cpp
index cf072b6..695396c 100644
--- a/services/vr/bufferhubd/buffer_channel.cpp
+++ b/services/vr/bufferhubd/buffer_channel.cpp
@@ -32,7 +32,7 @@
     : BufferHubChannel(service, buffer_id, channel_id, kDetachedBufferType),
       buffer_node_(buffer_node) {
   client_state_mask_ = buffer_node_->AddNewActiveClientsBitToMask();
-  if (client_state_mask_ == 0ULL) {
+  if (client_state_mask_ == 0U) {
     ALOGE("BufferChannel::BufferChannel: %s", strerror(errno));
     buffer_node_ = nullptr;
   }
@@ -41,7 +41,7 @@
 BufferChannel::~BufferChannel() {
   ALOGD_IF(TRACE, "BufferChannel::~BufferChannel: channel_id=%d buffer_id=%d.",
            channel_id(), buffer_id());
-  if (client_state_mask_ != 0ULL) {
+  if (client_state_mask_ != 0U) {
     buffer_node_->RemoveClientsBitFromMask(client_state_mask_);
   }
   Hangup();
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index 158ef9c..c7695bc 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -17,7 +17,7 @@
 namespace dvr {
 
 ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
-                                 int channel_id, uint64_t client_state_mask,
+                                 int channel_id, uint32_t client_state_mask,
                                  const std::shared_ptr<Channel> producer)
     : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
       client_state_mask_(client_state_mask),
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_channel.h b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
index 744c095..9888db6 100644
--- a/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_channel.h
@@ -51,8 +51,8 @@
   // The concrete implementation of the Buffer object.
   std::shared_ptr<BufferNode> buffer_node_ = nullptr;
 
-  // The state bit of this buffer. Must be one the lower 63 bits.
-  uint64_t client_state_mask_ = 0ULL;
+  // The state bit of this buffer.
+  uint32_t client_state_mask_ = 0U;
 };
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
index 5fb4ec1..5ee551f 100644
--- a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
@@ -16,14 +16,14 @@
   using Message = pdx::Message;
 
   ConsumerChannel(BufferHubService* service, int buffer_id, int channel_id,
-                  uint64_t client_state_mask,
+                  uint32_t client_state_mask,
                   const std::shared_ptr<Channel> producer);
   ~ConsumerChannel() override;
 
   bool HandleMessage(Message& message) override;
   void HandleImpulse(Message& message) override;
 
-  uint64_t client_state_mask() const { return client_state_mask_; }
+  uint32_t client_state_mask() const { return client_state_mask_; }
   BufferInfo GetBufferInfo() const override;
 
   void OnProducerGained();
@@ -39,7 +39,7 @@
   pdx::Status<void> OnConsumerRelease(Message& message,
                                       LocalFence release_fence);
 
-  uint64_t client_state_mask_{0};
+  uint32_t client_state_mask_{0U};
   bool acquired_{false};
   bool released_{true};
   std::weak_ptr<Channel> producer_;
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
index 4734439..96ef1a2 100644
--- a/services/vr/bufferhubd/include/private/dvr/producer_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
@@ -42,7 +42,7 @@
 
   ~ProducerChannel() override;
 
-  uint64_t buffer_state() const {
+  uint32_t buffer_state() const {
     return buffer_state_->load(std::memory_order_acquire);
   }
 
@@ -51,18 +51,18 @@
 
   BufferInfo GetBufferInfo() const override;
 
-  BufferDescription<BorrowedHandle> GetBuffer(uint64_t client_state_mask);
+  BufferDescription<BorrowedHandle> GetBuffer(uint32_t client_state_mask);
 
   pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message,
-                                                  uint64_t consumer_state_mask);
-  pdx::Status<uint64_t> CreateConsumerStateMask();
+                                                  uint32_t consumer_state_mask);
+  pdx::Status<uint32_t> CreateConsumerStateMask();
   pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
 
   pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
   pdx::Status<void> OnConsumerRelease(Message& message,
                                       LocalFence release_fence);
 
-  void OnConsumerOrphaned(const uint64_t& consumer_state_mask);
+  void OnConsumerOrphaned(const uint32_t& consumer_state_mask);
 
   void AddConsumer(ConsumerChannel* channel);
   void RemoveConsumer(ConsumerChannel* channel);
@@ -79,13 +79,13 @@
   // IonBuffer that is shared between bufferhubd, producer, and consumers.
   IonBuffer metadata_buffer_;
   BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
-  std::atomic<uint64_t>* buffer_state_ = nullptr;
-  std::atomic<uint64_t>* fence_state_ = nullptr;
-  std::atomic<uint64_t>* active_clients_bit_mask_ = nullptr;
+  std::atomic<uint32_t>* buffer_state_ = nullptr;
+  std::atomic<uint32_t>* fence_state_ = nullptr;
+  std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
 
   // All orphaned consumer bits. Valid bits are the lower 63 bits, while the
   // highest bit is reserved for the producer and should not be set.
-  uint64_t orphaned_consumer_bit_mask_{0ULL};
+  uint32_t orphaned_consumer_bit_mask_{0U};
 
   LocalFence post_fence_;
   LocalFence returned_fence_;
@@ -110,7 +110,7 @@
 
   // Remove consumer from atomics in shared memory based on consumer_state_mask.
   // This function is used for clean up for failures in CreateConsumer method.
-  void RemoveConsumerClientMask(uint64_t consumer_state_mask);
+  void RemoveConsumerClientMask(uint32_t consumer_state_mask);
 
   ProducerChannel(const ProducerChannel&) = delete;
   void operator=(const ProducerChannel&) = delete;
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index b541fb3..1682bfe 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -93,10 +93,10 @@
   // Using placement new here to reuse shared memory instead of new allocation
   // and also initialize the value to zero.
   buffer_state_ =
-      new (&metadata_header_->buffer_state) std::atomic<uint64_t>(0);
-  fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint64_t>(0);
+      new (&metadata_header_->buffer_state) std::atomic<uint32_t>(0);
+  fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint32_t>(0);
   active_clients_bit_mask_ =
-      new (&metadata_header_->active_clients_bit_mask) std::atomic<uint64_t>(0);
+      new (&metadata_header_->active_clients_bit_mask) std::atomic<uint32_t>(0);
 
   // Producer channel is never created after consumer channel, and one buffer
   // only have one fixed producer for now. Thus, it is correct to assume
@@ -119,7 +119,7 @@
 
   epoll_event event;
   event.events = 0;
-  event.data.u64 = 0ULL;
+  event.data.u32 = 0U;
   if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_ADD, dummy_fence_fd_.Get(),
                 &event) < 0) {
     ALOGE(
@@ -164,7 +164,7 @@
 ProducerChannel::~ProducerChannel() {
   ALOGD_IF(TRACE,
            "ProducerChannel::~ProducerChannel: channel_id=%d buffer_id=%d "
-           "state=%" PRIx64 ".",
+           "state=%" PRIx32 ".",
            channel_id(), buffer_id(),
            buffer_state_->load(std::memory_order_acquire));
   for (auto consumer : consumer_channels_) {
@@ -175,7 +175,7 @@
 
 BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
   // Derive the mask of signaled buffers in this producer / consumer set.
-  uint64_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
+  uint32_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
   for (const ConsumerChannel* consumer : consumer_channels_) {
     signaled_mask |= consumer->signaled() ? consumer->client_state_mask() : 0;
   }
@@ -228,7 +228,7 @@
 }
 
 BufferDescription<BorrowedHandle> ProducerChannel::GetBuffer(
-    uint64_t client_state_mask) {
+    uint32_t client_state_mask) {
   return {buffer_,
           metadata_buffer_,
           buffer_id(),
@@ -241,27 +241,27 @@
 Status<BufferDescription<BorrowedHandle>> ProducerChannel::OnGetBuffer(
     Message& /*message*/) {
   ATRACE_NAME("ProducerChannel::OnGetBuffer");
-  ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx64 ".",
+  ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx32 ".",
            buffer_id(), buffer_state_->load(std::memory_order_acquire));
   return {GetBuffer(BufferHubDefs::kFirstClientBitMask)};
 }
 
-Status<uint64_t> ProducerChannel::CreateConsumerStateMask() {
+Status<uint32_t> ProducerChannel::CreateConsumerStateMask() {
   // Try find the next consumer state bit which has not been claimed by any
   // consumer yet.
   // memory_order_acquire is chosen here because all writes in other threads
   // that release active_clients_bit_mask_ need to be visible here.
-  uint64_t current_active_clients_bit_mask =
+  uint32_t current_active_clients_bit_mask =
       active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint64_t consumer_state_mask =
+  uint32_t consumer_state_mask =
       BufferHubDefs::FindNextAvailableClientStateMask(
           current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
-  if (consumer_state_mask == 0ULL) {
+  if (consumer_state_mask == 0U) {
     ALOGE("%s: reached the maximum mumber of consumers per producer: 63.",
           __FUNCTION__);
     return ErrorStatus(E2BIG);
   }
-  uint64_t updated_active_clients_bit_mask =
+  uint32_t updated_active_clients_bit_mask =
       current_active_clients_bit_mask | consumer_state_mask;
   // Set the updated value only if the current value stays the same as what was
   // read before. If the comparison succeeds, update the value without
@@ -274,15 +274,15 @@
   while (!active_clients_bit_mask_->compare_exchange_weak(
       current_active_clients_bit_mask, updated_active_clients_bit_mask,
       std::memory_order_acq_rel, std::memory_order_acquire)) {
-    ALOGE("%s: Current active clients bit mask is changed to %" PRIx64
-          ", which was expected to be %" PRIx64
+    ALOGE("%s: Current active clients bit mask is changed to %" PRIx32
+          ", which was expected to be %" PRIx32
           ". Trying to generate a new client state mask to resolve race "
           "condition.",
           __FUNCTION__, updated_active_clients_bit_mask,
           current_active_clients_bit_mask);
     consumer_state_mask = BufferHubDefs::FindNextAvailableClientStateMask(
         current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
-    if (consumer_state_mask == 0ULL) {
+    if (consumer_state_mask == 0U) {
       ALOGE("%s: reached the maximum mumber of consumers per producer: %d.",
             __FUNCTION__, (BufferHubDefs::kMaxNumberOfClients - 1));
       return ErrorStatus(E2BIG);
@@ -294,7 +294,7 @@
   return {consumer_state_mask};
 }
 
-void ProducerChannel::RemoveConsumerClientMask(uint64_t consumer_state_mask) {
+void ProducerChannel::RemoveConsumerClientMask(uint32_t consumer_state_mask) {
   // Clear up the buffer state and fence state in case there is already
   // something there due to possible race condition between producer post and
   // consumer failed to create channel.
@@ -308,7 +308,7 @@
 }
 
 Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(
-    Message& message, uint64_t consumer_state_mask) {
+    Message& message, uint32_t consumer_state_mask) {
   ATRACE_NAME(__FUNCTION__);
   ALOGD_IF(TRACE, "%s: buffer_id=%d", __FUNCTION__, buffer_id());
 
@@ -332,7 +332,7 @@
     return ErrorStatus(ENOMEM);
   }
 
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (BufferHubDefs::IsBufferReleased(current_buffer_state) ||
       BufferHubDefs::AnyClientGained(current_buffer_state)) {
@@ -343,7 +343,7 @@
   bool update_buffer_state = true;
   if (!BufferHubDefs::IsClientPosted(current_buffer_state,
                                      consumer_state_mask)) {
-    uint64_t updated_buffer_state =
+    uint32_t updated_buffer_state =
         current_buffer_state ^
         (consumer_state_mask & BufferHubDefs::kHighBitsMask);
     while (!buffer_state_->compare_exchange_weak(
@@ -351,15 +351,15 @@
         std::memory_order_acquire)) {
       ALOGI(
           "%s: Failed to post to the new consumer. "
-          "Current buffer state was changed to %" PRIx64
+          "Current buffer state was changed to %" PRIx32
           " when trying to acquire the buffer and modify the buffer state to "
-          "%" PRIx64
+          "%" PRIx32
           ". About to try again if the buffer is still not gained nor fully "
           "released.",
           __FUNCTION__, current_buffer_state, updated_buffer_state);
       if (BufferHubDefs::IsBufferReleased(current_buffer_state) ||
           BufferHubDefs::AnyClientGained(current_buffer_state)) {
-        ALOGI("%s: buffer is gained or fully released, state=%" PRIx64 ".",
+        ALOGI("%s: buffer is gained or fully released, state=%" PRIx32 ".",
               __FUNCTION__, current_buffer_state);
         update_buffer_state = false;
         break;
@@ -393,7 +393,7 @@
 
   epoll_event event;
   event.events = 0;
-  event.data.u64 = 0ULL;
+  event.data.u32 = 0U;
   int ret = epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
                       dummy_fence_fd_.Get(), &event);
   ALOGE_IF(ret < 0,
@@ -401,7 +401,7 @@
            "release fence to include the dummy fence: %s",
            strerror(errno));
 
-  eventfd_t dummy_fence_count = 0ULL;
+  eventfd_t dummy_fence_count = 0U;
   if (eventfd_read(dummy_fence_fd_.Get(), &dummy_fence_count) < 0) {
     const int error = errno;
     if (error != EAGAIN) {
@@ -451,13 +451,13 @@
   ALOGD_IF(TRACE, "ProducerChannel::OnProducerDetach: buffer_id=%d",
            buffer_id());
 
-  uint64_t buffer_state = buffer_state_->load(std::memory_order_acquire);
+  uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
   if (!BufferHubDefs::IsClientGained(
       buffer_state, BufferHubDefs::kFirstClientStateMask)) {
     // Can only detach a BufferProducer when it's in gained state.
     ALOGW(
         "ProducerChannel::OnProducerDetach: The buffer (id=%d, state=%"
-        PRIx64
+        PRIx32
         ") is not in gained state.",
         buffer_id(), buffer_state);
     return {};
@@ -534,7 +534,7 @@
     }
   }
 
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
                                       ~orphaned_consumer_bit_mask_)) {
@@ -542,7 +542,7 @@
     if (orphaned_consumer_bit_mask_) {
       ALOGW(
           "%s: orphaned buffer detected during the this acquire/release cycle: "
-          "id=%d orphaned=0x%" PRIx64 " queue_index=%" PRIx64 ".",
+          "id=%d orphaned=0x%" PRIx32 " queue_index=%" PRIx64 ".",
           __FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
           metadata_header_->queue_index);
       orphaned_consumer_bit_mask_ = 0;
@@ -552,16 +552,16 @@
   return {};
 }
 
-void ProducerChannel::OnConsumerOrphaned(const uint64_t& consumer_state_mask) {
+void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) {
   // Remember the ignored consumer so that newly added consumer won't be
   // taking the same state mask as this orphaned consumer.
   ALOGE_IF(orphaned_consumer_bit_mask_ & consumer_state_mask,
-           "%s: Consumer (consumer_state_mask=%" PRIx64
+           "%s: Consumer (consumer_state_mask=%" PRIx32
            ") is already orphaned.",
            __FUNCTION__, consumer_state_mask);
   orphaned_consumer_bit_mask_ |= consumer_state_mask;
 
-  uint64_t current_buffer_state =
+  uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
                                       ~orphaned_consumer_bit_mask_)) {
@@ -577,8 +577,8 @@
 
   ALOGW(
       "%s: detected new orphaned consumer buffer_id=%d "
-      "consumer_state_mask=%" PRIx64 " queue_index=%" PRIx64
-      " buffer_state=%" PRIx64 " fence_state=%" PRIx64 ".",
+      "consumer_state_mask=%" PRIx32 " queue_index=%" PRIx64
+      " buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
       __FUNCTION__, buffer_id(), consumer_state_mask,
       metadata_header_->queue_index,
       buffer_state_->load(std::memory_order_acquire),
@@ -594,18 +594,18 @@
       std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
   // Restore the consumer state bit and make it visible in other threads that
   // acquire the active_clients_bit_mask_.
-  uint64_t consumer_state_mask = channel->client_state_mask();
-  uint64_t current_active_clients_bit_mask =
+  uint32_t consumer_state_mask = channel->client_state_mask();
+  uint32_t current_active_clients_bit_mask =
       active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint64_t updated_active_clients_bit_mask =
+  uint32_t updated_active_clients_bit_mask =
       current_active_clients_bit_mask & (~consumer_state_mask);
   while (!active_clients_bit_mask_->compare_exchange_weak(
       current_active_clients_bit_mask, updated_active_clients_bit_mask,
       std::memory_order_acq_rel, std::memory_order_acquire)) {
     ALOGI(
         "%s: Failed to remove consumer state mask. Current active clients bit "
-        "mask is changed to %" PRIu64
-        " when trying to acquire and modify it to %" PRIu64
+        "mask is changed to %" PRIx32
+        " when trying to acquire and modify it to %" PRIx32
         ". About to try again.",
         __FUNCTION__, current_active_clients_bit_mask,
         updated_active_clients_bit_mask);
@@ -613,7 +613,7 @@
         current_active_clients_bit_mask & (~consumer_state_mask);
   }
 
-  const uint64_t current_buffer_state =
+  const uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
   if (BufferHubDefs::IsClientPosted(current_buffer_state,
                                     consumer_state_mask) ||
@@ -634,7 +634,7 @@
     if (fence_state_->load(std::memory_order_acquire) & consumer_state_mask) {
       epoll_event event;
       event.events = EPOLLIN;
-      event.data.u64 = consumer_state_mask;
+      event.data.u32 = consumer_state_mask;
       if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
                     dummy_fence_fd_.Get(), &event) < 0) {
         ALOGE(