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

Commit 12c193e6 authored by Brandon Dayauon's avatar Brandon Dayauon
Browse files

Implement diff haptics going into all apps

Notes:
* the reason why 0.6 -> 1 never happened was because of AllAppsSwipeController where
it had a clampToProgress. By changing lowerbound to 0 the progress actually shows fully 0->1

- composed the haptics in the constructor
- added new listener class in AATransitionController

Added featureflag

bug: 233751149
test: Manually - presubmit, ran “make -j7 Launcher3” from master branch  photo: https://screenshot.googleplex.com/8r5FZh6buzkQMjk
Change-Id: I5e1a24170fdbfdd35b8d8f24af0ec5e8586641a2
parent 7b7130db
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() {
@@ -304,6 +313,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,
@@ -332,6 +346,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);
@@ -349,7 +377,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);
        }
@@ -487,4 +515,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
@@ -375,6 +375,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