Loading packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +3 −2 Original line number Diff line number Diff line Loading @@ -192,8 +192,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD // and the old last stack active time, they were not visible and in the // TaskStack so we don't need to remove any associated TaskViews but we do // need to load the task id's from the system RecentsTaskLoadPlan loadPlan = Recents.getTaskLoader().createLoadPlan(ctx); loadPlan.preloadRawTasks(false /* includeFrontMostExcludedTask */); RecentsTaskLoader loader = Recents.getTaskLoader(); RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(ctx); loader.preloadRawTasks(loadPlan, false /* includeFrontMostExcludedTask */); List<ActivityManager.RecentTaskInfo> tasks = loadPlan.getRawTasks(); for (int i = tasks.size() - 1; i >= 0; i--) { ActivityManager.RecentTaskInfo task = tasks.get(i); Loading packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +92 −76 Original line number Diff line number Diff line Loading @@ -108,36 +108,39 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * task stacks and update recents accordingly. */ class TaskStackListenerImpl extends TaskStackListener { @Override public void onTaskStackChanged() { public void onTaskStackChangedBackground() { // Preloads the next task RecentsConfiguration config = Recents.getConfiguration(); if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) { RecentsTaskLoader loader = Recents.getTaskLoader(); SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask(); // Load the next task only if we aren't svelte SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask(); RecentsTaskLoader loader = Recents.getTaskLoader(); RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext); loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */); RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); // This callback is made when a new activity is launched and the old one is paused // so ignore the current activity and try and preload the thumbnail for the // previous one. if (runningTaskInfo != null) { launchOpts.runningTaskId = runningTaskInfo.id; } VisibilityReport visibilityReport; synchronized (mDummyStackView) { mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */); updateDummyStackViewLayout(plan.getTaskStack(), getWindowRect(null /* windowRectOverride */)); // Launched from app is always the worst case (in terms of how many thumbnails/tasks // visible) // Launched from app is always the worst case (in terms of how many // thumbnails/tasks visible) RecentsActivityLaunchState launchState = new RecentsActivityLaunchState(); launchState.launchedFromApp = true; mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */, launchState); visibilityReport = mDummyStackView.computeStackVisibilityReport(); } VisibilityReport visibilityReport = mDummyStackView.computeStackVisibilityReport(); RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1; launchOpts.numVisibleTasks = visibilityReport.numVisibleTasks; launchOpts.numVisibleTaskThumbnails = visibilityReport.numVisibleThumbnails; launchOpts.onlyLoadForCache = true; Loading Loading @@ -221,10 +224,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } public void onConfigurationChanged() { Resources res = mContext.getResources(); reloadResources(); synchronized (mDummyStackView) { mDummyStackView.reloadOnConfigurationChange(); } } /** * This is only called from the system user's Recents. Secondary users will instead proxy their Loading Loading @@ -393,7 +397,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener RecentsTaskLoader loader = Recents.getTaskLoader(); sInstanceLoadPlan = loader.createLoadPlan(mContext); sInstanceLoadPlan.preloadRawTasks(!isHomeStackVisible.value); loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value); TaskStack stack = sInstanceLoadPlan.getTaskStack(); if (stack.getTaskCount() > 0) { Loading Loading @@ -633,6 +636,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener calculateWindowStableInsets(systemInsets, windowRect); windowRect.offsetTo(0, 0); synchronized (mDummyStackView) { TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm(); // Rebind the header bar and draw it for the transition Loading @@ -645,6 +649,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack)); } } } private Rect getWindowRect(Rect windowRectOverride) { return windowRectOverride != null Loading @@ -663,29 +668,35 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener */ private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) { Rect windowRect = getWindowRect(windowRectOverride); int taskViewWidth = 0; boolean useGridLayout = false; synchronized (mDummyStackView) { useGridLayout = mDummyStackView.useGridLayout(); updateDummyStackViewLayout(stack, windowRect); if (stack != null) { TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm(); mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */); // Get the width of a task view so that we know how wide to draw the header bar. int taskViewWidth = 0; if (mDummyStackView.useGridLayout()) { if (useGridLayout) { TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm(); gridLayout.initialize(windowRect); taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */, stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width(); stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width(); } else { Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds(); if (!taskViewBounds.isEmpty()) { taskViewWidth = taskViewBounds.width(); } } } } if (taskViewWidth > 0) { if (stack != null && taskViewWidth > 0) { synchronized (mHeaderBarLock) { if (mHeaderBar.getMeasuredWidth() != taskViewWidth || mHeaderBar.getMeasuredHeight() != mTaskBarHeight) { if (mDummyStackView.useGridLayout()) { if (useGridLayout) { mHeaderBar.setShouldDarkenBackgroundColor(true); mHeaderBar.setNoUserInteractionState(); } Loading @@ -706,7 +717,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } } } } /** * Given the stable insets and the rect for our window, calculates the insets that affect our Loading Loading @@ -764,16 +774,21 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * Creates the activity options for an app->recents transition. */ private ActivityOptions getThumbnailTransitionActivityOptions( ActivityManager.RunningTaskInfo runningTask, TaskStackView stackView, Rect windowOverrideRect) { ActivityManager.RunningTaskInfo runningTask, Rect windowOverrideRect) { if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) { ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>(); ArrayList<Task> tasks = stackView.getStack().getStackTasks(); TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm(); TaskStackViewScroller stackScroller = stackView.getScroller(); ArrayList<Task> tasks; TaskStackLayoutAlgorithm stackLayout; TaskStackViewScroller stackScroller; stackView.updateLayoutAlgorithm(true /* boundScroll */); stackView.updateToInitialState(); synchronized (mDummyStackView) { tasks = mDummyStackView.getStack().getStackTasks(); stackLayout = mDummyStackView.getStackAlgorithm(); stackScroller = mDummyStackView.getScroller(); mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */); mDummyStackView.updateToInitialState(); } for (int i = tasks.size() - 1; i >= 0; i--) { Task task = tasks.get(i); Loading @@ -795,7 +810,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } else { // Update the destination rect Task toTask = new Task(); TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask, TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask, windowOverrideRect); Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform, mThumbTransitionBitmapCache); Loading Loading @@ -919,8 +934,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener updateHeaderBarLayout(stack, windowOverrideRect); // Prepare the dummy stack for the transition TaskStackLayoutAlgorithm.VisibilityReport stackVr = mDummyStackView.computeStackVisibilityReport(); TaskStackLayoutAlgorithm.VisibilityReport stackVr; synchronized (mDummyStackView) { stackVr = mDummyStackView.computeStackVisibilityReport(); } // Update the remaining launch state launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks; Loading @@ -936,8 +953,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener opts = getUnknownTransitionActivityOptions(); } else if (useThumbnailTransition) { // Try starting with a thumbnail transition opts = getThumbnailTransitionActivityOptions(runningTask, mDummyStackView, windowOverrideRect); opts = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect); } else { // If there is no thumbnail transition, but is launching from home into recents, then // use a quick home transition Loading packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +85 −68 Original line number Diff line number Diff line Loading @@ -149,6 +149,10 @@ public class SystemServicesProxy { * to reduce IPC calls from system services. These callbacks will be called on the main thread. */ public abstract static class TaskStackListener { /** * NOTE: This call is made of the thread that the binder call comes in on. */ public void onTaskStackChangedBackground() { } public void onTaskStackChanged() { } public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { } public void onActivityPinned(String packageName) { } Loading Loading @@ -187,8 +191,20 @@ public class SystemServicesProxy { * This simply passes callbacks to listeners through {@link H}. * */ private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() { private final List<SystemServicesProxy.TaskStackListener> mTmpListeners = new ArrayList<>(); @Override public void onTaskStackChanged() throws RemoteException { // Call the task changed callback for the non-ui thread listeners first synchronized (mTaskStackListeners) { mTmpListeners.clear(); mTmpListeners.addAll(mTaskStackListeners); } for (int i = mTmpListeners.size() - 1; i >= 0; i--) { mTmpListeners.get(i).onTaskStackChangedBackground(); } mHandler.removeMessages(H.ON_TASK_STACK_CHANGED); mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED); } Loading Loading @@ -309,10 +325,7 @@ public class SystemServicesProxy { * Returns the single instance of the {@link SystemServicesProxy}. * This should only be called on the main thread. */ public static SystemServicesProxy getInstance(Context context) { if (!Looper.getMainLooper().isCurrentThread()) { throw new RuntimeException("Must be called on the UI thread"); } public static synchronized SystemServicesProxy getInstance(Context context) { if (sSystemServicesProxy == null) { sSystemServicesProxy = new SystemServicesProxy(context); } Loading Loading @@ -1136,6 +1149,7 @@ public class SystemServicesProxy { public void registerTaskStackListener(TaskStackListener listener) { if (mIam == null) return; synchronized (mTaskStackListeners) { mTaskStackListeners.add(listener); if (mTaskStackListeners.size() == 1) { // Register mTaskStackListener to IActivityManager only once if needed. Loading @@ -1146,6 +1160,7 @@ public class SystemServicesProxy { } } } } public void endProlongedAnimations() { if (mWm == null) { Loading Loading @@ -1245,6 +1260,7 @@ public class SystemServicesProxy { @Override public void handleMessage(Message msg) { synchronized (mTaskStackListeners) { switch (msg.what) { case ON_TASK_STACK_CHANGED: { for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { Loading Loading @@ -1318,3 +1334,4 @@ public class SystemServicesProxy { } } } } packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +11 −3 Original line number Diff line number Diff line Loading @@ -103,8 +103,10 @@ public class RecentsTaskLoadPlan { /** * An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent * to most-recent order. * * Note: Do not lock, callers should synchronize on the loader before making this call. */ public synchronized void preloadRawTasks(boolean includeFrontMostExcludedTask) { void preloadRawTasks(boolean includeFrontMostExcludedTask) { int currentUserId = UserHandle.USER_CURRENT; updateCurrentQuietProfilesCache(currentUserId); SystemServicesProxy ssp = Recents.getSystemServices(); Loading @@ -123,8 +125,11 @@ public class RecentsTaskLoadPlan { * The tasks will be ordered by: * - least-recent to most-recent stack tasks * - least-recent to most-recent freeform tasks * * Note: Do not lock, since this can be calling back to the loader, which separately also drives * this call (callers should synchronize on the loader before making this call). */ public synchronized void preloadPlan(RecentsTaskLoader loader, int runningTaskId, void preloadPlan(RecentsTaskLoader loader, int runningTaskId, boolean includeFrontMostExcludedTask) { Resources res = mContext.getResources(); ArrayList<Task> allTasks = new ArrayList<>(); Loading Loading @@ -223,8 +228,11 @@ public class RecentsTaskLoadPlan { /** * Called to apply the actual loading based on the specified conditions. * * Note: Do not lock, since this can be calling back to the loader, which separately also drives * this call (callers should synchronize on the loader before making this call). */ public synchronized void executePlan(Options opts, RecentsTaskLoader loader) { void executePlan(Options opts, RecentsTaskLoader loader) { Resources res = mContext.getResources(); // Iterate through each of the tasks and load them according to the load conditions. Loading packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +14 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.Looper; import android.util.Log; import android.util.LruCache; import com.android.internal.annotations.GuardedBy; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsConfiguration; Loading Loading @@ -243,7 +244,9 @@ public class RecentsTaskLoader { private final TaskResourceLoadQueue mLoadQueue; private final BackgroundTaskLoader mLoader; private final HighResThumbnailLoader mHighResThumbnailLoader; @GuardedBy("this") private final TaskKeyStrongCache<ThumbnailData> mThumbnailCache = new TaskKeyStrongCache<>(); @GuardedBy("this") private final TaskKeyStrongCache<ThumbnailData> mTempCache = new TaskKeyStrongCache<>(); private final int mMaxThumbnailCacheSize; private final int mMaxIconCacheSize; Loading Loading @@ -318,14 +321,20 @@ public class RecentsTaskLoader { return plan; } /** Preloads raw recents tasks using the specified plan to store the output. */ public synchronized void preloadRawTasks(RecentsTaskLoadPlan plan, boolean includeFrontMostExcludedTask) { plan.preloadRawTasks(includeFrontMostExcludedTask); } /** Preloads recents tasks using the specified plan to store the output. */ public void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId, public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId, boolean includeFrontMostExcludedTask) { plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask); } /** Begins loading the heavy task data according to the specified options. */ public void loadTasks(Context context, RecentsTaskLoadPlan plan, public synchronized void loadTasks(Context context, RecentsTaskLoadPlan plan, RecentsTaskLoadPlan.Options opts) { if (opts == null) { throw new RuntimeException("Requires load options"); Loading Loading @@ -380,8 +389,7 @@ public class RecentsTaskLoader { * Handles signals from the system, trimming memory when requested to prevent us from running * out of memory. */ public void onTrimMemory(int level) { RecentsConfiguration config = Recents.getConfiguration(); public synchronized void onTrimMemory(int level) { switch (level) { case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: // Stop the loader immediately when the UI is no longer visible Loading Loading @@ -516,7 +524,7 @@ public class RecentsTaskLoader { /** * Returns the cached thumbnail if the task key is not expired, updating the cache if it is. */ ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached, synchronized ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached, boolean storeInCache) { SystemServicesProxy ssp = Recents.getSystemServices(); Loading Loading @@ -616,7 +624,7 @@ public class RecentsTaskLoader { } } public void dump(String prefix, PrintWriter writer) { public synchronized void dump(String prefix, PrintWriter writer) { String innerPrefix = prefix + " "; writer.print(prefix); writer.println(TAG); Loading Loading
packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +3 −2 Original line number Diff line number Diff line Loading @@ -192,8 +192,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD // and the old last stack active time, they were not visible and in the // TaskStack so we don't need to remove any associated TaskViews but we do // need to load the task id's from the system RecentsTaskLoadPlan loadPlan = Recents.getTaskLoader().createLoadPlan(ctx); loadPlan.preloadRawTasks(false /* includeFrontMostExcludedTask */); RecentsTaskLoader loader = Recents.getTaskLoader(); RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(ctx); loader.preloadRawTasks(loadPlan, false /* includeFrontMostExcludedTask */); List<ActivityManager.RecentTaskInfo> tasks = loadPlan.getRawTasks(); for (int i = tasks.size() - 1; i >= 0; i--) { ActivityManager.RecentTaskInfo task = tasks.get(i); Loading
packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +92 −76 Original line number Diff line number Diff line Loading @@ -108,36 +108,39 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * task stacks and update recents accordingly. */ class TaskStackListenerImpl extends TaskStackListener { @Override public void onTaskStackChanged() { public void onTaskStackChangedBackground() { // Preloads the next task RecentsConfiguration config = Recents.getConfiguration(); if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) { RecentsTaskLoader loader = Recents.getTaskLoader(); SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask(); // Load the next task only if we aren't svelte SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask(); RecentsTaskLoader loader = Recents.getTaskLoader(); RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext); loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */); RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); // This callback is made when a new activity is launched and the old one is paused // so ignore the current activity and try and preload the thumbnail for the // previous one. if (runningTaskInfo != null) { launchOpts.runningTaskId = runningTaskInfo.id; } VisibilityReport visibilityReport; synchronized (mDummyStackView) { mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */); updateDummyStackViewLayout(plan.getTaskStack(), getWindowRect(null /* windowRectOverride */)); // Launched from app is always the worst case (in terms of how many thumbnails/tasks // visible) // Launched from app is always the worst case (in terms of how many // thumbnails/tasks visible) RecentsActivityLaunchState launchState = new RecentsActivityLaunchState(); launchState.launchedFromApp = true; mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */, launchState); visibilityReport = mDummyStackView.computeStackVisibilityReport(); } VisibilityReport visibilityReport = mDummyStackView.computeStackVisibilityReport(); RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options(); launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1; launchOpts.numVisibleTasks = visibilityReport.numVisibleTasks; launchOpts.numVisibleTaskThumbnails = visibilityReport.numVisibleThumbnails; launchOpts.onlyLoadForCache = true; Loading Loading @@ -221,10 +224,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } public void onConfigurationChanged() { Resources res = mContext.getResources(); reloadResources(); synchronized (mDummyStackView) { mDummyStackView.reloadOnConfigurationChange(); } } /** * This is only called from the system user's Recents. Secondary users will instead proxy their Loading Loading @@ -393,7 +397,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener RecentsTaskLoader loader = Recents.getTaskLoader(); sInstanceLoadPlan = loader.createLoadPlan(mContext); sInstanceLoadPlan.preloadRawTasks(!isHomeStackVisible.value); loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value); TaskStack stack = sInstanceLoadPlan.getTaskStack(); if (stack.getTaskCount() > 0) { Loading Loading @@ -633,6 +636,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener calculateWindowStableInsets(systemInsets, windowRect); windowRect.offsetTo(0, 0); synchronized (mDummyStackView) { TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm(); // Rebind the header bar and draw it for the transition Loading @@ -645,6 +649,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack)); } } } private Rect getWindowRect(Rect windowRectOverride) { return windowRectOverride != null Loading @@ -663,29 +668,35 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener */ private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) { Rect windowRect = getWindowRect(windowRectOverride); int taskViewWidth = 0; boolean useGridLayout = false; synchronized (mDummyStackView) { useGridLayout = mDummyStackView.useGridLayout(); updateDummyStackViewLayout(stack, windowRect); if (stack != null) { TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm(); mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */); // Get the width of a task view so that we know how wide to draw the header bar. int taskViewWidth = 0; if (mDummyStackView.useGridLayout()) { if (useGridLayout) { TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm(); gridLayout.initialize(windowRect); taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */, stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width(); stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width(); } else { Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds(); if (!taskViewBounds.isEmpty()) { taskViewWidth = taskViewBounds.width(); } } } } if (taskViewWidth > 0) { if (stack != null && taskViewWidth > 0) { synchronized (mHeaderBarLock) { if (mHeaderBar.getMeasuredWidth() != taskViewWidth || mHeaderBar.getMeasuredHeight() != mTaskBarHeight) { if (mDummyStackView.useGridLayout()) { if (useGridLayout) { mHeaderBar.setShouldDarkenBackgroundColor(true); mHeaderBar.setNoUserInteractionState(); } Loading @@ -706,7 +717,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } } } } /** * Given the stable insets and the rect for our window, calculates the insets that affect our Loading Loading @@ -764,16 +774,21 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * Creates the activity options for an app->recents transition. */ private ActivityOptions getThumbnailTransitionActivityOptions( ActivityManager.RunningTaskInfo runningTask, TaskStackView stackView, Rect windowOverrideRect) { ActivityManager.RunningTaskInfo runningTask, Rect windowOverrideRect) { if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) { ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>(); ArrayList<Task> tasks = stackView.getStack().getStackTasks(); TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm(); TaskStackViewScroller stackScroller = stackView.getScroller(); ArrayList<Task> tasks; TaskStackLayoutAlgorithm stackLayout; TaskStackViewScroller stackScroller; stackView.updateLayoutAlgorithm(true /* boundScroll */); stackView.updateToInitialState(); synchronized (mDummyStackView) { tasks = mDummyStackView.getStack().getStackTasks(); stackLayout = mDummyStackView.getStackAlgorithm(); stackScroller = mDummyStackView.getScroller(); mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */); mDummyStackView.updateToInitialState(); } for (int i = tasks.size() - 1; i >= 0; i--) { Task task = tasks.get(i); Loading @@ -795,7 +810,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } else { // Update the destination rect Task toTask = new Task(); TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask, TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask, windowOverrideRect); Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform, mThumbTransitionBitmapCache); Loading Loading @@ -919,8 +934,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener updateHeaderBarLayout(stack, windowOverrideRect); // Prepare the dummy stack for the transition TaskStackLayoutAlgorithm.VisibilityReport stackVr = mDummyStackView.computeStackVisibilityReport(); TaskStackLayoutAlgorithm.VisibilityReport stackVr; synchronized (mDummyStackView) { stackVr = mDummyStackView.computeStackVisibilityReport(); } // Update the remaining launch state launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks; Loading @@ -936,8 +953,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener opts = getUnknownTransitionActivityOptions(); } else if (useThumbnailTransition) { // Try starting with a thumbnail transition opts = getThumbnailTransitionActivityOptions(runningTask, mDummyStackView, windowOverrideRect); opts = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect); } else { // If there is no thumbnail transition, but is launching from home into recents, then // use a quick home transition Loading
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +85 −68 Original line number Diff line number Diff line Loading @@ -149,6 +149,10 @@ public class SystemServicesProxy { * to reduce IPC calls from system services. These callbacks will be called on the main thread. */ public abstract static class TaskStackListener { /** * NOTE: This call is made of the thread that the binder call comes in on. */ public void onTaskStackChangedBackground() { } public void onTaskStackChanged() { } public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { } public void onActivityPinned(String packageName) { } Loading Loading @@ -187,8 +191,20 @@ public class SystemServicesProxy { * This simply passes callbacks to listeners through {@link H}. * */ private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() { private final List<SystemServicesProxy.TaskStackListener> mTmpListeners = new ArrayList<>(); @Override public void onTaskStackChanged() throws RemoteException { // Call the task changed callback for the non-ui thread listeners first synchronized (mTaskStackListeners) { mTmpListeners.clear(); mTmpListeners.addAll(mTaskStackListeners); } for (int i = mTmpListeners.size() - 1; i >= 0; i--) { mTmpListeners.get(i).onTaskStackChangedBackground(); } mHandler.removeMessages(H.ON_TASK_STACK_CHANGED); mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED); } Loading Loading @@ -309,10 +325,7 @@ public class SystemServicesProxy { * Returns the single instance of the {@link SystemServicesProxy}. * This should only be called on the main thread. */ public static SystemServicesProxy getInstance(Context context) { if (!Looper.getMainLooper().isCurrentThread()) { throw new RuntimeException("Must be called on the UI thread"); } public static synchronized SystemServicesProxy getInstance(Context context) { if (sSystemServicesProxy == null) { sSystemServicesProxy = new SystemServicesProxy(context); } Loading Loading @@ -1136,6 +1149,7 @@ public class SystemServicesProxy { public void registerTaskStackListener(TaskStackListener listener) { if (mIam == null) return; synchronized (mTaskStackListeners) { mTaskStackListeners.add(listener); if (mTaskStackListeners.size() == 1) { // Register mTaskStackListener to IActivityManager only once if needed. Loading @@ -1146,6 +1160,7 @@ public class SystemServicesProxy { } } } } public void endProlongedAnimations() { if (mWm == null) { Loading Loading @@ -1245,6 +1260,7 @@ public class SystemServicesProxy { @Override public void handleMessage(Message msg) { synchronized (mTaskStackListeners) { switch (msg.what) { case ON_TASK_STACK_CHANGED: { for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) { Loading Loading @@ -1318,3 +1334,4 @@ public class SystemServicesProxy { } } } }
packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +11 −3 Original line number Diff line number Diff line Loading @@ -103,8 +103,10 @@ public class RecentsTaskLoadPlan { /** * An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent * to most-recent order. * * Note: Do not lock, callers should synchronize on the loader before making this call. */ public synchronized void preloadRawTasks(boolean includeFrontMostExcludedTask) { void preloadRawTasks(boolean includeFrontMostExcludedTask) { int currentUserId = UserHandle.USER_CURRENT; updateCurrentQuietProfilesCache(currentUserId); SystemServicesProxy ssp = Recents.getSystemServices(); Loading @@ -123,8 +125,11 @@ public class RecentsTaskLoadPlan { * The tasks will be ordered by: * - least-recent to most-recent stack tasks * - least-recent to most-recent freeform tasks * * Note: Do not lock, since this can be calling back to the loader, which separately also drives * this call (callers should synchronize on the loader before making this call). */ public synchronized void preloadPlan(RecentsTaskLoader loader, int runningTaskId, void preloadPlan(RecentsTaskLoader loader, int runningTaskId, boolean includeFrontMostExcludedTask) { Resources res = mContext.getResources(); ArrayList<Task> allTasks = new ArrayList<>(); Loading Loading @@ -223,8 +228,11 @@ public class RecentsTaskLoadPlan { /** * Called to apply the actual loading based on the specified conditions. * * Note: Do not lock, since this can be calling back to the loader, which separately also drives * this call (callers should synchronize on the loader before making this call). */ public synchronized void executePlan(Options opts, RecentsTaskLoader loader) { void executePlan(Options opts, RecentsTaskLoader loader) { Resources res = mContext.getResources(); // Iterate through each of the tasks and load them according to the load conditions. Loading
packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +14 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.os.Looper; import android.util.Log; import android.util.LruCache; import com.android.internal.annotations.GuardedBy; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsConfiguration; Loading Loading @@ -243,7 +244,9 @@ public class RecentsTaskLoader { private final TaskResourceLoadQueue mLoadQueue; private final BackgroundTaskLoader mLoader; private final HighResThumbnailLoader mHighResThumbnailLoader; @GuardedBy("this") private final TaskKeyStrongCache<ThumbnailData> mThumbnailCache = new TaskKeyStrongCache<>(); @GuardedBy("this") private final TaskKeyStrongCache<ThumbnailData> mTempCache = new TaskKeyStrongCache<>(); private final int mMaxThumbnailCacheSize; private final int mMaxIconCacheSize; Loading Loading @@ -318,14 +321,20 @@ public class RecentsTaskLoader { return plan; } /** Preloads raw recents tasks using the specified plan to store the output. */ public synchronized void preloadRawTasks(RecentsTaskLoadPlan plan, boolean includeFrontMostExcludedTask) { plan.preloadRawTasks(includeFrontMostExcludedTask); } /** Preloads recents tasks using the specified plan to store the output. */ public void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId, public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId, boolean includeFrontMostExcludedTask) { plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask); } /** Begins loading the heavy task data according to the specified options. */ public void loadTasks(Context context, RecentsTaskLoadPlan plan, public synchronized void loadTasks(Context context, RecentsTaskLoadPlan plan, RecentsTaskLoadPlan.Options opts) { if (opts == null) { throw new RuntimeException("Requires load options"); Loading Loading @@ -380,8 +389,7 @@ public class RecentsTaskLoader { * Handles signals from the system, trimming memory when requested to prevent us from running * out of memory. */ public void onTrimMemory(int level) { RecentsConfiguration config = Recents.getConfiguration(); public synchronized void onTrimMemory(int level) { switch (level) { case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: // Stop the loader immediately when the UI is no longer visible Loading Loading @@ -516,7 +524,7 @@ public class RecentsTaskLoader { /** * Returns the cached thumbnail if the task key is not expired, updating the cache if it is. */ ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached, synchronized ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached, boolean storeInCache) { SystemServicesProxy ssp = Recents.getSystemServices(); Loading Loading @@ -616,7 +624,7 @@ public class RecentsTaskLoader { } } public void dump(String prefix, PrintWriter writer) { public synchronized void dump(String prefix, PrintWriter writer) { String innerPrefix = prefix + " "; writer.print(prefix); writer.println(TAG); Loading