Merge "Added takeScreenshot API to WindowOrganizer" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5d2781b772
@@ -16,9 +16,12 @@
|
||||
|
||||
package android.window;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import android.window.IDisplayAreaOrganizerController;
|
||||
import android.window.ITaskOrganizerController;
|
||||
import android.window.IWindowContainerTransactionCallback;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
/** @hide */
|
||||
@@ -47,4 +50,15 @@ interface IWindowOrganizerController {
|
||||
|
||||
/** @return An interface enabling the management of display area organizers. */
|
||||
IDisplayAreaOrganizerController getDisplayAreaOrganizerController();
|
||||
|
||||
/**
|
||||
* Take a screenshot of the requested Window token and place the content of the screenshot into
|
||||
* outSurfaceControl. The SurfaceControl will be a child of the token's parent, so it will be
|
||||
* a sibling of the token's window
|
||||
* @param token The token for the WindowContainer that should get a screenshot taken.
|
||||
* @param outSurfaceControl The SurfaceControl where the screenshot will be attached.
|
||||
*
|
||||
* @return true if the screenshot was successful, false otherwise.
|
||||
*/
|
||||
boolean takeScreenshot(in WindowContainerToken token, out SurfaceControl outSurfaceControl);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Singleton;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
/**
|
||||
* Base class for organizing specific types of windows like Tasks and DisplayAreas
|
||||
@@ -63,6 +65,28 @@ public class WindowOrganizer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a screenshot for a specified Window
|
||||
* @param token The token for the WindowContainer that should get a screenshot taken.
|
||||
* @return A SurfaceControl where the screenshot will be attached, or null if failed.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
@RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER)
|
||||
public static SurfaceControl takeScreenshot(@NonNull WindowContainerToken token) {
|
||||
try {
|
||||
SurfaceControl surfaceControl = new SurfaceControl();
|
||||
if (getWindowOrganizerController().takeScreenshot(token, surfaceControl)) {
|
||||
return surfaceControl;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
|
||||
static IWindowOrganizerController getWindowOrganizerController() {
|
||||
return IWindowOrganizerControllerSingleton.get();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
|
||||
import static android.Manifest.permission.READ_FRAME_BUFFER;
|
||||
|
||||
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
|
||||
@@ -27,17 +28,20 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.IDisplayAreaOrganizerController;
|
||||
import android.window.ITaskOrganizerController;
|
||||
import android.window.IWindowContainerTransactionCallback;
|
||||
import android.window.IWindowOrganizerController;
|
||||
import android.window.WindowContainerToken;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
import com.android.internal.util.function.pooled.PooledConsumer;
|
||||
@@ -377,6 +381,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
mTransactionCallbacksByPendingSyncId.remove(mSyncId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeScreenshot(WindowContainerToken token, SurfaceControl outSurfaceControl) {
|
||||
mService.mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "takeScreenshot()");
|
||||
final WindowContainer wc = WindowContainer.fromBinder(token.asBinder());
|
||||
if (wc == null) {
|
||||
throw new RuntimeException("Invalid token in screenshot transaction");
|
||||
}
|
||||
|
||||
final Rect bounds = new Rect();
|
||||
wc.getBounds(bounds);
|
||||
bounds.offsetTo(0, 0);
|
||||
SurfaceControl.ScreenshotGraphicBuffer buffer = SurfaceControl.captureLayers(
|
||||
wc.getSurfaceControl(), bounds, 1);
|
||||
|
||||
if (buffer == null || buffer.getGraphicBuffer() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SurfaceControl screenshot = mService.mWindowManager.mSurfaceControlFactory.apply(null)
|
||||
.setName(wc.getName() + " - Organizer Screenshot")
|
||||
.setBufferSize(bounds.width(), bounds.height())
|
||||
.setFormat(PixelFormat.TRANSLUCENT)
|
||||
.setParent(wc.getParentSurfaceControl())
|
||||
.build();
|
||||
|
||||
Surface surface = new Surface();
|
||||
surface.copyFrom(screenshot);
|
||||
surface.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(), null);
|
||||
surface.release();
|
||||
|
||||
outSurfaceControl.copyFrom(screenshot);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void enforceStackPermission(String func) {
|
||||
mService.mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, func);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user