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(