SurfaceFlinger: only focused layers can use appRequestRange
When DisplayManager sets the DisplayConfigsSpecs with a policy
that the appRequestRange is broader than the primaryRange,
it means that an app can choose a refresh rate from the
appRequestRange and not from the primaryRange only if that app
explicitly specified a frame rate using setFrameRate API. However,
to avoid cases where we switch the refresh rate back and forth from
the two ranges, we are allowing only applications that their window
is focused from WindowManager's perspective to select refresh rate out
the primaryRange. This matches the behavior of an application that sets
the preferredDisplayModeId.
Bug: 144307188
Bug: 159940172
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Test: YouTube in PIP mode while device is restricted by primaryRange
Change-Id: I26a9690210bb5771bd8aae2bff301031617f7c8f
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 8a51b85..27bf0ec 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -195,15 +195,22 @@
// Captures the layer requirements for a refresh rate. This will be used to determine the
// display refresh rate.
struct LayerRequirement {
- std::string name; // Layer's name. Used for debugging purposes.
- LayerVoteType vote; // Layer vote type.
- float desiredRefreshRate; // Layer's desired refresh rate, if applicable.
- float weight; // Layer's weight in the range of [0, 1]. The higher the weight the more
- // impact this layer would have on choosing the refresh rate.
+ // Layer's name. Used for debugging purposes.
+ std::string name;
+ // Layer vote type.
+ LayerVoteType vote = LayerVoteType::NoVote;
+ // Layer's desired refresh rate, if applicable.
+ float desiredRefreshRate = 0.0f;
+ // Layer's weight in the range of [0, 1]. The higher the weight the more impact this layer
+ // would have on choosing the refresh rate.
+ float weight = 0.0f;
+ // Whether layer is in focus or not based on WindowManager's state
+ bool focused = false;
bool operator==(const LayerRequirement& other) const {
return name == other.name && vote == other.vote &&
- desiredRefreshRate == other.desiredRefreshRate && weight == other.weight;
+ desiredRefreshRate == other.desiredRefreshRate && weight == other.weight &&
+ focused == other.focused;
}
bool operator!=(const LayerRequirement& other) const { return !(*this == other); }