Merge changes I5c414d67,I83d74c94 into nyc-dev

am: 6195e8af1e

* commit '6195e8af1ef057dd1b8114bb560f0d620fe2a148':
  Just return the task to the pool if it is not in the current stack.
  Refactoring to update stack in onResume.
This commit is contained in:
Winson
2016-03-05 01:25:21 +00:00
committed by android-build-merger
15 changed files with 358 additions and 339 deletions

View File

@@ -513,8 +513,9 @@ public class Recents extends SystemUI
* Handle Recents activity visibility changed.
*/
public final void onBusEvent(final RecentsVisibilityChangedEvent event) {
int processUser = event.systemServicesProxy.getProcessUser();
if (event.systemServicesProxy.isSystemUser(processUser)) {
SystemServicesProxy ssp = Recents.getSystemServices();
int processUser = ssp.getProcessUser();
if (ssp.isSystemUser(processUser)) {
mImpl.onVisibilityChanged(event.applicationContext, event.visible);
} else {
postToSystemUser(new Runnable() {

View File

@@ -55,7 +55,7 @@ import com.android.systemui.recents.events.activity.IterateRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
import com.android.systemui.recents.events.activity.ShowHistoryEvent;
import com.android.systemui.recents.events.activity.TaskStackUpdatedEvent;
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -97,6 +97,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
private long mLastTabKeyEventTime;
private boolean mFinishedOnStartup;
private boolean mIgnoreAltTabRelease;
private boolean mIsVisible;
// Top level views
private RecentsView mRecentsView;
@@ -174,59 +175,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
}
};
/** Updates the set of recent tasks */
void updateRecentsTasks() {
// If AlternateRecentsComponent has preloaded a load plan, then use that to prevent
// reconstructing the task stack
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan plan = RecentsImpl.consumeInstanceLoadPlan();
if (plan == null) {
plan = loader.createLoadPlan(this);
}
// Start loading tasks according to the load plan
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!plan.hasTasks()) {
loader.preloadTasks(plan, -1, launchState.launchedFromHome);
}
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.runningTaskId = launchState.launchedToTaskId;
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
loader.loadTasks(this, plan, loadOpts);
TaskStack stack = plan.getTaskStack();
mRecentsView.setTaskStack(stack);
// Animate the SystemUI scrims into view
Task launchTarget = stack.getLaunchTarget();
int taskCount = stack.getTaskCount();
int launchTaskIndexInStack = launchTarget != null
? stack.indexOfStackTask(launchTarget)
: 0;
boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
boolean animateNavBarScrim = !launchState.launchedWhileDocking;
mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
// Keep track of whether we launched from the nav bar button or via alt-tab
if (launchState.launchedWithAltTab) {
MetricsLogger.count(this, "overview_trigger_alttab", 1);
} else {
MetricsLogger.count(this, "overview_trigger_nav_btn", 1);
}
// Keep track of whether we launched from an app or from home
if (launchState.launchedFromApp) {
MetricsLogger.count(this, "overview_source_app", 1);
// If from an app, track the stack index of the app in the stack (for affiliated tasks)
MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
} else {
MetricsLogger.count(this, "overview_source_home", 1);
}
// Keep track of the total stack task count
MetricsLogger.histogram(this, "overview_task_count", taskCount);
}
/**
* Dismisses the history view back into the stack view.
*/
@@ -345,6 +293,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
// Set the Recents layout
setContentView(R.layout.recents);
takeKeyEvents(true);
mRecentsView = (RecentsView) findViewById(R.id.recents_view);
mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
@@ -381,46 +330,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
registerReceiver(mSystemBroadcastReceiver, filter);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
@Override
protected void onStart() {
super.onStart();
// Update the recent tasks
updateRecentsTasks();
// If this is a new instance from a configuration change, then we have to manually trigger
// the enter animation state, or if recents was relaunched by AM, without going through
// the normal mechanisms
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
boolean wasLaunchedByAm = !launchState.launchedFromHome &&
!launchState.launchedFromApp;
if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
// Notify that recents is now visible
SystemServicesProxy ssp = Recents.getSystemServices();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, true));
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
mRecentsView.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
EventBus.getDefault().post(new RecentsDrawnEvent());
return true;
}
});
}
@Override
@@ -430,26 +346,91 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
}
@Override
protected void onPause() {
super.onPause();
protected void onResume() {
super.onResume();
// Stop the fast-toggle dozer
mIterateTrigger.stopDozing();
// If the Recents component has preloaded a load plan, then use that to prevent
// reconstructing the task stack
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan loadPlan = RecentsImpl.consumeInstanceLoadPlan();
if (loadPlan == null) {
loadPlan = loader.createLoadPlan(this);
}
// Start loading tasks according to the load plan
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!loadPlan.hasTasks()) {
loader.preloadTasks(loadPlan, -1, launchState.launchedFromHome);
}
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.runningTaskId = launchState.launchedToTaskId;
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
loader.loadTasks(this, loadPlan, loadOpts);
TaskStack stack = loadPlan.getTaskStack();
mRecentsView.onResume(mIsVisible, stack);
// Animate the SystemUI scrims into view
Task launchTarget = stack.getLaunchTarget();
int taskCount = stack.getTaskCount();
int launchTaskIndexInStack = launchTarget != null
? stack.indexOfStackTask(launchTarget)
: 0;
boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
boolean animateNavBarScrim = !launchState.launchedWhileDocking;
mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
// If this is a new instance from a configuration change, then we have to manually trigger
// the enter animation state, or if recents was relaunched by AM, without going through
// the normal mechanisms
boolean wasLaunchedByAm = !launchState.launchedFromHome &&
!launchState.launchedFromApp;
if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
}
mRecentsView.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
EventBus.getDefault().post(new RecentsDrawnEvent());
return true;
}
});
// Keep track of whether we launched from the nav bar button or via alt-tab
if (launchState.launchedWithAltTab) {
MetricsLogger.count(this, "overview_trigger_alttab", 1);
} else {
MetricsLogger.count(this, "overview_trigger_nav_btn", 1);
}
// Keep track of whether we launched from an app or from home
if (launchState.launchedFromApp) {
MetricsLogger.count(this, "overview_source_app", 1);
// If from an app, track the stack index of the app in the stack (for affiliated tasks)
MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
} else {
MetricsLogger.count(this, "overview_source_home", 1);
}
// Keep track of the total stack task count
MetricsLogger.histogram(this, "overview_task_count", taskCount);
// After we have resumed, set the visible state until the next onStop() call
mIsVisible = true;
}
@Override
protected void onStop() {
super.onStop();
protected void onPause() {
super.onPause();
// Reset some states
mIgnoreAltTabRelease = false;
if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
EventBus.getDefault().send(new HideHistoryEvent(false /* animate */));
}
// Notify that recents is now hidden
SystemServicesProxy ssp = Recents.getSystemServices();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, false));
mIterateTrigger.stopDozing();
// Workaround for b/22542869, if the RecentsActivity is started again, but without going
// through SystemUI, we need to reset the config launch flags to ensure that we do not
@@ -457,7 +438,20 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
launchState.reset();
}
@Override
protected void onStop() {
super.onStop();
// Only hide the history if Recents is completely hidden
if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
EventBus.getDefault().send(new HideHistoryEvent(false /* animate */));
}
// Notify that recents is now hidden
mIsVisible = false;
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
}
@@ -525,16 +519,22 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
public void onMultiWindowChanged(boolean inMultiWindow) {
super.onMultiWindowChanged(inMultiWindow);
EventBus.getDefault().send(new ConfigurationChangedEvent());
// Reload the task stack completely
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
launchOpts.loadIcons = false;
launchOpts.loadThumbnails = false;
launchOpts.onlyLoadForCache = true;
RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
loader.preloadTasks(loadPlan, -1, false);
loader.loadTasks(this, loadPlan, launchOpts);
EventBus.getDefault().send(new TaskStackUpdatedEvent(loadPlan.getTaskStack(),
inMultiWindow));
loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
loader.loadTasks(this, loadPlan, loadOpts);
mRecentsView.onResume(mIsVisible, loadPlan.getTaskStack());
EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
}
@Override

View File

@@ -602,7 +602,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
com.android.internal.R.dimen.navigation_bar_width);
mTaskBarHeight = res.getDimensionPixelSize(
R.dimen.recents_task_bar_height);
mDummyStackView = new TaskStackView(mContext, new TaskStack());
mDummyStackView = new TaskStackView(mContext);
mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
null, false);
}
@@ -615,8 +615,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
* is not already bound (can be expensive)
* @param stack the stack to initialize the stack layout with
*/
private void updateHeaderBarLayout(boolean tryAndBindSearchWidget,
TaskStack stack) {
private void updateHeaderBarLayout(boolean tryAndBindSearchWidget, TaskStack stack) {
RecentsConfiguration config = Recents.getConfiguration();
SystemServicesProxy ssp = Recents.getSystemServices();
Rect systemInsets = new Rect();
@@ -640,14 +639,15 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
mSearchBarBounds, mTaskStackBounds);
// Rebind the header bar and draw it for the transition
TaskStackLayoutAlgorithm algo = mDummyStackView.getStackAlgorithm();
TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
Rect taskStackBounds = new Rect(mTaskStackBounds);
algo.setSystemInsets(systemInsets);
stackLayout.setSystemInsets(systemInsets);
if (stack != null) {
algo.initialize(taskStackBounds,
stackLayout.initialize(taskStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
mDummyStackView.setTasks(stack, false /* notifyStackChanges */);
}
Rect taskViewBounds = algo.getUntransformedTaskViewBounds();
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
if (!taskViewBounds.equals(mLastTaskViewBounds)) {
mLastTaskViewBounds.set(taskViewBounds);
@@ -705,7 +705,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
updateHeaderBarLayout(false /* tryAndBindSearchWidget */, stack);
// Update the destination rect
mDummyStackView.updateLayoutForStack(stack);
final Task toTask = new Task();
final TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask);
ForegroundThread.getHandler().postAtFrontOfQueue(new Runnable() {
@@ -887,7 +886,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
updateHeaderBarLayout(false /* tryAndBindSearchWidget */, stack);
// Prepare the dummy stack for the transition
mDummyStackView.updateLayoutForStack(stack);
TaskStackLayoutAlgorithm.VisibilityReport stackVr =
mDummyStackView.computeStackVisibilityReport();

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2015 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.recents.events.activity;
import com.android.systemui.recents.events.EventBus;
/**
* This is sent by the activity whenever the multi-window state has changed.
*/
public class MultiWindowStateChangedEvent extends EventBus.Event {
public final boolean inMultiWindow;
public MultiWindowStateChangedEvent(boolean inMultiWindow) {
this.inMultiWindow = inMultiWindow;
}
}

View File

@@ -19,21 +19,18 @@ package com.android.systemui.recents.events.component;
import android.content.Context;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.misc.SystemServicesProxy;
/**
* This is sent when the visibility of the RecentsActivity for the current user changes.
* This is sent when the visibility of the RecentsActivity for the current user changes. Handlers
* of this event should not alter the UI, as the activity may still be visible.
*/
public class RecentsVisibilityChangedEvent extends EventBus.Event {
public final Context applicationContext;
public final SystemServicesProxy systemServicesProxy;
public final boolean visible;
public RecentsVisibilityChangedEvent(Context context, SystemServicesProxy systemServicesProxy,
boolean visible) {
public RecentsVisibilityChangedEvent(Context context, boolean visible) {
this.applicationContext = context.getApplicationContext();
this.systemServicesProxy = systemServicesProxy;
this.visible = visible;
}
}

View File

@@ -212,8 +212,7 @@ public class RecentsTaskLoadPlan {
// Initialize the stacks
mStack = new TaskStack();
mStack.setTasks(allTasks, false /* notifyStackChanges */);
mStack.createAffiliatedGroupings(mContext);
mStack.setTasks(mContext, allTasks, false /* notifyStackChanges */);
}
/**

View File

@@ -100,11 +100,7 @@ public class Task {
@Override
public String toString() {
return "Task.Key: " + id + ", "
+ "s: " + stackId + ", "
+ "u: " + userId + ", "
+ "lat: " + lastActiveTime + ", "
+ getComponent().getPackageName();
return "t" + id + ", s" + stackId + ", u" + userId;
}
private void updateHashCode() {
@@ -204,7 +200,9 @@ public class Task {
this.isDockable = isDockable;
}
/** Copies the other task. */
/**
* Copies the metadata from another task, but retains the current callbacks.
*/
public void copyFrom(Task o) {
this.key = o.key;
this.group = o.group;
@@ -300,11 +298,6 @@ public class Task {
@Override
public String toString() {
String groupAffiliation = "no group";
if (group != null) {
groupAffiliation = Integer.toString(group.affiliation);
}
return "Task (" + groupAffiliation + "): " + key +
" [" + super.toString() + "]";
return "[" + key.toString() + "] " + title;
}
}

View File

@@ -92,15 +92,6 @@ class FilteredTaskList {
}
}
/**
* Resets the task list, but does not remove the filter.
*/
void reset() {
mTasks.clear();
mFilteredTasks.clear();
mTaskIndices.clear();
}
/** Removes the task filter and returns the previous touch state */
void removeFilter() {
mFilter = null;
@@ -481,15 +472,6 @@ public class TaskStack {
mCb = cb;
}
/** Resets this TaskStack. */
public void reset() {
mCb = null;
mStackTaskList.reset();
mHistoryTaskList.reset();
mGroups.clear();
mAffinitiesGroups.clear();
}
/**
* Moves the given task to either the front of the freeform workspace or the stack.
*/
@@ -556,12 +538,12 @@ public class TaskStack {
* @param tasks the new set of tasks to replace the current set.
* @param notifyStackChanges whether or not to callback on specific changes to the list of tasks.
*/
public void setTasks(List<Task> tasks, boolean notifyStackChanges) {
public void setTasks(Context context, List<Task> tasks, boolean notifyStackChanges) {
// Compute a has set for each of the tasks
ArrayMap<Task.TaskKey, Task> currentTasksMap = createTaskKeyMapFromList(mRawTaskList);
ArrayMap<Task.TaskKey, Task> newTasksMap = createTaskKeyMapFromList(tasks);
ArrayList<Task> newTasks = new ArrayList<>();
ArrayList<Task> addedTasks = new ArrayList<>();
ArrayList<Task> allTasks = new ArrayList<>();
// Disable notifications if there are no callbacks
if (mCb == null) {
@@ -570,10 +552,13 @@ public class TaskStack {
// Remove any tasks that no longer exist
int taskCount = mRawTaskList.size();
for (int i = 0; i < taskCount; i++) {
for (int i = taskCount - 1; i >= 0; i--) {
Task task = mRawTaskList.get(i);
if (!newTasksMap.containsKey(task.key)) {
if (notifyStackChanges) {
// If we are notifying, then remove the task now, otherwise the raw task list
// will be reset at the end of this method
removeTask(task, AnimationProps.IMMEDIATE);
mCb.onStackTaskRemoved(this, task, i == (taskCount - 1), null,
AnimationProps.IMMEDIATE);
}
@@ -584,26 +569,28 @@ public class TaskStack {
// Add any new tasks
taskCount = tasks.size();
for (int i = 0; i < taskCount; i++) {
Task task = tasks.get(i);
if (!currentTasksMap.containsKey(task.key)) {
if (notifyStackChanges) {
mCb.onStackTaskAdded(this, task);
}
newTasks.add(task);
} else {
newTasks.add(currentTasksMap.get(task.key));
Task newTask = tasks.get(i);
Task currentTask = currentTasksMap.get(newTask.key);
if (currentTask == null && notifyStackChanges) {
addedTasks.add(newTask);
} else if (currentTask != null) {
// The current task has bound callbacks, so just copy the data from the new task
// state and add it back into the list
currentTask.copyFrom(newTask);
newTask = currentTask;
}
allTasks.add(newTask);
}
// Sort all the tasks to ensure they are ordered correctly
Collections.sort(newTasks, FREEFORM_LAST_ACTIVE_TIME_COMPARATOR);
Collections.sort(allTasks, FREEFORM_LAST_ACTIVE_TIME_COMPARATOR);
// Filter out the historical tasks from this new list
ArrayList<Task> stackTasks = new ArrayList<>();
ArrayList<Task> historyTasks = new ArrayList<>();
int newTaskCount = newTasks.size();
int newTaskCount = allTasks.size();
for (int i = 0; i < newTaskCount; i++) {
Task task = newTasks.get(i);
Task task = allTasks.get(i);
if (task.isHistorical) {
historyTasks.add(task);
} else {
@@ -613,10 +600,16 @@ public class TaskStack {
mStackTaskList.set(stackTasks);
mHistoryTaskList.set(historyTasks);
mRawTaskList.clear();
mRawTaskList.addAll(newTasks);
mGroups.clear();
mAffinitiesGroups.clear();
mRawTaskList = allTasks;
// Only callback for the newly added tasks after this stack has been updated
int addedTaskCount = addedTasks.size();
for (int i = 0; i < addedTaskCount; i++) {
mCb.onStackTaskAdded(this, addedTasks.get(i));
}
// Update the affiliated groupings
createAffiliatedGroupings(context);
}
/**
@@ -779,9 +772,12 @@ public class TaskStack {
}
/**
* Temporary: This method will simulate affiliation groups by
* Temporary: This method will simulate affiliation groups
*/
public void createAffiliatedGroupings(Context context) {
void createAffiliatedGroupings(Context context) {
mGroups.clear();
mAffinitiesGroups.clear();
if (RecentsDebugFlags.Static.EnableMockTaskGroups) {
ArrayMap<Task.TaskKey, Task> taskMap = new ArrayMap<>();
// Sort all tasks by increasing firstActiveTime of the task
@@ -926,13 +922,13 @@ public class TaskStack {
@Override
public String toString() {
String str = "Stack Tasks:\n";
String str = "Stack Tasks (" + mStackTaskList.size() + "):\n";
for (Task t : mStackTaskList.getTasks()) {
str += " " + t.toString() + "\n";
str += " " + t.toString() + "\n";
}
str += "Historical Tasks:\n";
str += "Historical Tasks(" + mHistoryTaskList.size() + "):\n";
for (Task t : mHistoryTaskList.getTasks()) {
str += " " + t.toString() + "\n";
str += " " + t.toString() + "\n";
}
return str;
}

View File

@@ -294,7 +294,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
// Notify that recents is now visible
SystemServicesProxy ssp = Recents.getSystemServices();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, true));
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
if (mPipManager.isPipShown()) {
// Place mPipView at the PIP bounds for fine tuned focus handling.
@@ -343,8 +343,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
mPipManager.removeListener(mPipListener);
mIgnoreAltTabRelease = false;
// Notify that recents is now hidden
SystemServicesProxy ssp = Recents.getSystemServices();
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, false));
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
// Workaround for b/22542869, if the RecentsActivity is started again, but without going
// through SystemUI, we need to reset the config launch flags to ensure that we do not

View File

@@ -177,6 +177,7 @@ public class RecentsTransitionHelper {
// Keep track of failed launches
EventBus.getDefault().send(new LaunchTaskFailedEvent());
}
if (transitionFuture != null) {
IRemoteCallback.Stub callback = null;
if (animStartedListener != null) {

View File

@@ -60,9 +60,7 @@ import com.android.systemui.recents.events.activity.HideHistoryEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent;
import com.android.systemui.recents.events.activity.ShowHistoryEvent;
import com.android.systemui.recents.events.activity.TaskStackUpdatedEvent;
import com.android.systemui.recents.events.activity.ToggleHistoryEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
import com.android.systemui.recents.events.ui.ResetBackgroundScrimEvent;
@@ -168,35 +166,39 @@ public class RecentsView extends FrameLayout {
}
/** Set/get the bsp root node */
public void setTaskStack(TaskStack stack) {
public void onResume(boolean isResumingFromVisible, TaskStack stack) {
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
mStack = stack;
if (launchState.launchedReuseTaskStackViews) {
if (mTaskStackView != null) {
// If onRecentsHidden is not triggered, we need to the stack view again here
mTaskStackView.reset();
mTaskStackView.setStack(stack);
} else {
mTaskStackView = new TaskStackView(getContext(), stack);
addView(mTaskStackView);
}
} else {
if (mTaskStackView != null) {
removeView(mTaskStackView);
}
mTaskStackView = new TaskStackView(getContext(), stack);
if (mTaskStackView == null || !launchState.launchedReuseTaskStackViews) {
isResumingFromVisible = false;
removeView(mTaskStackView);
mTaskStackView = new TaskStackView(getContext());
mStack = mTaskStackView.getStack();
addView(mTaskStackView);
}
// If we are already occluded by the app, then just set the default background scrim now.
// Otherwise, defer until the enter animation completes to animate the scrim with the
// tasks for the home animation.
if (launchState.launchedWhileDocking || launchState.launchedFromApp
|| mStack.getTaskCount() == 0) {
mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
// Reset the state
mAwaitingFirstLayout = !isResumingFromVisible;
mLastTaskLaunchedWasFreeform = false;
// Update the stack
mTaskStackView.onResume(isResumingFromVisible);
mTaskStackView.setTasks(stack, isResumingFromVisible /* notifyStackChanges */);
if (isResumingFromVisible) {
// If we are already visible, then restore the background scrim
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
} else {
mBackgroundScrim.setAlpha(0);
// If we are already occluded by the app, then set the final background scrim alpha now.
// Otherwise, defer until the enter animation completes to animate the scrim alpha with
// the tasks for the home animation.
if (launchState.launchedWhileDocking || launchState.launchedFromApp
|| mStack.getTaskCount() == 0) {
mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
} else {
mBackgroundScrim.setAlpha(0);
}
}
// Update the top level view's visibilities
@@ -205,9 +207,6 @@ public class RecentsView extends FrameLayout {
} else {
showEmptyView();
}
// Trigger a new layout
requestLayout();
}
/**
@@ -662,13 +661,6 @@ public class RecentsView extends FrameLayout {
animator.start();
}
public final void onBusEvent(TaskStackUpdatedEvent event) {
if (!event.inMultiWindow) {
mStack.setTasks(event.stack.computeAllTasksList(), true /* notifyStackChanges */);
mStack.createAffiliatedGroupings(getContext());
}
}
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
if (!launchState.launchedWhileDocking && !launchState.launchedFromApp
@@ -686,17 +678,6 @@ public class RecentsView extends FrameLayout {
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
}
public final void onBusEvent(RecentsVisibilityChangedEvent event) {
if (!event.visible) {
// Reset the view state
mAwaitingFirstLayout = true;
mLastTaskLaunchedWasFreeform = false;
if (RecentsDebugFlags.Static.EnableHistory) {
hideHistoryButton(0, false /* translate */);
}
}
}
public final void onBusEvent(ToggleHistoryEvent event) {
if (!RecentsDebugFlags.Static.EnableHistory) {
return;

View File

@@ -16,9 +16,11 @@
package com.android.systemui.recents.views;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewPropertyAnimator;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -56,25 +58,41 @@ public class SystemBarScrimViews {
View.VISIBLE : View.INVISIBLE);
}
/**
* Animates the nav bar scrim visibility.
*/
public void animateNavBarScrimVisibility(boolean visible, AnimationProps animation) {
int toY = 0;
if (visible) {
mNavBarScrimView.setVisibility(View.VISIBLE);
mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
} else {
toY = mNavBarScrimView.getMeasuredHeight();
}
if (animation != AnimationProps.IMMEDIATE) {
mNavBarScrimView.animate()
.translationY(toY)
.setDuration(animation.getDuration(AnimationProps.BOUNDS))
.setInterpolator(animation.getInterpolator(AnimationProps.BOUNDS))
.start();
} else {
mNavBarScrimView.setTranslationY(toY);
}
}
/**** EventBus events ****/
/**
* Starts animating the scrim views when entering Recents.
*/
public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
if (mHasNavBarScrim && mShouldAnimateNavBarScrim) {
mNavBarScrimView.setTranslationY(mNavBarScrimView.getMeasuredHeight());
mNavBarScrimView.animate()
.translationY(0)
.setDuration(mNavBarScrimEnterDuration)
.setInterpolator(Interpolators.DECELERATE_QUINT)
.withStartAction(new Runnable() {
@Override
public void run() {
mNavBarScrimView.setVisibility(View.VISIBLE);
}
})
.start();
if (mHasNavBarScrim) {
AnimationProps animation = mShouldAnimateNavBarScrim
? new AnimationProps()
.setDuration(AnimationProps.BOUNDS, mNavBarScrimEnterDuration)
.setInterpolator(AnimationProps.BOUNDS, Interpolators.DECELERATE_QUINT)
: AnimationProps.IMMEDIATE;
animateNavBarScrimVisibility(true, animation);
}
}
@@ -83,13 +101,12 @@ public class SystemBarScrimViews {
* going home).
*/
public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
if (mHasNavBarScrim && mShouldAnimateNavBarScrim) {
mNavBarScrimView.animate()
.translationY(mNavBarScrimView.getMeasuredHeight())
.setStartDelay(0)
.setDuration(TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.start();
if (mHasNavBarScrim) {
AnimationProps animation = new AnimationProps()
.setDuration(AnimationProps.BOUNDS,
TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION)
.setInterpolator(AnimationProps.BOUNDS, Interpolators.FAST_OUT_SLOW_IN);
animateNavBarScrimVisibility(false, animation);
}
}
}

View File

@@ -531,7 +531,6 @@ public class TaskStackLayoutAlgorithm {
return;
}
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
mUnfocusedRange.offset(0f);
int taskCount = tasks.size();
for (int i = taskCount - 1; i >= 0; i--) {
@@ -571,6 +570,10 @@ public class TaskStackLayoutAlgorithm {
* Updates this stack when a scroll happens.
*/
public void updateFocusStateOnScroll(float stackScroll, float deltaScroll) {
if (deltaScroll == 0f) {
return;
}
for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) {
int taskId = mTaskIndexOverrideMap.keyAt(i);
float x = mTaskIndexMap.get(taskId);
@@ -630,6 +633,13 @@ public class TaskStackLayoutAlgorithm {
return mState;
}
/**
* Returns whether this stack layout has been initialized.
*/
public boolean isInitialized() {
return !mStackRect.isEmpty();
}
/**
* Computes the maximum number of visible tasks and thumbnails when the scroll is at the initial
* stack scroll. Requires that update() is called first.

View File

@@ -65,11 +65,10 @@ import com.android.systemui.recents.events.activity.IterateRecentsEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent;
import com.android.systemui.recents.events.activity.ShowHistoryEvent;
import com.android.systemui.recents.events.activity.TaskStackUpdatedEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
@@ -117,7 +116,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
LayoutInflater mInflater;
TaskStack mStack;
TaskStack mStack = new TaskStack();
@ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
TaskStackLayoutAlgorithm mLayoutAlgorithm;
@ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
@@ -206,13 +205,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
};
public TaskStackView(Context context, TaskStack stack) {
public TaskStackView(Context context) {
super(context);
SystemServicesProxy ssp = Recents.getSystemServices();
Resources res = context.getResources();
// Set the stack first
setStack(stack);
mStack.setCallbacks(this);
mViewPool = new ViewPool<>(context, this);
mInflater = LayoutInflater.from(context);
mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
@@ -248,6 +247,41 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
}
/**
* Called only if we are resuming Recents.
*/
void onResume(boolean isResumingFromVisible) {
if (!isResumingFromVisible) {
// Reset the focused task
resetFocusedTask(getFocusedTask());
}
// Reset the state of each of the task views
List<TaskView> taskViews = new ArrayList<>();
taskViews.addAll(getTaskViews());
taskViews.addAll(mViewPool.getViews());
for (int i = taskViews.size() - 1; i >= 0; i--) {
taskViews.get(i).onResume(isResumingFromVisible);
}
// Reset the stack state
readSystemFlags();
mTaskViewsClipDirty = true;
mEnterAnimationComplete = false;
mUIDozeTrigger.stopDozing();
if (isResumingFromVisible) {
// Animate in the freeform workspace
int ffBgAlpha = mLayoutAlgorithm.getStackState().freeformBackgroundAlpha;
animateFreeformWorkspaceBackgroundAlpha(ffBgAlpha, new AnimationProps(150,
Interpolators.FAST_OUT_SLOW_IN));
} else {
mStackScroller.reset();
mLayoutAlgorithm.reset();
mAwaitingFirstLayout = true;
requestLayout();
}
}
@Override
protected void onAttachedToWindow() {
EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
@@ -261,15 +295,20 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
EventBus.getDefault().unregister(this);
}
/** Sets the task stack */
void setStack(TaskStack stack) {
// Set the new stack
mStack = stack;
if (mStack != null) {
mStack.setCallbacks(this);
/**
* Sets the stack tasks of this TaskStackView from the given TaskStack.
*/
public void setTasks(TaskStack stack, boolean notifyStackChanges) {
boolean isInitialized = mLayoutAlgorithm.isInitialized();
mStack.setTasks(getContext(), stack.computeAllTasksList(),
notifyStackChanges && isInitialized);
if (isInitialized) {
// Only update the layout if we are notifying, otherwise, we will update it in the next
// measure/layout pass
updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
updateToInitialState();
relayoutTaskViewsOnNextFrame(AnimationProps.IMMEDIATE);
}
// Layout again with the new stack
requestLayout();
}
/** Returns the task stack. */
@@ -338,36 +377,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
return null;
}
/** Resets this TaskStackView for reuse. */
void reset() {
// Reset the focused task
resetFocusedTask(getFocusedTask());
// Return all the views to the pool
List<TaskView> taskViews = getTaskViews();
int taskViewCount = taskViews.size();
for (int i = taskViewCount - 1; i >= 0; i--) {
mViewPool.returnViewToPool(taskViews.get(i));
}
// Mark each task view for relayout
List<TaskView> poolViews = mViewPool.getViews();
for (TaskView tv : poolViews) {
tv.reset();
}
// Reset the stack state
mStack.reset();
mTaskViewsClipDirty = true;
mAwaitingFirstLayout = true;
mEnterAnimationComplete = false;
mUIDozeTrigger.stopDozing();
mStackScroller.reset();
mLayoutAlgorithm.reset();
readSystemFlags();
requestLayout();
}
/** Returns the stack algorithm for this task stack. */
public TaskStackLayoutAlgorithm getStackAlgorithm() {
return mLayoutAlgorithm;
@@ -514,15 +523,22 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
for (int i = taskViewCount - 1; i >= 0; i--) {
TaskView tv = taskViews.get(i);
Task task = tv.getTask();
int taskIndex = mStack.indexOfStackTask(task);
TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
// Skip ignored tasks
if (ignoreTasksSet.contains(task.key)) {
continue;
}
if (task.isFreeformTask() || transform.visible) {
// It is possible for the set of lingering TaskViews to differ from the stack if the
// stack was updated before the relayout. If the task view is no longer in the stack,
// then just return it back to the view pool.
int taskIndex = mStack.indexOfStackTask(task);
TaskViewTransform transform = null;
if (taskIndex != -1) {
transform = mCurrentTaskTransforms.get(taskIndex);
}
if (task.isFreeformTask() || (transform != null && transform.visible)) {
mTmpTaskViewMap.put(task.key, tv);
} else {
if (mTouchExplorationEnabled) {
@@ -1119,15 +1135,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
}
/**
* This is ONLY used from the Recents component to update the dummy stack view for purposes
* of getting the task rect to animate to.
*/
public void updateLayoutForStack(TaskStack stack) {
mStack = stack;
updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
}
/**
* Computes the maximum number of visible tasks and thumbnails. Requires that
* updateLayoutForStack() is called first.
@@ -1423,7 +1430,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public void onReturnViewToPool(TaskView tv) {
final Task task = tv.getTask();
// Report that this tasks's data is no longer being used
// Report that this task's data is no longer being used
Recents.getTaskLoader().unloadTaskData(task);
// Reset the view properties and view state
@@ -1670,12 +1677,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
}
public final void onBusEvent(RecentsVisibilityChangedEvent event) {
if (!event.visible) {
reset();
}
}
public final void onBusEvent(DragStartEvent event) {
// Ensure that the drag task is not animated
addIgnoreTask(event.task);
@@ -1772,12 +1773,14 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
taskViewRect.right, taskViewRect.bottom);
// Animate all the TaskViews back into position
// Animate the non-drag TaskViews back into position
mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
mTmpTransform, null);
event.getAnimationTrigger().increment();
relayoutTaskViews(new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
Interpolators.FAST_OUT_SLOW_IN));
// Animate the drag TaskView back into position
updateTaskViewToTransform(event.taskView, mTmpTransform,
new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN,
event.getAnimationTrigger().decrementOnAnimationEnd()));
@@ -1850,31 +1853,22 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mAnimationHelper.startHideHistoryAnimation();
}
public final void onBusEvent(TaskStackUpdatedEvent event) {
public final void onBusEvent(MultiWindowStateChangedEvent event) {
if (!event.inMultiWindow) {
// Scroll the stack to the front after it has been updated
event.addPostAnimationCallback(new Runnable() {
// Scroll the stack to the front to see the undocked task
mStackScroller.animateScroll(mLayoutAlgorithm.mMaxScrollP, new Runnable() {
@Override
public void run() {
mStackScroller.animateScroll(mLayoutAlgorithm.mMaxScrollP,
null /* postScrollRunnable */);
List<TaskView> taskViews = getTaskViews();
int taskViewCount = taskViews.size();
for (int i = 0; i < taskViewCount; i++) {
TaskView tv = taskViews.get(i);
tv.getHeaderView().rebindToTask(tv.getTask(), tv.mTouchExplorationEnabled,
tv.mIsDisabledInSafeMode);
}
}
});
}
// When the multi-window state changes, rebind all task view headers again to update their
// dockable state
event.addPostAnimationCallback(new Runnable() {
@Override
public void run() {
List<TaskView> taskViews = getTaskViews();
int taskViewCount = taskViews.size();
for (int i = 0; i < taskViewCount; i++) {
TaskView tv = taskViews.get(i);
tv.getHeaderView().rebindToTask(tv.getTask(), tv.mTouchExplorationEnabled,
tv.mIsDisabledInSafeMode);
}
}
});
}
public final void onBusEvent(ConfigurationChangedEvent event) {

View File

@@ -193,11 +193,13 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
}
/** Resets this TaskView for reuse. */
void reset() {
resetViewProperties();
void onResume(boolean isResumingFromVisible) {
resetNoUserInteractionState();
readSystemFlags();
setClipViewInStack(false);
if (!isResumingFromVisible) {
resetViewProperties();
setClipViewInStack(false);
}
setCallbacks(null);
}