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
This commit is contained in:
@@ -31,8 +31,10 @@ import com.android.systemui.recents.RecentsConfiguration;
|
|||||||
import com.android.systemui.recents.RecentsImpl;
|
import com.android.systemui.recents.RecentsImpl;
|
||||||
import com.android.systemui.recents.events.EventBus;
|
import com.android.systemui.recents.events.EventBus;
|
||||||
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
|
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.RecentsTaskLoader;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
|
import com.android.systemui.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.recents.tv.views.TaskCardView;
|
import com.android.systemui.recents.tv.views.TaskCardView;
|
||||||
|
|
||||||
public class RecentsTvImpl extends RecentsImpl{
|
public class RecentsTvImpl extends RecentsImpl{
|
||||||
@@ -124,12 +126,15 @@ public class RecentsTvImpl extends RecentsImpl{
|
|||||||
*/
|
*/
|
||||||
private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
|
private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
|
||||||
ActivityManager.RunningTaskInfo topTask) {
|
ActivityManager.RunningTaskInfo topTask) {
|
||||||
Bitmap thumbnail = mThumbTransitionBitmapCache;
|
|
||||||
Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
|
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,
|
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
|
||||||
null, (int) rect.left, (int) rect.top,
|
thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
|
||||||
(int) rect.width(), (int) rect.height(), mHandler, null);
|
(int) rect.height(), mHandler, null);
|
||||||
}
|
}
|
||||||
// If both the screenshot and thumbnail fails, then just fall back to the default transition
|
// If both the screenshot and thumbnail fails, then just fall back to the default transition
|
||||||
return getUnknownTransitionActivityOptions();
|
return getUnknownTransitionActivityOptions();
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
package com.android.systemui.recents.tv.views;
|
package com.android.systemui.recents.tv.views;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -120,8 +122,10 @@ public class RecentsTvTransitionHelper {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Rect taskRect = taskView.getFocusedThumbnailRect();
|
Rect taskRect = taskView.getFocusedThumbnailRect();
|
||||||
|
Bitmap thumbnail = Bitmap.createScaledBitmap(task.thumbnail, taskRect.width(),
|
||||||
|
taskRect.height(), false);
|
||||||
WindowManagerGlobal.getWindowManagerService()
|
WindowManagerGlobal.getWindowManagerService()
|
||||||
.overridePendingAppTransitionAspectScaledThumb(task.thumbnail, taskRect.left,
|
.overridePendingAppTransitionAspectScaledThumb(thumbnail, taskRect.left,
|
||||||
taskRect.top, taskRect.width(), taskRect.height(), callback, true);
|
taskRect.top, taskRect.width(), taskRect.height(), callback, true);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "Failed to override transition: " + e);
|
Log.w(TAG, "Failed to override transition: " + e);
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ package com.android.systemui.recents.tv.views;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.support.v7.widget.DefaultItemAnimator;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowInsets;
|
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.EventBus;
|
||||||
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
|
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
|
||||||
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
|
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.activity.LaunchTvTaskEvent;
|
||||||
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
|
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
|
||||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
|
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
|
||||||
|
import android.support.v7.widget.RecyclerView.OnScrollListener;
|
||||||
import java.util.ArrayList;
|
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level layout of recents for TV. This will show the TaskStacks using a HorizontalGridView.
|
* 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 Rect mSystemInsets = new Rect();
|
||||||
private RecentsTvTransitionHelper mTransitionHelper;
|
private RecentsTvTransitionHelper mTransitionHelper;
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
|
private OnScrollListener mScrollListener;
|
||||||
public RecentsTvView(Context context) {
|
public RecentsTvView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
@@ -111,8 +114,7 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
if (mTaskStackHorizontalView != null) {
|
if (mTaskStackHorizontalView != null) {
|
||||||
Task task = mTaskStackHorizontalView.getFocusedTask();
|
Task task = mTaskStackHorizontalView.getFocusedTask();
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
launchTaskFomRecents(task);
|
||||||
ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,25 +127,53 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
TaskStack stack = mTaskStackHorizontalView.getStack();
|
TaskStack stack = mTaskStackHorizontalView.getStack();
|
||||||
Task task = stack.getLaunchTarget();
|
Task task = stack.getLaunchTarget();
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
launchTaskFomRecents(task);
|
||||||
ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Launches a given task. */
|
/**
|
||||||
public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
|
* Launch the given task from recents with animation. If the task is not focused, this will
|
||||||
if (mTaskStackHorizontalView != null) {
|
* attempt to scroll to focus the task before launching.
|
||||||
// Iterate the stack views and try and find the given task.
|
* @param task
|
||||||
if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
|
*/
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
private void launchTaskFomRecents(final Task task) {
|
||||||
ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
|
if(task != mTaskStackHorizontalView.getFocusedTask()) {
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -91,13 +91,6 @@ public class TaskCardView extends LinearLayout {
|
|||||||
public Rect getFocusedThumbnailRect() {
|
public Rect getFocusedThumbnailRect() {
|
||||||
Rect r = new Rect();
|
Rect r = new Rect();
|
||||||
mThumbnailView.getGlobalVisibleRect(r);
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,4 +131,9 @@ public class TaskStackHorizontalViewAdapter extends
|
|||||||
mTaskList.remove(position);
|
mTaskList.remove(position);
|
||||||
notifyItemRemoved(position);
|
notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPositionOfTask(Task task) {
|
||||||
|
int position = mTaskList.indexOf(task);
|
||||||
|
return (position >= 0) ? position : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user