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

Commit 541f71a7 authored by Yeabkal Wubshit's avatar Yeabkal Wubshit Committed by Android (Google) Code Review
Browse files

Merge "Add scroll haptics for AbsListView and ScrollView" into main

parents 4391aaa1 cbb08ee3
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ java_defaults {
        ":telecom_flags_core_java_lib{.generated_srcjars}",
        ":android.companion.virtual.flags-aconfig-java{.generated_srcjars}",
        ":android.view.inputmethod.flags-aconfig-java{.generated_srcjars}",
        ":android.widget.flags-aconfig-java{.generated_srcjars}",
    ],
    // Add aconfig-annotations-lib as a dependency for the optimization
    libs: ["aconfig-annotations-lib"],
@@ -185,3 +186,17 @@ java_aconfig_library {
    aconfig_declarations: "android.view.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

// Widget
aconfig_declarations {
    name: "android.widget.flags-aconfig",
    package: "android.widget.flags",
    srcs: ["core/java/android/widget/flags/*.aconfig"],
}

java_aconfig_library {
    name: "android.widget.flags-aconfig-java",
    aconfig_declarations: "android.widget.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+22 −8
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.view.ActionMode;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.HapticScrollFeedbackProvider;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -91,6 +92,7 @@ import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.SurroundingText;
import android.view.inspector.InspectableProperty;
import android.view.inspector.InspectableProperty.EnumEntry;
import android.widget.flags.Flags;
import android.widget.RemoteViews.InteractionHandler;

import com.android.internal.R;
@@ -918,6 +920,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te

    private DifferentialMotionFlingHelper mDifferentialMotionFlingHelper;

    private HapticScrollFeedbackProvider mHapticScrollFeedbackProvider;

    public AbsListView(Context context) {
        super(context);
        setupDeviceConfigProperties();
@@ -4502,10 +4506,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final float axisValue = (axis == -1) ? 0 : event.getAxisValue(axis);
                final int delta = Math.round(axisValue * mVerticalScrollFactor);
                if (delta != 0) {
                    // Tracks whether or not we should attempt fling for this event.
                    // Fling should not be attempted if the view is already at the limit of scroll,
                    // since it conflicts with EdgeEffect.
                    boolean shouldAttemptFling = true;
                    // If we're moving down, we want the top item. If we're moving up, bottom item.
                    final int motionIndex = delta > 0 ? 0 : getChildCount() - 1;

@@ -4518,10 +4518,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    final int overscrollMode = getOverScrollMode();

                    if (!trackMotionScroll(delta, delta)) {
                        if (shouldAttemptFling) {
                        if (Flags.platformWidgetHapticScrollFeedback()) {
                            initHapticScrollFeedbackProviderIfNotExists();
                            mHapticScrollFeedbackProvider.onScrollProgress(event, axis, delta);
                        }
                        initDifferentialFlingHelperIfNotExists();
                        mDifferentialMotionFlingHelper.onMotionEvent(event, axis);
                        }
                        return true;
                    } else if (!event.isFromSource(InputDevice.SOURCE_MOUSE) && motionView != null
                            && (overscrollMode == OVER_SCROLL_ALWAYS
@@ -4530,7 +4532,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                        int motionViewRealTop = motionView.getTop();
                        float overscroll = (delta - (motionViewRealTop - motionViewPrevTop))
                                / ((float) getHeight());
                        if (delta > 0) {
                        boolean hitTopLimit = delta > 0;
                        if (Flags.platformWidgetHapticScrollFeedback()) {
                            initHapticScrollFeedbackProviderIfNotExists();
                            mHapticScrollFeedbackProvider.onScrollLimit(
                                    event, axis, /* isStart= */ hitTopLimit);
                        }
                        if (hitTopLimit) {
                            mEdgeGlowTop.onPullDistance(overscroll, 0.5f);
                            mEdgeGlowTop.onRelease();
                        } else {
@@ -4696,6 +4704,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        }
    }

    private void initHapticScrollFeedbackProviderIfNotExists() {
        if (mHapticScrollFeedbackProvider == null) {
            mHapticScrollFeedbackProvider = new HapticScrollFeedbackProvider(this);
        }
    }

    private void recycleVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
+24 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.StrictMode;
import android.util.AttributeSet;
import android.util.Log;
import android.view.FocusFinder;
import android.view.HapticScrollFeedbackProvider;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -47,6 +48,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.inspector.InspectableProperty;
import android.widget.flags.Flags;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -206,6 +208,8 @@ public class ScrollView extends FrameLayout {

    private DifferentialMotionFlingHelper mDifferentialMotionFlingHelper;

    private HapticScrollFeedbackProvider mHapticScrollFeedbackProvider;

    /**
     * Sentinel value for no current active pointer.
     * Used by {@link #mActivePointerId}.
@@ -604,6 +608,12 @@ public class ScrollView extends FrameLayout {
        }
    }

    private void initHapticScrollFeedbackProviderIfNotExists() {
        if (mHapticScrollFeedbackProvider == null) {
            mHapticScrollFeedbackProvider = new HapticScrollFeedbackProvider(this);
        }
    }

    private void recycleVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
@@ -967,7 +977,7 @@ public class ScrollView extends FrameLayout {
                    // Tracks whether or not we should attempt fling for this event.
                    // Fling should not be attempted if the view is already at the limit of scroll,
                    // since it conflicts with EdgeEffect.
                    boolean shouldAttemptFling = true;
                    boolean hitLimit = false;
                    final int range = getScrollRange();
                    int oldScrollY = mScrollY;
                    int newScrollY = oldScrollY - delta;
@@ -986,7 +996,7 @@ public class ScrollView extends FrameLayout {
                            absorbed = true;
                        }
                        newScrollY = 0;
                        shouldAttemptFling = false;
                        hitLimit = true;
                    } else if (newScrollY > range) {
                        if (canOverscroll) {
                            mEdgeGlowBottom.onPullDistance(
@@ -996,11 +1006,21 @@ public class ScrollView extends FrameLayout {
                            absorbed = true;
                        }
                        newScrollY = range;
                        shouldAttemptFling = false;
                        hitLimit = true;
                    }
                    if (newScrollY != oldScrollY) {
                        super.scrollTo(mScrollX, newScrollY);
                        if (shouldAttemptFling) {
                        if (hitLimit) {
                            if (Flags.platformWidgetHapticScrollFeedback()) {
                                initHapticScrollFeedbackProviderIfNotExists();
                                mHapticScrollFeedbackProvider.onScrollLimit(
                                        event, axis, /* isStart= */ newScrollY == 0);
                            }
                        } else {
                            if (Flags.platformWidgetHapticScrollFeedback()) {
                                initHapticScrollFeedbackProviderIfNotExists();
                                mHapticScrollFeedbackProvider.onScrollProgress(event, axis, delta);
                            }
                            initDifferentialFlingHelperIfNotExists();
                            mDifferentialMotionFlingHelper.onMotionEvent(event, axis);
                        }
+8 −0
Original line number Diff line number Diff line
package: "android.widget.flags"

flag {
    namespace: "widget"
    name: "platform_widget_haptic_scroll_feedback"
    description: "Enables haptic scroll feedback in platform widgets"
    bug: "287914819"
}
 No newline at end of file