Fixing crash when trying to reset focused task after removing task.
- Moving the focused state back into the stack, since the task view is transient and can be rebound. Also ensuring that we update the task view focus state as we return and pick up views from the view pool - Fixing issue where going back from recents would not go back home - Properly calculating the task visibility (regression) Bug: 25975225 Change-Id: Ica861f0d8996e4e254e875199a2d704a65bf8e58
This commit is contained in:
@@ -283,6 +283,20 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses recents back to the launch target task.
|
||||
*/
|
||||
boolean dismissRecentsToLaunchTargetTaskOrHome() {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
|
||||
// If we have a focused Task, launch that Task now
|
||||
if (mRecentsView.launchPreviousTask()) return true;
|
||||
// If none of the other cases apply, then just go Home
|
||||
dismissRecentsToHome(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses recents if we are already visible and the intent is to toggle the recents view.
|
||||
*/
|
||||
@@ -566,9 +580,8 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (!dismissHistory()) {
|
||||
dismissRecentsToFocusedTaskOrHome();
|
||||
}
|
||||
// Back behaves like the recents button so just trigger a toggle event
|
||||
EventBus.getDefault().send(new ToggleRecentsEvent());
|
||||
}
|
||||
|
||||
/**** RecentsResizeTaskDialog ****/
|
||||
@@ -584,7 +597,12 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
|
||||
public final void onBusEvent(ToggleRecentsEvent event) {
|
||||
if (!dismissHistory()) {
|
||||
dismissRecentsToFocusedTaskOrHome();
|
||||
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
|
||||
if (launchState.launchedFromHome) {
|
||||
dismissRecentsToHome(true);
|
||||
} else {
|
||||
dismissRecentsToLaunchTargetTaskOrHome();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -199,8 +199,11 @@ public class TaskStack {
|
||||
/** Task stack callbacks */
|
||||
public interface TaskStackCallbacks {
|
||||
/* Notifies when a task has been removed from the stack */
|
||||
void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
|
||||
Task newFrontMostTask);
|
||||
void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
|
||||
boolean wasFrontMostTask, Task newFrontMostTask);
|
||||
|
||||
/* Notifies when a task has been removed from the history */
|
||||
void onHistoryTaskRemoved(TaskStack stack, Task removedTask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,6 +385,7 @@ public class TaskStack {
|
||||
public void removeTask(Task t) {
|
||||
if (mStackTaskList.contains(t)) {
|
||||
boolean wasFrontMostTask = (getStackFrontMostTask() == t);
|
||||
int removedTaskIndex = indexOfStackTask(t);
|
||||
removeTaskImpl(mStackTaskList, t);
|
||||
Task newFrontMostTask = getStackFrontMostTask();
|
||||
if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) {
|
||||
@@ -389,13 +393,14 @@ public class TaskStack {
|
||||
}
|
||||
if (mCb != null) {
|
||||
// Notify that a task has been removed
|
||||
mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask);
|
||||
mCb.onStackTaskRemoved(this, t, removedTaskIndex, wasFrontMostTask,
|
||||
newFrontMostTask);
|
||||
}
|
||||
} else if (mHistoryTaskList.contains(t)) {
|
||||
removeTaskImpl(mHistoryTaskList, t);
|
||||
if (mCb != null) {
|
||||
// Notify that a task has been removed
|
||||
mCb.onStackTaskRemoved(this, t, false, null);
|
||||
mCb.onHistoryTaskRemoved(this, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,12 +308,6 @@ public class RecentsTransitionHelper {
|
||||
*/
|
||||
private static AppTransitionAnimationSpec composeAnimationSpec(TaskView taskView,
|
||||
TaskViewTransform transform, boolean addHeaderBitmap) {
|
||||
// Disable any focused state before we draw the header
|
||||
// Upfront the processing of the thumbnail
|
||||
if (taskView.isFocusedTask()) {
|
||||
taskView.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
|
||||
}
|
||||
|
||||
Bitmap b = null;
|
||||
if (addHeaderBitmap) {
|
||||
float scale = transform.scale;
|
||||
|
||||
@@ -213,6 +213,21 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Launches the task that recents was launched from if possible */
|
||||
public boolean launchPreviousTask() {
|
||||
if (mTaskStackView != null) {
|
||||
TaskStack stack = mTaskStackView.getStack();
|
||||
Task task = stack.getLaunchTarget();
|
||||
if (task != null) {
|
||||
TaskView taskView = mTaskStackView.getChildViewForTask(task);
|
||||
onTaskViewClicked(mTaskStackView, taskView, stack, task, false, null,
|
||||
INVALID_STACK_ID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Launches a given task. */
|
||||
public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
|
||||
if (mTaskStackView != null) {
|
||||
@@ -471,9 +486,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
|
||||
|
||||
// Remove the task after it is docked
|
||||
if (event.taskView.isFocusedTask()) {
|
||||
mTaskStackView.resetFocusedTask();
|
||||
}
|
||||
event.taskView.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(150)
|
||||
|
||||
@@ -658,7 +658,8 @@ public class TaskStackLayoutAlgorithm {
|
||||
transformOut.rect.set(mTaskRect);
|
||||
transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
|
||||
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
|
||||
transformOut.visible = true;
|
||||
transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
|
||||
(frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
|
||||
transformOut.clipBottom = 0;
|
||||
transformOut.clipRight = 0;
|
||||
transformOut.thumbnailScale = 1f;
|
||||
|
||||
@@ -280,7 +280,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
/** Resets this TaskStackView for reuse. */
|
||||
void reset() {
|
||||
// Reset the focused task
|
||||
resetFocusedTask();
|
||||
resetFocusedTask(getFocusedTask());
|
||||
|
||||
// Return all the views to the pool
|
||||
List<TaskView> taskViews = getTaskViews();
|
||||
@@ -426,7 +426,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// Return all the invisible children to the pool
|
||||
mTmpTaskViewMap.clear();
|
||||
List<TaskView> taskViews = getTaskViews();
|
||||
boolean wasLastFocusedTaskAnimated = false;
|
||||
int lastFocusedTaskIndex = -1;
|
||||
int taskViewCount = taskViews.size();
|
||||
for (int i = taskViewCount - 1; i >= 0; i--) {
|
||||
@@ -437,10 +436,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
visibleStackRange[1] <= taskIndex && taskIndex <= visibleStackRange[0]) {
|
||||
mTmpTaskViewMap.put(task, tv);
|
||||
} else {
|
||||
if (mTouchExplorationEnabled && tv.isFocusedTask()) {
|
||||
wasLastFocusedTaskAnimated = tv.isFocusAnimated();
|
||||
if (mTouchExplorationEnabled) {
|
||||
lastFocusedTaskIndex = taskIndex;
|
||||
resetFocusedTask();
|
||||
resetFocusedTask(task);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "returning to pool: " + task.key);
|
||||
@@ -467,6 +465,21 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
if (mLayersDisabled) {
|
||||
tv.disableLayersForOneFrame();
|
||||
}
|
||||
} else {
|
||||
// Reattach it in the right z order
|
||||
detachViewFromParent(tv);
|
||||
int insertIndex = -1;
|
||||
int taskIndex = mStack.indexOfStackTask(task);
|
||||
taskViews = getTaskViews();
|
||||
taskViewCount = taskViews.size();
|
||||
for (int j = 0; j < taskViewCount; j++) {
|
||||
Task tvTask = taskViews.get(j).getTask();
|
||||
if (taskIndex <= mStack.indexOfStackTask(tvTask)) {
|
||||
insertIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
attachViewToParent(tv, insertIndex, tv.getLayoutParams());
|
||||
}
|
||||
|
||||
// Animate the task into place
|
||||
@@ -474,21 +487,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
mStackViewsAnimationDuration, mFastOutSlowInInterpolator,
|
||||
mRequestUpdateClippingListener);
|
||||
|
||||
// Reattach it in the right z order
|
||||
detachViewFromParent(tv);
|
||||
int insertIndex = -1;
|
||||
int taskIndex = mStack.indexOfStackTask(task);
|
||||
taskViews = getTaskViews();
|
||||
taskViewCount = taskViews.size();
|
||||
for (int j = 0; j < taskViewCount; j++) {
|
||||
Task tvTask = taskViews.get(j).getTask();
|
||||
if (taskIndex < mStack.indexOfStackTask(tvTask)) {
|
||||
insertIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
attachViewToParent(tv, insertIndex, tv.getLayoutParams());
|
||||
|
||||
// Update the task views list after adding the new task view
|
||||
updateTaskViewsList();
|
||||
}
|
||||
@@ -538,9 +536,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// Update the focus if the previous focused task was returned to the view pool
|
||||
if (lastFocusedTaskIndex != -1) {
|
||||
if (lastFocusedTaskIndex < visibleStackRange[1]) {
|
||||
setFocusedTask(visibleStackRange[1], false, wasLastFocusedTaskAnimated);
|
||||
setFocusedTask(visibleStackRange[1], false /* animated */,
|
||||
true /* requestViewFocus */);
|
||||
} else {
|
||||
setFocusedTask(visibleStackRange[0], false, wasLastFocusedTaskAnimated);
|
||||
setFocusedTask(visibleStackRange[0], false /* animated */,
|
||||
true /* requestViewFocus */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
if (mFocusedTaskIndex != -1) {
|
||||
Task focusedTask = mStack.getStackTasks().get(mFocusedTaskIndex);
|
||||
if (focusedTask != newFocusedTask) {
|
||||
resetFocusedTask();
|
||||
resetFocusedTask(focusedTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,10 +777,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
/**
|
||||
* Resets the focused task.
|
||||
*/
|
||||
void resetFocusedTask() {
|
||||
if (mFocusedTaskIndex != -1) {
|
||||
Task t = mStack.getStackTasks().get(mFocusedTaskIndex);
|
||||
TaskView tv = getChildViewForTask(t);
|
||||
void resetFocusedTask(Task task) {
|
||||
if (task != null) {
|
||||
TaskView tv = getChildViewForTask(task);
|
||||
if (tv != null) {
|
||||
tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
|
||||
}
|
||||
@@ -1183,8 +1182,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
/**** TaskStackCallbacks Implementation ****/
|
||||
|
||||
@Override
|
||||
public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
|
||||
Task newFrontMostTask) {
|
||||
public void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
|
||||
boolean wasFrontMostTask, Task newFrontMostTask) {
|
||||
if (mFocusedTaskIndex == removedTaskIndex) {
|
||||
resetFocusedTask(removedTask);
|
||||
}
|
||||
|
||||
if (!removedTask.isFreeformTask()) {
|
||||
// Remove the view associated with this task, we can't rely on updateTransforms
|
||||
// to work here because the task is no longer in the list
|
||||
@@ -1260,6 +1263,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHistoryTaskRemoved(TaskStack stack, Task removedTask) {
|
||||
// To be implemented
|
||||
}
|
||||
|
||||
/**** ViewPoolConsumer Implementation ****/
|
||||
|
||||
@Override
|
||||
@@ -1282,6 +1290,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// Reset the view properties
|
||||
tv.resetViewProperties();
|
||||
|
||||
// Reset the focused view state
|
||||
tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
|
||||
|
||||
// Reset the clip state of the task view
|
||||
tv.setClipViewInStack(false);
|
||||
}
|
||||
@@ -1332,6 +1343,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
tv.setCallbacks(this);
|
||||
tv.setTouchEnabled(true);
|
||||
tv.setClipViewInStack(true);
|
||||
if (mFocusedTaskIndex == taskIndex) {
|
||||
tv.setFocusedState(true, false /* animated */, false /* requestViewFocus */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1553,11 +1567,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
private void removeTaskViewFromStack(TaskView tv) {
|
||||
Task task = tv.getTask();
|
||||
|
||||
// Reset the previously focused task before it is removed from the stack
|
||||
if (tv.isFocusedTask()) {
|
||||
resetFocusedTask();
|
||||
}
|
||||
|
||||
// Announce for accessibility
|
||||
tv.announceForAccessibility(getContext().getString(
|
||||
R.string.accessibility_recents_item_dismissed, tv.getTask().activityLabel));
|
||||
|
||||
@@ -78,8 +78,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
|
||||
|
||||
Task mTask;
|
||||
boolean mTaskDataLoaded;
|
||||
boolean mIsFocused;
|
||||
boolean mIsFocusAnimated;
|
||||
boolean mClipViewInStack;
|
||||
AnimateableViewBounds mViewBounds;
|
||||
private AnimatorSet mClipAnimation;
|
||||
@@ -640,14 +638,12 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
|
||||
public void setFocusedState(boolean isFocused, boolean animated, boolean requestViewFocus) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setFocusedState: " + mTask.activityLabel + " focused: " + isFocused +
|
||||
" mIsFocused: " + mIsFocused + " animated: " + animated +
|
||||
" requestViewFocus: " + requestViewFocus + " isFocused(): " + isFocused() +
|
||||
" animated: " + animated + " requestViewFocus: " + requestViewFocus +
|
||||
" isFocused(): " + isFocused() +
|
||||
" isAccessibilityFocused(): " + isAccessibilityFocused());
|
||||
}
|
||||
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
mIsFocused = isFocused;
|
||||
mIsFocusAnimated = animated;
|
||||
mHeaderView.onTaskViewFocusChanged(isFocused, animated);
|
||||
if (isFocused) {
|
||||
if (requestViewFocus && !isFocused()) {
|
||||
@@ -663,20 +659,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we have explicitly been focused.
|
||||
*/
|
||||
public boolean isFocusedTask() {
|
||||
return mIsFocused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this focused task is animated.
|
||||
*/
|
||||
public boolean isFocusAnimated() {
|
||||
return mIsFocusAnimated;
|
||||
}
|
||||
|
||||
public void disableLayersForOneFrame() {
|
||||
mHeaderView.disableLayersForOneFrame();
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ import com.android.systemui.recents.model.Task;
|
||||
public class TaskViewHeader extends FrameLayout
|
||||
implements View.OnClickListener, View.OnLongClickListener {
|
||||
|
||||
private static final float FOCUS_TRANSLATION_Z = 4f;
|
||||
|
||||
Task mTask;
|
||||
|
||||
// Header views
|
||||
@@ -367,13 +369,14 @@ public class TaskViewHeader extends FrameLayout
|
||||
Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
|
||||
|
||||
if (focused) {
|
||||
// If we are not animating the visible state, just return
|
||||
if (!animateFocusedState) return;
|
||||
|
||||
// Bump up the translation
|
||||
mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", 8f);
|
||||
mFocusAnimator.setDuration(200);
|
||||
mFocusAnimator.start();
|
||||
if (animateFocusedState) {
|
||||
// Bump up the translation
|
||||
mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", FOCUS_TRANSLATION_Z);
|
||||
mFocusAnimator.setDuration(200);
|
||||
mFocusAnimator.start();
|
||||
} else {
|
||||
setTranslationZ(FOCUS_TRANSLATION_Z);
|
||||
}
|
||||
} else {
|
||||
if (isRunning) {
|
||||
// Restore the translation
|
||||
|
||||
Reference in New Issue
Block a user