Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a22e6f4 authored by Jian-Syuan (Shane) Wong's avatar Jian-Syuan (Shane) Wong Committed by Android (Google) Code Review
Browse files

Merge "[VRR] Update touch boost logic to support Chrome scrolling" into main

parents 24b592ab 7fc356c4
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ import static android.view.flags.Flags.toolkitFrameRateTouchBoost25q1;
import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
import static android.view.flags.Flags.toolkitInitialTouchBoost;
import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
@@ -1113,9 +1114,13 @@ public final class ViewRootImpl implements ViewParent,
    private boolean mIsFrameRateConflicted = false;
    // Used to check whether SurfaceControl has been replaced.
    private boolean mSurfaceReplaced = false;
    // Indicates whether a draw operation occurred during this frame while a touch event was active.
    private boolean mTouchAndDrawn = false;
    // Used to set frame rate compatibility.
    @Surface.FrameRateCompatibility int mFrameRateCompatibility =
            FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
    // time for initial touch boost period.
    private static final int FRAME_RATE_INITIAL_TOUCH_BOOST_TIME = 30;
    // time for touch boost period.
    private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
    // Timeout for the other frame rate boosts other than touch boost.
@@ -1213,6 +1218,7 @@ public final class ViewRootImpl implements ViewParent,
    private static boolean sSurfaceFlingerBugfixFlagValue =
            com.android.graphics.surfaceflinger.flags.Flags.vrrBugfix24q4();
    private static final boolean sEnableVrr = ViewProperties.vrr_enabled().orElse(true);
    private static final boolean sToolkitInitialTouchBoostFlagValue = toolkitInitialTouchBoost();
    static {
        sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
@@ -4435,6 +4441,10 @@ public final class ViewRootImpl implements ViewParent,
        // We set the preferred frame rate and frame rate category at the end of performTraversals
        // when the values are applicable.
        if (mDrawnThisFrame) {
            if (sToolkitInitialTouchBoostFlagValue && mIsTouchBoosting) {
                mTouchAndDrawn = true;
            }
            mDrawnThisFrame = false;
            if (!mInvalidationIdleMessagePosted && sSurfaceFlingerBugfixFlagValue) {
                mInvalidationIdleMessagePosted = true;
@@ -6718,6 +6728,7 @@ public final class ViewRootImpl implements ViewParent,
    private static final int MSG_REFRESH_POINTER_ICON = 41;
    private static final int MSG_FRAME_RATE_SETTING = 42;
    private static final int MSG_SURFACE_REPLACED_TIMEOUT = 43;
    private static final int MSG_INITIAL_TOUCH_BOOST_TIMEOUT = 44;
    final class ViewRootHandler extends Handler {
        @Override
@@ -6791,6 +6802,8 @@ public final class ViewRootImpl implements ViewParent,
                    return "MSG_FRAME_RATE_SETTING";
                case MSG_SURFACE_REPLACED_TIMEOUT:
                    return "MSG_SURFACE_REPLACED_TIMEOUT";
                case MSG_INITIAL_TOUCH_BOOST_TIMEOUT:
                    return "MSG_INITIAL_TOUCH_BOOST_TIMEOUT";
            }
            return super.getMessageName(message);
        }
@@ -7066,6 +7079,17 @@ public final class ViewRootImpl implements ViewParent,
                        setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE);
                    }
                    break;
                case MSG_INITIAL_TOUCH_BOOST_TIMEOUT:
                    if (mTouchAndDrawn) {
                        mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
                        mHandler.sendEmptyMessageDelayed(MSG_TOUCH_BOOST_TIMEOUT,
                                FRAME_RATE_TOUCH_BOOST_TIME);
                    } else {
                        mIsTouchBoosting = false;
                        setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE);
                    }
                    mTouchAndDrawn = false;
                    break;
                case MSG_REFRESH_POINTER_ICON:
                    if (mPointerIconEvent == null) {
                        break;
@@ -8130,10 +8154,17 @@ public final class ViewRootImpl implements ViewParent,
             */
            if (mIsTouchBoosting && (action == MotionEvent.ACTION_UP
                    || action == MotionEvent.ACTION_CANCEL)) {
                if (sToolkitInitialTouchBoostFlagValue) {
                    mHandler.removeMessages(MSG_INITIAL_TOUCH_BOOST_TIMEOUT);
                    mHandler.sendEmptyMessageDelayed(MSG_INITIAL_TOUCH_BOOST_TIMEOUT,
                            FRAME_RATE_INITIAL_TOUCH_BOOST_TIME);
                } else {
                    mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
                    mHandler.sendEmptyMessageDelayed(MSG_TOUCH_BOOST_TIMEOUT,
                            FRAME_RATE_TOUCH_BOOST_TIME);
                }
            }
            return handled ? FINISH_HANDLED : FORWARD;
        }
+7 −0
Original line number Diff line number Diff line
@@ -137,3 +137,10 @@ flag {
    bug: "335874198"
    is_exported: true
}

flag {
    name: "toolkit_initial_touch_boost"
    namespace: "toolkit"
    description: "Feature flag to update initial touch boost logic"
    bug: "393004744"
}
 No newline at end of file
+71 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_ANIMATION_BUGFIX_
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1;
import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
import static android.view.flags.Flags.FLAG_TOOLKIT_INITIAL_TOUCH_BOOST;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
@@ -34,6 +35,7 @@ import static android.view.flags.Flags.toolkitFrameRateSmallUsesPercentReadOnly;

import static junit.framework.Assert.assertEquals;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.annotation.NonNull;
@@ -179,6 +181,75 @@ public class ViewFrameRateTest {
        assertTrue(mViewRoot.mWindowAttributes.type == windowType);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_TOOLKIT_INITIAL_TOUCH_BOOST)
    public void initialTouchBoost() throws Throwable {
        if (!ViewProperties.vrr_enabled().orElse(true)) {
            return;
        }

        mActivityRule.runOnUiThread(() -> {
            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
            mMovingView.setLayoutParams(layoutParams);
            mMovingView.setOnClickListener((v) -> {});
        });
        waitForFrameRateCategoryToSettle();

        int[] position = new int[2];
        mActivityRule.runOnUiThread(() -> {
            mMovingView.getLocationOnScreen(position);
            position[0] += mMovingView.getWidth() / 2;
            position[1] += mMovingView.getHeight() / 2;
        });
        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();

        assertFalse(mViewRoot.getIsTouchBoosting());

        long now = SystemClock.uptimeMillis();
        MotionEvent down = MotionEvent.obtain(
                now, // downTime
                now, // eventTime
                MotionEvent.ACTION_DOWN, // action
                position[0], // x
                position[1], // y
                0 // metaState
        );

        mActivityRule.runOnUiThread(() -> {
            mMovingView.getViewRootImpl().dispatchAppVisibility(false);
        });

        down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
        instrumentation.sendPointerSync(down);
        down.recycle();

        Thread.sleep(100);
        // should have touch boost
        assertTrue(mViewRoot.getIsTouchBoosting());

        MotionEvent up = MotionEvent.obtain(
                now, // downTime
                now, // eventTime
                MotionEvent.ACTION_UP, // action
                position[0], // x
                position[1], // y
                0 // metaState
        );
        up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
        instrumentation.sendPointerSync(up);
        up.recycle();

        // Should not be boosted if nothing is drawn
        Thread.sleep(30);
        assertFalse(mViewRoot.getIsTouchBoosting());

        mActivityRule.runOnUiThread(() -> {
            mMovingView.getViewRootImpl().dispatchAppVisibility(true);
        });
    }

    @Test
    @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
    public void inputMethodWithContentMoves() throws Throwable {