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

Commit 6a9bc7df authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Revert "Revert "Long swipe from an app goes all the way to all-apps""

This reverts commit 1b6e81ed.

Reason for revert: <INSERT REASONING HERE>

Change-Id: I3d97f70a04a7d75d959b24f79198f6c9f7014b10
parent 1b6e81ed
Loading
Loading
Loading
Loading
+52 −6
Original line number Diff line number Diff line
@@ -102,6 +102,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
     */
    boolean deferStartingActivity(int downHitTarget);

    boolean supportsLongSwipe(T activity);

    /**
     * Must return a non-null controller is supportsLongSwipe was true.
     */
    LongSwipeHelper getLongSwipeController(T activity, RemoteAnimationTargetSet targetSet);

    class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {

        @Override
@@ -164,11 +171,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
        @Override
        public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible,
                Consumer<AnimatorPlaybackController> callback) {
            LauncherState startState = activity.getStateManager().getState();
            final LauncherState startState = activity.getStateManager().getState();

            LauncherState resetState = startState;
            if (startState.disableRestore) {
                startState = activity.getStateManager().getRestState();
                resetState = activity.getStateManager().getRestState();
            }
            activity.getStateManager().setRestState(startState);
            activity.getStateManager().setRestState(resetState);

            if (!activityVisible) {
                // Since the launcher is not visible, we can safely reset the scroll position.
@@ -180,11 +189,21 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
                activity.getAppsView().getContentView().setVisibility(View.GONE);
            }

            return (transitionLength) ->
                    createActivityController(activity, activityVisible, transitionLength, callback);
            return new AnimationFactory() {
                @Override
                public void createActivityController(long transitionLength) {
                    createActivityControllerInternal(activity, activityVisible, transitionLength,
                            callback);
                }

                @Override
                public void onTransitionCancelled() {
                    activity.getStateManager().goToState(startState, false /* animate */);
                }
            };
        }

        private void createActivityController(Launcher activity, boolean wasVisible,
        private void createActivityControllerInternal(Launcher activity, boolean wasVisible,
                long transitionLength, Consumer<AnimatorPlaybackController> callback) {
            if (wasVisible) {
                DeviceProfile dp = activity.getDeviceProfile();
@@ -272,6 +291,20 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
        public boolean shouldMinimizeSplitScreen() {
            return true;
        }

        @Override
        public boolean supportsLongSwipe(Launcher activity) {
            return !activity.getDeviceProfile().isVerticalBarLayout();
        }

        @Override
        public LongSwipeHelper getLongSwipeController(Launcher activity,
                RemoteAnimationTargetSet targetSet) {
            if (activity.getDeviceProfile().isVerticalBarLayout()) {
                return null;
            }
            return new LongSwipeHelper(activity, targetSet);
        }
    }

    class FallbackActivityControllerHelper implements ActivityControlHelper<RecentsActivity> {
@@ -419,6 +452,17 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
            // TODO: Remove this once b/77875376 is fixed
            return false;
        }

        @Override
        public boolean supportsLongSwipe(RecentsActivity activity) {
            return false;
        }

        @Override
        public LongSwipeHelper getLongSwipeController(RecentsActivity activity,
                RemoteAnimationTargetSet targetSet) {
            return null;
        }
    }

    interface LayoutListener {
@@ -445,5 +489,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
        default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }

        void createActivityController(long transitionLength);

        default void onTransitionCancelled() { }
    }
}
+162 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.quickstep;

import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION;
import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;

import android.animation.ValueAnimator;
import android.view.Surface;

import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.TransactionCompat;

/**
 * Utility class to handle long swipe from an app.
 * This assumes the presence of Launcher activity as long swipe is not supported on the
 * fallback activity.
 */
public class LongSwipeHelper {

    private static final float MIN_PROGRESS_TO_ALL_APPS = 0.35f;
    private static final float SWIPE_DURATION_MULTIPLIER =
            Math.min(1 / MIN_PROGRESS_TO_ALL_APPS, 1 / (1 - MIN_PROGRESS_TO_ALL_APPS));

    private final Launcher mLauncher;
    private final RemoteAnimationTargetSet mTargetSet;

    private float mMaxSwipeDistance = 1;
    private AnimatorPlaybackController mAnimator;

    LongSwipeHelper(Launcher launcher, RemoteAnimationTargetSet targetSet) {
        mLauncher = launcher;
        mTargetSet = targetSet;
        init();
    }

    private void init() {
        setTargetAlpha(0, true);

        // Init animations
        AllAppsTransitionController controller = mLauncher.getAllAppsController();
        // TODO: Scale it down so that we can reach all-apps in screen space
        mMaxSwipeDistance = Math.max(1, controller.getProgress() * controller.getShiftRange());
        mAnimator = mLauncher.getStateManager()
                .createAnimationToNewWorkspace(ALL_APPS, Math.round(2 * mMaxSwipeDistance));
        mAnimator.dispatchOnStart();
    }

    public void onMove(float displacement) {
        mAnimator.setPlayFraction(displacement / mMaxSwipeDistance);
    }

    public void destroy() {
        // TODO: We can probably also hide the task view
        setTargetAlpha(1, false);

        mLauncher.getStateManager().goToState(OVERVIEW, false);
    }

    public void end(float velocity, boolean isFling, Runnable callback) {
        long duration = MAX_SWIPE_DURATION;

        final float currentFraction = mAnimator.getProgressFraction();
        final boolean toAllApps;
        float endProgress;

        if (!isFling) {
            toAllApps = currentFraction > MIN_PROGRESS_TO_ALL_APPS;
            endProgress = toAllApps ? 1 : 0;

            long expectedDuration = Math.abs(Math.round((endProgress - currentFraction)
                    * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
            duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
        } else {
            toAllApps = velocity < 0;
            endProgress = toAllApps ? 1 : 0;

            float minFlingVelocity = mLauncher.getResources()
                    .getDimension(R.dimen.quickstep_fling_min_velocity);
            if (Math.abs(velocity) > minFlingVelocity && mMaxSwipeDistance > 0) {
                float distanceToTravel = (endProgress - currentFraction) * mMaxSwipeDistance;

                // we want the page's snap velocity to approximately match the velocity at
                // which the user flings, so we scale the duration by a value near to the
                // derivative of the scroll interpolator at zero, ie. 2.
                long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / velocity));
                duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);
            }
        }

        mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, isFling, callback));
        ValueAnimator animator = mAnimator.getAnimationPlayer();
        animator.setDuration(duration).setInterpolator(DEACCEL);
        animator.setFloatValues(currentFraction, endProgress);
        animator.start();
    }

    private void setTargetAlpha(float alpha, boolean defer) {
        final Surface surface = getSurface(mLauncher.getDragLayer());
        final long frameNumber = defer && surface != null ? getNextFrameNumber(surface) : -1;
        if (defer) {
            if (frameNumber == -1) {
                defer = false;
            } else {
                mLauncher.getDragLayer().invalidate();
            }
        }

        TransactionCompat transaction = new TransactionCompat();
        for (RemoteAnimationTargetCompat app : mTargetSet.apps) {
            if (!(app.isNotInRecents
                    || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME)) {
                transaction.setAlpha(app.leash, alpha);
                if (defer) {
                    transaction.deferTransactionUntil(app.leash, surface, frameNumber);
                }
            }
        }
        transaction.apply();
    }

    private void onSwipeAnimationComplete(boolean toAllApps, boolean isFling, Runnable callback) {
        mLauncher.getStateManager().goToState(toAllApps ? ALL_APPS : OVERVIEW, false);
        if (!toAllApps) {
            DiscoveryBounce.showForOverviewIfNeeded(mLauncher);
        }

        mLauncher.getUserEventDispatcher().logStateChangeAction(
                isFling ? Touch.FLING : Touch.SWIPE, Direction.UP,
                ContainerType.NAVBAR, ContainerType.APP,
                toAllApps ? ContainerType.ALLAPPS : ContainerType.TASKSWITCHER,
                0);

        callback.run();
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -59,4 +59,8 @@ public class MultiStateCallback {
    public int getState() {
        return mState;
    }

    public boolean hasStates(int stateMask) {
        return (mState & stateMask) == stateMask;
    }
}
+176 −54

File changed.

Preview size limit exceeded, changes collapsed.