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

Commit 92207df7 authored by Jeff Brown's avatar Jeff Brown
Browse files

Add support for dynamically setting the virtual display surface.

Previously, the surface that backs a virtual display had to be set
at the time when the display was created.  This change now makes
it possible to set or remove the surface later.  The virtual display
is treated as if it were "off" while no surface is attached to it.

Change-Id: Ib4fdbbb8b4ee79f0fb9ceb648f9bda4a8fa6a2ca
parent b04f3f74
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10950,7 +10950,9 @@ package android.hardware.display {
  public final class VirtualDisplay {
    method public android.view.Display getDisplay();
    method public android.view.Surface getSurface();
    method public void release();
    method public void setSurface(android.view.Surface);
  }
}
+9 −1
Original line number Diff line number Diff line
@@ -437,6 +437,14 @@ public final class DisplayManager {
     * The behavior of the virtual display depends on the flags that are provided
     * to this method.  By default, virtual displays are created to be private,
     * non-presentation and unsecure.  Permissions may be required to use certain flags.
     * </p><p>
     * As of {@link android.os.Build.VERSION_CODES#KITKAT_WATCH}, the surface may
     * be attached or detached dynamically using {@link VirtualDisplay#setSurface}.
     * Previously, the surface had to be non-null when {@link #createVirtualDisplay}
     * was called and could not be changed for the lifetime of the display.
     * </p><p>
     * Detaching the surface that backs a virtual display has a similar effect to
     * turning off the screen.
     * </p>
     *
     * @param name The name of the virtual display, must be non-empty.
@@ -444,7 +452,7 @@ public final class DisplayManager {
     * @param height The height of the virtual display in pixels, must be greater than 0.
     * @param densityDpi The density of the virtual display in dpi, must be greater than 0.
     * @param surface The surface to which the content of the virtual display should
     * be rendered, must be non-null.
     * be rendered, or null if there is none initially.
     * @param flags A combination of virtual display flags:
     * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
     * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, or {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
+9 −4
Original line number Diff line number Diff line
@@ -377,9 +377,6 @@ public final class DisplayManagerGlobal {
            throw new IllegalArgumentException("width, height, and densityDpi must be "
                    + "greater than 0");
        }
        if (surface == null) {
            throw new IllegalArgumentException("surface must not be null");
        }

        Binder token = new Binder();
        int displayId;
@@ -404,7 +401,15 @@ public final class DisplayManagerGlobal {
            }
            return null;
        }
        return new VirtualDisplay(this, display, token);
        return new VirtualDisplay(this, display, token, surface);
    }

    public void setVirtualDisplaySurface(IBinder token, Surface surface) {
        try {
            mDm.setVirtualDisplaySurface(token, surface);
        } catch (RemoteException ex) {
            Log.w(TAG, "Failed to set virtual display surface.", ex);
        }
    }

    public void releaseVirtualDisplay(IBinder token) {
+3 −0
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ interface IDisplayManager {
    int createVirtualDisplay(IBinder token, String packageName,
            String name, int width, int height, int densityDpi, in Surface surface, int flags);

    // No permissions required but must be same Uid as the creator.
    void setVirtualDisplaySurface(in IBinder token, in Surface surface);

    // No permissions required but must be same Uid as the creator.
    void releaseVirtualDisplay(in IBinder token);
}
+38 −5
Original line number Diff line number Diff line
@@ -17,15 +17,18 @@ package android.hardware.display;

import android.os.IBinder;
import android.view.Display;
import android.view.Surface;

/**
 * Represents a virtual display. The content of a virtual display is rendered to a
 * {@link android.view.Surface} that you must provide to {@link DisplayManager#createVirtualDisplay
 * createVirtualDisplay()}.
 * <p>Because a virtual display renders to a surface provided by the application, it will be
 * <p>
 * Because a virtual display renders to a surface provided by the application, it will be
 * released automatically when the process terminates and all remaining windows on it will
 * be forcibly removed. However, you should also explicitly call {@link #release} when you're
 * done with it.
 * be forcibly removed.  However, you should also explicitly call {@link #release} when
 * you're done with it.
 * </p>
 *
 * @see DisplayManager#createVirtualDisplay
 */
@@ -33,11 +36,14 @@ public final class VirtualDisplay {
    private final DisplayManagerGlobal mGlobal;
    private final Display mDisplay;
    private IBinder mToken;
    private Surface mSurface;

    VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) {
    VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token,
            Surface surface) {
        mGlobal = global;
        mDisplay = display;
        mToken = token;
        mSurface = surface;
    }

    /**
@@ -47,6 +53,32 @@ public final class VirtualDisplay {
        return mDisplay;
    }

    /**
     * Gets the surface that backs the virtual display.
     */
    public Surface getSurface() {
        return mSurface;
    }

    /**
     * Sets the surface that backs the virtual display.
     * <p>
     * Detaching the surface that backs a virtual display has a similar effect to
     * turning off the screen.
     * </p><p>
     * It is still the caller's responsibility to destroy the surface after it has
     * been detached.
     * </p>
     *
     * @param surface The surface to set, or null to detach the surface from the virtual display.
     */
    public void setSurface(Surface surface) {
        if (mSurface != surface) {
            mGlobal.setVirtualDisplaySurface(mToken, surface);
            mSurface = surface;
        }
    }

    /**
     * Releases the virtual display and destroys its underlying surface.
     * <p>
@@ -63,6 +95,7 @@ public final class VirtualDisplay {

    @Override
    public String toString() {
        return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken + "}";
        return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken
                + ", surface=" + mSurface + "}";
    }
}
Loading