Merge "Drop task snapshot with invalid hw buffer" into tm-dev

This commit is contained in:
Riddle Hsu
2022-03-24 14:23:49 +00:00
committed by Android (Google) Code Review
8 changed files with 43 additions and 14 deletions

View File

@@ -19,7 +19,6 @@ package android.app;
import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo;
import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName; import android.content.ComponentName;
import android.os.Binder;
import android.os.Build; import android.os.Build;
import android.os.RemoteException; import android.os.RemoteException;
import android.window.TaskSnapshot; import android.window.TaskSnapshot;
@@ -32,10 +31,18 @@ import android.window.TaskSnapshot;
*/ */
public abstract class TaskStackListener extends ITaskStackListener.Stub { public abstract class TaskStackListener extends ITaskStackListener.Stub {
/** Whether this listener and the callback dispatcher are in different processes. */
private boolean mIsRemote = true;
@UnsupportedAppUsage @UnsupportedAppUsage
public TaskStackListener() { public TaskStackListener() {
} }
/** Indicates that this listener lives in system server. */
public void setIsLocal() {
mIsRemote = false;
}
@Override @Override
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void onTaskStackChanged() throws RemoteException { public void onTaskStackChanged() throws RemoteException {
@@ -154,8 +161,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
@Override @Override
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException { public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
if (Binder.getCallingPid() != android.os.Process.myPid() if (mIsRemote && snapshot != null && snapshot.getHardwareBuffer() != null) {
&& snapshot != null && snapshot.getHardwareBuffer() != null) {
// Preemptively clear any reference to the buffer // Preemptively clear any reference to the buffer
snapshot.getHardwareBuffer().close(); snapshot.getHardwareBuffer().close();
} }

View File

@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo;
import android.app.ITaskStackListener; import android.app.ITaskStackListener;
import android.app.TaskInfo; import android.app.TaskInfo;
import android.app.TaskStackListener;
import android.content.ComponentName; import android.content.ComponentName;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
@@ -286,6 +287,9 @@ class TaskChangeNotificationController {
if (listener instanceof Binder) { if (listener instanceof Binder) {
synchronized (mLocalTaskStackListeners) { synchronized (mLocalTaskStackListeners) {
if (!mLocalTaskStackListeners.contains(listener)) { if (!mLocalTaskStackListeners.contains(listener)) {
if (listener instanceof TaskStackListener) {
((TaskStackListener) listener).setIsLocal();
}
mLocalTaskStackListeners.add(listener); mLocalTaskStackListeners.add(listener);
} }
} }

View File

@@ -480,12 +480,17 @@ class TaskSnapshotController {
} }
final HardwareBuffer buffer = screenshotBuffer == null ? null final HardwareBuffer buffer = screenshotBuffer == null ? null
: screenshotBuffer.getHardwareBuffer(); : screenshotBuffer.getHardwareBuffer();
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) { if (isInvalidHardwareBuffer(buffer)) {
return null; return null;
} }
return screenshotBuffer; return screenshotBuffer;
} }
static boolean isInvalidHardwareBuffer(HardwareBuffer buffer) {
return buffer == null || buffer.isClosed() // This must be checked before getting size.
|| buffer.getWidth() <= 1 || buffer.getHeight() <= 1;
}
@Nullable @Nullable
TaskSnapshot snapshotTask(Task task) { TaskSnapshot snapshotTask(Task task) {
return snapshotTask(task, PixelFormat.UNKNOWN); return snapshotTask(task, PixelFormat.UNKNOWN);

View File

@@ -407,6 +407,10 @@ class TaskSnapshotPersister {
} }
boolean writeBuffer() { boolean writeBuffer() {
if (TaskSnapshotController.isInvalidHardwareBuffer(mSnapshot.getHardwareBuffer())) {
Slog.e(TAG, "Invalid task snapshot hw buffer, taskId=" + mTaskId);
return false;
}
final Bitmap bitmap = Bitmap.wrapHardwareBuffer( final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace()); mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
if (bitmap == null) { if (bitmap == null) {

View File

@@ -9045,6 +9045,8 @@ public class WindowManagerService extends IWindowManager.Stub
} }
TaskSnapshot taskSnapshot; TaskSnapshot taskSnapshot;
final long token = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
Task task = mRoot.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS); Task task = mRoot.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
if (task == null) { if (task == null) {
@@ -9053,6 +9055,9 @@ public class WindowManagerService extends IWindowManager.Stub
} }
taskSnapshot = mTaskSnapshotController.captureTaskSnapshot(task, false); taskSnapshot = mTaskSnapshotController.captureTaskSnapshot(task, false);
} }
} finally {
Binder.restoreCallingIdentity(token);
}
if (taskSnapshot == null || taskSnapshot.getHardwareBuffer() == null) { if (taskSnapshot == null || taskSnapshot.getHardwareBuffer() == null) {
return null; return null;

View File

@@ -31,13 +31,13 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.window.TaskSnapshot;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.SystemClock; import android.os.SystemClock;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.util.ArraySet; import android.util.ArraySet;
import android.view.Surface; import android.view.Surface;
import android.window.TaskSnapshot;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
@@ -83,6 +83,12 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
assertEquals(TEST_INSETS, snapshot.getContentInsets()); assertEquals(TEST_INSETS, snapshot.getContentInsets());
assertNotNull(snapshot.getSnapshot()); assertNotNull(snapshot.getSnapshot());
assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation()); assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
snapshot.getHardwareBuffer().close();
mPersister.persistSnapshot(1, mTestUserId, snapshot);
mPersister.waitForQueueEmpty();
assertTrueForFiles(files, file -> !file.exists(),
" snapshot files must be removed by invalid buffer");
} }
@Test @Test

View File

@@ -131,8 +131,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
} }
TaskSnapshot createSnapshot() { TaskSnapshot createSnapshot() {
return new TaskSnapshotBuilder() return new TaskSnapshotBuilder().setTopActivityComponent(getUniqueComponentName()).build();
.build();
} }
protected static void assertTrueForFiles(File[] files, Predicate<File> predicate, protected static void assertTrueForFiles(File[] files, Predicate<File> predicate,

View File

@@ -903,7 +903,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
doReturn(100).when(hardwareBuffer).getHeight(); doReturn(100).when(hardwareBuffer).getHeight();
} }
private static ComponentName getUniqueComponentName() { static ComponentName getUniqueComponentName() {
return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME, return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++); DEFAULT_COMPONENT_CLASS_NAME + sCurrentActivityId++);
} }