Loading core/java/android/view/IWindowManager.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -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); } core/java/android/view/SurfaceControl.java +23 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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. */ Loading core/jni/android_view_SurfaceControl.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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[] = { Loading Loading @@ -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) Loading services/core/java/com/android/server/wm/WindowManagerService.java +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -7747,4 +7748,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; } } tests/MirrorSurfaceTest/Android.bp 0 → 100644 +6 −0 Original line number Diff line number Diff line android_test { name: "MirrorSurfaceTest", srcs: ["src/**/*.java"], platform_apis: true, certificate: "platform", } Loading
core/java/android/view/IWindowManager.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -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); }
core/java/android/view/SurfaceControl.java +23 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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. */ Loading
core/jni/android_view_SurfaceControl.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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[] = { Loading Loading @@ -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) Loading
services/core/java/com/android/server/wm/WindowManagerService.java +24 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -7747,4 +7748,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; } }
tests/MirrorSurfaceTest/Android.bp 0 → 100644 +6 −0 Original line number Diff line number Diff line android_test { name: "MirrorSurfaceTest", srcs: ["src/**/*.java"], platform_apis: true, certificate: "platform", }