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

Commit eeee7371 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topics "viewconf-cache-instances", "viewconf-nonstatic" into main

* changes:
  Cache ViewConfiguration instances per device
  Migrate usages of ViewConfiguration static methods
  Add non-static methods in ViewConfiguration
parents 4dd8644d cfac92b3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -54931,6 +54931,7 @@ package android.view {
    method @Deprecated @FloatRange(from=1.0) public static float getAmbiguousGestureMultiplier();
    method public static long getDefaultActionModeHideDuration();
    method public static int getDoubleTapTimeout();
    method @FlaggedApi("android.companion.virtualdevice.flags.viewconfiguration_apis") public int getDoubleTapTimeoutMillis();
    method @Deprecated public static int getEdgeSlop();
    method @Deprecated public static int getFadingEdgeLength();
    method @Deprecated public static long getGlobalActionKeyTimeout();
@@ -54968,7 +54969,9 @@ package android.view {
    method @Deprecated public static int getScrollBarSize();
    method public static int getScrollDefaultDelay();
    method public static float getScrollFriction();
    method @FlaggedApi("android.companion.virtualdevice.flags.viewconfiguration_apis") public float getScrollFrictionAmount();
    method public static int getTapTimeout();
    method @FlaggedApi("android.companion.virtualdevice.flags.viewconfiguration_apis") public int getTapTimeoutMillis();
    method @Deprecated public static int getTouchSlop();
    method @Deprecated public static int getWindowTouchSlop();
    method public static long getZoomControlsTimeout();
+7 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.DimenRes;
import android.companion.virtualdevice.flags.Flags;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
@@ -73,6 +74,7 @@ final class KeyButtonRipple extends Drawable {
    private final Interpolator mInterpolator = new LogInterpolator();
    private boolean mSupportHardware;
    private final View mTargetView;
    private final int mTapTimeoutMillis;
    private final Handler mHandler = new Handler();

    private final HashSet<Animator> mRunningAnimations = new HashSet<>();
@@ -94,6 +96,9 @@ final class KeyButtonRipple extends Drawable {
        mMaxWidthResource = maxWidthResource;
        mMaxWidth = ctx.getResources().getDimensionPixelSize(maxWidthResource);
        mTargetView = targetView;
        mTapTimeoutMillis = Flags.viewconfigurationApis()
                ? ViewConfiguration.get(mTargetView.getContext()).getTapTimeoutMillis()
                : ViewConfiguration.getTapTimeout();
    }

    public void updateResources() {
@@ -308,7 +313,7 @@ final class KeyButtonRipple extends Drawable {
            if (mDelayTouchFeedback) {
                if (mRunningAnimations.isEmpty()) {
                    mHandler.removeCallbacksAndMessages(null);
                    mHandler.postDelayed(this::enterSoftware, ViewConfiguration.getTapTimeout());
                    mHandler.postDelayed(this::enterSoftware, mTapTimeoutMillis);
                } else if (mVisible) {
                    enterSoftware();
                }
@@ -353,7 +358,7 @@ final class KeyButtonRipple extends Drawable {
            if (mDelayTouchFeedback) {
                if (mRunningAnimations.isEmpty()) {
                    mHandler.removeCallbacksAndMessages(null);
                    mHandler.postDelayed(this::enterHardware, ViewConfiguration.getTapTimeout());
                    mHandler.postDelayed(this::enterHardware, mTapTimeoutMillis);
                } else if (mVisible) {
                    enterHardware();
                }
+20 −12
Original line number Diff line number Diff line
@@ -27,9 +27,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.app.Activity;
import android.companion.virtualdevice.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -239,7 +239,6 @@ public class GestureDetector {
        }
    }

    private static final String TAG = GestureDetector.class.getSimpleName();
    @UnsupportedAppUsage
    private int mTouchSlopSquare;
    private int mDoubleTapTouchSlopSquare;
@@ -248,12 +247,9 @@ public class GestureDetector {
    @UnsupportedAppUsage
    private int mMinimumFlingVelocity;
    private int mMaximumFlingVelocity;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
    private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
    private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
    private static final int DOUBLE_TAP_MIN_TIME = ViewConfiguration.getDoubleTapMinTime();
    private int mTapTimeout;
    private int mDoubleTapTimeout;
    private int mDoubleTapMinTime;

    // constants for Message.what used by GestureHandler below
    private static final int SHOW_PRESS = 1;
@@ -303,7 +299,7 @@ public class GestureDetector {
    /**
     * Determines strategy for velocity calculation
     */
    private @VelocityTracker.VelocityTrackerStrategy int mVelocityTrackerStrategy;
    private final @VelocityTracker.VelocityTrackerStrategy int mVelocityTrackerStrategy;

    /**
     * Consistency verifier for debugging purposes.
@@ -502,6 +498,9 @@ public class GestureDetector {
            mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity();
            mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity();
            mAmbiguousGestureMultiplier = ViewConfiguration.getAmbiguousGestureMultiplier();
            mTapTimeout = ViewConfiguration.getTapTimeout();
            mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout();
            mDoubleTapMinTime = ViewConfiguration.getDoubleTapMinTime();
        } else {
            StrictMode.assertConfigurationContext(context, "GestureDetector#init");
            final ViewConfiguration configuration = ViewConfiguration.get(context);
@@ -511,6 +510,15 @@ public class GestureDetector {
            mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
            mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity();
            mAmbiguousGestureMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
            if (Flags.viewconfigurationApis()) {
                mTapTimeout = configuration.getTapTimeoutMillis();
                mDoubleTapTimeout = configuration.getDoubleTapTimeoutMillis();
                mDoubleTapMinTime = configuration.getDoubleTapMinTimeMillis();
            } else {
                mTapTimeout = ViewConfiguration.getTapTimeout();
                mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout();
                mDoubleTapMinTime = ViewConfiguration.getDoubleTapMinTime();
            }
        }
        mTouchSlopSquare = touchSlop * touchSlop;
        mDoubleTapTouchSlopSquare = doubleTapTouchSlop * doubleTapTouchSlop;
@@ -654,7 +662,7 @@ public class GestureDetector {
                        handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                    } else {
                        // This is a first tap
                        mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
                        mHandler.sendEmptyMessageDelayed(TAP, mDoubleTapTimeout);
                    }
                }

@@ -682,7 +690,7 @@ public class GestureDetector {
                                    + ViewConfiguration.getLongPressTimeout());
                }
                mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                        mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
                        mCurrentDownEvent.getDownTime() + mTapTimeout);
                handled |= mListener.onDown(ev);
                break;

@@ -907,7 +915,7 @@ public class GestureDetector {
        }

        final long deltaTime = secondDown.getEventTime() - firstUp.getEventTime();
        if (deltaTime > DOUBLE_TAP_TIMEOUT || deltaTime < DOUBLE_TAP_MIN_TIME) {
        if (deltaTime > mDoubleTapTimeout || deltaTime < mDoubleTapMinTime) {
            return false;
        }

+10 −4
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ import android.annotation.UiThread;
import android.app.PendingIntent;
import android.app.jank.AppJankStats;
import android.app.jank.JankTracker;
import android.companion.virtualdevice.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AutofillOptions;
import android.content.ClipData;
@@ -5431,6 +5432,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    private int mTouchSlop;
    /**
     * Cache the tap timeout from the context that created the view.
     */
    private int mTapTimeoutMillis;
    /**
     * Cache the ambiguous gesture multiplier from the context that created the view.
     */
@@ -5868,6 +5874,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
        mTapTimeoutMillis = Flags.viewconfigurationApis()
                ? configuration.getTapTimeoutMillis() : ViewConfiguration.getTapTimeout();
        mAmbiguousGestureMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
        setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
@@ -7362,7 +7370,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
        scrollabilityCache.fadeScrollBars = fadeScrollbars;
        scrollabilityCache.scrollBarFadeDuration = a.getInt(
                R.styleable.View_scrollbarFadeDuration, ViewConfiguration
                        .getScrollBarFadeDuration());
@@ -7370,7 +7377,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                R.styleable.View_scrollbarDefaultDelayBeforeFade,
                ViewConfiguration.getScrollDefaultDelay());
        scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
                com.android.internal.R.styleable.View_scrollbarSize,
                ViewConfiguration.get(mContext).getScaledScrollBarSize());
@@ -18220,7 +18226,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                        }
                        mPendingCheckForTap.x = event.getX();
                        mPendingCheckForTap.y = event.getY();
                        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                        postDelayed(mPendingCheckForTap, mTapTimeoutMillis);
                    } else {
                        // Not inside a scrolling container, so show the feedback right away
                        setPressed(true, x, y);
@@ -31543,7 +31549,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            mPrivateFlags &= ~PFLAG_PREPRESSED;
            setPressed(true, x, y);
            final long delay =
                    ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout();
                    (long) ViewConfiguration.getLongPressTimeout() - mTapTimeoutMillis;
            checkForLongClick(delay, x, y, TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
        }
    }
+71 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.TestApi;
@@ -37,7 +38,7 @@ import android.os.RemoteException;
import android.os.StrictMode;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.util.LongSparseArray;
import android.util.TypedValue;
import android.view.flags.Flags;

@@ -387,15 +388,17 @@ public class ViewConfiguration {
    private final int mSmartSelectionInitializingTimeout;
    private final boolean mPreferKeepClearForFocusEnabled;
    private final boolean mViewBasedRotaryEncoderScrollHapticsEnabledConfig;
    private final int mTapTimeoutMillis;
    private final int mDoubleTapTimeoutMillis;
    private final int mDoubleTapMinTimeMillis;
    private final float mScrollFriction;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
    private boolean sHasPermanentMenuKey;
    @UnsupportedAppUsage
    private boolean sHasPermanentMenuKeySet;

    @UnsupportedAppUsage
    static final SparseArray<ViewConfiguration> sConfigurations =
            new SparseArray<ViewConfiguration>(2);
    static final LongSparseArray<ViewConfiguration> sConfigurations = new LongSparseArray<>(2);

    /**
     * @deprecated Use {@link android.view.ViewConfiguration#get(android.content.Context)} instead.
@@ -441,6 +444,11 @@ public class ViewConfiguration {
        mSmartSelectionInitializingTimeout = SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND;
        mPreferKeepClearForFocusEnabled = false;
        mViewTouchScreenHapticScrollFeedbackEnabled = false;

        mTapTimeoutMillis = sResourceCache.getTapTimeout();
        mDoubleTapTimeoutMillis = sResourceCache.getDoubleTapTimeout();
        mDoubleTapMinTimeMillis = sResourceCache.getDoubleTapMinTime();
        mScrollFriction = sResourceCache.getScrollFriction();
    }

    /**
@@ -579,6 +587,11 @@ public class ViewConfiguration {
                Flags.enableScrollFeedbackForTouch()
                        ? res.getBoolean(R.bool.config_viewTouchScreenHapticScrollFeedbackEnabled)
                        : false;

        mTapTimeoutMillis = res.getInteger(R.integer.config_tapTimeoutMillis);
        mDoubleTapTimeoutMillis = res.getInteger(R.integer.config_doubleTapTimeoutMillis);
        mDoubleTapMinTimeMillis = res.getInteger(R.integer.config_doubleTapMinTimeMillis);
        mScrollFriction = res.getFloat(R.dimen.config_scrollFriction);
    }

    /**
@@ -594,12 +607,11 @@ public class ViewConfiguration {
    public static ViewConfiguration get(@NonNull @UiContext Context context) {
        StrictMode.assertConfigurationContext(context, "ViewConfiguration");

        final int density = getDisplayDensity(context);

        ViewConfiguration configuration = sConfigurations.get(density);
        final long key = createKey(context);
        ViewConfiguration configuration = sConfigurations.get(key);
        if (configuration == null) {
            configuration = new ViewConfiguration(context);
            sConfigurations.put(density, configuration);
            sConfigurations.put(key, configuration);
        }

        return configuration;
@@ -625,7 +637,7 @@ public class ViewConfiguration {
     */
    @VisibleForTesting
    public static void setInstanceForTesting(Context context, ViewConfiguration instance) {
        sConfigurations.put(getDisplayDensity(context), instance);
        sConfigurations.put(createKey(context), instance);
    }

    /**
@@ -739,6 +751,16 @@ public class ViewConfiguration {
        return sResourceCache.getTapTimeout();
    }

    /**
     * @return the duration in milliseconds we will wait to see if a touch event
     * is a tap or a scroll. If the user does not move within this interval, it is
     * considered to be a tap.
     */
    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIEWCONFIGURATION_APIS)
    public int getTapTimeoutMillis() {
        return mTapTimeoutMillis;
    }

    /**
     * @return the duration in milliseconds we will wait to see if a touch event
     * is a jump tap. If the user does not move within this interval, it is
@@ -757,6 +779,16 @@ public class ViewConfiguration {
        return sResourceCache.getDoubleTapTimeout();
    }

    /**
     * @return the duration in milliseconds between the first tap's up event and
     * the second tap's down event for an interaction to be considered a
     * double-tap.
     */
    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIEWCONFIGURATION_APIS)
    public int getDoubleTapTimeoutMillis() {
        return mDoubleTapTimeoutMillis;
    }

    /**
     * @return the minimum duration in milliseconds between the first tap's
     * up event and the second tap's down event for an interaction to be considered a
@@ -769,6 +801,17 @@ public class ViewConfiguration {
        return sResourceCache.getDoubleTapMinTime();
    }

    /**
     * @return the minimum duration in milliseconds between the first tap's
     * up event and the second tap's down event for an interaction to be considered a
     * double-tap.
     *
     * @hide
     */
    public int getDoubleTapMinTimeMillis() {
        return mDoubleTapMinTimeMillis;
    }

    /**
     * @return the maximum duration in milliseconds between a touch pad
     * touch and release for a given touch to be considered a tap (click) as
@@ -1100,6 +1143,17 @@ public class ViewConfiguration {
        return sResourceCache.getScrollFriction();
    }

    /**
     * The amount of friction applied to scrolls and flings.
     *
     * @return A scalar dimensionless value representing the coefficient of
     *         friction.
     */
    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIEWCONFIGURATION_APIS)
    public float getScrollFrictionAmount() {
        return mScrollFriction;
    }

    /**
     * @return the default duration in milliseconds for {@link ActionMode#hide(long)}.
     */
@@ -1460,6 +1514,14 @@ public class ViewConfiguration {
        return (int) (100.0f * metrics.density);
    }

    /**
     * Returns a key of type long using the display density and deviceId from the {@link Context}.
     */
    private static long createKey(Context context) {
        int displayDensity = getDisplayDensity(context);
        return (((long) displayDensity) << 32) | (context.getDeviceId() & 0xffffffffL);
    }

    /**
     * Fetches resource values statically and caches them locally for fast lookup. Note that these
     * values will not be updated during the lifetime of a process, even if resource overlays are
Loading