diff options
| author | 2024-11-01 21:36:52 +0000 | |
|---|---|---|
| committer | 2024-11-01 21:36:52 +0000 | |
| commit | 4926db9d5da96c1627fe7448f96dec26acfcd8f9 (patch) | |
| tree | 1ca0b202bceb48a1a84681a58d6402ad17643f9d | |
| parent | 2901d635842fd0317bd696cf9dbf1868222704c5 (diff) | |
| parent | 0796d527866da21f0f0deb2869b59ba2dc50ce33 (diff) | |
Merge "[VRR] Add new frame rate settings APIs to ViewGruop" into main
| -rw-r--r-- | core/api/current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 58 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 88 | ||||
| -rw-r--r-- | core/java/android/view/flags/refresh_rate_flags.aconfig | 8 |
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" |