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

Commit 8f4fe6ec authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

When snapshots are disabled, fill it with single color.

Test: Launch DisableScreenshotsActivity, go to recents, make sure
content is blue. Reopen activity from home, make sure starting
window is blue.

Bug: 31339431
Change-Id: I29689774c3cdcb784d8f5bfa4f947a6f35b91e01
parent 0fe7ce96
Loading
Loading
Loading
Loading
+74 −8
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@
package com.android.server.wm;

import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
import static android.graphics.GraphicBuffer.USAGE_SW_READ_NEVER;
import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_RARELY;
import static android.graphics.PixelFormat.RGBA_8888;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.StackId;
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Canvas;
import android.graphics.GraphicBuffer;
import android.os.Environment;
import android.util.ArraySet;
@@ -48,6 +53,26 @@ import java.io.PrintWriter;
 */
class TaskSnapshotController {

    /**
     * Return value for {@link #getSnapshotMode}: We are allowed to take a real screenshot to be
     * used as the snapshot.
     */
    @VisibleForTesting
    static final int SNAPSHOT_MODE_REAL = 0;

    /**
     * Return value for {@link #getSnapshotMode}: We are not allowed to take a real screenshot but
     * we should try to use the app theme to create a dummy representation of the app.
     */
    @VisibleForTesting
    static final int SNAPSHOT_MODE_APP_THEME = 1;

    /**
     * Return value for {@link #getSnapshotMode}: We aren't allowed to take any snapshot.
     */
    @VisibleForTesting
    static final int SNAPSHOT_MODE_NONE = 2;

    private final WindowManagerService mService;

    private final TaskSnapshotCache mCache;
@@ -88,10 +113,21 @@ class TaskSnapshotController {
        getClosingTasks(closingApps, mTmpTasks);
        for (int i = mTmpTasks.size() - 1; i >= 0; i--) {
            final Task task = mTmpTasks.valueAt(i);
            if (!canSnapshotTask(task)) {
            final int mode = getSnapshotMode(task);
            final TaskSnapshot snapshot;
            switch (mode) {
                case SNAPSHOT_MODE_NONE:
                    continue;
                case SNAPSHOT_MODE_APP_THEME:
                    snapshot = drawAppThemeSnapshot(task);
                    break;
                case SNAPSHOT_MODE_REAL:
                    snapshot = snapshotTask(task);
                    break;
                default:
                    snapshot = null;
                    break;
            }
            final TaskSnapshot snapshot = snapshotTask(task);
            if (snapshot != null) {
                mCache.putSnapshot(task, snapshot);
                mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
@@ -153,12 +189,42 @@ class TaskSnapshotController {
    }

    @VisibleForTesting
    boolean canSnapshotTask(Task task) {
        // TODO: Figure out what happens when snapshots are disabled. Can we draw a splash screen
        // instead?
    int getSnapshotMode(Task task) {
        final AppWindowToken topChild = task.getTopChild();
        return !StackId.isHomeOrRecentsStack(task.mStack.mStackId)
                && topChild != null && !topChild.shouldDisablePreviewScreenshots();
        if (StackId.isHomeOrRecentsStack(task.mStack.mStackId)) {
            return SNAPSHOT_MODE_NONE;
        } else if (topChild != null && topChild.shouldDisablePreviewScreenshots()) {
            return SNAPSHOT_MODE_APP_THEME;
        } else {
            return SNAPSHOT_MODE_REAL;
        }
    }

    /**
     * If we are not allowed to take a real screenshot, this attempts to represent the app as best
     * as possible by using the theme's window background.
     */
    private TaskSnapshot drawAppThemeSnapshot(Task task) {
        final AppWindowToken topChild = task.getTopChild();
        if (topChild == null) {
            return null;
        }
        final WindowState mainWindow = topChild.findMainWindow();
        if (mainWindow == null) {
            return null;
        }
        final int color = task.getTaskDescription().getBackgroundColor();
        final GraphicBuffer buffer = GraphicBuffer.create(mainWindow.getFrameLw().width(),
                mainWindow.getFrameLw().height(),
                RGBA_8888, USAGE_HW_TEXTURE | USAGE_SW_WRITE_RARELY | USAGE_SW_READ_NEVER);
        if (buffer == null) {
            return null;
        }
        final Canvas c = buffer.lockCanvas();
        c.drawColor(color);
        buffer.unlockCanvasAndPost(c);
        return new TaskSnapshot(buffer, topChild.getConfiguration().orientation,
                mainWindow.mStableInsets, false /* reduced */, 1.0f /* scale */);
    }

    /**
+6 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.wm;

import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
import static com.android.server.wm.TaskSnapshotController.*;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -72,13 +73,15 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
    }

    @Test
    public void testSnapshotsDisabled() throws Exception {
    public void testGetSnapshotMode() throws Exception {
        final WindowState disabledWindow = createWindow(null,
                FIRST_APPLICATION_WINDOW, sDisplayContent, "disabledWindow");
        disabledWindow.mAppToken.setDisablePreviewSnapshots(true);
        assertFalse(sWm.mTaskSnapshotController.canSnapshotTask(disabledWindow.getTask()));
        assertEquals(SNAPSHOT_MODE_APP_THEME,
                sWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
        final WindowState normalWindow = createWindow(null,
                FIRST_APPLICATION_WINDOW, sDisplayContent, "normalWindow");
        assertTrue(sWm.mTaskSnapshotController.canSnapshotTask(normalWindow.getTask()));
        assertEquals(SNAPSHOT_MODE_REAL,
                sWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -80,7 +80,8 @@
        <receiver android:name="TrackTimeReceiver" />
        <receiver android:name="AlarmSpamReceiver" />
        <activity android:name="DisableScreenshotsActivity"
                android:label="DisableScreenshots">
                android:label="DisableScreenshots"
                android:theme="@style/DisableScreenshots">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
+18 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright (C) 2017 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.
-->
<resources>
    <color name="blue">#0000ff</color>
</resources>
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -22,4 +22,8 @@
        <item name="android:windowEnterAnimation">@anim/slow_enter</item>
        <item name="android:windowExitAnimation">@anim/slow_exit</item>
    </style>
    <style name="DisableScreenshots" parent="@android:style/Theme.Material">
        <item name="android:colorBackground">@color/blue</item>
        <item name="android:windowBackground">@color/blue</item>
    </style>
</resources>
Loading