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

Commit a51724fc authored by chaviw's avatar chaviw
Browse files

Added API to mirror display and added sample app.

Added the WMS.mirrorDisplay API to mirror a specified displayId. The
request requires the ACCESS_SURFACE_FLINGER permission.

Added a sample app to demonstrate the useablility of this API and
different ways the mirror SurfaceControl can be used.

Test: mmma tests/MirrorSurfaceTest and install apk
Bug: 131622422
Change-Id: Ic86115786d37473650b3c7ed39cba0bd4c65b281
parent 4d310631
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -644,4 +644,16 @@ interface IWindowManager
     * Enables/disables SurfaceFlinger layer tracing.
     */
    void setLayerTracing(boolean enabled);

    /**
     * Mirrors a specified display. The root of the mirrored hierarchy will be stored in
     * outSurfaceControl.
     * Requires the ACCESS_SURFACE_FLINGER permission.
     *
     * @param displayId The id of the display to mirror
     * @param outSurfaceControl The SurfaceControl for the root of the mirrored hierarchy.
     *
     * @return true if the display was successfully mirrored.
     */
    boolean mirrorDisplay(int displayId, out SurfaceControl outSurfaceControl);
}
+23 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public final class SurfaceControl implements Parcelable {
            boolean captureSecureLayers);
    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
            long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects);

    private static native long nativeMirrorSurface(long mirrorOfObject);
    private static native long nativeCreateTransaction();
    private static native long nativeGetNativeTransactionFinalizer();
    private static native void nativeApplyTransaction(long transactionObj, boolean sync);
@@ -2034,6 +2034,28 @@ public final class SurfaceControl implements Parcelable {
        return nativeSetDisplayBrightness(displayToken, brightness);
    }

    /**
     * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl}
     *
     * Real Hierarchy    Mirror
     *                     SC (value that's returned)
     *                      |
     *      A               A'
     *      |               |
     *      B               B'
     *
     * @param mirrorOf The root of the hierarchy that should be mirrored.
     * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy.
     *
     * @hide
     */
    public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) {
        long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject);
        SurfaceControl sc = new SurfaceControl();
        sc.assignNativeObject(nativeObj);
        return sc;
    }

     /**
     * An atomic set of changes to a set of SurfaceControl.
     */
+11 −0
Original line number Diff line number Diff line
@@ -1244,6 +1244,15 @@ static jlong nativeReadTransactionFromParcel(JNIEnv* env, jclass clazz, jobject
    return reinterpret_cast<jlong>(transaction.release());
}

static jlong nativeMirrorSurface(JNIEnv* env, jclass clazz, jlong mirrorOfObj) {
    sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
    SurfaceControl *mirrorOf = reinterpret_cast<SurfaceControl*>(mirrorOfObj);
    sp<SurfaceControl> surface = client->mirrorSurface(mirrorOf);

    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}

// ----------------------------------------------------------------------------

static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1394,6 +1403,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeReadTransactionFromParcel },
    {"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
            (void*)nativeWriteTransactionToParcel },
    {"nativeMirrorSurface", "(J)J",
            (void*)nativeMirrorSurface },
};

int register_android_view_SurfaceControl(JNIEnv* env)
+24 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.Manifest.permission.ACCESS_SURFACE_FLINGER;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -7746,4 +7747,27 @@ public class WindowManagerService extends IWindowManager.Stub
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public boolean mirrorDisplay(int displayId, SurfaceControl outSurfaceControl) {
        if (!checkCallingPermission(ACCESS_SURFACE_FLINGER, "mirrorDisplay()")) {
            throw new SecurityException("Requires ACCESS_SURFACE_FLINGER permission");
        }

        final SurfaceControl displaySc;
        synchronized (mGlobalLock) {
            DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                Slog.e(TAG, "Invalid displayId " + displayId + " for mirrorDisplay");
                return false;
            }

            displaySc = displayContent.getSurfaceControl();
        }

        final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc);
        outSurfaceControl.copyFrom(mirror);

        return true;
    }
}
+6 −0
Original line number Diff line number Diff line
android_test {
    name: "MirrorSurfaceTest",
    srcs: ["src/**/*.java"],
    platform_apis: true,
    certificate: "platform",
}
Loading