Merge "Return events from mappers and InputDevice"
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 481d704..5e725a9 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -232,7 +232,10 @@
: mRpcServer(rpcServer), mKeepAliveBinder(keepAliveBinder), mBinder(binder) {}
virtual ~RpcServerLink();
void binderDied(const wp<IBinder>&) override {
- LOG_RPC_DETAIL("RpcServerLink: binder died, shutting down RpcServer");
+ auto promoted = mBinder.promote();
+ ALOGI("RpcBinder: binder died, shutting down RpcServer for %s",
+ promoted ? String8(promoted->getInterfaceDescriptor()).c_str() : "<NULL>");
+
if (mRpcServer == nullptr) {
ALOGW("RpcServerLink: Unable to shut down RpcServer because it does not exist.");
} else {
@@ -241,11 +244,7 @@
}
mRpcServer.clear();
- auto promoted = mBinder.promote();
- if (promoted == nullptr) {
- ALOGW("RpcServerLink: Unable to remove link from parent binder object because parent "
- "binder object is gone.");
- } else {
+ if (promoted) {
promoted->removeRpcServerLink(sp<RpcServerLink>::fromExisting(this));
}
mBinder.clear();
@@ -706,6 +705,7 @@
return status;
}
rpcServer->setMaxThreads(binderThreadPoolMaxCount);
+ LOG(INFO) << "RpcBinder: Started Binder debug on " << getInterfaceDescriptor();
rpcServer->start();
e->mRpcServerLinks.emplace(link);
LOG_RPC_DETAIL("%s(fd=%d) successful", __PRETTY_FUNCTION__, socketFdForPrint);
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index c411f4f..7067328 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -886,6 +886,7 @@
it->second.asyncTodo.push(BinderNode::AsyncTodo{
.ref = target,
.data = std::move(transactionData),
+ .ancillaryFds = std::move(ancillaryFds),
.asyncNumber = transaction->asyncNumber,
});
@@ -1046,6 +1047,7 @@
// reset up arguments
transactionData = std::move(todo.data);
+ ancillaryFds = std::move(todo.ancillaryFds);
LOG_ALWAYS_FATAL_IF(target != todo.ref,
"async list should be associated with a binder");
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index 7aab5ee..ac86585 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -250,6 +250,7 @@
struct AsyncTodo {
sp<IBinder> ref;
CommandData data;
+ std::vector<std::variant<base::unique_fd, base::borrowed_fd>> ancillaryFds;
uint64_t asyncNumber = 0;
bool operator<(const AsyncTodo& o) const {
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 7ea9be7..fccc0af 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -349,7 +349,7 @@
/**
* See AIBinder_Weak_promote.
*/
- SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); }
+ SpAIBinder promote() const { return SpAIBinder(AIBinder_Weak_promote(get())); }
};
namespace internal {
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 6d29238..01b9472 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -670,6 +670,26 @@
EXPECT_EQ(42, pparcel->readInt32());
}
+TEST(NdkBinder, GetAndVerifyScopedAIBinder_Weak) {
+ for (const ndk::SpAIBinder& binder :
+ {// remote
+ ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
+ // local
+ ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
+ // get a const ScopedAIBinder_Weak and verify promote
+ EXPECT_NE(binder.get(), nullptr);
+ const ndk::ScopedAIBinder_Weak wkAIBinder =
+ ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
+ EXPECT_EQ(wkAIBinder.promote().get(), binder.get());
+ // get another ScopedAIBinder_Weak and verify
+ ndk::ScopedAIBinder_Weak wkAIBinder2 =
+ ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
+ EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder.get(), wkAIBinder2.get()));
+ EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder2.get(), wkAIBinder.get()));
+ EXPECT_EQ(wkAIBinder2.promote(), wkAIBinder.promote());
+ }
+}
+
class MyResultReceiver : public BnResultReceiver {
public:
Mutex mMutex;
diff --git a/libs/binder/tests/IBinderRpcTest.aidl b/libs/binder/tests/IBinderRpcTest.aidl
index b15a225..a3ed571 100644
--- a/libs/binder/tests/IBinderRpcTest.aidl
+++ b/libs/binder/tests/IBinderRpcTest.aidl
@@ -71,4 +71,13 @@
ParcelFileDescriptor echoAsFile(@utf8InCpp String content);
ParcelFileDescriptor concatFiles(in List<ParcelFileDescriptor> files);
+
+ // FDs sent via `blockingSendFdOneway` can be received via
+ // `blockingRecvFd`. The handler for `blockingSendFdOneway` will block
+ // until the next `blockingRecvFd` call.
+ //
+ // This is useful for carefully controlling how/when oneway transactions
+ // get queued.
+ oneway void blockingSendFdOneway(in ParcelFileDescriptor fd);
+ ParcelFileDescriptor blockingRecvFd();
}
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 652da99..2b70492 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -788,12 +788,12 @@
ts.push_back(std::thread([&] { proc.rootIface->lockUnlock(); }));
}
- usleep(100000); // give chance for calls on other threads
+ usleep(10000); // give chance for calls on other threads
// other calls still work
EXPECT_EQ(OK, proc.rootBinder->pingBinder());
- constexpr size_t blockTimeMs = 500;
+ constexpr size_t blockTimeMs = 50;
size_t epochMsBefore = epochMillis();
// after this, we should never see a response within this time
EXPECT_OK(proc.rootIface->unlockInMsAsync(blockTimeMs));
@@ -922,6 +922,45 @@
EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
}
+TEST_P(BinderRpc, OnewayCallQueueingWithFds) {
+ if (!supportsFdTransport()) {
+ GTEST_SKIP() << "Would fail trivially (which is tested elsewhere)";
+ }
+ if (clientOrServerSingleThreaded()) {
+ GTEST_SKIP() << "This test requires multiple threads";
+ }
+
+ // This test forces a oneway transaction to be queued by issuing two
+ // `blockingSendFdOneway` calls, then drains the queue by issuing two
+ // `blockingRecvFd` calls.
+ //
+ // For more details about the queuing semantics see
+ // https://developer.android.com/reference/android/os/IBinder#FLAG_ONEWAY
+
+ auto proc = createRpcTestSocketServerProcess({
+ .numThreads = 3,
+ .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
+ .serverSupportedFileDescriptorTransportModes =
+ {RpcSession::FileDescriptorTransportMode::UNIX},
+ });
+
+ EXPECT_OK(proc.rootIface->blockingSendFdOneway(
+ android::os::ParcelFileDescriptor(mockFileDescriptor("a"))));
+ EXPECT_OK(proc.rootIface->blockingSendFdOneway(
+ android::os::ParcelFileDescriptor(mockFileDescriptor("b"))));
+
+ android::os::ParcelFileDescriptor fdA;
+ EXPECT_OK(proc.rootIface->blockingRecvFd(&fdA));
+ std::string result;
+ CHECK(android::base::ReadFdToString(fdA.get(), &result));
+ EXPECT_EQ(result, "a");
+
+ android::os::ParcelFileDescriptor fdB;
+ EXPECT_OK(proc.rootIface->blockingRecvFd(&fdB));
+ CHECK(android::base::ReadFdToString(fdB.get(), &result));
+ EXPECT_EQ(result, "b");
+}
+
TEST_P(BinderRpc, OnewayCallQueueing) {
if (clientOrServerSingleThreaded()) {
GTEST_SKIP() << "This test requires multiple threads";
@@ -1085,7 +1124,7 @@
}
std::unique_lock<std::mutex> lock(dr->mMtx);
- ASSERT_TRUE(dr->mCv.wait_for(lock, 1000ms, [&]() { return dr->dead; }));
+ ASSERT_TRUE(dr->mCv.wait_for(lock, 100ms, [&]() { return dr->dead; }));
// need to wait for the session to shutdown so we don't "Leak session"
EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
@@ -1120,7 +1159,7 @@
std::unique_lock<std::mutex> lock(dr->mMtx);
if (!dr->dead) {
- EXPECT_EQ(std::cv_status::no_timeout, dr->mCv.wait_for(lock, 1000ms));
+ EXPECT_EQ(std::cv_status::no_timeout, dr->mCv.wait_for(lock, 100ms));
}
EXPECT_TRUE(dr->dead) << "Failed to receive the death notification.";
@@ -1703,7 +1742,7 @@
bool shutdown = false;
for (int i = 0; i < 10 && !shutdown; i++) {
- usleep(300 * 1000); // 300ms; total 3s
+ usleep(30 * 1000); // 30ms; total 300ms
if (server->shutdown()) shutdown = true;
}
ASSERT_TRUE(shutdown) << "server->shutdown() never returns true";
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index 4513d36..fddf5f3 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -167,6 +167,42 @@
return readFd;
}
+// A threadsafe channel where writes block until the value is read.
+template <typename T>
+class HandoffChannel {
+public:
+ void write(T v) {
+ {
+ RpcMutexUniqueLock lock(mMutex);
+ // Wait for space to send.
+ mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
+ mValue.emplace(std::move(v));
+ }
+ mCvFull.notify_all();
+ RpcMutexUniqueLock lock(mMutex);
+ // Wait for it to be taken.
+ mCvEmpty.wait(lock, [&]() { return !mValue.has_value(); });
+ }
+
+ T read() {
+ RpcMutexUniqueLock lock(mMutex);
+ if (!mValue.has_value()) {
+ mCvFull.wait(lock, [&]() { return mValue.has_value(); });
+ }
+ T v = std::move(mValue.value());
+ mValue.reset();
+ lock.unlock();
+ mCvEmpty.notify_all();
+ return std::move(v);
+ }
+
+private:
+ RpcMutex mMutex;
+ RpcConditionVariable mCvEmpty;
+ RpcConditionVariable mCvFull;
+ std::optional<T> mValue;
+};
+
using android::binder::Status;
class MyBinderRpcSession : public BnBinderRpcSession {
@@ -374,6 +410,18 @@
out->reset(mockFileDescriptor(acc));
return Status::ok();
}
+
+ HandoffChannel<android::base::unique_fd> mFdChannel;
+
+ Status blockingSendFdOneway(const android::os::ParcelFileDescriptor& fd) override {
+ mFdChannel.write(android::base::unique_fd(fcntl(fd.get(), F_DUPFD_CLOEXEC, 0)));
+ return Status::ok();
+ }
+
+ Status blockingRecvFd(android::os::ParcelFileDescriptor* fd) override {
+ fd->reset(mFdChannel.read());
+ return Status::ok();
+ }
};
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index a57af09..c63d57f 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -216,7 +216,6 @@
to_string(getId()).c_str());
return BAD_VALUE;
}
- mNumModeSwitchesInPolicy++;
mUpcomingActiveMode = info;
ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue());
return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(),
@@ -498,27 +497,6 @@
mDesiredActiveModeChanged = false;
}
-status_t DisplayDevice::setRefreshRatePolicy(
- const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
- const auto oldPolicy = mRefreshRateConfigs->getCurrentPolicy();
- const status_t setPolicyResult = overridePolicy
- ? mRefreshRateConfigs->setOverridePolicy(policy)
- : mRefreshRateConfigs->setDisplayManagerPolicy(*policy);
-
- if (setPolicyResult == OK) {
- const int numModeChanges = mNumModeSwitchesInPolicy.exchange(0);
-
- ALOGI("Display %s policy changed\n"
- "Previous: {%s}\n"
- "Current: {%s}\n"
- "%d mode changes were performed under the previous policy",
- to_string(getId()).c_str(), oldPolicy.toString().c_str(),
- policy ? policy->toString().c_str() : "null", numModeChanges);
- }
-
- return setPolicyResult;
-}
-
std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e155ca1..06a812b 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -236,10 +236,6 @@
nsecs_t getVsyncPeriodFromHWC() const;
- status_t setRefreshRatePolicy(
- const std::optional<scheduler::RefreshRateConfigs::Policy>& policy,
- bool overridePolicy);
-
// release HWC resources (if any) for removable displays
void disconnect();
@@ -287,8 +283,6 @@
TracedOrdinal<bool> mDesiredActiveModeChanged
GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false};
ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext);
-
- std::atomic_int mNumModeSwitchesInPolicy = 0;
};
struct DisplayDeviceState {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index fb50588..c10b817 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -28,6 +28,7 @@
#include <android-base/stringprintf.h>
#include <ftl/enum.h>
#include <ftl/fake_guard.h>
+#include <ftl/match.h>
#include <utils/Trace.h>
#include "../SurfaceFlingerProperties.h"
@@ -117,6 +118,20 @@
return false;
}
+std::string toString(const RefreshRateConfigs::PolicyVariant& policy) {
+ using namespace std::string_literals;
+
+ return ftl::match(
+ policy,
+ [](const RefreshRateConfigs::DisplayManagerPolicy& policy) {
+ return "DisplayManagerPolicy"s + policy.toString();
+ },
+ [](const RefreshRateConfigs::OverridePolicy& policy) {
+ return "OverridePolicy"s + policy.toString();
+ },
+ [](RefreshRateConfigs::NoOverridePolicy) { return "NoOverridePolicy"s; });
+}
+
} // namespace
struct RefreshRateConfigs::RefreshRateScoreComparator {
@@ -874,35 +889,60 @@
policy.appRequestRange.max >= policy.primaryRange.max;
}
-status_t RefreshRateConfigs::setDisplayManagerPolicy(const Policy& policy) {
- std::lock_guard lock(mLock);
- if (!isPolicyValidLocked(policy)) {
- ALOGE("Invalid refresh rate policy: %s", policy.toString().c_str());
- return BAD_VALUE;
- }
- mGetRankedRefreshRatesCache.reset();
- Policy previousPolicy = *getCurrentPolicyLocked();
- mDisplayManagerPolicy = policy;
- if (*getCurrentPolicyLocked() == previousPolicy) {
- return CURRENT_POLICY_UNCHANGED;
- }
- constructAvailableRefreshRates();
- return NO_ERROR;
-}
+auto RefreshRateConfigs::setPolicy(const PolicyVariant& policy) -> SetPolicyResult {
+ Policy oldPolicy;
+ {
+ std::lock_guard lock(mLock);
+ oldPolicy = *getCurrentPolicyLocked();
-status_t RefreshRateConfigs::setOverridePolicy(const std::optional<Policy>& policy) {
- std::lock_guard lock(mLock);
- if (policy && !isPolicyValidLocked(*policy)) {
- return BAD_VALUE;
+ const bool valid = ftl::match(
+ policy,
+ [this](const auto& policy) {
+ ftl::FakeGuard guard(mLock);
+ if (!isPolicyValidLocked(policy)) {
+ ALOGE("Invalid policy: %s", policy.toString().c_str());
+ return false;
+ }
+
+ using T = std::decay_t<decltype(policy)>;
+
+ if constexpr (std::is_same_v<T, DisplayManagerPolicy>) {
+ mDisplayManagerPolicy = policy;
+ } else {
+ static_assert(std::is_same_v<T, OverridePolicy>);
+ mOverridePolicy = policy;
+ }
+ return true;
+ },
+ [this](NoOverridePolicy) {
+ ftl::FakeGuard guard(mLock);
+ mOverridePolicy.reset();
+ return true;
+ });
+
+ if (!valid) {
+ return SetPolicyResult::Invalid;
+ }
+
+ mGetRankedRefreshRatesCache.reset();
+
+ if (*getCurrentPolicyLocked() == oldPolicy) {
+ return SetPolicyResult::Unchanged;
+ }
+ constructAvailableRefreshRates();
}
- mGetRankedRefreshRatesCache.reset();
- Policy previousPolicy = *getCurrentPolicyLocked();
- mOverridePolicy = policy;
- if (*getCurrentPolicyLocked() == previousPolicy) {
- return CURRENT_POLICY_UNCHANGED;
- }
- constructAvailableRefreshRates();
- return NO_ERROR;
+
+ const auto displayId = getActiveMode().getPhysicalDisplayId();
+ const unsigned numModeChanges = std::exchange(mNumModeSwitchesInPolicy, 0u);
+
+ ALOGI("Display %s policy changed\n"
+ "Previous: %s\n"
+ "Current: %s\n"
+ "%u mode changes were performed under the previous policy",
+ to_string(displayId).c_str(), oldPolicy.toString().c_str(), toString(policy).c_str(),
+ numModeChanges);
+
+ return SetPolicyResult::Changed;
}
const RefreshRateConfigs::Policy* RefreshRateConfigs::getCurrentPolicyLocked() const {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 8b89104..2c2e34a 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -21,6 +21,7 @@
#include <optional>
#include <type_traits>
#include <utility>
+#include <variant>
#include <gui/DisplayEventReceiver.h>
@@ -67,8 +68,7 @@
static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
std::chrono::nanoseconds(800us).count();
- struct Policy {
- private:
+ class Policy {
static constexpr int kAllowGroupSwitchingDefault = false;
public:
@@ -118,23 +118,28 @@
std::string toString() const;
};
- // Return code set*Policy() to indicate the current policy is unchanged.
- static constexpr int CURRENT_POLICY_UNCHANGED = 1;
+ enum class SetPolicyResult { Invalid, Unchanged, Changed };
// We maintain the display manager policy and the override policy separately. The override
// policy is used by CTS tests to get a consistent device state for testing. While the override
// policy is set, it takes precedence over the display manager policy. Once the override policy
// is cleared, we revert to using the display manager policy.
+ struct DisplayManagerPolicy : Policy {
+ using Policy::Policy;
+ };
- // Sets the display manager policy to choose refresh rates. The return value will be:
- // - A negative value if the policy is invalid or another error occurred.
- // - NO_ERROR if the policy was successfully updated, and the current policy is different from
- // what it was before the call.
- // - CURRENT_POLICY_UNCHANGED if the policy was successfully updated, but the current policy
- // is the same as it was before the call.
- status_t setDisplayManagerPolicy(const Policy& policy) EXCLUDES(mLock);
- // Sets the override policy. See setDisplayManagerPolicy() for the meaning of the return value.
- status_t setOverridePolicy(const std::optional<Policy>& policy) EXCLUDES(mLock);
+ struct OverridePolicy : Policy {
+ using Policy::Policy;
+ };
+
+ struct NoOverridePolicy {};
+
+ using PolicyVariant = std::variant<DisplayManagerPolicy, OverridePolicy, NoOverridePolicy>;
+
+ SetPolicyResult setPolicy(const PolicyVariant&) EXCLUDES(mLock) REQUIRES(kMainThreadContext);
+
+ void onModeChangeInitiated() REQUIRES(kMainThreadContext) { mNumModeSwitchesInPolicy++; }
+
// Gets the current policy, which will be the override policy if active, and the display manager
// policy otherwise.
Policy getCurrentPolicy() const EXCLUDES(mLock);
@@ -418,6 +423,8 @@
Policy mDisplayManagerPolicy GUARDED_BY(mLock);
std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
+ unsigned mNumModeSwitchesInPolicy GUARDED_BY(kMainThreadContext) = 0;
+
mutable std::mutex mLock;
// A sorted list of known frame rates that a Heuristic layer will choose
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4055769..fac0792 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1105,7 +1105,7 @@
}
const char* const whence = __func__;
- auto future = mScheduler->schedule([=]() -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
const auto displayOpt =
FTL_FAKE_GUARD(mStateLock,
ftl::find_if(mPhysicalDisplays,
@@ -1130,13 +1130,16 @@
}
const Fps fps = *fpsOpt;
+
// Keep the old switching type.
const bool allowGroupSwitching =
display->refreshRateConfigs().getCurrentPolicy().allowGroupSwitching;
- const scheduler::RefreshRateConfigs::Policy policy{modeId, allowGroupSwitching, {fps, fps}};
- constexpr bool kOverridePolicy = false;
- return setDesiredDisplayModeSpecsInternal(display, policy, kOverridePolicy);
+ const scheduler::RefreshRateConfigs::DisplayManagerPolicy policy{modeId,
+ allowGroupSwitching,
+ {fps, fps}};
+
+ return setDesiredDisplayModeSpecsInternal(display, policy);
});
return future.get();
@@ -1187,7 +1190,7 @@
void SurfaceFlinger::clearDesiredActiveModeState(const sp<DisplayDevice>& display) {
display->clearDesiredActiveModeState();
- if (isDisplayActiveLocked(display)) {
+ if (display->getPhysicalId() == mActiveDisplayId) {
mScheduler->setModeChangePending(false);
}
}
@@ -1217,12 +1220,12 @@
// Store the local variable to release the lock.
const auto desiredActiveMode = display->getDesiredActiveMode();
if (!desiredActiveMode) {
- // No desired active mode pending to be applied
+ // No desired active mode pending to be applied.
continue;
}
- if (!isDisplayActiveLocked(display)) {
- // display is no longer the active display, so abort the mode change
+ if (id != mActiveDisplayId) {
+ // Display is no longer the active display, so abort the mode change.
clearDesiredActiveModeState(display);
continue;
}
@@ -1273,6 +1276,8 @@
ALOGW("initiateModeChange failed: %d", status);
continue;
}
+
+ display->refreshRateConfigs().onModeChangeInitiated();
mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
if (outTimeline.refreshRequired) {
@@ -1853,10 +1858,8 @@
return;
}
- const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
- const bool isActiveDisplay =
- displayId && getPhysicalDisplayTokenLocked(*displayId) == mActiveDisplayToken;
- if (!isActiveDisplay) {
+ if (const auto displayId = getHwComposer().toPhysicalDisplayId(hwcDisplayId);
+ displayId != mActiveDisplayId) {
// For now, we don't do anything with non active display vsyncs.
return;
}
@@ -2052,8 +2055,7 @@
// Save this once per commit + composite to ensure consistency
// TODO (b/240619471): consider removing active display check once AOD is fixed
- const auto activeDisplay =
- FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayToken));
+ const auto activeDisplay = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(mActiveDisplayId));
mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession() && activeDisplay &&
activeDisplay->getPowerMode() == hal::PowerMode::ON;
if (mPowerHintSessionEnabled) {
@@ -3026,7 +3028,7 @@
(currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
display->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
currentState.orientedDisplaySpaceRect);
- if (isDisplayActiveLocked(display)) {
+ if (display->getId() == mActiveDisplayId) {
mActiveDisplayTransformHint = display->getTransformHint();
}
}
@@ -3034,7 +3036,7 @@
currentState.height != drawingState.height) {
display->setDisplaySize(currentState.width, currentState.height);
- if (isDisplayActiveLocked(display)) {
+ if (display->getId() == mActiveDisplayId) {
onActiveDisplaySizeChanged(display);
}
}
@@ -4721,11 +4723,12 @@
return;
}
+ const bool isActiveDisplay = displayId == mActiveDisplayId;
const bool isInternalDisplay = mPhysicalDisplays.get(displayId)
.transform(&PhysicalDisplay::isInternal)
.value_or(false);
- const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayToken);
+ const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayId);
if (isInternalDisplay && activeDisplay != display && activeDisplay &&
activeDisplay->isPoweredOn()) {
ALOGW("Trying to change power mode on non active display while the active display is ON");
@@ -4751,7 +4754,7 @@
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
getHwComposer().setPowerMode(displayId, mode);
- if (isDisplayActiveLocked(display) && mode != hal::PowerMode::DOZE_SUSPEND) {
+ if (isActiveDisplay && mode != hal::PowerMode::DOZE_SUSPEND) {
setHWCVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, refreshRate);
@@ -4767,7 +4770,7 @@
if (SurfaceFlinger::setSchedAttr(false) != NO_ERROR) {
ALOGW("Couldn't set uclamp.min on display off: %s\n", strerror(errno));
}
- if (isDisplayActiveLocked(display) && *currentMode != hal::PowerMode::DOZE_SUSPEND) {
+ if (isActiveDisplay && *currentMode != hal::PowerMode::DOZE_SUSPEND) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4781,7 +4784,7 @@
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
- if (isDisplayActiveLocked(display) && *currentMode == hal::PowerMode::DOZE_SUSPEND) {
+ if (isActiveDisplay && *currentMode == hal::PowerMode::DOZE_SUSPEND) {
ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
mVisibleRegionsDirty = true;
scheduleRepaint();
@@ -4790,7 +4793,7 @@
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
- if (isDisplayActiveLocked(display)) {
+ if (isActiveDisplay) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
@@ -4800,7 +4803,7 @@
getHwComposer().setPowerMode(displayId, mode);
}
- if (isDisplayActiveLocked(display)) {
+ if (isActiveDisplay) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
mScheduler->setDisplayPowerMode(mode);
@@ -5186,7 +5189,7 @@
}
StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),
- (isDisplayActiveLocked(display) ? "active" : "inactive"));
+ displayId == mActiveDisplayId ? "active" : "inactive");
Layer::miniDumpHeader(result);
const DisplayDevice& ref = *display;
@@ -5827,7 +5830,7 @@
case 1036: {
if (data.readInt32() > 0) { // turn on
return mScheduler
- ->schedule([this] {
+ ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
const auto display =
FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
@@ -5837,24 +5840,21 @@
// defaultMode. The defaultMode doesn't matter for the override
// policy though, since we set allowGroupSwitching to true, so it's
// not a problem.
- scheduler::RefreshRateConfigs::Policy overridePolicy;
+ scheduler::RefreshRateConfigs::OverridePolicy overridePolicy;
overridePolicy.defaultMode = display->refreshRateConfigs()
.getDisplayManagerPolicy()
.defaultMode;
overridePolicy.allowGroupSwitching = true;
- constexpr bool kOverridePolicy = true;
- return setDesiredDisplayModeSpecsInternal(display, overridePolicy,
- kOverridePolicy);
+ return setDesiredDisplayModeSpecsInternal(display, overridePolicy);
})
.get();
} else { // turn off
return mScheduler
- ->schedule([this] {
+ ->schedule([this]() FTL_FAKE_GUARD(kMainThreadContext) {
const auto display =
FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
- constexpr bool kOverridePolicy = true;
- return setDesiredDisplayModeSpecsInternal(display, {},
- kOverridePolicy);
+ return setDesiredDisplayModeSpecsInternal(
+ display, scheduler::RefreshRateConfigs::NoOverridePolicy{});
})
.get();
}
@@ -6693,7 +6693,9 @@
status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
const sp<DisplayDevice>& display,
- const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
+ const scheduler::RefreshRateConfigs::PolicyVariant& policy) {
+ const auto displayId = display->getPhysicalId();
+
Mutex::Autolock lock(mStateLock);
if (mDebugDisplayModeSetByBackdoor) {
@@ -6701,31 +6703,31 @@
return NO_ERROR;
}
- const status_t setPolicyResult = display->setRefreshRatePolicy(policy, overridePolicy);
- if (setPolicyResult < 0) {
- return BAD_VALUE;
- }
- if (setPolicyResult == scheduler::RefreshRateConfigs::CURRENT_POLICY_UNCHANGED) {
- return NO_ERROR;
+ auto& configs = display->refreshRateConfigs();
+ using SetPolicyResult = scheduler::RefreshRateConfigs::SetPolicyResult;
+
+ switch (configs.setPolicy(policy)) {
+ case SetPolicyResult::Invalid:
+ return BAD_VALUE;
+ case SetPolicyResult::Unchanged:
+ return NO_ERROR;
+ case SetPolicyResult::Changed:
+ break;
}
- const scheduler::RefreshRateConfigs::Policy currentPolicy =
- display->refreshRateConfigs().getCurrentPolicy();
-
+ const scheduler::RefreshRateConfigs::Policy currentPolicy = configs.getCurrentPolicy();
ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
// be depending in this callback.
- const auto activeModePtr = display->refreshRateConfigs().getActiveModePtr();
- if (isDisplayActiveLocked(display)) {
+ if (const auto activeModePtr = configs.getActiveModePtr(); displayId == mActiveDisplayId) {
mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeModePtr);
toggleKernelIdleTimer();
} else {
mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, activeModePtr);
}
- auto preferredModeOpt =
- getPreferredDisplayMode(display->getPhysicalId(), currentPolicy.defaultMode);
+ auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode);
if (!preferredModeOpt) {
ALOGE("%s: Preferred mode is unknown", __func__);
return NAME_NOT_FOUND;
@@ -6737,7 +6739,7 @@
ALOGV("Switching to Scheduler preferred mode %d (%s)", preferredModeId.value(),
to_string(preferredMode->getFps()).c_str());
- if (!display->refreshRateConfigs().isModeAllowed(preferredModeId)) {
+ if (!configs.isModeAllowed(preferredModeId)) {
ALOGE("%s: Preferred mode %d is disallowed", __func__, preferredModeId.value());
return INVALID_OPERATION;
}
@@ -6756,7 +6758,7 @@
return BAD_VALUE;
}
- auto future = mScheduler->schedule([=]() -> status_t {
+ auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(kMainThreadContext) -> status_t {
const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
if (!display) {
ALOGE("Attempt to set desired display modes for invalid display token %p",
@@ -6766,16 +6768,15 @@
ALOGW("Attempt to set desired display modes for virtual display");
return INVALID_OPERATION;
} else {
- using Policy = scheduler::RefreshRateConfigs::Policy;
+ using Policy = scheduler::RefreshRateConfigs::DisplayManagerPolicy;
const Policy policy{DisplayModeId(defaultMode),
allowGroupSwitching,
{Fps::fromValue(primaryRefreshRateMin),
Fps::fromValue(primaryRefreshRateMax)},
{Fps::fromValue(appRequestRefreshRateMin),
Fps::fromValue(appRequestRefreshRateMax)}};
- constexpr bool kOverridePolicy = false;
- return setDesiredDisplayModeSpecsInternal(display, policy, kOverridePolicy);
+ return setDesiredDisplayModeSpecsInternal(display, policy);
}
});
@@ -7019,7 +7020,7 @@
void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
ATRACE_CALL();
- if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
+ if (const auto display = getDisplayDeviceLocked(mActiveDisplayId)) {
display->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
}
@@ -7027,7 +7028,7 @@
ALOGE("%s: activeDisplay is null", __func__);
return;
}
- mActiveDisplayToken = activeDisplay->getDisplayToken();
+ mActiveDisplayId = activeDisplay->getPhysicalId();
activeDisplay->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);
updateInternalDisplayVsyncLocked(activeDisplay);
mScheduler->setModeChangePending(false);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5f4ab14..cf226a5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -680,11 +680,9 @@
DisplayModeId defaultModeId) const
REQUIRES(mStateLock);
- // Sets the desired display mode specs.
- status_t setDesiredDisplayModeSpecsInternal(
- const sp<DisplayDevice>& display,
- const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
- EXCLUDES(mStateLock);
+ status_t setDesiredDisplayModeSpecsInternal(const sp<DisplayDevice>&,
+ const scheduler::RefreshRateConfigs::PolicyVariant&)
+ EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
void commitTransactions() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
void commitTransactionsLocked(uint32_t transactionFlags)
@@ -837,10 +835,6 @@
void initializeDisplays();
void onInitializeDisplays() REQUIRES(mStateLock, kMainThreadContext);
- bool isDisplayActiveLocked(const sp<const DisplayDevice>& display) const REQUIRES(mStateLock) {
- return display->getDisplayToken() == mActiveDisplayToken;
- }
-
sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const
REQUIRES(mStateLock) {
return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
@@ -875,12 +869,12 @@
}
sp<DisplayDevice> getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) {
- if (const auto display = getDisplayDeviceLocked(mActiveDisplayToken)) {
+ if (const auto display = getDisplayDeviceLocked(mActiveDisplayId)) {
return display;
}
// The active display is outdated, so fall back to the primary display.
- mActiveDisplayToken.clear();
- return getDisplayDeviceLocked(getPrimaryDisplayTokenLocked());
+ mActiveDisplayId = getPrimaryDisplayIdLocked();
+ return getDisplayDeviceLocked(mActiveDisplayId);
}
sp<const DisplayDevice> getDefaultDisplayDevice() const EXCLUDES(mStateLock) {
@@ -1203,6 +1197,9 @@
display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock);
+ // The inner or outer display for foldables, assuming they have mutually exclusive power states.
+ PhysicalDisplayId mActiveDisplayId GUARDED_BY(mStateLock);
+
struct {
DisplayIdGenerator<GpuVirtualDisplayId> gpu;
std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal;
@@ -1392,8 +1389,6 @@
[](const auto& display) { return display.isRefreshRateOverlayEnabled(); });
}
- wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock);
-
const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
FlagManager mFlagManager;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index 66bac44..a949440 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -362,11 +362,24 @@
mFdp.ConsumeFloatingPoint<float>()),
globalSignals);
- refreshRateConfigs.setDisplayManagerPolicy(
- {modeId,
- {Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()),
- Fps::fromValue(mFdp.ConsumeFloatingPoint<float>())}});
- FTL_FAKE_GUARD(kMainThreadContext, refreshRateConfigs.setActiveModeId(modeId));
+ {
+ ftl::FakeGuard guard(kMainThreadContext);
+
+ refreshRateConfigs.setPolicy(
+ RefreshRateConfigs::
+ DisplayManagerPolicy{modeId,
+ {Fps::fromValue(mFdp.ConsumeFloatingPoint<float>()),
+ Fps::fromValue(mFdp.ConsumeFloatingPoint<float>())}});
+ refreshRateConfigs.setPolicy(
+ RefreshRateConfigs::OverridePolicy{modeId,
+ {Fps::fromValue(
+ mFdp.ConsumeFloatingPoint<float>()),
+ Fps::fromValue(
+ mFdp.ConsumeFloatingPoint<float>())}});
+ refreshRateConfigs.setPolicy(RefreshRateConfigs::NoOverridePolicy{});
+
+ refreshRateConfigs.setActiveModeId(modeId);
+ }
RefreshRateConfigs::isFractionalPairOrMultiple(Fps::fromValue(
mFdp.ConsumeFloatingPoint<float>()),
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index a706c4b..00f1b08 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -34,6 +34,7 @@
namespace hal = android::hardware::graphics::composer::hal;
+using SetPolicyResult = RefreshRateConfigs::SetPolicyResult;
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
using LayerRequirement = RefreshRateConfigs::LayerRequirement;
@@ -93,6 +94,15 @@
GlobalSignals signals = {}) const {
return getRankedRefreshRatesAndSignals(layers, signals).first.front().displayModePtr;
}
+
+ SetPolicyResult setPolicy(const PolicyVariant& policy) {
+ ftl::FakeGuard guard(kMainThreadContext);
+ return RefreshRateConfigs::setPolicy(policy);
+ }
+
+ SetPolicyResult setDisplayManagerPolicy(const DisplayManagerPolicy& policy) {
+ return setPolicy(policy);
+ }
};
class RefreshRateConfigsTest : public testing::Test {
@@ -178,9 +188,33 @@
}
TEST_F(RefreshRateConfigsTest, invalidPolicy) {
- RefreshRateConfigs configs(kModes_60, kModeId60);
- EXPECT_LT(configs.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}}), 0);
- EXPECT_LT(configs.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}}), 0);
+ TestableRefreshRateConfigs configs(kModes_60, kModeId60);
+
+ EXPECT_EQ(SetPolicyResult::Invalid,
+ configs.setDisplayManagerPolicy({DisplayModeId(10), {60_Hz, 60_Hz}}));
+ EXPECT_EQ(SetPolicyResult::Invalid,
+ configs.setDisplayManagerPolicy({kModeId60, {20_Hz, 40_Hz}}));
+}
+
+TEST_F(RefreshRateConfigsTest, unchangedPolicy) {
+ TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
+
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
+
+ EXPECT_EQ(SetPolicyResult::Unchanged,
+ configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
+
+ // Override to the same policy.
+ EXPECT_EQ(SetPolicyResult::Unchanged,
+ configs.setPolicy(RefreshRateConfigs::OverridePolicy{kModeId90, {60_Hz, 90_Hz}}));
+
+ // Clear override to restore DisplayManagerPolicy.
+ EXPECT_EQ(SetPolicyResult::Unchanged,
+ configs.setPolicy(RefreshRateConfigs::NoOverridePolicy{}));
+
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {30_Hz, 90_Hz}}));
}
TEST_F(RefreshRateConfigsTest, twoModes_storesFullRefreshRateMap) {
@@ -211,7 +245,8 @@
EXPECT_EQ(kMode60, minRate60);
EXPECT_EQ(kMode60, performanceRate60);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
configs.setActiveModeId(kModeId90);
const auto minRate90 = configs.getMinRefreshRateByPolicy();
@@ -234,7 +269,8 @@
EXPECT_EQ(kMode60, minRate60);
EXPECT_EQ(kMode60, performanceRate60);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
configs.setActiveModeId(kModeId90);
const auto minRate90 = configs.getMinRefreshRateByPolicy();
@@ -254,7 +290,8 @@
EXPECT_EQ(kMode60, minRate);
EXPECT_EQ(kMode90, performanceRate);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
const auto minRate60 = configs.getMinRefreshRateByPolicy();
const auto performanceRate60 = configs.getMaxRefreshRateByPolicy();
@@ -276,7 +313,8 @@
EXPECT_EQ(mode.getId(), kModeId90);
}
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
{
const auto& mode = configs.getActiveMode();
EXPECT_EQ(mode.getId(), kModeId90);
@@ -291,15 +329,17 @@
// range.
EXPECT_EQ(kMode90, configs.getBestRefreshRate());
- EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), NO_ERROR);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(kMode60, configs.getBestRefreshRate());
}
{
// We select max even when this will cause a non-seamless switch.
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
constexpr bool kAllowGroupSwitching = true;
- EXPECT_EQ(configs.setDisplayManagerPolicy({kModeId90, kAllowGroupSwitching, {0_Hz, 90_Hz}}),
- NO_ERROR);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy(
+ {kModeId90, kAllowGroupSwitching, {0_Hz, 90_Hz}}));
EXPECT_EQ(kMode90_G1, configs.getBestRefreshRate());
}
}
@@ -340,7 +380,8 @@
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
lr.name = "";
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
@@ -364,7 +405,8 @@
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
@@ -388,7 +430,8 @@
lr.desiredRefreshRate = 24_Hz;
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 120_Hz}}));
lr.vote = LayerVoteType::Min;
EXPECT_EQ(kMode60, configs.getBestRefreshRate(layers));
@@ -1039,7 +1082,8 @@
RefreshRateRanking{kMode60},
RefreshRateRanking{kMode90}};
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}));
const std::vector<RefreshRateRanking>& refreshRates =
configs.getRefreshRatesByPolicy(/*anchorGroupOpt*/ std::nullopt,
@@ -1062,7 +1106,8 @@
RefreshRateRanking{kMode60},
RefreshRateRanking{kMode30}};
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}));
const std::vector<RefreshRateRanking>& refreshRates =
configs.getRefreshRatesByPolicy(/*anchorGroupOpt*/ std::nullopt,
@@ -1300,9 +1345,10 @@
TEST_F(RefreshRateConfigsTest,
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresTouchFlag) {
- RefreshRateConfigs configs(kModes_60_90, kModeId90);
+ TestableRefreshRateConfigs configs(kModes_60_90, kModeId90);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
@@ -1323,7 +1369,8 @@
getBestRefreshRate_withDisplayManagerRequestingSingleRate_ignoresIdleFlag) {
TestableRefreshRateConfigs configs(kModes_60_90, kModeId60);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 90_Hz}}));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr = layers[0];
@@ -1472,7 +1519,8 @@
getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) {
TestableRefreshRateConfigs configs(kModes_60_90, kModeId90);
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}));
const auto [mode, signals] = configs.getRankedRefreshRatesAndSignals({}, {});
EXPECT_EQ(mode.front().displayModePtr, kMode90);
@@ -1546,10 +1594,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayer) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
@@ -1564,10 +1612,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamless) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
// Verify that we won't change the group if seamless switch is required.
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
@@ -1583,10 +1631,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerOnlySeamlessDefaultFps) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
configs.setActiveModeId(kModeId90);
@@ -1604,10 +1652,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithOneLayerDefaultSeamlessness) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
configs.setActiveModeId(kModeId90);
@@ -1628,10 +1676,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersOnlySeamlessAndSeamed) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
configs.setActiveModeId(kModeId90);
@@ -1657,10 +1705,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultFocusedAndSeamed) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
configs.setActiveModeId(kModeId90);
@@ -1690,10 +1738,10 @@
TEST_F(RefreshRateConfigsTest, groupSwitchingWithTwoLayersDefaultNotFocusedAndSeamed) {
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId60);
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
configs.setActiveModeId(kModeId90);
@@ -1721,10 +1769,10 @@
TestableRefreshRateConfigs configs(kModes_30_60, kModeId60);
// Allow group switching.
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& layer = layers[0];
@@ -1744,10 +1792,10 @@
TestableRefreshRateConfigs configs(kModes_25_30_50_60, kModeId60);
// Allow group switching.
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
std::vector<LayerRequirement> layers = {{.name = "60Hz ExplicitDefault",
.vote = LayerVoteType::ExplicitDefault,
@@ -1776,10 +1824,10 @@
TestableRefreshRateConfigs configs(kModes_60_90_G1, kModeId90);
// Allow group switching.
- RefreshRateConfigs::Policy policy;
+ RefreshRateConfigs::DisplayManagerPolicy policy;
policy.defaultMode = configs.getCurrentPolicy().defaultMode;
policy.allowGroupSwitching = true;
- EXPECT_GE(configs.setDisplayManagerPolicy(policy), 0);
+ EXPECT_EQ(SetPolicyResult::Changed, configs.setPolicy(policy));
std::vector<LayerRequirement> layers = {
{.name = "Min", .vote = LayerVoteType::Min, .weight = 1.f, .focused = true}};
@@ -1807,7 +1855,8 @@
return configs.getBestRefreshRate(layers, {.touch = args.touch})->getId();
};
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 60_Hz}, {30_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 60_Hz}, {30_Hz, 90_Hz}}));
EXPECT_EQ(kModeId60, configs.getBestRefreshRate()->getId());
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz));
@@ -1831,7 +1880,8 @@
EXPECT_EQ(kModeId60,
getFrameRate(LayerVoteType::ExplicitExactOrMultiple, 90_Hz, {.touch = true}));
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 60_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}, {60_Hz, 60_Hz}}));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::NoVote, 90_Hz));
EXPECT_EQ(kModeId60, getFrameRate(LayerVoteType::Min, 90_Hz));
@@ -1860,7 +1910,8 @@
return refreshRate.front().displayModePtr->getId();
};
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}, {60_Hz, 90_Hz}}));
// Idle should be lower priority than touch boost.
{
@@ -2156,43 +2207,50 @@
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) {
using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction;
- RefreshRateConfigs configs(kModes_60_90, kModeId90);
+ TestableRefreshRateConfigs configs(kModes_60_90, kModeId90);
- // SetPolicy(60, 90), current 90Hz => TurnOn.
+ // setPolicy(60, 90), current 90Hz => TurnOn.
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
- // SetPolicy(60, 90), current 60Hz => TurnOn.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}), 0);
+ // setPolicy(60, 90), current 60Hz => TurnOn.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
- // SetPolicy(60, 60), current 60Hz => TurnOff
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
+ // setPolicy(60, 60), current 60Hz => TurnOff
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
- // SetPolicy(90, 90), current 90Hz => TurnOff.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}), 0);
+ // setPolicy(90, 90), current 90Hz => TurnOff.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
}
TEST_F(RefreshRateConfigsTest, testKernelIdleTimerActionFor120Hz) {
using KernelIdleTimerAction = RefreshRateConfigs::KernelIdleTimerAction;
- RefreshRateConfigs configs(kModes_60_120, kModeId120);
+ TestableRefreshRateConfigs configs(kModes_60_120, kModeId120);
- // SetPolicy(0, 60), current 60Hz => TurnOn.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}}), 0);
+ // setPolicy(0, 60), current 60Hz => TurnOn.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {0_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
- // SetPolicy(60, 60), current 60Hz => TurnOff.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}), 0);
+ // setPolicy(60, 60), current 60Hz => TurnOff.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 60_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
- // SetPolicy(60, 120), current 60Hz => TurnOn.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}}), 0);
+ // setPolicy(60, 120), current 60Hz => TurnOn.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 120_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOn, configs.getIdleTimerAction());
- // SetPolicy(120, 120), current 120Hz => TurnOff.
- EXPECT_GE(configs.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}}), 0);
+ // setPolicy(120, 120), current 120Hz => TurnOff.
+ EXPECT_EQ(SetPolicyResult::Changed,
+ configs.setDisplayManagerPolicy({kModeId120, {120_Hz, 120_Hz}}));
EXPECT_EQ(KernelIdleTimerAction::TurnOff, configs.getIdleTimerAction());
}
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
index e256d2c..bc66961 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
@@ -97,7 +97,7 @@
.setNativeWindow(mNativeWindow)
.setPowerMode(hal::PowerMode::ON)
.inject();
- mFlinger.mutableActiveDisplayToken() = mDisplay->getDisplayToken();
+ mFlinger.mutableActiveDisplayId() = mDisplay->getPhysicalId();
}
void SurfaceFlingerPowerHintTest::setupScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index 9e54083..6f84437 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -262,7 +262,7 @@
if (injector.physicalDisplay()
.transform(&display::PhysicalDisplay::isInternal)
.value_or(false)) {
- test->mFlinger.mutableActiveDisplayToken() = display->getDisplayToken();
+ test->mFlinger.mutableActiveDisplayId() = display->getPhysicalId();
}
return display;
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index cff529c..eedd9cf 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -524,7 +524,7 @@
auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; }
auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
auto& mutablePrimaryHwcDisplayId() { return getHwComposer().mPrimaryHwcDisplayId; }
- auto& mutableActiveDisplayToken() { return mFlinger->mActiveDisplayToken; }
+ auto& mutableActiveDisplayId() { return mFlinger->mActiveDisplayId; }
auto fromHandle(const sp<IBinder>& handle) {
return mFlinger->fromHandle(handle);