diff options
| author | 2017-03-14 18:21:40 +0100 | |
|---|---|---|
| committer | 2017-03-22 16:29:15 +0100 | |
| commit | 8f4fe6eccbc3849686f08389cb5868f2d59f5fbb (patch) | |
| tree | 2bc1c8981f728f7f76255e487eaabc12ff33cbcd | |
| parent | 0fe7ce968bc7f0eff64f08e2d51c8b1e6b4a6fc8 (diff) | |
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
6 files changed, 114 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 4ae6dbe21721..b8d0b8c096fe 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -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)) { - continue; + 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 */); } /** diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java index 45a799948801..275234095887 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java @@ -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())); } } diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml index 4dd51dcc7d09..64cdcf78fdcc 100644 --- a/tests/ActivityTests/AndroidManifest.xml +++ b/tests/ActivityTests/AndroidManifest.xml @@ -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" /> diff --git a/tests/ActivityTests/res/values/colors.xml b/tests/ActivityTests/res/values/colors.xml new file mode 100644 index 000000000000..99257228dc48 --- /dev/null +++ b/tests/ActivityTests/res/values/colors.xml @@ -0,0 +1,18 @@ +<?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 diff --git a/tests/ActivityTests/res/values/themes.xml b/tests/ActivityTests/res/values/themes.xml index 67f5938ff217..b8dd83039ed8 100644 --- a/tests/ActivityTests/res/values/themes.xml +++ b/tests/ActivityTests/res/values/themes.xml @@ -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> diff --git a/tests/ActivityTests/src/com/google/android/test/activity/DisableScreenshotsActivity.java b/tests/ActivityTests/src/com/google/android/test/activity/DisableScreenshotsActivity.java index de24ca2ac9e8..fa5724ea64bc 100644 --- a/tests/ActivityTests/src/com/google/android/test/activity/DisableScreenshotsActivity.java +++ b/tests/ActivityTests/src/com/google/android/test/activity/DisableScreenshotsActivity.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; +import android.os.SystemClock; /** * Activity for which screenshotting is disabled. @@ -32,4 +33,13 @@ public class DisableScreenshotsActivity extends Activity { setDisablePreviewScreenshots(true); getWindow().getDecorView().setBackgroundColor(Color.RED); } + + @Override + protected void onResume() { + super.onResume(); + + // This is to simulate slowness over resuming the app, such that we have plenty of time to + // see the starting window. + SystemClock.sleep(500); + } } |