diff options
17 files changed, 368 insertions, 334 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index f5ae3514d780..54bf68bcb678 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -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() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index a2934d743441..cd1a27fd0515 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -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 | @@ -382,82 +331,127 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD } @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); + protected void onStart() { + super.onStart(); + + // Notify that recents is now visible + EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true)); + MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY); } @Override - protected void onStart() { - super.onStart(); + public void onEnterAnimationComplete() { + super.onEnterAnimationComplete(); + EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent()); + } + + @Override + protected void onResume() { + super.onResume(); + + // 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); + } - // Update the recent tasks - updateRecentsTasks(); + 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 - 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)); - - 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 + public boolean onPreDraw() { + mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this); + EventBus.getDefault().post(new RecentsDrawnEvent()); + return true; + } + }); - @Override - public void onEnterAnimationComplete() { - super.onEnterAnimationComplete(); - EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent()); + // 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 onPause() { super.onPause(); - // Stop the fast-toggle dozer + mIgnoreAltTabRelease = 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 + // wait on the system to send a signal that was never queued. + RecentsConfiguration config = Recents.getConfiguration(); + RecentsActivityLaunchState launchState = config.getLaunchState(); + launchState.reset(); } @Override protected void onStop() { super.onStop(); - // Reset some states - mIgnoreAltTabRelease = false; + // 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 - SystemServicesProxy ssp = Recents.getSystemServices(); - EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, ssp, 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 - // wait on the system to send a signal that was never queued. - RecentsConfiguration config = Recents.getConfiguration(); - RecentsActivityLaunchState launchState = config.getLaunchState(); - launchState.reset(); - + 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 diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 1458d7bbffc5..ac23f446cdc4 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java new file mode 100644 index 000000000000..19245d9534df --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java @@ -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; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java index 4140bcde58d6..8843eb41210f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/events/component/RecentsVisibilityChangedEvent.java @@ -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; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index abcb563339aa..6ae07fc89a5a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -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 */); } /** diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index e5d4f1bf50bc..b5a5949d0c48 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -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; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index 1f91dceb3e99..4d1c552f2687 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java index 02c8d962f411..dae522f2c072 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java index e5022a48cd07..dd825cb4331f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 10f491eb2bdc..1af5a55f7a1e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java index 1cd0850ef7fa..19b219a49b2c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java @@ -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); } } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index 17c3eeb1a429..699b85e34348 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -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); @@ -631,6 +634,13 @@ public class TaskStackLayoutAlgorithm { } /** + * 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. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index c2bfc2817545..6abb82686c63 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -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) { @@ -1120,15 +1136,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) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index e9c7ac6ccbb5..0bc7f8927a9c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -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); } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 252dda7984c6..e51a2e1aa526 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -57,6 +57,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.CompatibilityInfo; @@ -76,6 +77,7 @@ import android.media.Ringtone; import android.media.RingtoneManager; import android.media.session.MediaSessionLegacyHelper; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.FactoryTest; @@ -2057,7 +2059,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // check if user has enabled this operation. SecurityException will be thrown if // this app has not been allowed by the user - final int mode = mAppOpsManager.checkOp(outAppOp[0], callingUid, + final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid, attrs.packageName); switch (mode) { case AppOpsManager.MODE_ALLOWED: @@ -2066,6 +2068,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { // actually be hidden in WindowManagerService return WindowManagerGlobal.ADD_OKAY; case AppOpsManager.MODE_ERRORED: + try { + ApplicationInfo appInfo = mContext.getPackageManager() + .getApplicationInfo(attrs.packageName, + UserHandle.getUserId(callingUid)); + // Don't crash legacy apps + if (appInfo.targetSdkVersion < Build.VERSION_CODES.M) { + return WindowManagerGlobal.ADD_OKAY; + } + } catch (PackageManager.NameNotFoundException e) { + /* ignore */ + } return WindowManagerGlobal.ADD_PERMISSION_DENIED; default: // in the default mode, we will make a decision here based on diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index aa14fff7d741..60ed4977f984 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -1205,7 +1205,8 @@ static jobject translate_gps_measurement(JNIEnv* env, SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY, CarrierPhaseUncertainty, measurement->carrier_phase_uncertainty); - SET(MultipathIndicator, measurement->multipath_indicator); + SET(MultipathIndicator, + static_cast<int32_t>(measurement->multipath_indicator)); SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db); return object.get(); @@ -1244,7 +1245,8 @@ static jobject translate_gnss_measurement(JNIEnv* env, SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY, CarrierPhaseUncertainty, measurement->carrier_phase_uncertainty); - SET(MultipathIndicator, measurement->multipath_indicator); + SET(MultipathIndicator, + static_cast<int32_t>(measurement->multipath_indicator)); SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db); return object.get(); |