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

Commit f4437f74 authored by Brandon Dayauon's avatar Brandon Dayauon Committed by Android (Google) Code Review
Browse files

Merge "Implement diff haptics going into all apps" into tm-qpr-dev

parents a184e0de 12c193e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
    <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
    <uses-permission android:name="android.permission.VIBRATE"/>
    <!-- for rotating surface by arbitrary degree -->
    <uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+8 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -62,6 +63,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
    private static final long TRANSLATION_ANIM_MIN_DURATION_MS = 80;
    private static final float TRANSLATION_ANIM_VELOCITY_DP_PER_MS = 0.8f;

    private final VibratorWrapper mVibratorWrapper;
    private final RecentsView mRecentsView;
    private final MotionPauseDetector mMotionPauseDetector;
    private final float mMotionPauseMinDisplacement;
@@ -82,6 +84,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
        mRecentsView = l.getOverviewPanel();
        mMotionPauseDetector = new MotionPauseDetector(l);
        mMotionPauseMinDisplacement = ViewConfiguration.get(l).getScaledTouchSlop();
        mVibratorWrapper = VibratorWrapper.INSTANCE.get(l.getApplicationContext());
    }

    @Override
@@ -188,6 +191,11 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
            // need to manually set the duration to a reasonable value.
            animator.setDuration(HINT_STATE.getTransitionDuration(mLauncher, true /* isToState */));
        }
        if (FeatureFlags.ENABLE_HAPTICS_ALL_APPS.get() &&
                ((mFromState == NORMAL && mToState == ALL_APPS)
                        || (mFromState == ALL_APPS && mToState == NORMAL)) && isFling) {
            mVibratorWrapper.vibrateForDragBump();
        }
    }

    private void onMotionPauseDetected() {
+70 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.launcher3.util.SystemUiController.UI_STATE_ALL_APPS;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.util.FloatProperty;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -47,17 +48,21 @@ import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.views.ScrimView;

/**
@@ -78,6 +83,8 @@ public class AllAppsTransitionController
    private static final int REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS = 200;

    private static final float NAV_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.1f;
    private static final float SWIPE_DRAG_COMMIT_THRESHOLD =
            1 - AllAppsSwipeController.ALL_APPS_STATE_TRANSITION_MANUAL;

    public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
            new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
@@ -181,6 +188,7 @@ public class AllAppsTransitionController
    private boolean mIsTablet;

    private boolean mHasScaleEffect;
    private final VibratorWrapper mVibratorWrapper;

    public AllAppsTransitionController(Launcher l) {
        mLauncher = l;
@@ -193,6 +201,7 @@ public class AllAppsTransitionController

        setShiftRange(dp.allAppsShiftRange);
        mLauncher.addOnDeviceProfileChangeListener(this);
        mVibratorWrapper = VibratorWrapper.INSTANCE.get(mLauncher.getApplicationContext());
    }

    public float getShiftRange() {
@@ -311,6 +320,11 @@ public class AllAppsTransitionController
    /**
     * Creates an animation which updates the vertical transition progress and updates all the
     * dependent UI using various animation events
     *
     * This method also dictates where along the progress the haptics should be played. As the user
     * scrolls up from workspace or down from AllApps, a drag haptic is being played until the
     * commit point where it plays a commit haptic. Where we play the haptics differs when going
     * from workspace -> allApps and vice versa.
     */
    @Override
    public void setStateWithAnimation(LauncherState toState,
@@ -339,6 +353,20 @@ public class AllAppsTransitionController
            });
        }

        if(FeatureFlags.ENABLE_HAPTICS_ALL_APPS.get() && config.userControlled
                && Utilities.ATLEAST_S) {
            if (toState == ALL_APPS) {
                builder.addOnFrameListener(
                        new VibrationAnimatorUpdateListener(this, mVibratorWrapper,
                                SWIPE_DRAG_COMMIT_THRESHOLD, 1));
            } else {
                builder.addOnFrameListener(
                        new VibrationAnimatorUpdateListener(this, mVibratorWrapper,
                                0, SWIPE_DRAG_COMMIT_THRESHOLD));
            }
            builder.addEndListener(mVibratorWrapper::cancelVibrate);
        }

        float targetProgress = toState.getVerticalProgress(mLauncher);
        if (Float.compare(mProgress, targetProgress) == 0) {
            setAlphas(toState, config, builder);
@@ -356,7 +384,7 @@ public class AllAppsTransitionController

        setAlphas(toState, config, builder);

        if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL)) {
        if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL) && !(Utilities.ATLEAST_S)) {
            mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
        }
@@ -494,4 +522,45 @@ public class AllAppsTransitionController
            }
        }
    }

    /**
     * This VibrationAnimatorUpdateListener class takes in four parameters, a controller, start
     * threshold, end threshold, and a Vibrator wrapper. We use the progress given by the controller
     * as it gives an accurate progress that dictates where the vibrator should vibrate.
     * Note: once the user begins a gesture and does the commit haptic, there should not be anymore
     * haptics played for that gesture.
     */
    private static class VibrationAnimatorUpdateListener implements
            ValueAnimator.AnimatorUpdateListener {
        private final VibratorWrapper mVibratorWrapper;
        private final AllAppsTransitionController mController;
        private final float mStartThreshold;
        private final float mEndThreshold;
        private boolean mHasCommitted;

        VibrationAnimatorUpdateListener(AllAppsTransitionController controller,
                                        VibratorWrapper vibratorWrapper, float startThreshold,
                                        float endThreshold) {
            mController = controller;
            mVibratorWrapper = vibratorWrapper;
            mStartThreshold = startThreshold;
            mEndThreshold = endThreshold;
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            if (mHasCommitted) {
                return;
            }
            float currentProgress =
                    AllAppsTransitionController.ALL_APPS_PROGRESS.get(mController);
            if (currentProgress > mStartThreshold && currentProgress < mEndThreshold) {
                mVibratorWrapper.vibrateForDragTexture();
            } else if (!(currentProgress == 0 || currentProgress == 1)) {
                // This check guards against committing at the location of the start of the gesture
                mVibratorWrapper.vibrateForDragCommit();
                mHasCommitted = true;
            }
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -371,6 +371,8 @@ public final class FeatureFlags {
            "ENABLE_LAUNCH_FROM_STAGED_APP", true,
            "Enable the ability to tap a staged app during split select to launch it in full screen"
    );
    public static final BooleanFlag ENABLE_HAPTICS_ALL_APPS = getDebugFlag(
            "ENABLE_HAPTICS_ALL_APPS", false, "Enables haptics opening/closing All apps");

    public static final BooleanFlag ENABLE_FORCED_MONO_ICON = getDebugFlag(
            "ENABLE_FORCED_MONO_ICON", false,
+1 −4
Original line number Diff line number Diff line
@@ -129,10 +129,7 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
            Interpolators.clampToProgress(
                    Interpolators.mapToProgress(EMPHASIZED_DECELERATE, 0.4f, 1f),
                    ALL_APPS_STATE_TRANSITION_ATOMIC, 1f);
    public static final Interpolator ALL_APPS_VERTICAL_PROGRESS_MANUAL =
            Interpolators.clampToProgress(
                    Interpolators.mapToProgress(LINEAR, ALL_APPS_STATE_TRANSITION_MANUAL, 1f),
                    ALL_APPS_STATE_TRANSITION_MANUAL, 1f);
    public static final Interpolator ALL_APPS_VERTICAL_PROGRESS_MANUAL = LINEAR;

    // --------

Loading