Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Move MediaProjectionGlobal API to DisplayManager
Browse files Browse the repository at this point in the history
Add a static method in DisplayManager that allows the caller to create a
VirtualDisplay without having an instance of DisplayManager (which
requires a context). This can only be used from a process that has the
CAPTURE_VIDEO_OUTPUT permission.

Also added RequiresPermission(CAPTURE_VIDEO_OUTPUT)
annotation for the new API.

Test: DisplayManagerTest
Bug: 247776252
Change-Id: I1eb94ab1063d89860cdfb2a58d4653d9a77eec98
  • Loading branch information
Chavi Weingarten committed Sep 23, 2022
1 parent 51847be commit c6f10b4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 132 deletions.
10 changes: 1 addition & 9 deletions core/api/system-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3951,6 +3951,7 @@ package android.hardware.display {
}

public final class DisplayManager {
method @Nullable @RequiresPermission("android.permission.CAPTURE_VIDEO_OUTPUT") public static android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface);
method @RequiresPermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS) public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats();
method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration();
method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfigurationForDisplay(@NonNull String);
Expand Down Expand Up @@ -6672,15 +6673,6 @@ package android.media.musicrecognition {

}

package android.media.projection {

public class MediaProjectionGlobal {
method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface);
method @NonNull public static android.media.projection.MediaProjectionGlobal getInstance();
}

}

package android.media.session {

public final class MediaSessionManager {
Expand Down
59 changes: 59 additions & 0 deletions core/java/android/hardware/display/DisplayManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@
import android.app.KeyguardManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.res.Resources;
import android.graphics.Point;
import android.media.projection.MediaProjection;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
Expand Down Expand Up @@ -1304,6 +1308,61 @@ private int toMatchContentFrameRateSetting(@SwitchingType int switchingType) {
}
}

/**
* Creates a VirtualDisplay that will mirror the content of displayIdToMirror
* @param name The name for the virtual display
* @param width The initial width for the virtual display
* @param height The initial height for the virtual display
* @param displayIdToMirror The displayId that will be mirrored into the virtual display.
* @return VirtualDisplay that can be used to update properties.
*
* @hide
*/
@RequiresPermission(Manifest.permission.CAPTURE_VIDEO_OUTPUT)
@Nullable
@SystemApi
public static VirtualDisplay createVirtualDisplay(@NonNull String name, int width, int height,
int displayIdToMirror, @Nullable Surface surface) {
IDisplayManager sDm = IDisplayManager.Stub.asInterface(
ServiceManager.getService(Context.DISPLAY_SERVICE));
IPackageManager sPackageManager = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));

// Density doesn't matter since this virtual display is only used for mirroring.
VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
height, 1 /* densityDpi */)
.setFlags(VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)
.setDisplayIdToMirror(displayIdToMirror);
if (surface != null) {
builder.setSurface(surface);
}
VirtualDisplayConfig virtualDisplayConfig = builder.build();

String[] packages;
try {
packages = sPackageManager.getPackagesForUid(Process.myUid());
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}

// Just use the first one since it just needs to match the package when looking it up by
// calling UID in system server.
// The call may come from a rooted device, in that case the requesting uid will be root so
// it will not have any package name
String packageName = packages == null ? null : packages[0];
DisplayManagerGlobal.VirtualDisplayCallback
callbackWrapper = new DisplayManagerGlobal.VirtualDisplayCallback(null, null);
int displayId;
try {
displayId = sDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper, null,
packageName);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
return DisplayManagerGlobal.getInstance().createVirtualDisplayWrapper(virtualDisplayConfig,
null, callbackWrapper, displayId);
}

/**
* Listens for changes in available display devices.
*/
Expand Down
5 changes: 2 additions & 3 deletions core/java/android/view/SurfaceControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplay;
import android.hardware.graphics.common.DisplayDecorationSupport;
import android.media.projection.MediaProjectionGlobal;
import android.opengl.EGLDisplay;
import android.opengl.EGLSync;
import android.os.Build;
Expand Down Expand Up @@ -2017,8 +2016,8 @@ public static IBinder createDisplay(String name, boolean secure) {
}

// We don't have a size yet so pass in 1 for width and height since 0 is invalid
VirtualDisplay vd = MediaProjectionGlobal.getInstance().createVirtualDisplay(name,
1 /* width */, 1 /* height */, INVALID_DISPLAY, null /* Surface */);
VirtualDisplay vd = DisplayManager.createVirtualDisplay(name, 1 /* width */, 1 /* height */,
INVALID_DISPLAY, null /* Surface */);
return vd == null ? null : vd.getToken().asBinder();
}

Expand Down
120 changes: 0 additions & 120 deletions media/java/android/media/projection/MediaProjectionGlobal.java

This file was deleted.

0 comments on commit c6f10b4

Please sign in to comment.