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

Commit c81082b7 authored by Sid Soundararajan's avatar Sid Soundararajan
Browse files

Improve Animation Calculations to remove Jank

Add animations to back button press path.

Add scroll for launches of unfocused apps.

Part 1 of 2 to fix:

b/27876144

Change-Id: I1ac345dffb06d7926558a4087b07061ee4be731b
parent 15971223
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -31,8 +31,10 @@ import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.model.ThumbnailData;
import com.android.systemui.recents.tv.views.TaskCardView;

public class RecentsTvImpl extends RecentsImpl{
@@ -124,12 +126,15 @@ public class RecentsTvImpl extends RecentsImpl{
     */
    private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
            ActivityManager.RunningTaskInfo topTask) {
        Bitmap thumbnail = mThumbTransitionBitmapCache;
        Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
        if (thumbnail != null) {
        SystemServicesProxy ssp = Recents.getSystemServices();
        ThumbnailData thumbnailData = ssp.getTaskThumbnail(topTask.id);
        if (thumbnailData.thumbnail != null) {
            Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
                    rect.height(), false);
            return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
                    null, (int) rect.left, (int) rect.top,
                    (int) rect.width(), (int) rect.height(), mHandler, null);
                    thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
                    (int) rect.height(), mHandler, null);
        }
        // If both the screenshot and thumbnail fails, then just fall back to the default transition
        return getUnknownTransitionActivityOptions();
+5 −1
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@
package com.android.systemui.recents.tv.views;

import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -120,8 +122,10 @@ public class RecentsTvTransitionHelper {
        }
        try {
            Rect taskRect = taskView.getFocusedThumbnailRect();
            Bitmap thumbnail = Bitmap.createScaledBitmap(task.thumbnail, taskRect.width(),
                    taskRect.height(), false);
            WindowManagerGlobal.getWindowManagerService()
                    .overridePendingAppTransitionAspectScaledThumb(task.thumbnail, taskRect.left,
                    .overridePendingAppTransitionAspectScaledThumb(thumbnail, taskRect.left,
                            taskRect.top, taskRect.width(), taskRect.height(), callback, true);
        } catch (RemoteException e) {
            Log.w(TAG, "Failed to override transition: " + e);
+47 −17
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package com.android.systemui.recents.tv.views;
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
@@ -32,15 +35,15 @@ import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
import com.android.systemui.recents.events.activity.LaunchTvTaskEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;

import java.util.ArrayList;
import java.util.List;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;

/**
 * Top level layout of recents for TV. This will show the TaskStacks using a HorizontalGridView.
@@ -58,7 +61,7 @@ public class RecentsTvView extends FrameLayout {
    private Rect mSystemInsets = new Rect();
    private RecentsTvTransitionHelper mTransitionHelper;
    private Handler mHandler;

    private OnScrollListener mScrollListener;
    public RecentsTvView(Context context) {
        this(context, null);
    }
@@ -111,8 +114,7 @@ public class RecentsTvView extends FrameLayout {
        if (mTaskStackHorizontalView != null) {
            Task task = mTaskStackHorizontalView.getFocusedTask();
            if (task != null) {
                SystemServicesProxy ssp = Recents.getSystemServices();
                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
                launchTaskFomRecents(task);
                return true;
            }
        }
@@ -125,25 +127,53 @@ public class RecentsTvView extends FrameLayout {
            TaskStack stack = mTaskStackHorizontalView.getStack();
            Task task = stack.getLaunchTarget();
            if (task != null) {
                SystemServicesProxy ssp = Recents.getSystemServices();
                ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
                launchTaskFomRecents(task);
                return true;
            }
        }
        return false;
    }

    /** Launches a given task. */
    public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
        if (mTaskStackHorizontalView != null) {
            // Iterate the stack views and try and find the given task.
            if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
    /**
     * Launch the given task from recents with animation. If the task is not focused, this will
     * attempt to scroll to focus the task before launching.
     * @param task
     */
    private void launchTaskFomRecents(final Task task) {
        if(task != mTaskStackHorizontalView.getFocusedTask()) {
            if(mScrollListener != null) {
                mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
            }
            mScrollListener = new OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    if(newState == RecyclerView.SCROLL_STATE_IDLE) {
                        TaskCardView cardView = mTaskStackHorizontalView.getChildViewForTask(task);
                        if(cardView != null) {
                            mTransitionHelper.launchTaskFromRecents(mStack, task,
                                    mTaskStackHorizontalView, cardView, null, INVALID_STACK_ID);
                        } else {
                            // This should not happen normally. If this happens then the data in
                            // the grid view was altered during the scroll. Log error and launch
                            // task with no animation.
                            Log.e(TAG, "Card view for task : " + task + ", returned null.");
                            SystemServicesProxy ssp = Recents.getSystemServices();
                            ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
                return true;
                        }
                        mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
                    }
                }
            };
            mTaskStackHorizontalView.addOnScrollListener(mScrollListener);
            mTaskStackHorizontalView.setSelectedPositionSmooth(
                    ((TaskStackHorizontalViewAdapter) mTaskStackHorizontalView.getAdapter())
                            .getPositionOfTask(task));
        } else {
            mTransitionHelper.launchTaskFromRecents(mStack, task, mTaskStackHorizontalView,
                    mTaskStackHorizontalView.getChildViewForTask(task), null,
                    INVALID_STACK_ID);
        }
        return false;
    }

    /**
+0 −7
Original line number Diff line number Diff line
@@ -91,13 +91,6 @@ public class TaskCardView extends LinearLayout {
    public Rect getFocusedThumbnailRect() {
        Rect r = new Rect();
        mThumbnailView.getGlobalVisibleRect(r);
        TypedValue out = new TypedValue();
        getContext().getResources().getValue(R.integer.selected_scale, out, true);
        float deltaScale = (out.getFloat() - 1.0f) / 2;
        r.set((int) (r.left - r.left * deltaScale),
                (int) (r.top - r.top * deltaScale),
                (int) (r.right + r.right * deltaScale),
                (int) (r.bottom + r.bottom * deltaScale));
        return r;
    }

+5 −0
Original line number Diff line number Diff line
@@ -131,4 +131,9 @@ public class TaskStackHorizontalViewAdapter extends
        mTaskList.remove(position);
        notifyItemRemoved(position);
    }

    public int getPositionOfTask(Task task) {
        int position = mTaskList.indexOf(task);
        return (position >= 0) ? position : 0;
    }
}