Merge "Add SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED to eventSizeBySensorType." into tm-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 24b201f..890c15f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2733,8 +2733,8 @@
const android::base::unique_fd& screenshot_fd_in,
bool is_screenshot_requested) {
// Duplicate the fds because the passed in fds don't outlive the binder transaction.
- bugreport_fd.reset(dup(bugreport_fd_in.get()));
- screenshot_fd.reset(dup(screenshot_fd_in.get()));
+ bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0));
+ screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0));
SetOptionsFromMode(bugreport_mode, this, is_screenshot_requested);
}
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 741b264..4e12579 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -118,6 +118,12 @@
static std::atomic<bool> sAppDataIsolationEnabled(false);
+/**
+ * Flag to control if project ids are supported for internal storage
+ */
+static std::atomic<bool> sUsingProjectIdsFlag(false);
+static std::once_flag flag;
+
namespace {
constexpr const char* kDump = "android.permission.DUMP";
@@ -460,11 +466,14 @@
}
static bool internal_storage_has_project_id() {
// The following path is populated in setFirstBoot, so if this file is present
- // then project ids can be used.
-
- auto using_project_ids =
- StringPrintf("%smisc/installd/using_project_ids", android_data_dir.c_str());
- return access(using_project_ids.c_str(), F_OK) == 0;
+ // then project ids can be used. Using call once to cache the result of this check
+ // to avoid having to check the file presence again and again.
+ std::call_once(flag, []() {
+ auto using_project_ids =
+ StringPrintf("%smisc/installd/using_project_ids", android_data_dir.c_str());
+ sUsingProjectIdsFlag = access(using_project_ids.c_str(), F_OK) == 0;
+ });
+ return sUsingProjectIdsFlag;
}
static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid, gid_t gid,
@@ -1167,6 +1176,25 @@
return res;
}
+binder::Status InstalldNativeService::deleteReferenceProfile(const std::string& packageName,
+ const std::string& profileName) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+ LOCK_PACKAGE();
+
+ // This function only supports primary dex'es.
+ std::string path =
+ create_reference_profile_path(packageName, profileName, /*is_secondary_dex=*/false);
+ if (unlink(path.c_str()) != 0) {
+ if (errno == ENOENT) {
+ return ok();
+ } else {
+ return error("Failed to delete profile " + profileName + " for " + packageName);
+ }
+ }
+ return ok();
+}
+
binder::Status InstalldNativeService::destroyAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
ENFORCE_UID(AID_SYSTEM);
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 87a9206..0432222 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -140,6 +140,8 @@
bool* _aidl_return);
binder::Status clearAppProfiles(const std::string& packageName, const std::string& profileName);
binder::Status destroyAppProfiles(const std::string& packageName);
+ binder::Status deleteReferenceProfile(const std::string& packageName,
+ const std::string& profileName);
binder::Status createProfileSnapshot(int32_t appId, const std::string& packageName,
const std::string& profileName, const std::string& classpath, bool* _aidl_return);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 79c02e8..db03411 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -82,6 +82,7 @@
@utf8InCpp String packageName, @utf8InCpp String profileName);
void clearAppProfiles(@utf8InCpp String packageName, @utf8InCpp String profileName);
void destroyAppProfiles(@utf8InCpp String packageName);
+ void deleteReferenceProfile(@utf8InCpp String packageName, @utf8InCpp String profileName);
boolean createProfileSnapshot(int appId, @utf8InCpp String packageName,
@utf8InCpp String profileName, @utf8InCpp String classpath);
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 9801a9b..45aeab6 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -707,16 +707,16 @@
auto temp_dir_path =
base::StringPrintf("%s/%s", Dirname(pathname).c_str(), temp_dir_name.c_str());
- if (::rename(pathname.c_str(), temp_dir_path.c_str())) {
+ auto dir_to_delete = temp_dir_path.c_str();
+ if (::rename(pathname.c_str(), dir_to_delete)) {
if (ignore_if_missing && (errno == ENOENT)) {
return 0;
}
- ALOGE("Couldn't rename %s -> %s: %s \n", pathname.c_str(), temp_dir_path.c_str(),
- strerror(errno));
- return -errno;
+ ALOGE("Couldn't rename %s -> %s: %s \n", pathname.c_str(), dir_to_delete, strerror(errno));
+ dir_to_delete = pathname.c_str();
}
- return delete_dir_contents(temp_dir_path.c_str(), 1, exclusion_predicate, ignore_if_missing);
+ return delete_dir_contents(dir_to_delete, 1, exclusion_predicate, ignore_if_missing);
}
bool is_renamed_deleted_dir(const std::string& path) {
diff --git a/include/ftl/Flags.h b/include/ftl/Flags.h
index 708eaf5..db3d9ea 100644
--- a/include/ftl/Flags.h
+++ b/include/ftl/Flags.h
@@ -19,13 +19,12 @@
#include <ftl/enum.h>
#include <ftl/string.h>
+#include <bitset>
#include <cstdint>
#include <iterator>
#include <string>
#include <type_traits>
-#include "utils/BitSet.h"
-
// TODO(b/185536303): Align with FTL style and namespace.
namespace android {
@@ -56,21 +55,22 @@
: mFlags(t) {}
class Iterator {
- // The type can't be larger than 64-bits otherwise it won't fit in BitSet64.
- static_assert(sizeof(U) <= sizeof(uint64_t));
+ using Bits = std::uint64_t;
+ static_assert(sizeof(U) <= sizeof(Bits));
public:
+ constexpr Iterator() = default;
Iterator(Flags<F> flags) : mRemainingFlags(flags.mFlags) { (*this)++; }
- Iterator() : mRemainingFlags(0), mCurrFlag(static_cast<F>(0)) {}
// Pre-fix ++
Iterator& operator++() {
- if (mRemainingFlags.isEmpty()) {
- mCurrFlag = static_cast<F>(0);
+ if (mRemainingFlags.none()) {
+ mCurrFlag = 0;
} else {
- uint64_t bit = mRemainingFlags.clearLastMarkedBit(); // counts from left
- const U flag = 1 << (64 - bit - 1);
- mCurrFlag = static_cast<F>(flag);
+ // TODO: Replace with std::countr_zero in C++20.
+ const Bits bit = static_cast<Bits>(__builtin_ctzll(mRemainingFlags.to_ullong()));
+ mRemainingFlags.reset(static_cast<std::size_t>(bit));
+ mCurrFlag = static_cast<U>(static_cast<Bits>(1) << bit);
}
return *this;
}
@@ -88,7 +88,7 @@
bool operator!=(Iterator other) const { return !(*this == other); }
- F operator*() { return mCurrFlag; }
+ F operator*() const { return F{mCurrFlag}; }
// iterator traits
@@ -107,8 +107,8 @@
using pointer = void;
private:
- BitSet64 mRemainingFlags;
- F mCurrFlag;
+ std::bitset<sizeof(Bits) * 8> mRemainingFlags;
+ U mCurrFlag = 0;
};
/*
diff --git a/include/ftl/enum.h b/include/ftl/enum.h
index 5234c05..82af1d6 100644
--- a/include/ftl/enum.h
+++ b/include/ftl/enum.h
@@ -261,10 +261,10 @@
const auto value = to_underlying(v);
// TODO: Replace with std::popcount and std::countr_zero in C++20.
- if (__builtin_popcountl(value) != 1) return {};
+ if (__builtin_popcountll(value) != 1) return {};
constexpr auto kRange = details::EnumRange<E, details::FlagName>{};
- return kRange.values[__builtin_ctzl(value)];
+ return kRange.values[__builtin_ctzll(value)];
}
// Returns a stringified enumerator, or its integral value if not named.
diff --git a/include/ftl/fake_guard.h b/include/ftl/fake_guard.h
new file mode 100644
index 0000000..bacd1b2
--- /dev/null
+++ b/include/ftl/fake_guard.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#pragma once
+
+#define FTL_ATTRIBUTE(a) __attribute__((a))
+
+namespace android::ftl {
+
+// Granular alternative to [[clang::no_thread_safety_analysis]]. Given a std::mutex-like object,
+// FakeGuard suppresses enforcement of thread-safe access to guarded variables within its scope.
+// While FakeGuard is scoped to a block, there are macro shorthands for a single expression, as
+// well as function/lambda scope (though calls must be indirect, e.g. virtual or std::function):
+//
+// struct {
+// std::mutex mutex;
+// int x FTL_ATTRIBUTE(guarded_by(mutex)) = -1;
+//
+// int f() {
+// {
+// ftl::FakeGuard guard(mutex);
+// x = 0;
+// }
+//
+// return FTL_FAKE_GUARD(mutex, x + 1);
+// }
+//
+// std::function<int()> g() const {
+// return [this]() FTL_FAKE_GUARD(mutex) { return x; };
+// }
+// } s;
+//
+// assert(s.f() == 1);
+// assert(s.g()() == 0);
+//
+// An example of a situation where FakeGuard helps is a mutex that guards writes on Thread 1, and
+// reads on Thread 2. Reads on Thread 1, which is the only writer, need not be under lock, so can
+// use FakeGuard to appease the thread safety analyzer. Another example is enforcing and documenting
+// exclusive access by a single thread. This is done by defining a global constant that represents a
+// thread context, and annotating guarded variables as if it were a mutex (though without any effect
+// at run time):
+//
+// constexpr class [[clang::capability("mutex")]] {
+// } kMainThreadContext;
+//
+template <typename Mutex>
+struct [[clang::scoped_lockable]] FakeGuard final {
+ explicit FakeGuard(const Mutex& mutex) FTL_ATTRIBUTE(acquire_capability(mutex)) {}
+ [[clang::release_capability()]] ~FakeGuard() {}
+
+ FakeGuard(const FakeGuard&) = delete;
+ FakeGuard& operator=(const FakeGuard&) = delete;
+};
+
+} // namespace android::ftl
+
+// TODO: Enable in C++23 once standard attributes can be used on lambdas.
+#if 0
+#define FTL_FAKE_GUARD1(mutex) [[using clang: acquire_capability(mutex), release_capability(mutex)]]
+#else
+#define FTL_FAKE_GUARD1(mutex) \
+ FTL_ATTRIBUTE(acquire_capability(mutex)) \
+ FTL_ATTRIBUTE(release_capability(mutex))
+#endif
+
+// The parentheses around `expr` are needed to deduce an lvalue or rvalue reference.
+#define FTL_FAKE_GUARD2(mutex, expr) \
+ [&]() -> decltype(auto) { \
+ const android::ftl::FakeGuard guard(mutex); \
+ return (expr); \
+ }()
+
+#define FTL_MAKE_FAKE_GUARD(arg1, arg2, guard, ...) guard
+
+// The void argument suppresses a warning about zero variadic macro arguments.
+#define FTL_FAKE_GUARD(...) \
+ FTL_MAKE_FAKE_GUARD(__VA_ARGS__, FTL_FAKE_GUARD2, FTL_FAKE_GUARD1, void)(__VA_ARGS__)
diff --git a/libs/binder/IUidObserver.cpp b/libs/binder/IUidObserver.cpp
index a1b08db..d952dc7 100644
--- a/libs/binder/IUidObserver.cpp
+++ b/libs/binder/IUidObserver.cpp
@@ -57,8 +57,7 @@
}
virtual void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
- int32_t capability)
- {
+ int32_t capability) {
Parcel data, reply;
data.writeInterfaceToken(IUidObserver::getInterfaceDescriptor());
data.writeInt32((int32_t) uid);
@@ -67,6 +66,12 @@
data.writeInt32(capability);
remote()->transact(ON_UID_STATE_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ virtual void onUidProcAdjChanged(uid_t uid) {
+ Parcel data, reply;
+ data.writeInt32((int32_t)uid);
+ remote()->transact(ON_UID_PROC_ADJ_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
// ----------------------------------------------------------------------
@@ -102,6 +107,7 @@
onUidIdle(uid, disabled);
return NO_ERROR;
} break;
+
case ON_UID_STATE_CHANGED_TRANSACTION: {
CHECK_INTERFACE(IUidObserver, data, reply);
uid_t uid = data.readInt32();
@@ -111,6 +117,14 @@
onUidStateChanged(uid, procState, procStateSeq, capability);
return NO_ERROR;
} break;
+
+ case ON_UID_PROC_ADJ_CHANGED_TRANSACTION: {
+ CHECK_INTERFACE(IUidObserver, data, reply);
+ uid_t uid = data.readInt32();
+ onUidProcAdjChanged(uid);
+ return NO_ERROR;
+ } break;
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a217a15..be50a75 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -569,6 +569,47 @@
return mHasFds;
}
+std::vector<sp<IBinder>> Parcel::debugReadAllStrongBinders() const {
+ std::vector<sp<IBinder>> ret;
+
+ size_t initPosition = dataPosition();
+ for (size_t i = 0; i < mObjectsSize; i++) {
+ binder_size_t offset = mObjects[i];
+ const flat_binder_object* flat =
+ reinterpret_cast<const flat_binder_object*>(mData + offset);
+ if (flat->hdr.type != BINDER_TYPE_BINDER) continue;
+
+ setDataPosition(offset);
+
+ sp<IBinder> binder = readStrongBinder();
+ if (binder != nullptr) ret.push_back(binder);
+ }
+
+ setDataPosition(initPosition);
+ return ret;
+}
+
+std::vector<int> Parcel::debugReadAllFileDescriptors() const {
+ std::vector<int> ret;
+
+ size_t initPosition = dataPosition();
+ for (size_t i = 0; i < mObjectsSize; i++) {
+ binder_size_t offset = mObjects[i];
+ const flat_binder_object* flat =
+ reinterpret_cast<const flat_binder_object*>(mData + offset);
+ if (flat->hdr.type != BINDER_TYPE_FD) continue;
+
+ setDataPosition(offset);
+
+ int fd = readFileDescriptor();
+ LOG_ALWAYS_FATAL_IF(fd == -1);
+ ret.push_back(fd);
+ }
+
+ setDataPosition(initPosition);
+ return ret;
+}
+
status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* result) const {
if (len > INT32_MAX || offset > INT32_MAX) {
// Don't accept size_t values which may have come from an inadvertent conversion from a
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 450e388..e2b2c51 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -95,6 +95,12 @@
bool hasFileDescriptors() const;
status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool* result) const;
+ // returns all binder objects in the Parcel
+ std::vector<sp<IBinder>> debugReadAllStrongBinders() const;
+ // returns all file descriptors in the Parcel
+ // does not dup
+ std::vector<int> debugReadAllFileDescriptors() const;
+
// Zeros data when reallocating. Other mitigations may be added
// in the future.
//
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 42c85f9..88790a8 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -86,7 +86,7 @@
*ret = nullptr;
return android::BAD_VALUE;
}
- *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ *ret = std::static_pointer_cast<T>(mParcelable);
return android::OK;
}
this->mParcelPtr->setDataPosition(0);
@@ -105,7 +105,7 @@
return status;
}
this->mParcelPtr = nullptr;
- *ret = std::shared_ptr<T>(mParcelable, reinterpret_cast<T*>(mParcelable.get()));
+ *ret = std::static_pointer_cast<T>(mParcelable);
return android::OK;
}
diff --git a/libs/binder/include_activitymanager/binder/ActivityManager.h b/libs/binder/include_activitymanager/binder/ActivityManager.h
index abc7f1d..5dfbd44 100644
--- a/libs/binder/include_activitymanager/binder/ActivityManager.h
+++ b/libs/binder/include_activitymanager/binder/ActivityManager.h
@@ -31,20 +31,21 @@
class ActivityManager
{
public:
-
enum {
// Flag for registerUidObserver: report uid state changed
- UID_OBSERVER_PROCSTATE = 1<<0,
+ UID_OBSERVER_PROCSTATE = 1 << 0,
// Flag for registerUidObserver: report uid gone
- UID_OBSERVER_GONE = 1<<1,
+ UID_OBSERVER_GONE = 1 << 1,
// Flag for registerUidObserver: report uid has become idle
- UID_OBSERVER_IDLE = 1<<2,
+ UID_OBSERVER_IDLE = 1 << 2,
// Flag for registerUidObserver: report uid has become active
- UID_OBSERVER_ACTIVE = 1<<3,
+ UID_OBSERVER_ACTIVE = 1 << 3,
// Flag for registerUidObserver: report uid cached state has changed
- UID_OBSERVER_CACHED = 1<<4,
+ UID_OBSERVER_CACHED = 1 << 4,
// Flag for registerUidObserver: report uid capability has changed
- UID_OBSERVER_CAPABILITY = 1<<5,
+ UID_OBSERVER_CAPABILITY = 1 << 5,
+ // Flag for registerUidObserver: report pid oom adj has changed
+ UID_OBSERVER_PROC_OOM_ADJ = 1 << 6,
};
// PROCESS_STATE_* must come from frameworks/base/core/java/android/app/ProcessStateEnum.aidl.
diff --git a/libs/binder/include_activitymanager/binder/IUidObserver.h b/libs/binder/include_activitymanager/binder/IUidObserver.h
index 9291c0b..17f03a9 100644
--- a/libs/binder/include_activitymanager/binder/IUidObserver.h
+++ b/libs/binder/include_activitymanager/binder/IUidObserver.h
@@ -33,13 +33,15 @@
virtual void onUidActive(uid_t uid) = 0;
virtual void onUidIdle(uid_t uid, bool disabled) = 0;
virtual void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
- int32_t capability) = 0;
+ int32_t capability) = 0;
+ virtual void onUidProcAdjChanged(uid_t uid) = 0;
enum {
ON_UID_GONE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
ON_UID_ACTIVE_TRANSACTION,
ON_UID_IDLE_TRANSACTION,
- ON_UID_STATE_CHANGED_TRANSACTION
+ ON_UID_STATE_CHANGED_TRANSACTION,
+ ON_UID_PROC_ADJ_CHANGED_TRANSACTION
};
};
diff --git a/libs/binder/tests/binderParcelUnitTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp
index aee15d8..359c783 100644
--- a/libs/binder/tests/binderParcelUnitTest.cpp
+++ b/libs/binder/tests/binderParcelUnitTest.cpp
@@ -20,9 +20,12 @@
#include <cutils/ashmem.h>
#include <gtest/gtest.h>
+using android::BBinder;
+using android::IBinder;
using android::IPCThreadState;
using android::OK;
using android::Parcel;
+using android::sp;
using android::status_t;
using android::String16;
using android::String8;
@@ -75,6 +78,40 @@
EXPECT_EQ(p.enforceNoDataAvail().exceptionCode(), Status::Exception::EX_NONE);
}
+TEST(Parcel, DebugReadAllBinders) {
+ sp<IBinder> binder1 = sp<BBinder>::make();
+ sp<IBinder> binder2 = sp<BBinder>::make();
+
+ Parcel p;
+ p.writeInt32(4);
+ p.writeStrongBinder(binder1);
+ p.writeStrongBinder(nullptr);
+ p.writeInt32(4);
+ p.writeStrongBinder(binder2);
+ p.writeInt32(4);
+
+ auto ret = p.debugReadAllStrongBinders();
+
+ ASSERT_EQ(ret.size(), 2);
+ EXPECT_EQ(ret[0], binder1);
+ EXPECT_EQ(ret[1], binder2);
+}
+
+TEST(Parcel, DebugReadAllFds) {
+ Parcel p;
+ p.writeInt32(4);
+ p.writeFileDescriptor(STDOUT_FILENO, false /*takeOwnership*/);
+ p.writeInt32(4);
+ p.writeFileDescriptor(STDIN_FILENO, false /*takeOwnership*/);
+ p.writeInt32(4);
+
+ auto ret = p.debugReadAllFileDescriptors();
+
+ ASSERT_EQ(ret.size(), 2);
+ EXPECT_EQ(ret[0], STDOUT_FILENO);
+ EXPECT_EQ(ret[1], STDIN_FILENO);
+}
+
// Tests a second operation results in a parcel at the same location as it
// started.
void parcelOpSameLength(const std::function<void(Parcel*)>& a, const std::function<void(Parcel*)>& b) {
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 13f7195..47ec776 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -109,6 +109,8 @@
},
PARCEL_READ_NO_STATUS(size_t, allowFds),
PARCEL_READ_NO_STATUS(size_t, hasFileDescriptors),
+ PARCEL_READ_NO_STATUS(std::vector<android::sp<android::IBinder>>, debugReadAllStrongBinders),
+ PARCEL_READ_NO_STATUS(std::vector<int>, debugReadAllFileDescriptors),
[] (const ::android::Parcel& p, uint8_t len) {
std::string interface(len, 'a');
FUZZ_LOG() << "about to enforceInterface: " << interface;
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
index 0a083d7..843b6e3 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_fd.h
@@ -16,12 +16,13 @@
#pragma once
+#include <android-base/unique_fd.h>
#include <fuzzer/FuzzedDataProvider.h>
namespace android {
-// ownership to callee, always valid or aborts
+// always valid or aborts
// get a random FD for use in fuzzing, of a few different specific types
-int getRandomFd(FuzzedDataProvider* provider);
+base::unique_fd getRandomFd(FuzzedDataProvider* provider);
} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
index 633626c..459fb12 100644
--- a/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
+++ b/libs/binder/tests/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
@@ -20,8 +20,16 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <functional>
+#include <vector>
namespace android {
+
+struct RandomParcelOptions {
+ std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader;
+ std::vector<sp<IBinder>> extraBinders;
+ std::vector<base::unique_fd> extraFds;
+};
+
/**
* Fill parcel data, including some random binder objects and FDs
*
@@ -30,7 +38,5 @@
* writeHeader - optional function to write a specific header once the format of the parcel is
* picked (for instance, to write an interface header)
*/
-void fillRandomParcel(
- Parcel* p, FuzzedDataProvider&& provider,
- std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader = nullptr);
+void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider, const RandomParcelOptions& = {});
} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index be39bb9..d5aa353 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -20,24 +20,45 @@
namespace android {
void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) {
+ sp<IBinder> target;
+
+ RandomParcelOptions options{
+ .extraBinders = {binder},
+ .extraFds = {},
+ };
+
while (provider.remaining_bytes() > 0) {
uint32_t code = provider.ConsumeIntegral<uint32_t>();
uint32_t flags = provider.ConsumeIntegral<uint32_t>();
Parcel data;
+ sp<IBinder> target = options.extraBinders.at(
+ provider.ConsumeIntegralInRange<size_t>(0, options.extraBinders.size() - 1));
+ options.writeHeader = [&target](Parcel* p, FuzzedDataProvider& provider) {
+ // most code will be behind checks that the head of the Parcel
+ // is exactly this, so make it easier for fuzzers to reach this
+ if (provider.ConsumeBool()) {
+ p->writeInterfaceToken(target->getInterfaceDescriptor());
+ }
+ };
+
std::vector<uint8_t> subData = provider.ConsumeBytes<uint8_t>(
provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes()));
- fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()),
- [&binder](Parcel* p, FuzzedDataProvider& provider) {
- // most code will be behind checks that the head of the Parcel
- // is exactly this, so make it easier for fuzzers to reach this
- if (provider.ConsumeBool()) {
- p->writeInterfaceToken(binder->getInterfaceDescriptor());
- }
- });
+ fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), options);
Parcel reply;
- (void)binder->transact(code, data, &reply, flags);
+ (void)target->transact(code, data, &reply, flags);
+
+ // feed back in binders and fds that are returned from the service, so that
+ // we can fuzz those binders, and use the fds and binders to feed back into
+ // the binders
+ auto retBinders = reply.debugReadAllStrongBinders();
+ options.extraBinders.insert(options.extraBinders.end(), retBinders.begin(),
+ retBinders.end());
+ auto retFds = reply.debugReadAllFileDescriptors();
+ for (size_t i = 0; i < retFds.size(); i++) {
+ options.extraFds.push_back(base::unique_fd(dup(retFds[i])));
+ }
}
}
diff --git a/libs/binder/tests/parcel_fuzzer/random_fd.cpp b/libs/binder/tests/parcel_fuzzer/random_fd.cpp
index cef6adb..ab0b7e3 100644
--- a/libs/binder/tests/parcel_fuzzer/random_fd.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_fd.cpp
@@ -23,13 +23,13 @@
namespace android {
-int getRandomFd(FuzzedDataProvider* provider) {
+base::unique_fd getRandomFd(FuzzedDataProvider* provider) {
int fd = provider->PickValueInArray<std::function<int()>>({
[]() { return ashmem_create_region("binder test region", 1024); },
[]() { return open("/dev/null", O_RDWR); },
})();
CHECK(fd >= 0);
- return fd;
+ return base::unique_fd(fd);
}
} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index cfabc1e..0204f5e 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -40,19 +40,23 @@
}
void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider,
- std::function<void(Parcel* p, FuzzedDataProvider& provider)> writeHeader) {
+ const RandomParcelOptions& options) {
if (provider.ConsumeBool()) {
auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
CHECK_EQ(OK, session->addNullDebuggingClient());
p->markForRpc(session);
- writeHeader(p, provider);
+ if (options.writeHeader) {
+ options.writeHeader(p, provider);
+ }
fillRandomParcelData(p, std::move(provider));
return;
}
- writeHeader(p, provider);
+ if (options.writeHeader) {
+ options.writeHeader(p, provider);
+ }
while (provider.remaining_bytes() > 0) {
auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
@@ -65,8 +69,16 @@
},
// write FD
[&]() {
- int fd = getRandomFd(&provider);
- CHECK(OK == p->writeFileDescriptor(fd, true /*takeOwnership*/));
+ if (options.extraFds.size() > 0 && provider.ConsumeBool()) {
+ const base::unique_fd& fd = options.extraFds.at(
+ provider.ConsumeIntegralInRange<size_t>(0,
+ options.extraFds.size() -
+ 1));
+ CHECK(OK == p->writeFileDescriptor(fd.get(), false /*takeOwnership*/));
+ } else {
+ base::unique_fd fd = getRandomFd(&provider);
+ CHECK(OK == p->writeFileDescriptor(fd.release(), true /*takeOwnership*/));
+ }
},
// write binder
[&]() {
@@ -85,7 +97,15 @@
// candidate for checking usage of an actual BpBinder
return IInterface::asBinder(defaultServiceManager());
},
- []() { return nullptr; },
+ [&]() -> sp<IBinder> {
+ if (options.extraBinders.size() > 0 && provider.ConsumeBool()) {
+ return options.extraBinders.at(
+ provider.ConsumeIntegralInRange<
+ size_t>(0, options.extraBinders.size() - 1));
+ } else {
+ return nullptr;
+ }
+ },
});
sp<IBinder> binder = makeFunc();
CHECK(OK == p->writeStrongBinder(binder));
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index bc2eb23..ef20196 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -18,6 +18,7 @@
"cast_test.cpp",
"concat_test.cpp",
"enum_test.cpp",
+ "fake_guard_test.cpp",
"future_test.cpp",
"small_map_test.cpp",
"small_vector_test.cpp",
@@ -29,13 +30,6 @@
"-Werror",
"-Wextra",
"-Wpedantic",
- ],
-
- header_libs: [
- "libbase_headers",
- ],
-
- shared_libs: [
- "libbase",
+ "-Wthread-safety",
],
}
diff --git a/libs/ftl/enum_test.cpp b/libs/ftl/enum_test.cpp
index d8ce7a5..5592a01 100644
--- a/libs/ftl/enum_test.cpp
+++ b/libs/ftl/enum_test.cpp
@@ -143,6 +143,16 @@
EXPECT_EQ(ftl::flag_string(Flags::kNone), "0b0");
EXPECT_EQ(ftl::flag_string(Flags::kMask), "0b10010010");
EXPECT_EQ(ftl::flag_string(Flags::kAll), "0b11111111");
+
+ enum class Flags64 : std::uint64_t {
+ kFlag0 = 0b1ull,
+ kFlag63 = 0x8000'0000'0000'0000ull,
+ kMask = kFlag0 | kFlag63
+ };
+
+ EXPECT_EQ(ftl::flag_string(Flags64::kFlag0), "kFlag0");
+ EXPECT_EQ(ftl::flag_string(Flags64::kFlag63), "kFlag63");
+ EXPECT_EQ(ftl::flag_string(Flags64::kMask), "0x8000000000000001");
}
{
EXPECT_EQ(ftl::enum_string(Planet::kEarth), "kEarth");
diff --git a/libs/ftl/fake_guard_test.cpp b/libs/ftl/fake_guard_test.cpp
new file mode 100644
index 0000000..9d36e69
--- /dev/null
+++ b/libs/ftl/fake_guard_test.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 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 <ftl/fake_guard.h>
+#include <gtest/gtest.h>
+
+#include <functional>
+#include <mutex>
+
+namespace android::test {
+
+// Keep in sync with example usage in header file.
+TEST(FakeGuard, Example) {
+ struct {
+ std::mutex mutex;
+ int x FTL_ATTRIBUTE(guarded_by(mutex)) = -1;
+
+ int f() {
+ {
+ ftl::FakeGuard guard(mutex);
+ x = 0;
+ }
+
+ return FTL_FAKE_GUARD(mutex, x + 1);
+ }
+
+ std::function<int()> g() const {
+ return [this]() FTL_FAKE_GUARD(mutex) { return x; };
+ }
+ } s;
+
+ EXPECT_EQ(s.f(), 1);
+ EXPECT_EQ(s.g()(), 0);
+}
+
+} // namespace android::test
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 39d380d..dfdce20 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -197,4 +197,9 @@
return gotVsync;
}
+status_t DisplayEventDispatcher::getLatestVsyncEventData(
+ ParcelableVsyncEventData* outVsyncEventData) const {
+ return mReceiver.getLatestVsyncEventData(outVsyncEventData);
+}
+
} // namespace android
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 49b669e..34db5b1 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -774,7 +774,13 @@
}; // namespace gui
ReleaseCallbackId BufferData::generateReleaseCallbackId() const {
- return {buffer->getId(), frameNumber};
+ uint64_t bufferId;
+ if (buffer) {
+ bufferId = buffer->getId();
+ } else {
+ bufferId = cachedBuffer.id;
+ }
+ return {bufferId, frameNumber};
}
status_t BufferData::writeToParcel(Parcel* output) const {
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 063dda5..654fb33 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -70,6 +70,7 @@
mLayerId = other->mLayerId;
mWidth = other->mWidth;
mHeight = other->mHeight;
+ mFormat = other->mFormat;
mCreateFlags = other->mCreateFlags;
}
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index 71968fa..a342539 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -34,6 +34,7 @@
void injectEvent(const DisplayEventReceiver::Event& event);
int getFd() const;
virtual int handleEvent(int receiveFd, int events, void* data);
+ status_t getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) const;
protected:
virtual ~DisplayEventDispatcher() = default;
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 1690e44..b72cf83 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -121,12 +121,12 @@
mutable sp<Surface> mSurfaceData;
mutable sp<BLASTBufferQueue> mBbq;
mutable sp<SurfaceControl> mBbqChild;
- int32_t mLayerId;
- uint32_t mTransformHint;
- uint32_t mWidth;
- uint32_t mHeight;
- PixelFormat mFormat;
- uint32_t mCreateFlags;
+ int32_t mLayerId = 0;
+ uint32_t mTransformHint = 0;
+ uint32_t mWidth = 0;
+ uint32_t mHeight = 0;
+ PixelFormat mFormat = PIXEL_FORMAT_NONE;
+ uint32_t mCreateFlags = 0;
uint64_t mFallbackFrameNumber = 100;
};
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index e69fc78..262987f 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -995,21 +995,6 @@
EXPECT_EQ(surface->consumeEvent(100), nullptr);
}
-TEST_F(InputSurfacesTest, layer_with_empty_crop_cannot_be_focused) {
- std::unique_ptr<InputSurface> bufferSurface =
- InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
-
- bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
-
- bufferSurface->requestFocus();
- EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
-
- bufferSurface->showAt(50, 50, Rect::INVALID_RECT);
-
- bufferSurface->requestFocus();
- EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
-}
-
TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index a6465ee..7f427f2 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -15,13 +15,6 @@
*/
#define LOG_TAG "VelocityTracker"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about velocity tracking.
-static constexpr bool DEBUG_VELOCITY = false;
-
-// Log debug messages about the progress of the algorithm itself.
-static constexpr bool DEBUG_STRATEGY = false;
#include <array>
#include <inttypes.h>
@@ -36,6 +29,27 @@
namespace android {
+/**
+ * Log debug messages about velocity tracking.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerVelocity DEBUG" (requires restart)
+ */
+const bool DEBUG_VELOCITY =
+ __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Velocity", ANDROID_LOG_INFO);
+
+/**
+ * Log debug messages about the progress of the algorithm itself.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerStrategy DEBUG" (requires restart)
+ */
+const bool DEBUG_STRATEGY =
+ __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Strategy", ANDROID_LOG_INFO);
+
+/**
+ * Log debug messages about the 'impulse' strategy.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerImpulse DEBUG" (requires restart)
+ */
+const bool DEBUG_IMPULSE =
+ __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Impulse", ANDROID_LOG_INFO);
+
// Nanoseconds per milliseconds.
static const nsecs_t NANOS_PER_MS = 1000000;
@@ -141,7 +155,7 @@
return std::make_unique<LeastSquaresVelocityTrackerStrategy>(1);
case VelocityTracker::Strategy::LSQ2:
- if (DEBUG_STRATEGY) {
+ if (DEBUG_STRATEGY && !DEBUG_IMPULSE) {
ALOGI("Initializing lsq2 strategy");
}
return std::make_unique<LeastSquaresVelocityTrackerStrategy>(2);
@@ -1172,7 +1186,25 @@
outEstimator->degree = 2; // similar results to 2nd degree fit
outEstimator->confidence = 1;
if (DEBUG_STRATEGY) {
- ALOGD("velocity: (%f, %f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
+ ALOGD("velocity: (%.1f, %.1f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
+ }
+ if (DEBUG_IMPULSE) {
+ // TODO(b/134179997): delete this block once the switch to 'impulse' is complete.
+ // Calculate the lsq2 velocity for the same inputs to allow runtime comparisons
+ VelocityTracker lsq2(VelocityTracker::Strategy::LSQ2);
+ BitSet32 idBits;
+ const uint32_t pointerId = 0;
+ idBits.markBit(pointerId);
+ for (ssize_t i = m - 1; i >= 0; i--) {
+ lsq2.addMovement(time[i], idBits, {{x[i], y[i]}});
+ }
+ float outVx = 0, outVy = 0;
+ const bool computed = lsq2.getVelocity(pointerId, &outVx, &outVy);
+ if (computed) {
+ ALOGD("lsq2 velocity: (%.1f, %.1f)", outVx, outVy);
+ } else {
+ ALOGD("lsq2 velocity: could not compute velocity");
+ }
}
return true;
}
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 381900e..4a1784e 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -207,7 +207,11 @@
if (result == 0) {
outPlanes->planeCount = 3;
outPlanes->planes[0].data = yuvData.y;
- outPlanes->planes[0].pixelStride = 1;
+ if (format == AHARDWAREBUFFER_FORMAT_YCbCr_P010) {
+ outPlanes->planes[0].pixelStride = 2;
+ } else {
+ outPlanes->planes[0].pixelStride = 1;
+ }
outPlanes->planes[0].rowStride = yuvData.ystride;
outPlanes->planes[1].data = yuvData.cb;
outPlanes->planes[1].pixelStride = yuvData.chroma_step;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 5e5618b..df9f8ab 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -39,6 +39,7 @@
#include <gui/TraceUtils.h>
#include <sync/sync.h>
#include <ui/BlurRegion.h>
+#include <ui/DataspaceUtils.h>
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
#include <utils/Trace.h>
@@ -872,18 +873,21 @@
// save a snapshot of the activeSurface to use as input to the blur shaders
blurInput = activeSurface->makeImageSnapshot();
- // TODO we could skip this step if we know the blur will cover the entire image
- // blit the offscreen framebuffer into the destination AHB
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc);
- if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
- uint64_t id = mCapture->endOffscreenCapture(&offscreenCaptureState);
- dstCanvas->drawAnnotation(SkRect::Make(dstCanvas->imageInfo().dimensions()),
- String8::format("SurfaceID|%" PRId64, id).c_str(),
- nullptr);
- dstCanvas->drawImage(blurInput, 0, 0, SkSamplingOptions(), &paint);
- } else {
- activeSurface->draw(dstCanvas, 0, 0, SkSamplingOptions(), &paint);
+ // blit the offscreen framebuffer into the destination AHB, but only
+ // if there are blur regions. backgroundBlurRadius blurs the entire
+ // image below, so it can skip this step.
+ if (layer.blurRegions.size()) {
+ SkPaint paint;
+ paint.setBlendMode(SkBlendMode::kSrc);
+ if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
+ uint64_t id = mCapture->endOffscreenCapture(&offscreenCaptureState);
+ dstCanvas->drawAnnotation(SkRect::Make(dstCanvas->imageInfo().dimensions()),
+ String8::format("SurfaceID|%" PRId64, id).c_str(),
+ nullptr);
+ dstCanvas->drawImage(blurInput, 0, 0, SkSamplingOptions(), &paint);
+ } else {
+ activeSurface->draw(dstCanvas, 0, 0, SkSamplingOptions(), &paint);
+ }
}
// assign dstCanvas to canvas and ensure that the canvas state is up to date
@@ -1102,9 +1106,15 @@
.requiresLinearEffect = requiresLinearEffect,
.layerDimmingRatio = layerDimmingRatio}));
- // Turn on dithering when dimming beyond this threshold.
+ // Turn on dithering when dimming beyond this (arbitrary) threshold...
static constexpr float kDimmingThreshold = 0.2f;
- if (layerDimmingRatio <= kDimmingThreshold) {
+ // ...or we're rendering an HDR layer down to an 8-bit target
+ // Most HDR standards require at least 10-bits of color depth for source content, so we
+ // can just extract the transfer function rather than dig into precise gralloc layout.
+ // Furthermore, we can assume that the only 8-bit target we support is RGBA8888.
+ const bool requiresDownsample = isHdrDataspace(layer.sourceDataspace) &&
+ buffer->getPixelFormat() == PIXEL_FORMAT_RGBA_8888;
+ if (layerDimmingRatio <= kDimmingThreshold || requiresDownsample) {
paint.setDither(true);
}
paint.setAlphaf(layer.alpha);
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 1a42642..c72ae1b 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -358,20 +358,19 @@
if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
continue;
}
- if (0 != planeLayoutComponent.offsetInBits % 8) {
- unlock(bufferHandle);
- return BAD_VALUE;
- }
- uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes +
- (planeLayoutComponent.offsetInBits / 8);
+ uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes;
+
+ // Note that `offsetInBits` may not be a multiple of 8 for packed formats (e.g. P010)
+ // but we still want to point to the start of the first byte.
+ tmpData += (planeLayoutComponent.offsetInBits / 8);
+
uint64_t sampleIncrementInBytes;
auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
switch (type) {
case PlaneLayoutComponentType::Y:
- if ((ycbcr.y != nullptr) || (planeLayoutComponent.sizeInBits != 8) ||
- (planeLayout.sampleIncrementInBits != 8)) {
+ if ((ycbcr.y != nullptr) || (planeLayout.sampleIncrementInBits % 8 != 0)) {
unlock(bufferHandle);
return BAD_VALUE;
}
@@ -387,7 +386,8 @@
}
sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
- if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2)) {
+ if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2) &&
+ (sampleIncrementInBytes != 4)) {
unlock(bufferHandle);
return BAD_VALUE;
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 3c164aa..8b81d48 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -2030,7 +2030,9 @@
// Runtime permissions can't use the cache as they may change.
if (sensor.isRequiredPermissionRuntime()) {
hasPermission = checkPermission(String16(requiredPermission),
- IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
+ IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid(),
+ /*logPermissionFailure=*/ false);
} else {
hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
}
@@ -2211,7 +2213,8 @@
int targetSdk = getTargetSdkVersion(opPackageName);
bool hasSamplingRatePermission = checkPermission(sAccessHighSensorSamplingRatePermission,
IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid());
+ IPCThreadState::self()->getCallingUid(),
+ /*logPermissionFailure=*/ false);
if (targetSdk < __ANDROID_API_S__ ||
(targetSdk >= __ANDROID_API_S__ && hasSamplingRatePermission)) {
return false;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 7194db3..b18d204 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -257,11 +257,13 @@
bool isUidActive(uid_t uid);
- void onUidGone(uid_t uid, bool disabled);
- void onUidActive(uid_t uid);
- void onUidIdle(uid_t uid, bool disabled);
+ void onUidGone(uid_t uid, bool disabled) override;
+ void onUidActive(uid_t uid) override;
+ void onUidIdle(uid_t uid, bool disabled) override;
void onUidStateChanged(uid_t uid __unused, int32_t procState __unused,
- int64_t procStateSeq __unused, int32_t capability __unused) {}
+ int64_t procStateSeq __unused,
+ int32_t capability __unused) override {}
+ void onUidProcAdjChanged(uid_t uid __unused) override {}
void addOverrideUid(uid_t uid, bool active);
void removeOverrideUid(uid_t uid);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index cd03235..5cc0f97 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -165,7 +165,6 @@
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
- EXPECT_CALL(mHwComposer, getBootDisplayModeSupport()).WillRepeatedly(Return(false));
}
DisplayCreationArgs getDisplayCreationArgsForPhysicalDisplay() {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 2c4a300..d5d87b4 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <android-base/thread_annotations.h>
#include <android/native_window.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
@@ -28,6 +29,7 @@
#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <ui/DisplayId.h>
+#include <ui/DisplayIdentification.h>
#include <ui/DisplayState.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
@@ -39,15 +41,11 @@
#include <utils/RefBase.h>
#include <utils/Timers.h>
-#include "MainThreadGuard.h"
-
-#include <ui/DisplayIdentification.h>
#include "DisplayHardware/DisplayMode.h"
#include "DisplayHardware/Hal.h"
#include "DisplayHardware/PowerAdvisor.h"
-
#include "Scheduler/RefreshRateConfigs.h"
-
+#include "ThreadContext.h"
#include "TracedOrdinal.h"
namespace android {
@@ -99,9 +97,9 @@
void setLayerStack(ui::LayerStack);
void setDisplaySize(int width, int height);
void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
- void stageBrightness(float brightness) REQUIRES(SF_MAIN_THREAD);
- void persistBrightness(bool needsComposite) REQUIRES(SF_MAIN_THREAD);
- bool isBrightnessStale() const REQUIRES(SF_MAIN_THREAD);
+ void stageBrightness(float brightness) REQUIRES(kMainThreadContext);
+ void persistBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
+ bool isBrightnessStale() const REQUIRES(kMainThreadContext);
void setFlags(uint32_t flags);
ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; }
@@ -109,7 +107,7 @@
static ui::Transform::RotationFlags getPrimaryDisplayRotationFlags();
- std::optional<float> getStagedBrightness() const REQUIRES(SF_MAIN_THREAD);
+ std::optional<float> getStagedBrightness() const REQUIRES(kMainThreadContext);
ui::Transform::RotationFlags getTransformHint() const;
const ui::Transform& getTransform() const;
const Rect& getLayerStackSpaceRect() const;
@@ -209,15 +207,15 @@
bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock);
std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock);
void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock);
- ActiveModeInfo getUpcomingActiveMode() const REQUIRES(SF_MAIN_THREAD) {
+ ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) {
return mUpcomingActiveMode;
}
- void setActiveMode(DisplayModeId) REQUIRES(SF_MAIN_THREAD);
+ void setActiveMode(DisplayModeId) REQUIRES(kMainThreadContext);
status_t initiateModeChange(const ActiveModeInfo&,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline)
- REQUIRES(SF_MAIN_THREAD);
+ REQUIRES(kMainThreadContext);
// Return the immutable list of supported display modes. The HWC may report different modes
// after a hotplug reconnect event, in which case the DisplayDevice object will be recreated.
@@ -304,7 +302,7 @@
ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock);
TracedOrdinal<bool> mDesiredActiveModeChanged
GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false};
- ActiveModeInfo mUpcomingActiveMode GUARDED_BY(SF_MAIN_THREAD);
+ ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext);
};
struct DisplayDeviceState {
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 8b376f1..297a776 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -247,7 +247,6 @@
case OptionalFeature::RefreshRateSwitching:
case OptionalFeature::ExpectedPresentTime:
case OptionalFeature::DisplayBrightnessCommand:
- case OptionalFeature::BootDisplayConfig:
case OptionalFeature::KernelIdleTimer:
case OptionalFeature::PhysicalDisplayOrientation:
return true;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 7d9946d..2dc0830 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -94,7 +94,6 @@
ExpectedPresentTime,
// Whether setDisplayBrightness is able to be applied as part of a display command.
DisplayBrightnessCommand,
- BootDisplayConfig,
KernelIdleTimer,
PhysicalDisplayOrientation,
};
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index d78562d..a805566 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -94,82 +94,78 @@
virtual bool hasDisplayIdleTimerCapability() const = 0;
virtual void onLayerDestroyed(hal::HWLayerId layerId) = 0;
- [[clang::warn_unused_result]] virtual hal::Error acceptChanges() = 0;
- [[clang::warn_unused_result]] virtual base::expected<std::shared_ptr<HWC2::Layer>, hal::Error>
+ [[nodiscard]] virtual hal::Error acceptChanges() = 0;
+ [[nodiscard]] virtual base::expected<std::shared_ptr<HWC2::Layer>, hal::Error>
createLayer() = 0;
- [[clang::warn_unused_result]] virtual hal::Error getChangedCompositionTypes(
+ [[nodiscard]] virtual hal::Error getChangedCompositionTypes(
std::unordered_map<Layer*, aidl::android::hardware::graphics::composer3::Composition>*
outTypes) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getColorModes(
- std::vector<hal::ColorMode>* outModes) const = 0;
+ [[nodiscard]] virtual hal::Error getColorModes(std::vector<hal::ColorMode>* outModes) const = 0;
// Returns a bitmask which contains HdrMetadata::Type::*.
- [[clang::warn_unused_result]] virtual int32_t getSupportedPerFrameMetadata() const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getRenderIntents(
+ [[nodiscard]] virtual int32_t getSupportedPerFrameMetadata() const = 0;
+ [[nodiscard]] virtual hal::Error getRenderIntents(
hal::ColorMode colorMode, std::vector<hal::RenderIntent>* outRenderIntents) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getDataspaceSaturationMatrix(
- hal::Dataspace dataspace, android::mat4* outMatrix) = 0;
+ [[nodiscard]] virtual hal::Error getDataspaceSaturationMatrix(hal::Dataspace dataspace,
+ android::mat4* outMatrix) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getName(std::string* outName) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getRequests(
+ [[nodiscard]] virtual hal::Error getName(std::string* outName) const = 0;
+ [[nodiscard]] virtual hal::Error getRequests(
hal::DisplayRequest* outDisplayRequests,
std::unordered_map<Layer*, hal::LayerRequest>* outLayerRequests) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getConnectionType(
- ui::DisplayConnectionType*) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error supportsDoze(bool* outSupport) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getHdrCapabilities(
+ [[nodiscard]] virtual hal::Error getConnectionType(ui::DisplayConnectionType*) const = 0;
+ [[nodiscard]] virtual hal::Error supportsDoze(bool* outSupport) const = 0;
+ [[nodiscard]] virtual hal::Error getHdrCapabilities(
android::HdrCapabilities* outCapabilities) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getDisplayedContentSamplingAttributes(
+ [[nodiscard]] virtual hal::Error getDisplayedContentSamplingAttributes(
hal::PixelFormat* outFormat, hal::Dataspace* outDataspace,
uint8_t* outComponentMask) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error setDisplayContentSamplingEnabled(
- bool enabled, uint8_t componentMask, uint64_t maxFrames) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getDisplayedContentSample(
+ [[nodiscard]] virtual hal::Error setDisplayContentSamplingEnabled(bool enabled,
+ uint8_t componentMask,
+ uint64_t maxFrames) const = 0;
+ [[nodiscard]] virtual hal::Error getDisplayedContentSample(
uint64_t maxFrames, uint64_t timestamp,
android::DisplayedFrameStats* outStats) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error getReleaseFences(
+ [[nodiscard]] virtual hal::Error getReleaseFences(
std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error present(
- android::sp<android::Fence>* outPresentFence) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setClientTarget(
+ [[nodiscard]] virtual hal::Error present(android::sp<android::Fence>* outPresentFence) = 0;
+ [[nodiscard]] virtual hal::Error setClientTarget(
uint32_t slot, const android::sp<android::GraphicBuffer>& target,
const android::sp<android::Fence>& acquireFence, hal::Dataspace dataspace) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setColorMode(
- hal::ColorMode mode, hal::RenderIntent renderIntent) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setColorTransform(
- const android::mat4& matrix) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setOutputBuffer(
+ [[nodiscard]] virtual hal::Error setColorMode(hal::ColorMode mode,
+ hal::RenderIntent renderIntent) = 0;
+ [[nodiscard]] virtual hal::Error setColorTransform(const android::mat4& matrix) = 0;
+ [[nodiscard]] virtual hal::Error setOutputBuffer(
const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& releaseFence) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setPowerMode(hal::PowerMode mode) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setVsyncEnabled(hal::Vsync enabled) = 0;
- [[clang::warn_unused_result]] virtual hal::Error validate(nsecs_t expectedPresentTime,
- uint32_t* outNumTypes,
- uint32_t* outNumRequests) = 0;
- [[clang::warn_unused_result]] virtual hal::Error presentOrValidate(
- nsecs_t expectedPresentTime, uint32_t* outNumTypes, uint32_t* outNumRequests,
- android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
- [[clang::warn_unused_result]] virtual std::future<hal::Error> setDisplayBrightness(
+ [[nodiscard]] virtual hal::Error setPowerMode(hal::PowerMode mode) = 0;
+ [[nodiscard]] virtual hal::Error setVsyncEnabled(hal::Vsync enabled) = 0;
+ [[nodiscard]] virtual hal::Error validate(nsecs_t expectedPresentTime, uint32_t* outNumTypes,
+ uint32_t* outNumRequests) = 0;
+ [[nodiscard]] virtual hal::Error presentOrValidate(nsecs_t expectedPresentTime,
+ uint32_t* outNumTypes,
+ uint32_t* outNumRequests,
+ android::sp<android::Fence>* outPresentFence,
+ uint32_t* state) = 0;
+ [[nodiscard]] virtual std::future<hal::Error> setDisplayBrightness(
float brightness, const Hwc2::Composer::DisplayBrightnessOptions& options) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
+ [[nodiscard]] virtual hal::Error setActiveConfigWithConstraints(
hal::HWConfigId configId, const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setBootDisplayConfig(
- hal::HWConfigId configId) = 0;
- [[clang::warn_unused_result]] virtual hal::Error clearBootDisplayConfig() = 0;
- [[clang::warn_unused_result]] virtual hal::Error getPreferredBootDisplayConfig(
+ [[nodiscard]] virtual hal::Error setBootDisplayConfig(hal::HWConfigId configId) = 0;
+ [[nodiscard]] virtual hal::Error clearBootDisplayConfig() = 0;
+ [[nodiscard]] virtual hal::Error getPreferredBootDisplayConfig(
hal::HWConfigId* configId) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
+ [[nodiscard]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
+ [[nodiscard]] virtual hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>*) const = 0;
- [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getClientTargetProperty(
+ [[nodiscard]] virtual hal::Error setContentType(hal::ContentType) = 0;
+ [[nodiscard]] virtual hal::Error getClientTargetProperty(
hal::ClientTargetProperty* outClientTargetProperty, float* outWhitePointNits) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getDisplayDecorationSupport(
+ [[nodiscard]] virtual hal::Error getDisplayDecorationSupport(
std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setIdleTimerEnabled(
- std::chrono::milliseconds timeout) = 0;
- [[clang::warn_unused_result]] virtual hal::Error getPhysicalDisplayOrientation(
+ [[nodiscard]] virtual hal::Error setIdleTimerEnabled(std::chrono::milliseconds timeout) = 0;
+ [[nodiscard]] virtual hal::Error getPhysicalDisplayOrientation(
Hwc2::AidlTransform* outTransform) const = 0;
};
@@ -299,45 +295,39 @@
virtual hal::HWLayerId getId() const = 0;
- [[clang::warn_unused_result]] virtual hal::Error setCursorPosition(int32_t x, int32_t y) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setBuffer(
- uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
- const android::sp<android::Fence>& acquireFence) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setSurfaceDamage(
- const android::Region& damage) = 0;
+ [[nodiscard]] virtual hal::Error setCursorPosition(int32_t x, int32_t y) = 0;
+ [[nodiscard]] virtual hal::Error setBuffer(uint32_t slot,
+ const android::sp<android::GraphicBuffer>& buffer,
+ const android::sp<android::Fence>& acquireFence) = 0;
+ [[nodiscard]] virtual hal::Error setSurfaceDamage(const android::Region& damage) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setBlendMode(hal::BlendMode mode) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setColor(
+ [[nodiscard]] virtual hal::Error setBlendMode(hal::BlendMode mode) = 0;
+ [[nodiscard]] virtual hal::Error setColor(
aidl::android::hardware::graphics::composer3::Color color) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setCompositionType(
+ [[nodiscard]] virtual hal::Error setCompositionType(
aidl::android::hardware::graphics::composer3::Composition type) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setDataspace(hal::Dataspace dataspace) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setPerFrameMetadata(
- const int32_t supportedPerFrameMetadata, const android::HdrMetadata& metadata) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setDisplayFrame(
- const android::Rect& frame) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setPlaneAlpha(float alpha) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setSidebandStream(
- const native_handle_t* stream) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setSourceCrop(
- const android::FloatRect& crop) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setTransform(hal::Transform transform) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setVisibleRegion(
- const android::Region& region) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setZOrder(uint32_t z) = 0;
+ [[nodiscard]] virtual hal::Error setDataspace(hal::Dataspace dataspace) = 0;
+ [[nodiscard]] virtual hal::Error setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
+ const android::HdrMetadata& metadata) = 0;
+ [[nodiscard]] virtual hal::Error setDisplayFrame(const android::Rect& frame) = 0;
+ [[nodiscard]] virtual hal::Error setPlaneAlpha(float alpha) = 0;
+ [[nodiscard]] virtual hal::Error setSidebandStream(const native_handle_t* stream) = 0;
+ [[nodiscard]] virtual hal::Error setSourceCrop(const android::FloatRect& crop) = 0;
+ [[nodiscard]] virtual hal::Error setTransform(hal::Transform transform) = 0;
+ [[nodiscard]] virtual hal::Error setVisibleRegion(const android::Region& region) = 0;
+ [[nodiscard]] virtual hal::Error setZOrder(uint32_t z) = 0;
// Composer HAL 2.3
- [[clang::warn_unused_result]] virtual hal::Error setColorTransform(
- const android::mat4& matrix) = 0;
+ [[nodiscard]] virtual hal::Error setColorTransform(const android::mat4& matrix) = 0;
// Composer HAL 2.4
- [[clang::warn_unused_result]] virtual hal::Error setLayerGenericMetadata(
- const std::string& name, bool mandatory, const std::vector<uint8_t>& value) = 0;
+ [[nodiscard]] virtual hal::Error setLayerGenericMetadata(const std::string& name,
+ bool mandatory,
+ const std::vector<uint8_t>& value) = 0;
// AIDL HAL
- [[clang::warn_unused_result]] virtual hal::Error setBrightness(float brightness) = 0;
- [[clang::warn_unused_result]] virtual hal::Error setBlockingRegion(
- const android::Region& region) = 0;
+ [[nodiscard]] virtual hal::Error setBrightness(float brightness) = 0;
+ [[nodiscard]] virtual hal::Error setBlockingRegion(const android::Region& region) = 0;
};
namespace impl {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index e2e4a99..459291a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -740,10 +740,6 @@
});
}
-bool HWComposer::getBootDisplayModeSupport() {
- return mComposer->isSupported(Hwc2::Composer::OptionalFeature::BootDisplayConfig);
-}
-
status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
hal::HWConfigId displayModeId) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 91fe1b7..0e15a7c 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -267,7 +267,6 @@
virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0;
// Composer 3.0
- virtual bool getBootDisplayModeSupport() = 0;
virtual status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) = 0;
virtual status_t clearBootDisplayMode(PhysicalDisplayId) = 0;
virtual std::optional<hal::HWConfigId> getPreferredBootDisplayMode(PhysicalDisplayId) = 0;
@@ -406,7 +405,6 @@
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
// Composer 3.0
- bool getBootDisplayModeSupport() override;
status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) override;
status_t clearBootDisplayMode(PhysicalDisplayId) override;
std::optional<hal::HWConfigId> getPreferredBootDisplayMode(PhysicalDisplayId) override;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index e8dc084..d9af553 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -235,7 +235,6 @@
return mClient_2_4 != nullptr;
case OptionalFeature::ExpectedPresentTime:
case OptionalFeature::DisplayBrightnessCommand:
- case OptionalFeature::BootDisplayConfig:
case OptionalFeature::KernelIdleTimer:
case OptionalFeature::PhysicalDisplayOrientation:
return false;
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 3dab389..44c086d 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -542,7 +542,7 @@
static constexpr double kAllowedTargetDeviationPercent = 0.05;
// Target used for init and normalization, the actual value does not really matter
static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
- // amount of time after the last message was sent before the session goes stale
+ // Amount of time after the last message was sent before the session goes stale
// actually 100ms but we use 80 here to ideally avoid going stale
static constexpr const std::chrono::nanoseconds kStaleTimeout = 80ms;
};
@@ -551,7 +551,7 @@
base::GetBoolProperty(std::string("debug.sf.trace_hint_sessions"), false);
const bool AidlPowerHalWrapper::sNormalizeTarget =
- base::GetBoolProperty(std::string("debug.sf.normalize_hint_session_durations"), true);
+ base::GetBoolProperty(std::string("debug.sf.normalize_hint_session_durations"), false);
PowerAdvisor::HalWrapper* PowerAdvisor::getPowerHal() {
static std::unique_ptr<HalWrapper> sHalWrapper = nullptr;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ac7bcde..894fb8d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -37,6 +37,7 @@
#include <cutils/native_handle.h>
#include <cutils/properties.h>
#include <ftl/enum.h>
+#include <ftl/fake_guard.h>
#include <gui/BufferItem.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
@@ -833,6 +834,14 @@
return false;
}
+ if (CC_UNLIKELY(relative->usingRelativeZ(LayerVector::StateSet::Drawing)) &&
+ (relative->mDrawingState.zOrderRelativeOf == this)) {
+ ALOGE("Detected relative layer loop between %s and %s",
+ mName.c_str(), relative->mName.c_str());
+ ALOGE("Ignoring new call to set relative layer");
+ return false;
+ }
+
mFlinger->mSomeChildrenChanged = true;
mDrawingState.sequence++;
@@ -1990,6 +1999,18 @@
}
}
+bool Layer::findInHierarchy(const sp<Layer>& l) {
+ if (l == this) {
+ return true;
+ }
+ for (auto& child : mDrawingChildren) {
+ if (child->findInHierarchy(l)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
const auto& child = mCurrentChildren[i];
@@ -1997,6 +2018,17 @@
}
mDrawingChildren = mCurrentChildren;
mDrawingParent = mCurrentParent;
+ if (CC_UNLIKELY(usingRelativeZ(LayerVector::StateSet::Drawing))) {
+ auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
+ if (zOrderRelativeOf == nullptr) return;
+ if (findInHierarchy(zOrderRelativeOf)) {
+ ALOGE("Detected Z ordering loop between %s and %s", mName.c_str(),
+ zOrderRelativeOf->mName.c_str());
+ ALOGE("Severing rel Z loop, potentially dangerous");
+ mDrawingState.isRelativeOf = false;
+ zOrderRelativeOf->removeZOrderRelative(this);
+ }
+ }
}
@@ -2014,10 +2046,10 @@
writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
+ ftl::FakeGuard guard(mFlinger->mStateLock); // Called from the main thread.
+
// Only populate for the primary display.
- UnnecessaryLock assumeLocked(mFlinger->mStateLock); // called from the main thread.
- const auto display = mFlinger->getDefaultDisplayDeviceLocked();
- if (display) {
+ if (const auto display = mFlinger->getDefaultDisplayDeviceLocked()) {
const auto compositionType = getCompositionType(*display);
layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
LayerProtoHelper::writeToProto(getVisibleRegion(display.get()),
@@ -2177,7 +2209,6 @@
void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) {
Rect tmpBounds = getInputBounds();
if (!tmpBounds.isValid()) {
- info.setInputConfig(WindowInfo::InputConfig::NOT_FOCUSABLE, true);
info.touchableRegion.clear();
// A layer could have invalid input bounds and still expect to receive touch input if it has
// replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 48a9bc5..846460d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1138,6 +1138,7 @@
bool mIsAtRoot = false;
uint32_t mLayerCreationFlags;
+ bool findInHierarchy(const sp<Layer>&);
};
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);
diff --git a/services/surfaceflinger/MainThreadGuard.h b/services/surfaceflinger/MainThreadGuard.h
deleted file mode 100644
index c1aa118..0000000
--- a/services/surfaceflinger/MainThreadGuard.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#pragma once
-
-#include <utils/Mutex.h>
-
-namespace android {
-namespace {
-
-// Helps to ensure that some functions runs on SF's main thread by using the
-// clang thread safety annotations.
-class CAPABILITY("mutex") MainThreadGuard {
-} SF_MAIN_THREAD;
-
-struct SCOPED_CAPABILITY MainThreadScopedGuard {
-public:
- explicit MainThreadScopedGuard(MainThreadGuard& mutex) ACQUIRE(mutex) {}
- ~MainThreadScopedGuard() RELEASE() {}
-};
-} // namespace
-} // namespace android
diff --git a/services/surfaceflinger/MutexUtils.h b/services/surfaceflinger/MutexUtils.h
new file mode 100644
index 0000000..f8be6f3
--- /dev/null
+++ b/services/surfaceflinger/MutexUtils.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#pragma once
+
+#include <log/log.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+struct SCOPED_CAPABILITY ConditionalLock {
+ ConditionalLock(Mutex& mutex, bool lock) ACQUIRE(mutex) : mutex(mutex), lock(lock) {
+ if (lock) mutex.lock();
+ }
+
+ ~ConditionalLock() RELEASE() {
+ if (lock) mutex.unlock();
+ }
+
+ Mutex& mutex;
+ const bool lock;
+};
+
+struct SCOPED_CAPABILITY TimedLock {
+ TimedLock(Mutex& mutex, nsecs_t timeout, const char* whence) ACQUIRE(mutex)
+ : mutex(mutex), status(mutex.timedLock(timeout)) {
+ ALOGE_IF(!locked(), "%s timed out locking: %s (%d)", whence, strerror(-status), status);
+ }
+
+ ~TimedLock() RELEASE() {
+ if (locked()) mutex.unlock();
+ }
+
+ bool locked() const { return status == NO_ERROR; }
+
+ Mutex& mutex;
+ const status_t status;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 74d7739..3aa0a5f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -726,10 +726,6 @@
}
void Scheduler::onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline) {
- if (timeline.refreshRequired) {
- mSchedulerCallback.scheduleComposite(FrameHint::kNone);
- }
-
std::lock_guard<std::mutex> lock(mVsyncTimelineLock);
mLastVsyncPeriodChangeTimeline = std::make_optional(timeline);
@@ -739,23 +735,17 @@
}
}
-void Scheduler::onPostComposition(nsecs_t presentTime) {
- const bool recomposite = [=] {
- std::lock_guard<std::mutex> lock(mVsyncTimelineLock);
- if (mLastVsyncPeriodChangeTimeline && mLastVsyncPeriodChangeTimeline->refreshRequired) {
- if (presentTime < mLastVsyncPeriodChangeTimeline->refreshTimeNanos) {
- // We need to composite again as refreshTimeNanos is still in the future.
- return true;
- }
-
- mLastVsyncPeriodChangeTimeline->refreshRequired = false;
+bool Scheduler::onPostComposition(nsecs_t presentTime) {
+ std::lock_guard<std::mutex> lock(mVsyncTimelineLock);
+ if (mLastVsyncPeriodChangeTimeline && mLastVsyncPeriodChangeTimeline->refreshRequired) {
+ if (presentTime < mLastVsyncPeriodChangeTimeline->refreshTimeNanos) {
+ // We need to composite again as refreshTimeNanos is still in the future.
+ return true;
}
- return false;
- }();
- if (recomposite) {
- mSchedulerCallback.scheduleComposite(FrameHint::kNone);
+ mLastVsyncPeriodChangeTimeline->refreshRequired = false;
}
+ return false;
}
void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index a8113d4..0c72124 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -83,12 +83,8 @@
namespace scheduler {
struct ISchedulerCallback {
- // Indicates frame activity, i.e. whether commit and/or composite is taking place.
- enum class FrameHint { kNone, kActive };
-
using DisplayModeEvent = scheduler::DisplayModeEvent;
- virtual void scheduleComposite(FrameHint) = 0;
virtual void setVsyncEnabled(bool) = 0;
virtual void requestDisplayMode(DisplayModePtr, DisplayModeEvent) = 0;
virtual void kernelTimerChanged(bool expired) = 0;
@@ -210,8 +206,8 @@
// Notifies the scheduler about a refresh rate timeline change.
void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
- // Notifies the scheduler post composition.
- void onPostComposition(nsecs_t presentTime);
+ // Notifies the scheduler post composition. Returns if recomposite is needed.
+ bool onPostComposition(nsecs_t presentTime);
// Notifies the scheduler when the display size has changed. Called from SF's main thread
void onActiveDisplayAreaChanged(uint32_t displayArea);
@@ -245,8 +241,6 @@
private:
friend class TestableScheduler;
- using FrameHint = ISchedulerCallback::FrameHint;
-
enum class ContentDetectionState { Off, On };
enum class TimerState { Reset, Expired };
enum class TouchState { Inactive, Active };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2edc05b..4fc9d27 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -24,7 +24,10 @@
#include "SurfaceFlinger.h"
+#include <android-base/parseint.h>
#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <android/configuration.h>
#include <android/gui/IDisplayEventConnection.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
@@ -49,6 +52,7 @@
#include <configstore/Utils.h>
#include <cutils/compiler.h>
#include <cutils/properties.h>
+#include <ftl/fake_guard.h>
#include <ftl/future.h>
#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
@@ -123,6 +127,7 @@
#include "LayerRenderArea.h"
#include "LayerVector.h"
#include "MonitoredProducer.h"
+#include "MutexUtils.h"
#include "NativeWindowSurface.h"
#include "RefreshRateOverlay.h"
#include "RegionSamplingThread.h"
@@ -138,49 +143,26 @@
#include "TimeStats/TimeStats.h"
#include "TunnelModeEnabledReporter.h"
#include "WindowInfosListenerInvoker.h"
-#include "android-base/parseint.h"
-#include "android-base/stringprintf.h"
-#include "android-base/strings.h"
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
-#define MAIN_THREAD ACQUIRE(mStateLock) RELEASE(mStateLock)
-
-// Note: The parentheses around `expr` are needed to deduce an lvalue or rvalue reference.
-#define ON_MAIN_THREAD(expr) \
- [&]() -> decltype(auto) { \
- LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \
- UnnecessaryLock lock(mStateLock); \
- return (expr); \
- }()
-
-#define MAIN_THREAD_GUARD(expr) \
- [&]() -> decltype(auto) { \
- LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \
- MainThreadScopedGuard lock(SF_MAIN_THREAD); \
- return (expr); \
- }()
-
#undef NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS \
- _Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"")
-
-using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
-using aidl::android::hardware::graphics::composer3::Capability;
-using aidl::android::hardware::graphics::composer3::DisplayCapability;
-using KernelIdleTimerController =
- ::android::scheduler::RefreshRateConfigs::KernelIdleTimerController;
+ _Pragma("GCC error \"Prefer <ftl/fake_guard.h> or MutexUtils.h helpers.\"")
namespace android {
using namespace std::string_literals;
-using namespace android::hardware::configstore;
-using namespace android::hardware::configstore::V1_0;
-using namespace android::sysprop;
+using namespace hardware::configstore;
+using namespace hardware::configstore::V1_0;
+using namespace sysprop;
-using android::hardware::power::Boost;
+using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
+using aidl::android::hardware::graphics::composer3::Capability;
+using aidl::android::hardware::graphics::composer3::DisplayCapability;
+
using base::StringAppendF;
using gui::DisplayInfo;
using gui::IDisplayEventConnection;
@@ -191,6 +173,8 @@
using ui::DisplayPrimaries;
using ui::RenderIntent;
+using KernelIdleTimerController = scheduler::RefreshRateConfigs::KernelIdleTimerController;
+
namespace hal = android::hardware::graphics::composer::hal;
namespace {
@@ -222,38 +206,6 @@
#pragma clang diagnostic pop
-template <typename Mutex>
-struct SCOPED_CAPABILITY ConditionalLockGuard {
- ConditionalLockGuard(Mutex& mutex, bool lock) ACQUIRE(mutex) : mutex(mutex), lock(lock) {
- if (lock) mutex.lock();
- }
-
- ~ConditionalLockGuard() RELEASE() {
- if (lock) mutex.unlock();
- }
-
- Mutex& mutex;
- const bool lock;
-};
-
-using ConditionalLock = ConditionalLockGuard<Mutex>;
-
-struct SCOPED_CAPABILITY TimedLock {
- TimedLock(Mutex& mutex, nsecs_t timeout, const char* whence) ACQUIRE(mutex)
- : mutex(mutex), status(mutex.timedLock(timeout)) {
- ALOGE_IF(!locked(), "%s timed out locking: %s (%d)", whence, strerror(-status), status);
- }
-
- ~TimedLock() RELEASE() {
- if (locked()) mutex.unlock();
- }
-
- bool locked() const { return status == NO_ERROR; }
-
- Mutex& mutex;
- const status_t status;
-};
-
// TODO(b/141333600): Consolidate with DisplayMode::Builder::getDefaultDensity.
constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV;
@@ -690,10 +642,9 @@
const nsecs_t duration = now - mBootTime;
ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
- mFlagManager = std::make_unique<android::FlagManager>();
mFrameTracer->initialize();
mFrameTimeline->onBootFinished();
- getRenderEngine().setEnableTracing(mFlagManager->use_skia_tracing());
+ getRenderEngine().setEnableTracing(mFlagManager.use_skia_tracing());
// wait patiently for the window manager death
const String16 name("window");
@@ -721,22 +672,22 @@
}
readPersistentProperties();
- std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
- std::vector<int32_t> tidList;
- tidList.emplace_back(gettid());
- if (renderEngineTid.has_value()) {
- tidList.emplace_back(*renderEngineTid);
- }
mPowerAdvisor.onBootFinished();
- mPowerAdvisor.enablePowerHint(mFlagManager->use_adpf_cpu_hint());
+ mPowerAdvisor.enablePowerHint(mFlagManager.use_adpf_cpu_hint());
if (mPowerAdvisor.usePowerHintSession()) {
+ std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid();
+ std::vector<int32_t> tidList;
+ tidList.emplace_back(gettid());
+ if (renderEngineTid.has_value()) {
+ tidList.emplace_back(*renderEngineTid);
+ }
mPowerAdvisor.startPowerHintSession(tidList);
}
mBootStage = BootStage::FINISHED;
if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
- ON_MAIN_THREAD(enableRefreshRateOverlay(true));
+ FTL_FAKE_GUARD(mStateLock, enableRefreshRateOverlay(true));
}
}));
}
@@ -937,8 +888,9 @@
FrameEvent::DEQUEUE_READY,
FrameEvent::RELEASE,
};
- ConditionalLock _l(mStateLock,
- std::this_thread::get_id() != mMainThreadId);
+
+ ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
+
if (!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
}
@@ -1086,7 +1038,8 @@
getHwComposer().supportsContentType(*displayId, hal::ContentType::GAME);
info->preferredBootDisplayMode = static_cast<ui::DisplayModeId>(-1);
- if (getHwComposer().getBootDisplayModeSupport()) {
+
+ if (getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(*displayId)) {
if (const auto modeId = display->translateModeId(*hwcId)) {
info->preferredBootDisplayMode = modeId->value();
@@ -1142,7 +1095,7 @@
}
auto future = mScheduler->schedule([=]() -> status_t {
- const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken));
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
if (!display) {
ALOGE("Attempt to set allowed display modes for invalid display token %p",
displayToken.get());
@@ -1183,7 +1136,9 @@
return;
}
- const auto upcomingModeInfo = MAIN_THREAD_GUARD(display->getUpcomingActiveMode());
+ const auto upcomingModeInfo =
+ FTL_FAKE_GUARD(kMainThreadContext, display->getUpcomingActiveMode());
+
if (!upcomingModeInfo.mode) {
// There is no pending mode change. This can happen if the active
// display changed and the mode change happened on a different display.
@@ -1202,9 +1157,8 @@
return;
}
- // We just created this display so we can call even if we are not on
- // the main thread
- MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ // We just created this display so we can call even if we are not on the main thread.
+ ftl::FakeGuard guard(kMainThreadContext);
display->setActiveMode(upcomingModeInfo.mode->getId());
const Fps refreshRate = upcomingModeInfo.mode->getFps();
@@ -1289,8 +1243,10 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline outTimeline;
- const auto status = MAIN_THREAD_GUARD(
- display->initiateModeChange(*desiredActiveMode, constraints, &outTimeline));
+ const auto status = FTL_FAKE_GUARD(kMainThreadContext,
+ display->initiateModeChange(*desiredActiveMode,
+ constraints, &outTimeline));
+
if (status != NO_ERROR) {
// initiateModeChange may fail if a hotplug event is just about
// to be sent. We just log the error in this case.
@@ -1300,7 +1256,7 @@
mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
if (outTimeline.refreshRequired) {
- // Scheduler will submit an empty frame to HWC.
+ scheduleComposite(FrameHint::kNone);
mSetActiveModePending = true;
} else {
// Updating the internal state should be done outside the loop,
@@ -1323,7 +1279,7 @@
}
void SurfaceFlinger::disableExpensiveRendering() {
- auto future = mScheduler->schedule([=]() MAIN_THREAD {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
ATRACE_CALL();
if (mPowerAdvisor.isUsingExpensiveRendering()) {
for (const auto& [_, display] : mDisplays) {
@@ -1372,7 +1328,7 @@
return BAD_VALUE;
}
- auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) -> status_t {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set active color mode %s (%d) for invalid display token %p",
@@ -1407,17 +1363,17 @@
}
status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const {
- auto future = mScheduler->schedule([=]() MAIN_THREAD mutable -> status_t {
- *outSupport = getHwComposer().getBootDisplayModeSupport();
- return NO_ERROR;
- });
- return future.get();
+ auto future = mScheduler->schedule(
+ [this] { return getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG); });
+
+ *outSupport = future.get();
+ return NO_ERROR;
}
status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken,
ui::DisplayModeId modeId) {
const char* const whence = __func__;
- auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) -> status_t {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("%s: Invalid display token %p", whence, displayToken.get());
@@ -1444,7 +1400,7 @@
status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
const char* const whence = __func__;
- auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) -> status_t {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().clearBootDisplayMode(*displayId);
} else {
@@ -1457,7 +1413,7 @@
void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
const char* const whence = __func__;
- static_cast<void>(mScheduler->schedule([=]() MAIN_THREAD {
+ static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
getHwComposer().setAutoLowLatencyMode(*displayId, on);
} else {
@@ -1468,7 +1424,7 @@
void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
const char* const whence = __func__;
- static_cast<void>(mScheduler->schedule([=]() MAIN_THREAD {
+ static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE;
getHwComposer().setContentType(*displayId, type);
@@ -1533,7 +1489,7 @@
bool enable, uint8_t componentMask,
uint64_t maxFrames) {
const char* const whence = __func__;
- auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) -> status_t {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
componentMask, maxFrames);
@@ -1610,7 +1566,7 @@
status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) {
outLayers->clear();
auto future = mScheduler->schedule([=] {
- const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
mDrawingState.traverseInZOrder([&](Layer* layer) {
outLayers->push_back(layer->getLayerDebugInfo(display.get()));
});
@@ -1722,7 +1678,7 @@
}
const char* const whence = __func__;
- return ftl::chain(mScheduler->schedule([=]() MAIN_THREAD {
+ return ftl::chain(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
const bool supportsDisplayBrightnessCommand =
getHwComposer().getComposer()->isSupported(
@@ -1736,7 +1692,9 @@
compositionDisplay->editState().displayBrightnessNits;
compositionDisplay->setDisplayBrightness(brightness.sdrWhitePointNits,
brightness.displayBrightnessNits);
- MAIN_THREAD_GUARD(display->stageBrightness(brightness.displayBrightness));
+ FTL_FAKE_GUARD(kMainThreadContext,
+ display->stageBrightness(brightness.displayBrightness));
+
if (brightness.sdrWhitePointNits / brightness.displayBrightnessNits !=
currentDimmingRatio) {
scheduleComposite(FrameHint::kNone);
@@ -1806,6 +1764,7 @@
}
status_t SurfaceFlinger::notifyPowerBoost(int32_t boostId) {
+ using hardware::power::Boost;
Boost powerBoost = static_cast<Boost>(boostId);
if (powerBoost == Boost::INTERACTION) {
@@ -1941,6 +1900,10 @@
hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline& timeline) {
Mutex::Autolock lock(mStateLock);
mScheduler->onNewVsyncPeriodChangeTimeline(timeline);
+
+ if (timeline.refreshRequired) {
+ scheduleComposite(FrameHint::kNone);
+ }
}
void SurfaceFlinger::onComposerHalSeamlessPossible(hal::HWDisplayId) {
@@ -1962,7 +1925,7 @@
ATRACE_CALL();
// On main thread to avoid race conditions with display power state.
- static_cast<void>(mScheduler->schedule([=]() MAIN_THREAD {
+ static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
mHWCVsyncPendingState = enabled ? hal::Vsync::ENABLE : hal::Vsync::DISABLE;
if (const auto display = getDefaultDisplayDeviceLocked();
@@ -2010,8 +1973,8 @@
: stats.vsyncTime + stats.vsyncPeriod;
}
-bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) {
- MainThreadScopedGuard mainThreadGuard(SF_MAIN_THREAD);
+bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime)
+ FTL_FAKE_GUARD(kMainThreadContext) {
// we set this once at the beginning of commit to ensure consistency throughout the whole frame
mPowerHintSessionData.sessionEnabled = mPowerAdvisor.usePowerHintSession();
if (mPowerHintSessionData.sessionEnabled) {
@@ -2177,20 +2140,21 @@
mLayerTracing.notify(mVisibleRegionsDirty, frameTime);
}
- MAIN_THREAD_GUARD(persistDisplayBrightness(mustComposite));
+ persistDisplayBrightness(mustComposite);
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}
-void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId) {
+void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
+ FTL_FAKE_GUARD(kMainThreadContext) {
ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId);
- MainThreadScopedGuard mainThreadGuard(SF_MAIN_THREAD);
+
if (mPowerHintSessionData.sessionEnabled) {
mPowerHintSessionData.compositeStart = systemTime();
}
compositionengine::CompositionRefreshArgs refreshArgs;
- const auto& displays = ON_MAIN_THREAD(mDisplays);
+ const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
refreshArgs.outputs.reserve(displays.size());
for (const auto& [_, display] : displays) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
@@ -2248,7 +2212,9 @@
mTimeStats->recordFrameDuration(frameTime, systemTime());
- mScheduler->onPostComposition(presentTime);
+ if (mScheduler->onPostComposition(presentTime)) {
+ scheduleComposite(FrameHint::kNone);
+ }
postFrame();
postComposition();
@@ -2426,7 +2392,7 @@
ATRACE_CALL();
ALOGV("postComposition");
- const auto* display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()).get();
+ const auto* display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
getBE().mGlCompositionDoneTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
@@ -2626,44 +2592,37 @@
}
FloatRect SurfaceFlinger::getMaxDisplayBounds() {
- // Find the largest width and height among all the displays.
- int32_t maxDisplayWidth = 0;
- int32_t maxDisplayHeight = 0;
+ const ui::Size maxSize = [this] {
+ ftl::FakeGuard guard(mStateLock);
- // If there are no displays, set a valid display bounds so we can still compute a valid layer
- // bounds.
- if (ON_MAIN_THREAD(mDisplays.size()) == 0) {
- maxDisplayWidth = maxDisplayHeight = 5000;
- }
+ // The LayerTraceGenerator tool runs without displays.
+ if (mDisplays.empty()) return ui::Size{5000, 5000};
- for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
- const auto& displayDevice = pair.second;
- int32_t width = displayDevice->getWidth();
- int32_t height = displayDevice->getHeight();
- if (width > maxDisplayWidth) {
- maxDisplayWidth = width;
- }
- if (height > maxDisplayHeight) {
- maxDisplayHeight = height;
- }
- }
+ return std::accumulate(mDisplays.begin(), mDisplays.end(), ui::kEmptySize,
+ [](ui::Size size, const auto& pair) -> ui::Size {
+ const auto& display = pair.second;
+ return {std::max(size.getWidth(), display->getWidth()),
+ std::max(size.getHeight(), display->getHeight())};
+ });
+ }();
// Ignore display bounds for now since they will be computed later. Use a large Rect bound
// to ensure it's bigger than an actual display will be.
- FloatRect maxBounds = FloatRect(-maxDisplayWidth * 10, -maxDisplayHeight * 10,
- maxDisplayWidth * 10, maxDisplayHeight * 10);
- return maxBounds;
+ const float xMax = maxSize.getWidth() * 10.f;
+ const float yMax = maxSize.getHeight() * 10.f;
+
+ return {-xMax, -yMax, xMax, yMax};
}
void SurfaceFlinger::computeLayerBounds() {
- FloatRect maxBounds = getMaxDisplayBounds();
+ const FloatRect maxBounds = getMaxDisplayBounds();
for (const auto& layer : mDrawingState.layersSortedByZ) {
layer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
}
}
void SurfaceFlinger::postFrame() {
- const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
if (display && getHwComposer().isConnected(display->getPhysicalId())) {
uint32_t flipCount = display->getPageFlipCount();
if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
@@ -2917,7 +2876,8 @@
RenderIntent::COLORIMETRIC,
Dataspace::UNKNOWN});
if (!state.isVirtual()) {
- MAIN_THREAD_GUARD(display->setActiveMode(state.physical->activeMode->getId()));
+ FTL_FAKE_GUARD(kMainThreadContext,
+ display->setActiveMode(state.physical->activeMode->getId()));
display->setDeviceProductInfo(state.physical->deviceProductInfo);
}
@@ -3287,7 +3247,7 @@
return;
}
- for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
+ for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
if (const auto brightness = display->getStagedBrightness(); brightness) {
if (!needsComposite) {
const status_t error =
@@ -3310,7 +3270,7 @@
std::vector<DisplayInfo>& outDisplayInfos) {
ftl::SmallMap<ui::LayerStack, DisplayDevice::InputInfo, 4> displayInputInfos;
- for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
+ for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
const auto layerStack = display->getLayerStack();
const auto info = display->getInputInfo();
@@ -3355,7 +3315,7 @@
void SurfaceFlinger::updateCursorAsync() {
compositionengine::CompositionRefreshArgs refreshArgs;
- for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
+ for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
if (HalDisplayId::tryCast(display->getId())) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
@@ -3540,7 +3500,7 @@
}
void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
- for (const auto& [token, displayDevice] : ON_MAIN_THREAD(mDisplays)) {
+ for (const auto& [token, displayDevice] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
auto display = displayDevice->getCompositionDisplay();
if (display->includesLayer(layer->getOutputFilter())) {
display->editState().dirtyRegion.orSelf(dirty);
@@ -3670,16 +3630,13 @@
return mTransactionFlags.fetch_and(~mask) & mask;
}
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t mask) {
- return setTransactionFlags(mask, TransactionSchedule::Late);
-}
-
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
- const sp<IBinder>& applyToken) {
- const uint32_t old = mTransactionFlags.fetch_or(mask);
+void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
+ const sp<IBinder>& applyToken) {
modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
- if ((old & mask) == 0) scheduleCommit(FrameHint::kActive);
- return old;
+
+ if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled) {
+ scheduleCommit(FrameHint::kActive);
+ }
}
bool SurfaceFlinger::stopTransactionProcessing(
@@ -3695,6 +3652,15 @@
return false;
}
+int SurfaceFlinger::flushUnsignaledPendingTransactionQueues(
+ std::vector<TransactionState>& transactions,
+ std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
+ std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) {
+ return flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent,
+ applyTokensWithUnsignaledTransactions,
+ /*tryApplyUnsignaled*/ true);
+}
+
int SurfaceFlinger::flushPendingTransactionQueues(
std::vector<TransactionState>& transactions,
std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
@@ -3729,8 +3695,8 @@
break;
}
transaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
- const bool frameNumberChanged =
- state.bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
+ const bool frameNumberChanged = state.bufferData->flags.test(
+ BufferData::BufferDataChange::frameNumberChanged);
if (frameNumberChanged) {
bufferLayersReadyToPresent[state.surface] = state.bufferData->frameNumber;
} else {
@@ -3810,8 +3776,8 @@
mPendingTransactionQueues[transaction.applyToken].push(std::move(transaction));
} else {
transaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
- const bool frameNumberChanged =
- state.bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
+ const bool frameNumberChanged = state.bufferData->flags.test(
+ BufferData::BufferDataChange::frameNumberChanged);
if (frameNumberChanged) {
bufferLayersReadyToPresent[state.surface] = state.bufferData->frameNumber;
} else {
@@ -3820,7 +3786,7 @@
bufferLayersReadyToPresent[state.surface] =
std::numeric_limits<uint64_t>::max();
}
- });
+ });
transactions.emplace_back(std::move(transaction));
}
mTransactionQueue.pop_front();
@@ -3849,9 +3815,8 @@
// If we are allowing latch unsignaled of some form, now it's the time to go over the
// transactions that were not applied and try to apply them unsignaled.
if (enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) {
- flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent,
- applyTokensWithUnsignaledTransactions,
- /*tryApplyUnsignaled*/ true);
+ flushUnsignaledPendingTransactionQueues(transactions, bufferLayersReadyToPresent,
+ applyTokensWithUnsignaledTransactions);
}
return applyTransactions(transactions, vsyncId);
@@ -4821,7 +4786,8 @@
void SurfaceFlinger::initializeDisplays() {
// Async since we may be called from the main thread.
- static_cast<void>(mScheduler->schedule([this]() MAIN_THREAD { onInitializeDisplays(); }));
+ static_cast<void>(
+ mScheduler->schedule([this]() FTL_FAKE_GUARD(mStateLock) { onInitializeDisplays(); }));
}
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
@@ -4921,7 +4887,7 @@
}
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
- auto future = mScheduler->schedule([=]() MAIN_THREAD {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
@@ -4968,7 +4934,7 @@
bool dumpLayers = true;
{
- TimedLock lock(mStateLock, s2ns(1), __FUNCTION__);
+ TimedLock lock(mStateLock, s2ns(1), __func__);
if (!lock.locked()) {
StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
strerror(-lock.status), lock.status);
@@ -5056,8 +5022,6 @@
mFrameTimeline->parseArgs(args, result);
}
-// This should only be called from the main thread. Otherwise it would need
-// the lock and should use mCurrentState rather than mDrawingState.
void SurfaceFlinger::logFrameStats() {
mDrawingState.traverse([&](Layer* layer) {
layer->logFrameStats();
@@ -5215,7 +5179,7 @@
}
void SurfaceFlinger::dumpDisplayProto(LayersTraceProto& layersTraceProto) const {
- for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
+ for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
DisplayProto* displayProto = layersTraceProto.add_displays();
displayProto->set_id(display->getId().value);
displayProto->set_name(display->getDisplayName());
@@ -5459,9 +5423,7 @@
/*
* Dump flag/property manager state
*/
- if (mFlagManager != nullptr) {
- mFlagManager->dump(result);
- }
+ mFlagManager.dump(result);
result.append(mTimeStats->miniDump());
result.append("\n");
@@ -5858,7 +5820,7 @@
int64_t startingTime =
(fixedStartingTime) ? fixedStartingTime : systemTime();
mScheduler
- ->schedule([&]() MAIN_THREAD {
+ ->schedule([&]() FTL_FAKE_GUARD(mStateLock) {
mLayerTracing.notify("start", startingTime);
})
.wait();
@@ -5971,10 +5933,12 @@
switch (n = data.readInt32()) {
case 0:
case 1:
- ON_MAIN_THREAD(enableRefreshRateOverlay(static_cast<bool>(n)));
+ FTL_FAKE_GUARD(mStateLock,
+ enableRefreshRateOverlay(static_cast<bool>(n)));
break;
default: {
- reply->writeBool(ON_MAIN_THREAD(isRefreshRateOverlayEnabled()));
+ reply->writeBool(
+ FTL_FAKE_GUARD(mStateLock, isRefreshRateOverlayEnabled()));
}
}
});
@@ -6012,7 +5976,7 @@
return mScheduler
->schedule([this] {
const auto display =
- ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
// This is a little racy, but not in a way that hurts anything. As
// we grab the defaultMode from the display manager policy, we could
@@ -6034,7 +5998,7 @@
return mScheduler
->schedule([this] {
const auto display =
- ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
constexpr bool kOverridePolicy = true;
return setDesiredDisplayModeSpecsInternal(display, {},
kOverridePolicy);
@@ -6150,7 +6114,7 @@
// Update the overlay on the main thread to avoid race conditions with
// mRefreshRateConfigs->getActiveMode()
static_cast<void>(mScheduler->schedule([=] {
- const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
if (!display) {
ALOGW("%s: default display is null", __func__);
return;
@@ -6948,7 +6912,7 @@
}
auto future = mScheduler->schedule([=]() -> status_t {
- const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken));
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
if (!display) {
ALOGE("Attempt to set desired display modes for invalid display token %p",
displayToken.get());
@@ -7193,7 +7157,7 @@
if (const auto frameRateOverride = mScheduler->getFrameRateOverride(uid)) {
refreshRate = *frameRateOverride;
} else if (!getHwComposer().isHeadless()) {
- if (const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked())) {
+ if (const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked())) {
refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index df59d50..97b0e8d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -56,6 +56,7 @@
#include "DisplayHardware/PowerAdvisor.h"
#include "DisplayIdGenerator.h"
#include "Effects/Daltonizer.h"
+#include "FlagManager.h"
#include "FrameTracker.h"
#include "LayerVector.h"
#include "Scheduler/RefreshRateConfigs.h"
@@ -63,6 +64,7 @@
#include "Scheduler/Scheduler.h"
#include "Scheduler/VsyncModulator.h"
#include "SurfaceFlingerFactory.h"
+#include "ThreadContext.h"
#include "TracedOrdinal.h"
#include "Tracing/LayerTracing.h"
#include "Tracing/TransactionTracing.h"
@@ -182,11 +184,6 @@
std::atomic<nsecs_t> mLastSwapTime = 0;
};
-struct SCOPED_CAPABILITY UnnecessaryLock {
- explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {}
- ~UnnecessaryLock() RELEASE() {}
-};
-
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
@@ -286,10 +283,13 @@
SurfaceFlingerBE& getBE() { return mBE; }
const SurfaceFlingerBE& getBE() const { return mBE; }
+ // Indicates frame activity, i.e. whether commit and/or composite is taking place.
+ enum class FrameHint { kNone, kActive };
+
// Schedule commit of transactions on the main thread ahead of the next VSYNC.
void scheduleCommit(FrameHint);
// As above, but also force composite regardless if transactions were committed.
- void scheduleComposite(FrameHint) override;
+ void scheduleComposite(FrameHint);
// As above, but also force dirty geometry to repaint.
void scheduleRepaint();
// Schedule sampling independently from commit or composite.
@@ -736,7 +736,7 @@
void updateLayerGeometry();
void updateInputFlinger();
- void persistDisplayBrightness(bool needsComposite) REQUIRES(SF_MAIN_THREAD);
+ void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos,
std::vector<gui::DisplayInfo>& outDisplayInfos);
void commitInputWindowCommands() REQUIRES(mStateLock);
@@ -770,27 +770,27 @@
std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions,
bool tryApplyUnsignaled) REQUIRES(mStateLock, mQueueLock);
+ int flushUnsignaledPendingTransactionQueues(
+ std::vector<TransactionState>& transactions,
+ std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
+ std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions)
+ REQUIRES(mStateLock, mQueueLock);
+
uint32_t setClientStateLocked(const FrameTimelineInfo&, ComposerState&,
int64_t desiredPresentTime, bool isAutoTimestamp,
int64_t postTime, uint32_t permissions) REQUIRES(mStateLock);
uint32_t getTransactionFlags() const;
- // Sets the masked bits, and returns the old flags.
- uint32_t setTransactionFlags(uint32_t mask);
+ // Sets the masked bits, and schedules a commit if needed.
+ void setTransactionFlags(uint32_t mask, TransactionSchedule = TransactionSchedule::Late,
+ const sp<IBinder>& applyToken = nullptr);
// Clears and returns the masked bits.
uint32_t clearTransactionFlags(uint32_t mask);
- // Indicate SF should call doTraversal on layers, but don't trigger a wakeup! We use this cases
- // where there are still pending transactions but we know they won't be ready until a frame
- // arrives from a different layer. So we need to ensure we performTransaction from invalidate
- // but there is no need to try and wake up immediately to do it. Rather we rely on
- // onFrameAvailable or another layer update to wake us up.
- void setTraversalNeeded();
- uint32_t setTransactionFlags(uint32_t mask, TransactionSchedule,
- const sp<IBinder>& applyToken = {});
void commitOffscreenLayers();
+
enum class TransactionReadiness {
NotReady,
NotReadyBarrier,
@@ -969,7 +969,7 @@
void setCompositorTimingSnapped(const DisplayStatInfo& stats,
nsecs_t compositeToPresentLatency);
- void postFrame();
+ void postFrame() REQUIRES(kMainThreadContext);
/*
* Display management
@@ -1084,7 +1084,7 @@
void clearStatsLocked(const DumpArgs& args, std::string& result);
void dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const;
void dumpFrameTimeline(const DumpArgs& args, std::string& result) const;
- void logFrameStats();
+ void logFrameStats() REQUIRES(kMainThreadContext);
void dumpVSync(std::string& result) const REQUIRES(mStateLock);
void dumpStaticScreenStats(std::string& result) const;
@@ -1415,7 +1415,7 @@
const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
- std::unique_ptr<FlagManager> mFlagManager;
+ FlagManager mFlagManager;
// returns the framerate of the layer with the given sequence ID
float getLayerFramerate(nsecs_t now, int32_t id) const {
@@ -1427,7 +1427,7 @@
nsecs_t commitStart;
nsecs_t compositeStart;
nsecs_t presentEnd;
- } mPowerHintSessionData GUARDED_BY(SF_MAIN_THREAD);
+ } mPowerHintSessionData GUARDED_BY(kMainThreadContext);
nsecs_t mAnimationTransactionTimeout = s2ns(5);
diff --git a/services/surfaceflinger/ThreadContext.h b/services/surfaceflinger/ThreadContext.h
new file mode 100644
index 0000000..85c379d
--- /dev/null
+++ b/services/surfaceflinger/ThreadContext.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#pragma once
+
+namespace android {
+
+// Enforces exclusive access by the main thread.
+constexpr class [[clang::capability("mutex")]] {
+} kMainThreadContext;
+
+} // namespace android
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
index a5a716d..f25043c 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
@@ -140,10 +140,8 @@
mFlinger->enableLatchUnsignaledConfig = mFdp.PickValueInArray(kLatchUnsignaledConfig);
- mFlinger->scheduleComposite(mFdp.ConsumeBool()
- ? scheduler::ISchedulerCallback::FrameHint::kActive
- : scheduler::ISchedulerCallback::FrameHint::kNone);
-
+ using FrameHint = SurfaceFlinger::FrameHint;
+ mFlinger->scheduleComposite(mFdp.ConsumeBool() ? FrameHint::kActive : FrameHint::kNone);
mFlinger->scheduleRepaint();
mFlinger->scheduleSample();
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 93abc9f..a80aca2 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -22,6 +22,7 @@
#include <compositionengine/impl/CompositionEngine.h>
#include <compositionengine/impl/Display.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <ftl/fake_guard.h>
#include <gui/LayerDebugInfo.h>
#include <gui/ScreenCaptureResults.h>
#include <gui/SurfaceComposerClient.h>
@@ -50,6 +51,7 @@
#include "SurfaceFlinger.h"
#include "SurfaceFlingerDefaultFactory.h"
#include "SurfaceInterceptor.h"
+#include "ThreadContext.h"
#include "TimeStats/TimeStats.h"
#include "renderengine/mock/RenderEngine.h"
@@ -445,7 +447,7 @@
mFlinger->clearStatsLocked(dumpArgs, result);
mFlinger->dumpTimeStats(dumpArgs, fdp->ConsumeBool(), result);
- mFlinger->logFrameStats();
+ FTL_FAKE_GUARD(kMainThreadContext, mFlinger->logFrameStats());
result = fdp->ConsumeRandomLengthString().c_str();
mFlinger->dumpFrameTimeline(dumpArgs, result);
@@ -651,7 +653,7 @@
updateCompositorTiming(&mFdp);
mFlinger->setCompositorTimingSnapped({}, mFdp.ConsumeIntegral<nsecs_t>());
- mFlinger->postFrame();
+ FTL_FAKE_GUARD(kMainThreadContext, mFlinger->postFrame());
mFlinger->calculateExpectedPresentTime({});
mFlinger->enableHalVirtualDisplays(mFdp.ConsumeBool());
@@ -810,7 +812,6 @@
}
private:
- void scheduleComposite(FrameHint) override {}
void setVsyncEnabled(bool) override {}
void requestDisplayMode(DisplayModePtr, DisplayModeEvent) override {}
void kernelTimerChanged(bool) override {}
diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp
index 73c60e1..225ad16 100644
--- a/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayDevice_SetDisplayBrightnessTest.cpp
@@ -19,6 +19,7 @@
#include "DisplayTransactionTestHelpers.h"
+#include <ftl/fake_guard.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -35,7 +36,7 @@
};
TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessNoComposite) {
- MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ ftl::FakeGuard guard(kMainThreadContext);
sp<DisplayDevice> displayDevice = getDisplayDevice();
EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
@@ -52,7 +53,7 @@
}
TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessWithComposite) {
- MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ ftl::FakeGuard guard(kMainThreadContext);
sp<DisplayDevice> displayDevice = getDisplayDevice();
EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
@@ -70,7 +71,7 @@
}
TEST_F(SetDisplayBrightnessTest, persistDisplayBrightnessWithCompositeShortCircuitsOnNoOp) {
- MainThreadScopedGuard fakeMainThreadGuard(SF_MAIN_THREAD);
+ ftl::FakeGuard guard(kMainThreadContext);
sp<DisplayDevice> displayDevice = getDisplayDevice();
EXPECT_EQ(std::nullopt, displayDevice->getStagedBrightness());
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
index 5083d56..5267586 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
@@ -23,7 +23,6 @@
namespace android::scheduler::mock {
struct SchedulerCallback final : ISchedulerCallback {
- MOCK_METHOD(void, scheduleComposite, (FrameHint), (override));
MOCK_METHOD(void, setVsyncEnabled, (bool), (override));
MOCK_METHOD(void, requestDisplayMode, (DisplayModePtr, DisplayModeEvent), (override));
MOCK_METHOD(void, kernelTimerChanged, (bool), (override));
@@ -31,7 +30,6 @@
};
struct NoOpSchedulerCallback final : ISchedulerCallback {
- void scheduleComposite(FrameHint) override {}
void setVsyncEnabled(bool) override {}
void requestDisplayMode(DisplayModePtr, DisplayModeEvent) override {}
void kernelTimerChanged(bool) override {}