diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java index fb62affd6ceea..7ed1f7fe50821 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java index a69f8a2cf3991..fb1127ed18597 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java index 9da8eed3996b0..8868acc8b61fe 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java @@ -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) { - SystemServicesProxy ssp = Recents.getSystemServices(); - ssp.startActivityFromRecents(getContext(), task.key, task.title, null); - return true; + /** + * 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); + } + 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; } /** diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java index d605748918999..ea2b92f62ccfc 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java index 378871934f704..97712ea9ce863 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java @@ -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; + } }