summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jian-Syuan (Shane) Wong <shanewong@google.com> 2024-11-01 21:36:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-11-01 21:36:52 +0000
commit4926db9d5da96c1627fe7448f96dec26acfcd8f9 (patch)
tree1ca0b202bceb48a1a84681a58d6402ad17643f9d
parent2901d635842fd0317bd696cf9dbf1868222704c5 (diff)
parent0796d527866da21f0f0deb2869b59ba2dc50ce33 (diff)
Merge "[VRR] Add new frame rate settings APIs to ViewGruop" into main
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/view/View.java58
-rw-r--r--core/java/android/view/ViewGroup.java88
-rw-r--r--core/java/android/view/flags/refresh_rate_flags.aconfig8
4 files changed, 155 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 675adcf91d89..0568e7666c5d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -54180,6 +54180,7 @@ package android.view {
method public void onStopNestedScroll(android.view.View);
method public void onViewAdded(android.view.View);
method public void onViewRemoved(android.view.View);
+ method @FlaggedApi("android.view.flags.toolkit_viewgroup_set_requested_frame_rate_api") public void propagateRequestedFrameRate(float, boolean);
method public void recomputeViewAttributes(android.view.View);
method public void removeAllViews();
method public void removeAllViewsInLayout();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6090b5ec1622..e49eec69fff5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -52,6 +52,7 @@ import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
+import static android.view.flags.Flags.toolkitViewgroupSetRequestedFrameRateApi;
import static android.view.flags.Flags.viewVelocityApi;
import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
import static android.view.inputmethod.Flags.initiationWithoutInputConnection;
@@ -2469,6 +2470,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
toolkitFrameRateVelocityMappingReadOnly();
private static boolean sToolkitFrameRateAnimationBugfix25q1FlagValue =
toolkitFrameRateAnimationBugfix25q1();
+ private static boolean sToolkitViewGroupFrameRateApiFlagValue =
+ toolkitViewgroupSetRequestedFrameRateApi();
// Used to set frame rate compatibility.
@Surface.FrameRateCompatibility int mFrameRateCompatibility =
@@ -3807,6 +3810,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* 1 PFLAG4_HAS_DRAWN
* 1 PFLAG4_HAS_MOVED
* 1 PFLAG4_HAS_VIEW_PROPERTY_INVALIDATION
+ * 1 PFLAG4_FORCED_OVERRIDE_FRAME_RATE
+ * 1 PFLAG4_SELF_REQUESTED_FRAME_RATE
* |-------|-------|-------|-------|
*/
@@ -3957,6 +3962,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private static final int PFLAG4_HAS_VIEW_PROPERTY_INVALIDATION = 0x20000000;
+ /**
+ * When set, this indicates whether the frame rate of the children should be
+ * forcibly overridden, even if it has been explicitly configured by a user request.
+ */
+ private static final int PFLAG4_FORCED_OVERRIDE_FRAME_RATE = 0x40000000;
+
+ /**
+ * When set, this indicates that the frame rate is configured based on a user request.
+ */
+ private static final int PFLAG4_SELF_REQUESTED_FRAME_RATE = 0x80000000;
+
/* End of masks for mPrivateFlags4 */
/** @hide */
@@ -34292,9 +34308,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
public void setRequestedFrameRate(float frameRate) {
+ // Skip setting the frame rate if it's currently in forced override mode.
+ if (sToolkitViewGroupFrameRateApiFlagValue && getForcedOverrideFrameRateFlag()) {
+ return;
+ }
+
if (sToolkitSetFrameRateReadOnlyFlagValue) {
mPreferredFrameRate = frameRate;
}
+
+ if (sToolkitViewGroupFrameRateApiFlagValue) {
+ // If frameRate is Float.NaN, it means it's set to the default value.
+ // We only want to make the flag true, when the value is not Float.nan
+ setSelfRequestedFrameRateFlag(!Float.isNaN(mPreferredFrameRate));
+ }
}
/**
@@ -34318,4 +34345,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
return 0;
}
+
+ void overrideFrameRate(float frameRate, boolean forceOverride) {
+ setForcedOverrideFrameRateFlag(forceOverride);
+ if (forceOverride || !getSelfRequestedFrameRateFlag()) {
+ mPreferredFrameRate = frameRate;
+ }
+ }
+
+ void setForcedOverrideFrameRateFlag(boolean forcedOverride) {
+ if (forcedOverride) {
+ mPrivateFlags4 |= PFLAG4_FORCED_OVERRIDE_FRAME_RATE;
+ } else {
+ mPrivateFlags4 &= ~PFLAG4_FORCED_OVERRIDE_FRAME_RATE;
+ }
+ }
+
+ boolean getForcedOverrideFrameRateFlag() {
+ return (mPrivateFlags4 & PFLAG4_FORCED_OVERRIDE_FRAME_RATE) != 0;
+ }
+
+ void setSelfRequestedFrameRateFlag(boolean forcedOverride) {
+ if (forcedOverride) {
+ mPrivateFlags4 |= PFLAG4_SELF_REQUESTED_FRAME_RATE;
+ } else {
+ mPrivateFlags4 &= ~PFLAG4_SELF_REQUESTED_FRAME_RATE;
+ }
+ }
+
+ boolean getSelfRequestedFrameRateFlag() {
+ return (mPrivateFlags4 & PFLAG4_SELF_REQUESTED_FRAME_RATE) != 0;
+ }
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 22374173b988..4a9916c007c4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -18,9 +18,12 @@ package android.view;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
+import static android.view.flags.Flags.FLAG_TOOLKIT_VIEWGROUP_SET_REQUESTED_FRAME_RATE_API;
+import static android.view.flags.Flags.toolkitViewgroupSetRequestedFrameRateApi;
import android.animation.LayoutTransition;
import android.annotation.CallSuper;
+import android.annotation.FlaggedApi;
import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -448,6 +451,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private static final int FLAG_SHOW_CONTEXT_MENU_WITH_COORDS = 0x20000000;
/**
+ * When set, this indicates that the frame rate is passed down from the parent.
+ */
+ private static final int FLAG_PROPAGATED_FRAME_RATE = 0x40000000;
+
+ private static boolean sToolkitViewGroupFrameRateApiFlagValue =
+ toolkitViewgroupSetRequestedFrameRateApi();
+
+ /**
* Indicates which types of drawing caches are to be kept in memory.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
@@ -5361,6 +5372,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
touchAccessibilityNodeProviderIfNeeded(child);
+
+ // If a propagated value exists, pass it to the child.
+ if (sToolkitViewGroupFrameRateApiFlagValue && !Float.isNaN(getRequestedFrameRate())
+ && (mGroupFlags & FLAG_PROPAGATED_FRAME_RATE) != 0) {
+ child.overrideFrameRate(getRequestedFrameRate(), getForcedOverrideFrameRateFlag());
+ }
}
/**
@@ -9465,4 +9482,75 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
return null;
}
+
+ /**
+ * You can set the preferred frame rate for a ViewGroup using a positive number
+ * or by specifying the preferred frame rate category using constants, including
+ * REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE, REQUESTED_FRAME_RATE_CATEGORY_LOW,
+ * REQUESTED_FRAME_RATE_CATEGORY_NORMAL, REQUESTED_FRAME_RATE_CATEGORY_HIGH.
+ * Keep in mind that the preferred frame rate affects the frame rate for the next frame,
+ * so use this method carefully. It's important to note that the preference is valid as
+ * long as the ViewGroup is invalidated. Please also be aware that the requested frame rate
+ * will not propagate to child views.
+ *
+ * @param frameRate the preferred frame rate of the ViewGroup.
+ */
+ @Override
+ @FlaggedApi(FLAG_TOOLKIT_VIEWGROUP_SET_REQUESTED_FRAME_RATE_API)
+ public void setRequestedFrameRate(float frameRate) {
+ if (sToolkitViewGroupFrameRateApiFlagValue) {
+ if (getForcedOverrideFrameRateFlag()) {
+ return;
+ }
+ super.setRequestedFrameRate(frameRate);
+ // If frameRate is Float.NaN, it means it's set to the default value.
+ // We only want to make the flag true, when the value is not Float.nan
+ setSelfRequestedFrameRateFlag(!Float.isNaN(getRequestedFrameRate()));
+ mGroupFlags &= ~FLAG_PROPAGATED_FRAME_RATE;
+ }
+ }
+
+ /**
+ * You can set the preferred frame rate for a ViewGroup and its children using a positive number
+ * or by specifying the preferred frame rate category using constants, including
+ * REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE, REQUESTED_FRAME_RATE_CATEGORY_LOW,
+ * REQUESTED_FRAME_RATE_CATEGORY_NORMAL, REQUESTED_FRAME_RATE_CATEGORY_HIGH.
+ * Keep in mind that the preferred frame rate affects the frame rate for the next frame,
+ * so use this method carefully. It's important to note that the preference is valid as
+ * long as the ViewGroup or any of its children is invalidated.
+ * To undo the frame rate propagation, call the API with REQUESTED_FRAME_RATE_CATEGORY_DEFAULT.
+ *
+ * @param frameRate the preferred frame rate of the ViewGroup.
+ * @param forceOverride indicate whether it should override the frame rate of
+ * all the children with the given frame rate.
+ */
+ @FlaggedApi(FLAG_TOOLKIT_VIEWGROUP_SET_REQUESTED_FRAME_RATE_API)
+ public void propagateRequestedFrameRate(float frameRate, boolean forceOverride) {
+ if (sToolkitViewGroupFrameRateApiFlagValue) {
+ // Skip setting the frame rate if it's currently in forced override mode.
+ if (getForcedOverrideFrameRateFlag()) {
+ return;
+ }
+
+ // frame rate could be set previously with setRequestedFrameRate
+ // or propagateRequestedFrameRate
+ setSelfRequestedFrameRateFlag(false);
+ overrideFrameRate(frameRate, forceOverride);
+ setSelfRequestedFrameRateFlag(true);
+ }
+ }
+
+ @Override
+ void overrideFrameRate(float frameRate, boolean forceOverride) {
+ // if it's in forceOverrid mode or has no self requested frame rate,
+ // it will override the frame rate.
+ if (forceOverride || !getSelfRequestedFrameRateFlag()) {
+ super.overrideFrameRate(frameRate, forceOverride);
+ mGroupFlags |= FLAG_PROPAGATED_FRAME_RATE;
+
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).overrideFrameRate(frameRate, forceOverride);
+ }
+ }
+ }
}
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index c31df73fbeae..1c7570efc26b 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -122,6 +122,14 @@ flag {
}
flag {
+ name: "toolkit_viewgroup_set_requested_frame_rate_api"
+ namespace: "toolkit"
+ description: "Feature flag to introduce new frame rate setting APIs on ViewGroup"
+ bug: "335874198"
+ is_fixed_read_only: true
+}
+
+flag {
name: "toolkit_frame_rate_touch_boost_25q1"
namespace: "toolkit"
description: "Feature flag to not suppress touch boost for specific windowTypes in VRR V QPR2"