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

Commit 829b9cd1 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fill task snapshot with background color

Make sure to fill the portions that are not covered by the
snapshot are filled with the task background color.

Also fix an issue where the starting window was removed across
configuration changes.

Test: runtest frameworks-services -c
com.android.server.wm.TaskSnapshotSurfaceTest
Bug: 31339431
Change-Id: I2451be87aff79b337015ab4bba72cfa03c0d3582
parent 8b702ede
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -416,7 +416,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
        final Configuration overrideConfig = getOverrideConfiguration();
        mWindowContainerController = new TaskWindowContainerController(taskId, this, getStackId(),
                userId, bounds, overrideConfig, mResizeMode, isHomeTask(), isOnTopLauncher(), onTop,
                showForAllUsers);
                showForAllUsers, lastTaskDescription);
    }

    void removeWindowContainer() {
@@ -1402,6 +1402,9 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
            }
            lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary,
                    colorBackground);
            if (mWindowContainerController != null) {
                mWindowContainerController.setTaskDescription(lastTaskDescription);
            }
            // Update the task affiliation color if we are the parent of the group
            if (taskId == mAffiliatedTaskId) {
                mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
+1 −1
Original line number Diff line number Diff line
@@ -675,7 +675,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
            // well there is no point now.
            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
            startingData = null;
        } else if (mChildren.size() == 1 && startingSurface != null) {
        } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
            // If this is the last window except for a starting transition window,
            // we need to get rid of the starting transition.
            if (getController() != null) {
+13 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.RESIZE_TASK;

import android.app.ActivityManager.StackId;
import android.app.ActivityManager.TaskDescription;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -90,9 +91,11 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
    // Whether this task is an on-top launcher task, which is determined by the root activity.
    private boolean mIsOnTopLauncher;

    private TaskDescription mTaskDescription;

    Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
            Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode, boolean homeTask,
            TaskWindowContainerController controller) {
            TaskDescription taskDescription, TaskWindowContainerController controller) {
        mTaskId = taskId;
        mStack = stack;
        mUserId = userId;
@@ -102,6 +105,7 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
        mHomeTask = homeTask;
        setController(controller);
        setBounds(bounds, overrideConfig);
        mTaskDescription = taskDescription;
    }

    DisplayContent getDisplayContent() {
@@ -647,6 +651,14 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
        }
    }

    void setTaskDescription(TaskDescription taskDescription) {
        mTaskDescription = taskDescription;
    }

    TaskDescription getTaskDescription() {
        return mTaskDescription;
    }

    @Override
    boolean fillsParent() {
        return mFillsParent || !StackId.isTaskResizeAllowed(mStack.mStackId);
@@ -688,6 +700,5 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU
            pw.println(triplePrefix + "Activity #" + i + " " + wtoken);
            wtoken.dump(pw, triplePrefix);
        }

    }
}
+37 −4
Original line number Diff line number Diff line
@@ -26,12 +26,16 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.app.ActivityManager.TaskDescription;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Slog;
@@ -43,6 +47,7 @@ import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy.StartingSurface;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.view.BaseIWindow;

/**
@@ -61,6 +66,7 @@ class TaskSnapshotSurface implements StartingSurface {
    private final WindowManagerService mService;
    private boolean mHasDrawn;
    private boolean mReportNextDraw;
    private Paint mFillBackgroundPaint = new Paint();

    static TaskSnapshotSurface create(WindowManagerService service, AppWindowToken token,
            GraphicBuffer snapshot) {
@@ -73,6 +79,7 @@ class TaskSnapshotSurface implements StartingSurface {
        final Rect tmpRect = new Rect();
        final Rect tmpFrame = new Rect();
        final Configuration tmpConfiguration = new Configuration();
        int fillBackgroundColor = Color.WHITE;
        synchronized (service.mWindowMap) {
            layoutParams.type = TYPE_APPLICATION_STARTING;
            layoutParams.format = snapshot.getFormat();
@@ -90,6 +97,12 @@ class TaskSnapshotSurface implements StartingSurface {
            layoutParams.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
            layoutParams.setTitle(String.format(TITLE_FORMAT, token.mTask.mTaskId));
            if (token.mTask != null) {
                final TaskDescription taskDescription = token.mTask.getTaskDescription();
                if (taskDescription != null) {
                    fillBackgroundColor = taskDescription.getBackgroundColor();
                }
            }
        }
        try {
            final int res = session.addToDisplay(window, window.mSeq, layoutParams,
@@ -103,7 +116,7 @@ class TaskSnapshotSurface implements StartingSurface {
            // Local call.
        }
        final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
                surface);
                surface, fillBackgroundColor);
        window.setOuter(snapshotSurface);
        try {
            session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, tmpFrame,
@@ -116,11 +129,14 @@ class TaskSnapshotSurface implements StartingSurface {
        return snapshotSurface;
    }

    private TaskSnapshotSurface(WindowManagerService service, Window window, Surface surface) {
    @VisibleForTesting
    TaskSnapshotSurface(WindowManagerService service, Window window, Surface surface,
            int fillBackgroundColor) {
        mService = service;
        mSession = WindowManagerGlobal.getWindowSession();
        mWindow = window;
        mSurface = surface;
        mFillBackgroundPaint.setColor(fillBackgroundColor);
    }

    @Override
@@ -136,7 +152,9 @@ class TaskSnapshotSurface implements StartingSurface {

        // TODO: Just wrap the buffer here without any copying.
        final Canvas c = mSurface.lockHardwareCanvas();
        c.drawBitmap(Bitmap.createHardwareBitmap(snapshot), 0, 0, null);
        final Bitmap b = Bitmap.createHardwareBitmap(snapshot);
        fillEmptyBackground(c, b);
        c.drawBitmap(b, 0, 0, null);
        mSurface.unlockCanvasAndPost(c);
        final boolean reportNextDraw;
        synchronized (mService.mWindowMap) {
@@ -149,6 +167,21 @@ class TaskSnapshotSurface implements StartingSurface {
        mSurface.release();
    }

    @VisibleForTesting
    void fillEmptyBackground(Canvas c, Bitmap b) {
        final boolean fillHorizontally = c.getWidth() > b.getWidth();
        final boolean fillVertically = c.getHeight() > b.getHeight();
        if (fillHorizontally) {
            c.drawRect(b.getWidth(), 0, c.getWidth(), fillVertically
                        ? b.getHeight()
                        : c.getHeight(),
                    mFillBackgroundPaint);
        }
        if (fillVertically) {
            c.drawRect(0, b.getHeight(), c.getWidth(), c.getHeight(), mFillBackgroundPaint);
        }
    }

    private void reportDrawn() {
        synchronized (mService.mWindowMap) {
            mReportNextDraw = false;
@@ -160,7 +193,7 @@ class TaskSnapshotSurface implements StartingSurface {
        }
    }

    private static Handler sHandler = new Handler() {
    private static Handler sHandler = new Handler(Looper.getMainLooper()) {

        @Override
        public void handleMessage(Message msg) {
+16 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import android.app.ActivityManager.TaskDescription;
import android.app.ActivityManager.TaskSnapshot;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -62,7 +63,8 @@ public class TaskWindowContainerController

    public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
            int stackId, int userId, Rect bounds, Configuration overrideConfig, int resizeMode,
            boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers) {
            boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
            TaskDescription taskDescription) {
        super(listener, WindowManagerService.getInstance());
        mTaskId = taskId;

@@ -79,7 +81,7 @@ public class TaskWindowContainerController
            }
            EventLog.writeEvent(WM_TASK_CREATED, taskId, stackId);
            final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
                    homeTask, isOnTopLauncher);
                    homeTask, isOnTopLauncher, taskDescription);
            final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
            stack.addTask(task, position, showForAllUsers, true /* moveParents */);
        }
@@ -88,9 +90,9 @@ public class TaskWindowContainerController
    @VisibleForTesting
    Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
            Configuration overrideConfig, int resizeMode, boolean homeTask,
            boolean isOnTopLauncher) {
            boolean isOnTopLauncher, TaskDescription taskDescription) {
        return new Task(taskId, stack, userId, mService, bounds, overrideConfig, isOnTopLauncher,
                resizeMode, homeTask, this);
                resizeMode, homeTask, taskDescription, this);
    }

    @Override
@@ -263,6 +265,16 @@ public class TaskWindowContainerController
        }
    }

    public void setTaskDescription(TaskDescription taskDescription) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "setTaskDescription: taskId " + mTaskId + " not found.");
                return;
            }
            mContainer.setTaskDescription(taskDescription);
        }
    }

    void reportSnapshotChanged(TaskSnapshot snapshot) {
        mHandler.obtainMessage(REPORT_SNAPSHOT_CHANGED, snapshot).sendToTarget();
    }
Loading