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

Commit 3c728fe6 authored by Jim Miller's avatar Jim Miller
Browse files

Fix 4689527: Improved curation for Recents + misc cleanup

This sets a threshhold for both the curation animation as well as the
snap back animation.  It now limits these to 500ms and 250ms, respectively.

Cleaned up misc log spew.

Updated after review.

Change-Id: Ie11a2fc4556b396257c33c3ebd7513c4c220ff95
parent 4a6d113b
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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.systemui.recent;

public class Constants {
    static final int MAX_ESCAPE_ANIMATION_DURATION = 500; // in ms
    static final float FADE_CONSTANT = 0.5f; // unitless
    static final int SNAP_BACK_DURATION = 250; // in ms
    static final int ESCAPE_VELOCITY = 100; // speed of item required to "curate" it in dp/s
}
+27 −13
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.RectF;
import android.util.AttributeSet;
@@ -33,6 +34,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.HorizontalScrollView;
@@ -42,12 +44,9 @@ import com.android.systemui.R;

public class RecentsHorizontalScrollView extends HorizontalScrollView
        implements View.OnClickListener, View.OnTouchListener {
    private static final float FADE_CONSTANT = 0.5f;
    private static final int SNAP_BACK_DURATION = 250;
    private static final int ESCAPE_VELOCITY = 100; // speed of item required to "curate" it
    private static final String TAG = RecentsPanelView.TAG;
    private static final float THRESHHOLD = 50;
    private static final boolean DEBUG_INVALIDATE = false;
    private static final String TAG = RecentsPanelView.TAG;
    private static final boolean DEBUG = RecentsPanelView.DEBUG;
    private LinearLayout mLinearLayout;
    private ActivityDescriptionAdapter mAdapter;
    private RecentsCallback mCallback;
@@ -56,6 +55,8 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
    private float mLastY;
    private boolean mDragging;
    private VelocityTracker mVelocityTracker;
    private float mDensityScale;
    private float mPagingTouchSlop;

    public RecentsHorizontalScrollView(Context context) {
        this(context, null);
@@ -63,6 +64,8 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView

    public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
        mDensityScale = getResources().getDisplayMetrics().density;
        mPagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
    }

    private int scrollPositionOfMostRecent() {
@@ -101,7 +104,8 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView

            case MotionEvent.ACTION_MOVE:
                float delta = ev.getY() - mLastY;
                if (Math.abs(delta) > THRESHHOLD) {
                if (DEBUG) Log.v(TAG, "ACTION_MOVE : " + delta);
                if (Math.abs(delta) > mPagingTouchSlop) {
                    mDragging = true;
                }
                break;
@@ -114,13 +118,14 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
    }

    private float getAlphaForOffset(View view, float thumbHeight) {
        final float fadeHeight = FADE_CONSTANT * thumbHeight;
        final float fadeHeight = Constants.FADE_CONSTANT * thumbHeight;
        float result = 1.0f;
        if (view.getY() >= thumbHeight) {
            result = 1.0f - (view.getY() - thumbHeight) / fadeHeight;
        } else if (view.getY() < 0.0f) {
            result = 1.0f + (thumbHeight + view.getY()) / fadeHeight;
        }
        if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
        return result;
    }

@@ -155,12 +160,13 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
                    final float velocityY = velocityTracker.getYVelocity();
                    final float curY = animView.getY();
                    final float newY = (velocityY >= 0.0f ? 1 : -1) * animView.getHeight();

                    final float maxVelocity = Constants.ESCAPE_VELOCITY * mDensityScale;
                    if (Math.abs(velocityY) > Math.abs(velocityX)
                            && Math.abs(velocityY) > ESCAPE_VELOCITY
                            && Math.abs(velocityY) > maxVelocity
                            && (velocityY >= 0.0f) == (animView.getY() >= 0)) {
                        final long duration =
                        long duration =
                            (long) (Math.abs(newY - curY) * 1000.0f / Math.abs(velocityY));
                        duration = Math.min(duration, Constants.MAX_ESCAPE_ANIMATION_DURATION);
                        anim = ObjectAnimator.ofFloat(animView, "y", curY, newY);
                        anim.setInterpolator(new LinearInterpolator());
                        final int swipeDirection = animView.getY() >= 0.0f ?
@@ -181,9 +187,10 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
                        });
                        anim.setDuration(duration);
                    } else { // Animate back to position
                        final long duration = Math.abs(velocityY) > 0.0f ?
                        long duration = Math.abs(velocityY) > 0.0f ?
                                (long) (Math.abs(newY - curY) * 1000.0f / Math.abs(velocityY))
                                : SNAP_BACK_DURATION;
                                : Constants.SNAP_BACK_DURATION;
                        duration = Math.min(duration, Constants.SNAP_BACK_DURATION);
                        anim = ObjectAnimator.ofFloat(animView, "y", animView.getY(), 0.0f);
                        anim.setInterpolator(new DecelerateInterpolator(2.0f));
                        anim.setDuration(duration);
@@ -241,8 +248,15 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
        setOverScrollEffectPadding(leftPadding, 0);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDensityScale = getResources().getDisplayMetrics().density;
        mPagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
    }

    private void setOverScrollEffectPadding(int leftPadding, int i) {
        // TODO Add to RecentsHorizontalScrollView
        // TODO Add to (Vertical)ScrollView
    }

    @Override
+4 −4
Original line number Diff line number Diff line
@@ -417,11 +417,11 @@ public class RecentsPanelView extends RelativeLayout
        mActivityDescriptions = getRecentTasks();
        mListAdapter.notifyDataSetInvalidated();
        if (mActivityDescriptions.size() > 0) {
            Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps");
            if (DEBUG) Log.v(TAG, "Showing " + mActivityDescriptions.size() + " apps");
            updateUiElements(getResources().getConfiguration());
        } else {
            // Immediately hide this panel
            Log.v(TAG, "Nothing to show");
            if (DEBUG) Log.v(TAG, "Nothing to show");
            hide(false);
        }
    }
@@ -436,7 +436,7 @@ public class RecentsPanelView extends RelativeLayout
            paint.setAlpha(255);
            final int srcWidth = thumbnail.getWidth();
            final int srcHeight = thumbnail.getHeight();
            Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight);
            if (DEBUG) Log.v(TAG, "Source thumb: " + srcWidth + "x" + srcHeight);
            canvas.drawBitmap(thumbnail,
                    new Rect(0, 0, srcWidth-1, srcHeight-1),
                    new RectF(mGlowBitmapPaddingLeftPx, mGlowBitmapPaddingTopPx,
@@ -486,7 +486,7 @@ public class RecentsPanelView extends RelativeLayout

    public void handleSwipe(View view, int direction) {
        ActivityDescription ad = ((ViewHolder) view.getTag()).activityDescription;
        Log.v(TAG, "Jettison " + ad.label);
        if (DEBUG) Log.v(TAG, "Jettison " + ad.label);
        mActivityDescriptions.remove(ad);

        // Handled by widget containers to enable LayoutTransitions properly
+25 −13
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.RectF;
import android.util.AttributeSet;
@@ -33,6 +34,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
@@ -42,12 +44,9 @@ import com.android.systemui.R;

public class RecentsVerticalScrollView extends ScrollView
        implements View.OnClickListener, View.OnTouchListener {
    private static final float FADE_CONSTANT = 0.5f;
    private static final int SNAP_BACK_DURATION = 250;
    private static final int ESCAPE_VELOCITY = 100; // speed of item required to "curate" it
    private static final String TAG = RecentsPanelView.TAG;
    private static final float THRESHHOLD = 50;
    private static final boolean DEBUG_INVALIDATE = false;
    private static final boolean DEBUG = RecentsPanelView.DEBUG;
    private LinearLayout mLinearLayout;
    private ActivityDescriptionAdapter mAdapter;
    private RecentsCallback mCallback;
@@ -56,6 +55,8 @@ public class RecentsVerticalScrollView extends ScrollView
    private float mLastX;
    private boolean mDragging;
    private VelocityTracker mVelocityTracker;
    private float mDensityScale;
    private float mPagingTouchSlop;

    public RecentsVerticalScrollView(Context context) {
        this(context, null);
@@ -63,6 +64,8 @@ public class RecentsVerticalScrollView extends ScrollView

    public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
        mDensityScale = getResources().getDisplayMetrics().density;
        mPagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
    }

    private int scrollPositionOfMostRecent() {
@@ -101,8 +104,8 @@ public class RecentsVerticalScrollView extends ScrollView

            case MotionEvent.ACTION_MOVE:
                float delta = ev.getX() - mLastX;
                Log.v(TAG, "ACTION_MOVE : " + delta);
                if (Math.abs(delta) > THRESHHOLD) {
                if (DEBUG) Log.v(TAG, "ACTION_MOVE : " + delta);
                if (Math.abs(delta) > mPagingTouchSlop) {
                    mDragging = true;
                }
                break;
@@ -115,14 +118,14 @@ public class RecentsVerticalScrollView extends ScrollView
    }

    private float getAlphaForOffset(View view, float thumbWidth) {
        final float fadeWidth = FADE_CONSTANT * thumbWidth;
        final float fadeWidth = Constants.FADE_CONSTANT * thumbWidth;
        float result = 1.0f;
        if (view.getX() >= thumbWidth) {
            result = 1.0f - (view.getX() - thumbWidth) / fadeWidth;
        } else if (view.getX() < 0.0f) {
            result = 1.0f + (thumbWidth + view.getX()) / fadeWidth;
        }
        Log.v(TAG, "FADE AMOUNT: " + result);
        if (DEBUG) Log.v(TAG, "FADE AMOUNT: " + result);
        return result;
    }

@@ -157,12 +160,13 @@ public class RecentsVerticalScrollView extends ScrollView
                    final float velocityY = velocityTracker.getYVelocity();
                    final float curX = animView.getX();
                    final float newX = (velocityX >= 0.0f ? 1 : -1) * animView.getWidth();

                    final float maxVelocity = Constants.ESCAPE_VELOCITY * mDensityScale;
                    if (Math.abs(velocityX) > Math.abs(velocityY)
                            && Math.abs(velocityX) > ESCAPE_VELOCITY
                            && Math.abs(velocityX) > maxVelocity
                            && (velocityX > 0.0f) == (animView.getX() >= 0)) {
                        final long duration =
                        long duration =
                            (long) (Math.abs(newX-curX) * 1000.0f / Math.abs(velocityX));
                        duration = Math.min(duration, Constants.MAX_ESCAPE_ANIMATION_DURATION);
                        anim = ObjectAnimator.ofFloat(animView, "x", curX, newX);
                        anim.setInterpolator(new LinearInterpolator());
                        final int swipeDirection = animView.getX() >= 0.0f ?
@@ -183,9 +187,10 @@ public class RecentsVerticalScrollView extends ScrollView
                        });
                        anim.setDuration(duration);
                    } else { // Animate back to position
                        final long duration = Math.abs(velocityX) > 0.0f ?
                        long duration = Math.abs(velocityX) > 0.0f ?
                                (long) (Math.abs(newX-curX) * 1000.0f / Math.abs(velocityX))
                                : SNAP_BACK_DURATION;
                                : Constants.SNAP_BACK_DURATION;
                        duration = Math.min(duration, Constants.SNAP_BACK_DURATION);
                        anim = ObjectAnimator.ofFloat(animView, "x", animView.getX(), 0.0f);
                        anim.setInterpolator(new DecelerateInterpolator(4.0f));
                        anim.setDuration(duration);
@@ -243,6 +248,13 @@ public class RecentsVerticalScrollView extends ScrollView
        setOverScrollEffectPadding(leftPadding, 0);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDensityScale = getResources().getDisplayMetrics().density;
        mPagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
    }

    private void setOverScrollEffectPadding(int leftPadding, int i) {
        // TODO Add to (Vertical)ScrollView
    }