Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 024f80ca authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move RecentsImpl task stack listener to background." into oc-dev

parents 59fe3108 f3cfa89d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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);
+92 −76
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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) {
@@ -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
@@ -645,6 +649,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
                        TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
            }
        }
    }

    private Rect getWindowRect(Rect windowRectOverride) {
       return windowRectOverride != null
@@ -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();
                    }
@@ -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
@@ -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);
@@ -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);
@@ -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;
@@ -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
+85 −68
Original line number Diff line number Diff line
@@ -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) { }
@@ -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);
        }
@@ -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);
        }
@@ -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.
@@ -1146,6 +1160,7 @@ public class SystemServicesProxy {
                }
            }
        }
    }

    public void endProlongedAnimations() {
        if (mWm == null) {
@@ -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--) {
@@ -1318,3 +1334,4 @@ public class SystemServicesProxy {
            }
        }
    }
}
+11 −3
Original line number Diff line number Diff line
@@ -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();
@@ -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<>();
@@ -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.
+14 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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");
@@ -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
@@ -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();

@@ -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);