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

Commit 9e177f05 authored by Matthew Ng's avatar Matthew Ng
Browse files

Handle clear all button show and hide functionality for low ram devices

Hides the clear all button at the beginning and shows it when scrolling
the list up or when swiping an app away. The clear all button will not
hide when already shown. Users can also start the scroll gesture over
the clear all button to scroll the list.

Test: manual - use low ram device and go to recents and scroll
Change-Id: Ie2d22db9bdd66308ce8ef3acf77b9f707d638ade
Fixes: 65571889
parent 9cc57140
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2017 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.
@@ -22,5 +22,15 @@ import com.android.systemui.recents.events.EventBus;
 * This is sent when the stack action button should be hidden.
 */
public class HideStackActionButtonEvent extends EventBus.Event {
    // Simple event

    // Whether or not to translate the stack action button when hiding it
    public final boolean translate;

    public HideStackActionButtonEvent() {
        this(true);
    }

    public HideStackActionButtonEvent(boolean translate) {
        this.translate = translate;
    }
}
+18 −12
Original line number Diff line number Diff line
@@ -174,8 +174,6 @@ public class RecentsView extends FrameLayout {
                        ? R.layout.recents_low_ram_stack_action_button
                        : R.layout.recents_stack_action_button,
                    this, false);
            mStackActionButton.setOnClickListener(
                    v -> EventBus.getDefault().send(new DismissAllTaskViewsEvent()));

            mStackButtonShadowRadius = mStackActionButton.getShadowRadius();
            mStackButtonShadowDistance = new PointF(mStackActionButton.getShadowDx(),
@@ -572,7 +570,7 @@ public class RecentsView extends FrameLayout {
        mTransitionHelper.launchTaskFromRecents(getStack(), event.task, mTaskStackView,
                event.taskView, event.screenPinningRequested, event.targetTaskStack);
        if (Recents.getConfiguration().isLowRamDevice) {
            hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, false /* translate */);
            EventBus.getDefault().send(new HideStackActionButtonEvent(false /* translate */));
        }
    }

@@ -580,7 +578,7 @@ public class RecentsView extends FrameLayout {
        int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
        if (RecentsDebugFlags.Static.EnableStackActionButton) {
            // Hide the stack action button
            hideStackActionButton(taskViewExitToHomeDuration, false /* translate */);
            EventBus.getDefault().send(new HideStackActionButtonEvent());
        }
        animateBackgroundScrim(0f, taskViewExitToHomeDuration);

@@ -741,13 +739,10 @@ public class RecentsView extends FrameLayout {
            animateBackgroundScrim(getOpaqueScrimAlpha(),
                    TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
        }
        if (Recents.getConfiguration().isLowRamDevice && mEmptyView.getVisibility() != View.VISIBLE) {
            showStackActionButton(SHOW_STACK_ACTION_BUTTON_DURATION, false /* translate */);
        }
    }

    public final void onBusEvent(AllTaskViewsDismissedEvent event) {
        hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
        EventBus.getDefault().send(new HideStackActionButtonEvent());
    }

    public final void onBusEvent(DismissAllTaskViewsEvent event) {
@@ -795,7 +790,8 @@ public class RecentsView extends FrameLayout {
            mStackActionButton.setVisibility(View.VISIBLE);
            mStackActionButton.setAlpha(0f);
            if (translate) {
                mStackActionButton.setTranslationY(-mStackActionButton.getMeasuredHeight() * 0.25f);
                mStackActionButton.setTranslationY(mStackActionButton.getMeasuredHeight() *
                        (Recents.getConfiguration().isLowRamDevice ? 1 : -0.25f));
            } else {
                mStackActionButton.setTranslationY(0f);
            }
@@ -841,8 +837,8 @@ public class RecentsView extends FrameLayout {

        if (mStackActionButton.getVisibility() == View.VISIBLE) {
            if (translate) {
                mStackActionButton.animate()
                    .translationY(-mStackActionButton.getMeasuredHeight() * 0.25f);
                mStackActionButton.animate().translationY(mStackActionButton.getMeasuredHeight()
                        * (Recents.getConfiguration().isLowRamDevice ? 1 : -0.25f));
            }
            mStackActionButton.animate()
                    .alpha(0f)
@@ -954,7 +950,7 @@ public class RecentsView extends FrameLayout {
    /**
     * @return the bounds of the stack action button.
     */
    private Rect getStackActionButtonBoundsFromStackLayout() {
    Rect getStackActionButtonBoundsFromStackLayout() {
        Rect actionButtonRect = new Rect(mTaskStackView.mLayoutAlgorithm.getStackActionButtonRect());
        int left, top;
        if (Recents.getConfiguration().isLowRamDevice) {
@@ -976,6 +972,16 @@ public class RecentsView extends FrameLayout {
        return actionButtonRect;
    }

    View getStackActionButton() {
        return mStackActionButton;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        super.requestDisallowInterceptTouchEvent(disallowIntercept);
        mTouchHandler.cancelStackActionButtonClick();
    }

    public void dump(String prefix, PrintWriter writer) {
        String innerPrefix = prefix + "  ";
        String id = Integer.toHexString(System.identityHashCode(this));
+39 −8
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.Rect;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewDebug;

@@ -31,6 +32,8 @@ import com.android.systemui.recents.Recents;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
@@ -99,8 +102,7 @@ public class RecentsViewTouchHandler {

    /** Touch preprocessing for handling below */
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        handleTouchEvent(ev);
        return mDragRequested;
        return handleTouchEvent(ev) || mDragRequested;
    }

    /** Handles touch events once we have intercepted them */
@@ -183,22 +185,47 @@ public class RecentsViewTouchHandler {
        }
    }

    void cancelStackActionButtonClick() {
        mRv.getStackActionButton().setPressed(false);
    }

    private boolean isWithinStackActionButton(float x, float y) {
        Rect rect = mRv.getStackActionButtonBoundsFromStackLayout();
        return mRv.getStackActionButton().getVisibility() == View.VISIBLE &&
                mRv.getStackActionButton().pointInView(x - rect.left, y - rect.top, 0 /* slop */);
    }

    private void changeStackActionButtonDrawableHotspot(float x, float y) {
        Rect rect = mRv.getStackActionButtonBoundsFromStackLayout();
        mRv.getStackActionButton().drawableHotspotChanged(x - rect.left, y - rect.top);
    }

    /**
     * Handles dragging touch events
     */
    private void handleTouchEvent(MotionEvent ev) {
    private boolean handleTouchEvent(MotionEvent ev) {
        int action = ev.getActionMasked();
        boolean consumed = false;
        float evX = ev.getX();
        float evY = ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mDownPos.set((int) ev.getX(), (int) ev.getY());
                mDownPos.set((int) evX, (int) evY);
                mDeviceId = ev.getDeviceId();

                if (isWithinStackActionButton(evX, evY)) {
                    changeStackActionButtonDrawableHotspot(evX, evY);
                    mRv.getStackActionButton().setPressed(true);
                }
                break;
            case MotionEvent.ACTION_MOVE: {
                float evX = ev.getX();
                float evY = ev.getY();
                float x = evX - mTaskViewOffset.x;
                float y = evY - mTaskViewOffset.y;

                if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) {
                    changeStackActionButtonDrawableHotspot(evX, evY);
                }

                if (mDragRequested) {
                    if (!mIsDragging) {
                        mIsDragging = Math.hypot(evX - mDownPos.x, evY - mDownPos.y) > mDragSlop;
@@ -232,9 +259,7 @@ public class RecentsViewTouchHandler {
                            EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask,
                                    currentDropTarget));
                        }

                    }

                    mTaskView.setTranslationX(x);
                    mTaskView.setTranslationY(y);
                }
@@ -242,6 +267,11 @@ public class RecentsViewTouchHandler {
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) {
                    EventBus.getDefault().send(new DismissAllTaskViewsEvent());
                    consumed = true;
                }
                cancelStackActionButtonClick();
                if (mDragRequested) {
                    boolean cancelled = action == MotionEvent.ACTION_CANCEL;
                    if (cancelled) {
@@ -254,5 +284,6 @@ public class RecentsViewTouchHandler {
                mDeviceId = -1;
            }
        }
        return consumed;
    }
}
+14 −2
Original line number Diff line number Diff line
@@ -1768,8 +1768,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        }

        // In grid layout, the stack action button always remains visible.
        if (mEnterAnimationComplete && !useGridLayout() &&
                !Recents.getConfiguration().isLowRamDevice) {
        if (mEnterAnimationComplete && !useGridLayout()) {
            if (Recents.getConfiguration().isLowRamDevice) {
                // Show stack button when user drags down to show older tasks on low ram devices
                if (mStack.getTaskCount() > 0 && !mStackActionButtonVisible
                        && mTouchHandler.mIsScrolling && curScroll - prevScroll < 0) {
                    // Going up
                    EventBus.getDefault().send(
                            new ShowStackActionButtonEvent(true /* translate */));
                }
                return;
            }
            if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                    curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
                    mStack.getTaskCount() > 0) {
@@ -1956,6 +1965,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        // Remove the task from the stack
        mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
        EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
        if (mStack.getTaskCount() > 0 && Recents.getConfiguration().isLowRamDevice) {
            EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
        }

        MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
                event.task.key.getComponent().toString());