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

Commit e5f1faa9 authored by Winson's avatar Winson
Browse files

Porting over keyboard changes from other branch.

- Allow ignoring alt-key release when interacting via touch while 
  alt-tab is pressed (ag/814903)
- Cancel window animations only if the stack scrolls via alt-tab 
  (ag/809873)
- Fixing issue with old task load plan being consumed if user alt-tabs
  before Recents is resumed (ag/811354)
- Canceling enter animations when the stack scrolls (ag/814461)

Change-Id: I7450f0a280571e98212f321b1e61219d149fed65
parent 397ae747
Loading
Loading
Loading
Loading
+32 −18
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.ResizeTaskEvent;
import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
import com.android.systemui.recents.events.ui.UserInteractionEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
@@ -87,29 +88,30 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD

    public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;

    RecentsPackageMonitor mPackageMonitor;
    long mLastTabKeyEventTime;
    boolean mFinishedOnStartup;
    private RecentsPackageMonitor mPackageMonitor;
    private long mLastTabKeyEventTime;
    private boolean mFinishedOnStartup;
    private boolean mIgnoreAltTabRelease;

    // Top level views
    RecentsView mRecentsView;
    SystemBarScrimViews mScrimViews;
    ViewStub mEmptyViewStub;
    View mEmptyView;
    private RecentsView mRecentsView;
    private SystemBarScrimViews mScrimViews;
    private ViewStub mEmptyViewStub;
    private View mEmptyView;

    // Resize task debug
    RecentsResizeTaskDialog mResizeTaskDebugDialog;
    private RecentsResizeTaskDialog mResizeTaskDebugDialog;

    // Search AppWidget
    AppWidgetProviderInfo mSearchWidgetInfo;
    RecentsAppWidgetHost mAppWidgetHost;
    RecentsAppWidgetHostView mSearchWidgetHostView;
    private AppWidgetProviderInfo mSearchWidgetInfo;
    private RecentsAppWidgetHost mAppWidgetHost;
    private RecentsAppWidgetHostView mSearchWidgetHostView;

    // Runnables to finish the Recents activity
    FinishRecentsRunnable mFinishLaunchHomeRunnable;
    private FinishRecentsRunnable mFinishLaunchHomeRunnable;

    // The trigger to automatically launch the current task
    DozeTrigger mIterateTrigger = new DozeTrigger(500, new Runnable() {
    private DozeTrigger mIterateTrigger = new DozeTrigger(500, new Runnable() {
        @Override
        public void run() {
            dismissRecentsToFocusedTask();
@@ -434,6 +436,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
    protected void onStop() {
        super.onStop();

        // Reset some states
        mIgnoreAltTabRelease = false;

        // Notify that recents is now hidden
        SystemServicesProxy ssp = Recents.getSystemServices();
        EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, false));
@@ -504,10 +509,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
                boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
                        mLastTabKeyEventTime) > altTabKeyDelay;
                if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
                    // As we iterate to the next/previous task, cancel any current/lagging window
                    // transition animations
                    EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));

                    // Focus the next task in the stack
                    final boolean backward = event.isShiftPressed();
                    if (backward) {
@@ -516,6 +517,11 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
                        EventBus.getDefault().send(new FocusNextTaskViewEvent());
                    }
                    mLastTabKeyEventTime = SystemClock.elapsedRealtime();

                    // In the case of another ALT event, don't ignore the next release
                    if (event.isAltPressed()) {
                        mIgnoreAltTabRelease = false;
                    }
                }
                return true;
            }
@@ -590,7 +596,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
    public final void onBusEvent(HideRecentsEvent event) {
        if (event.triggeredFromAltTab) {
            // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
            if (!mIgnoreAltTabRelease) {
                dismissRecentsToFocusedTaskOrHome();
            }
        } else if (event.triggeredFromHomeKey) {
            // Otherwise, dismiss Recents to Home
            dismissRecentsToHome(true /* animated */);
@@ -713,6 +721,12 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
        finish();
    }

    public final void onBusEvent(StackViewScrolledEvent event) {
        // Once the user has scrolled while holding alt-tab, then we should ignore the release of
        // the key
        mIgnoreAltTabRelease = true;
    }

    private void refreshSearchWidgetView() {
        if (mSearchWidgetInfo != null) {
            SystemServicesProxy ssp = Recents.getSystemServices();
+5 −4
Original line number Diff line number Diff line
@@ -799,12 +799,13 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub implements
        // Update the header bar if necessary
        reloadHeaderBarLayout(false /* tryAndBindSearchWidget */);

        if (sInstanceLoadPlan == null) {
            // Create a new load plan if onPreloadRecents() was never triggered
        // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
        // should always preload the tasks now
        if (mTriggeredFromAltTab ||sInstanceLoadPlan == null) {
            // Create a new load plan if preloadRecents() was never triggered
            sInstanceLoadPlan = loader.createLoadPlan(mContext);
        }

        if (!sInstanceLoadPlan.hasTasks()) {
        if (mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
            loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome);
        }
        TaskStack stack = sInstanceLoadPlan.getTaskStack();
+56 −6
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
@@ -100,6 +102,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
    boolean mStackViewsDirty = true;
    boolean mStackViewsClipDirty = true;
    boolean mAwaitingFirstLayout = true;
    boolean mEnterAnimationComplete = false;
    boolean mStartEnterAnimationRequestedAfterLayout;
    ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext;

@@ -288,6 +291,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        mStackViewsDirty = true;
        mStackViewsClipDirty = true;
        mAwaitingFirstLayout = true;
        mEnterAnimationComplete = false;
        if (mUIDozeTrigger != null) {
            mUIDozeTrigger.stopDozing();
            mUIDozeTrigger.resetTrigger();
@@ -604,15 +608,19 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

    /**
     * Sets the focused task to the provided (bounded taskIndex).
     *
     * @return whether or not the stack will scroll as a part of this focus change
     */
    private void setFocusedTask(int taskIndex, boolean scrollToTask, final boolean animated) {
        setFocusedTask(taskIndex, scrollToTask, animated, true);
    private boolean setFocusedTask(int taskIndex, boolean scrollToTask, final boolean animated) {
        return setFocusedTask(taskIndex, scrollToTask, animated, true);
    }

    /**
     * Sets the focused task to the provided (bounded taskIndex).
     *
     * @return whether or not the stack will scroll as a part of this focus change
     */
    private void setFocusedTask(int taskIndex, boolean scrollToTask, final boolean animated,
    private boolean setFocusedTask(int taskIndex, boolean scrollToTask, final boolean animated,
                                final boolean requestViewFocus) {
        // Find the next task to focus
        int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
@@ -628,6 +636,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
            }
        }

        boolean willScroll = false;
        mFocusedTaskIndex = newFocusedTaskIndex;
        if (mFocusedTaskIndex != -1) {
            Runnable focusTaskRunnable = new Runnable() {
@@ -648,18 +657,33 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                    newScroll -= 0.5f;
                }
                newScroll = mStackScroller.getBoundedStackScroll(newScroll);
                if (Float.compare(newScroll, mStackScroller.getStackScroll()) != 0) {
                    mStackScroller.animateScroll(mStackScroller.getStackScroll(), newScroll,
                            focusTaskRunnable);
                    willScroll = true;

                    // Cancel any running enter animations at this point when we scroll as well
                    if (!mEnterAnimationComplete) {
                        final List<TaskView> taskViews = getTaskViews();
                        for (TaskView tv : taskViews) {
                            tv.cancelEnterRecentsAnimation();
                        }
                    }
                } else {
                    focusTaskRunnable.run();
                }
                mLayoutAlgorithm.animateFocusState(TaskStackLayoutAlgorithm.STATE_FOCUSED);
            } else {
                focusTaskRunnable.run();
            }
        }
        return willScroll;
    }

    /**
     * Sets the focused task relative to the currently focused task.
     *
     * @param forward whether to go to the next task in the stack (along the curve) or the previous
     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
     *                       if the currently focused task is not a stack task, will set the focus
     *                       to the first visible stack task
@@ -667,6 +691,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
     *                            focus.
     */
    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated) {
        setRelativeFocusedTask(forward, stackTasksOnly, animated, false);
    }

    /**
     * Sets the focused task relative to the currently focused task.
     *
     * @param forward whether to go to the next task in the stack (along the curve) or the previous
     * @param stackTasksOnly if set, will ensure that the traversal only goes along stack tasks, and
     *                       if the currently focused task is not a stack task, will set the focus
     *                       to the first visible stack task
     * @param animated determines whether to actually draw the highlight along with the change in
     *                            focus.
     * @param cancelWindowAnimations if set, will attempt to cancel window animations if a scroll
     *                               happens
     */
    public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
                                       boolean cancelWindowAnimations) {
        int newIndex = -1;
        if (mFocusedTaskIndex != -1) {
            if (stackTasksOnly) {
@@ -703,7 +744,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
            }
        }
        if (newIndex != -1) {
            setFocusedTask(newIndex, true, animated);
            boolean willScroll = setFocusedTask(newIndex, true, animated);
            if (willScroll && cancelWindowAnimations) {
                // As we iterate to the next/previous task, cancel any current/lagging window
                // transition animations
                EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null));
            }
        }
    }

@@ -1418,6 +1464,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        mLayoutAlgorithm.animateFocusState(mLayoutAlgorithm.getDefaultFocusState());
    }

    public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
        mEnterAnimationComplete = true;
    }

    /**
     * Removes the task from the stack, and updates the focus to the next task in the stack if the
     * removed TaskView was focused.
+0 −6
Original line number Diff line number Diff line
@@ -166,12 +166,6 @@ public class TaskStackViewScroller {
        mScrollAnimator.setDuration(mContext.getResources().getInteger(
                R.integer.recents_animate_task_stack_scroll_duration));
        mScrollAnimator.setInterpolator(mLinearOutSlowInInterpolator);
        mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                setStackScroll((Float) animation.getAnimatedValue());
            }
        });
        mScrollAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
+27 −14
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.recents.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -29,7 +30,6 @@ import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -40,12 +40,10 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
@@ -340,15 +338,21 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
                    animate().alpha(1f)
                            .translationY(transform.translationY)
                            .setUpdateListener(null)
                            .setInterpolator(mFastOutSlowInInterpolator)
                            .setDuration(taskViewEnterFromHomeDuration)
                            .withEndAction(new Runnable() {
                            .setListener(new AnimatorListenerAdapter() {
                                private boolean hasEnded;

                                // We use the animation listener instead of withEndAction() to
                                // ensure that onAnimationEnd() is called when the animator is
                                // cancelled
                                @Override
                                public void run() {
                                    // Decrement the post animation trigger
                                public void onAnimationEnd(Animator animation) {
                                    if (hasEnded) return;
                                    ctx.postAnimationTrigger.decrement();
                                    hasEnded = true;
                                }
                            })
                            .setInterpolator(mFastOutSlowInInterpolator)
                            .setDuration(taskViewEnterFromHomeDuration)
                            .start();
                    ctx.postAnimationTrigger.increment();
                }
@@ -368,21 +372,30 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
                    .translationY(transform.translationY)
                    .setStartDelay(delay)
                    .setUpdateListener(ctx.updateListener)
                    .setInterpolator(mQuintOutInterpolator)
                    .setDuration(taskViewEnterFromHomeDuration +
                            frontIndex * taskViewEnterFromHomeStaggerDelay)
                    .withEndAction(new Runnable() {
                    .setListener(new AnimatorListenerAdapter() {
                        private boolean hasEnded;

                        // We use the animation listener instead of withEndAction() to ensure that
                        // onAnimationEnd() is called when the animator is cancelled
                        @Override
                        public void run() {
                            // Decrement the post animation trigger
                        public void onAnimationEnd(Animator animation) {
                            if (hasEnded) return;
                            ctx.postAnimationTrigger.decrement();
                            hasEnded = true;
                        }
                    })
                    .setInterpolator(mQuintOutInterpolator)
                    .setDuration(taskViewEnterFromHomeDuration +
                            frontIndex * taskViewEnterFromHomeStaggerDelay)
                    .start();
            ctx.postAnimationTrigger.increment();
        }
    }

    public void cancelEnterRecentsAnimation() {
        animate().cancel();
    }

    public void fadeInActionButton(int duration) {
        // Hide the action button
        mActionButtonView.setAlpha(0f);