diff options
| -rw-r--r-- | api/current.txt | 34 | ||||
| -rw-r--r-- | core/java/android/app/ActivityView.java | 4 | ||||
| -rw-r--r-- | core/java/android/view/IWindowManager.aidl | 5 | ||||
| -rw-r--r-- | core/java/android/view/Surface.java | 13 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 218 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 219 | ||||
| -rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 32 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/AppWindowToken.java | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DisplayContent.java | 10 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/SurfaceAnimator.java | 10 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 4 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java | 6 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java | 2 |
13 files changed, 308 insertions, 253 deletions
diff --git a/api/current.txt b/api/current.txt index 0ff804e67728..1520a01a3965 100644 --- a/api/current.txt +++ b/api/current.txt @@ -49692,6 +49692,7 @@ package android.view { } public class Surface implements android.os.Parcelable { + ctor public Surface(android.view.SurfaceControl); ctor public Surface(android.graphics.SurfaceTexture); method public int describeContents(); method public boolean isValid(); @@ -49714,6 +49715,38 @@ package android.view { ctor public Surface.OutOfResourcesException(String); } + public final class SurfaceControl implements android.os.Parcelable { + method public int describeContents(); + method public boolean isValid(); + method public void readFromParcel(android.os.Parcel); + method public void release(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.view.SurfaceControl> CREATOR; + } + + public static class SurfaceControl.Builder { + ctor public SurfaceControl.Builder(); + method public android.view.SurfaceControl build(); + method public android.view.SurfaceControl.Builder setBufferSize(@IntRange(from=0) int, @IntRange(from=0) int); + method @NonNull public android.view.SurfaceControl.Builder setFormat(int); + method public android.view.SurfaceControl.Builder setName(String); + method @NonNull public android.view.SurfaceControl.Builder setOpaque(boolean); + method @NonNull public android.view.SurfaceControl.Builder setParent(@Nullable android.view.SurfaceControl); + } + + public static class SurfaceControl.Transaction implements java.io.Closeable { + ctor public SurfaceControl.Transaction(); + method public void apply(); + method public void close(); + method @NonNull public android.view.SurfaceControl.Transaction merge(@NonNull android.view.SurfaceControl.Transaction); + method @NonNull public android.view.SurfaceControl.Transaction reparent(@NonNull android.view.SurfaceControl, @Nullable android.view.SurfaceControl); + method @NonNull public android.view.SurfaceControl.Transaction setAlpha(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0, to=1.0) float); + method @NonNull public android.view.SurfaceControl.Transaction setBufferSize(@NonNull android.view.SurfaceControl, @IntRange(from=0) int, @IntRange(from=0) int); + method @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int); + method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int); + method @NonNull public android.view.SurfaceControl.Transaction setVisibility(@NonNull android.view.SurfaceControl, boolean); + } + public interface SurfaceHolder { method public void addCallback(android.view.SurfaceHolder.Callback); method public android.view.Surface getSurface(); @@ -49758,6 +49791,7 @@ package android.view { ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int); method public boolean gatherTransparentRegion(android.graphics.Region); method public android.view.SurfaceHolder getHolder(); + method public android.view.SurfaceControl getSurfaceControl(); method public void setSecure(boolean); method public void setZOrderMediaOverlay(boolean); method public void setZOrderOnTop(boolean); diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index ab8f234766d6..4d3711ae7ff5 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -328,7 +328,7 @@ public class ActivityView extends ViewGroup { } } else { mTmpTransaction.reparent(mRootSurfaceControl, - mSurfaceView.getSurfaceControl().getHandle()).apply(); + mSurfaceView.getSurfaceControl()).apply(); } if (mVirtualDisplay != null) { @@ -390,7 +390,7 @@ public class ActivityView extends ViewGroup { .build(); try { - wm.reparentDisplayContent(displayId, mRootSurfaceControl.getHandle()); + wm.reparentDisplayContent(displayId, mRootSurfaceControl); wm.dontOverrideDisplayInfo(displayId); if (mSingleTaskInstance) { mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 330d72f139db..42ac8801629f 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -51,6 +51,7 @@ import android.view.IInputFilter; import android.view.AppTransitionAnimationSpec; import android.view.WindowContentFrameStats; import android.view.WindowManager; +import android.view.SurfaceControl; /** * System private interface to the window manager. @@ -555,8 +556,8 @@ interface IWindowManager * display content info to any SurfaceControl, as this would be a security issue. * * @param displayId The id of the display. - * @param surfaceControlHandle The SurfaceControl handle that the top level layers for the + * @param surfaceControlHandle The SurfaceControl that the top level layers for the * display should be re-parented to. */ - void reparentDisplayContent(int displayId, in IBinder surfaceControlHandle); + void reparentDisplayContent(int displayId, in SurfaceControl sc); } diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index f3cb3767ec9d..7fcb2afa48a9 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -185,6 +185,18 @@ public class Surface implements Parcelable { } /** + * Create a Surface assosciated with a given {@link SurfaceControl}. Buffers submitted to this + * surface will be displayed by the system compositor according to the parameters + * specified by the control. Multiple surfaces may be constructed from one SurfaceControl, + * but only one can be connected (e.g. have an active EGL context) at a time. + * + * @param from The SurfaceControl to assosciate this Surface with + */ + public Surface(SurfaceControl from) { + copyFrom(from); + } + + /** * Create Surface from a {@link SurfaceTexture}. * * Images drawn to the Surface will be made available to the {@link @@ -494,7 +506,6 @@ public class Surface implements Parcelable { * in to it. * * @param other {@link SurfaceControl} to copy from. - * * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 5e98236f7535..863b717008d2 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -27,6 +27,10 @@ import static android.view.Surface.ROTATION_90; import static android.view.SurfaceControlProto.HASH_CODE; import static android.view.SurfaceControlProto.NAME; +import android.annotation.FloatRange; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.Size; import android.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; @@ -58,10 +62,16 @@ import libcore.util.NativeAllocationRegistry; import java.io.Closeable; /** - * SurfaceControl - * @hide + * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is + * a combination of a buffer source, and metadata about how to display the buffers. + * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be + * composited. Using {@link SurfaceControl.Transaction} you can manipulate various + * properties of how the buffer will be displayed on-screen. SurfaceControl's are + * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have + * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited + * from the parent, as if the child were content in the parents buffer stream. */ -public class SurfaceControl implements Parcelable { +public final class SurfaceControl implements Parcelable { private static final String TAG = "SurfaceControl"; private static native long nativeCreate(SurfaceSession session, String name, @@ -103,6 +113,8 @@ public class SurfaceControl implements Parcelable { float dtdy, float dsdy); private static native void nativeSetColorTransform(long transactionObj, long nativeObject, float[] matrix, float[] translation); + private static native void nativeSetGeometry(long transactionObj, long nativeObject, + Rect sourceCrop, Rect dest, long orientation); private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color); private static native void nativeSetFlags(long transactionObj, long nativeObject, int flags, int mask); @@ -156,7 +168,7 @@ public class SurfaceControl implements Parcelable { private static native void nativeReparentChildren(long transactionObj, long nativeObject, IBinder handle); private static native void nativeReparent(long transactionObj, long nativeObject, - IBinder parentHandle); + long newParentNativeObject); private static native void nativeSeverChildren(long transactionObj, long nativeObject); private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject, int scalingMode); @@ -331,8 +343,7 @@ public class SurfaceControl implements Parcelable { */ public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; - /* Display power modes * / - + // Display power modes. /** * Display power mode off: used while blanking the screen. * Use only with {@link SurfaceControl#setDisplayPowerMode}. @@ -403,7 +414,6 @@ public class SurfaceControl implements Parcelable { /** * Builder class for {@link SurfaceControl} objects. - * @hide */ public static class Builder { private SurfaceSession mSession; @@ -427,8 +437,14 @@ public class SurfaceControl implements Parcelable { } /** - * Construct a new {@link SurfaceControl} with the set parameters. - * @hide + * Begin building a SurfaceControl. + */ + public Builder() { + } + + /** + * Construct a new {@link SurfaceControl} with the set parameters. The builder + * remains valid. */ public SurfaceControl build() { if (mWidth < 0 || mHeight < 0) { @@ -447,7 +463,6 @@ public class SurfaceControl implements Parcelable { * Set a debugging-name for the SurfaceControl. * * @param name A name to identify the Surface in debugging. - * @hide */ public Builder setName(String name) { mName = name; @@ -459,9 +474,9 @@ public class SurfaceControl implements Parcelable { * * @param width The buffer width in pixels. * @param height The buffer height in pixels. - * @hide */ - public Builder setBufferSize(int width, int height) { + public Builder setBufferSize(@IntRange(from = 0) int width, + @IntRange(from = 0) int height) { if (width < 0 || height < 0) { throw new IllegalArgumentException( "width and height must be positive"); @@ -474,8 +489,8 @@ public class SurfaceControl implements Parcelable { /** * Set the pixel format of the controlled surface's buffers, using constants from * {@link android.graphics.PixelFormat}. - * @hide */ + @NonNull public Builder setFormat(@PixelFormat.Format int format) { mFormat = format; return this; @@ -490,6 +505,7 @@ public class SurfaceControl implements Parcelable { * @param protectedContent Whether to require a protected sink. * @hide */ + @NonNull public Builder setProtected(boolean protectedContent) { if (protectedContent) { mFlags |= PROTECTED_APP; @@ -506,6 +522,7 @@ public class SurfaceControl implements Parcelable { * not a complete prevention of readback as {@link #setProtected}. * @hide */ + @NonNull public Builder setSecure(boolean secure) { if (secure) { mFlags |= SECURE; @@ -537,8 +554,8 @@ public class SurfaceControl implements Parcelable { * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) * were set automatically. * @param opaque Whether the Surface is OPAQUE. - * @hide */ + @NonNull public Builder setOpaque(boolean opaque) { if (opaque) { mFlags |= OPAQUE; @@ -556,9 +573,9 @@ public class SurfaceControl implements Parcelable { * of the parent. * * @param parent The parent control. - * @hide */ - public Builder setParent(SurfaceControl parent) { + @NonNull + public Builder setParent(@Nullable SurfaceControl parent) { mParent = parent; return this; } @@ -673,9 +690,6 @@ public class SurfaceControl implements Parcelable { private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid) throws OutOfResourcesException, IllegalArgumentException { - if (session == null) { - throw new IllegalArgumentException("session must not be null"); - } if (name == null) { throw new IllegalArgumentException("name must not be null"); } @@ -729,9 +743,6 @@ public class SurfaceControl implements Parcelable { mCloseGuard.open("release"); } - /** - * @hide - */ public void readFromParcel(Parcel in) { if (in == null) { throw new IllegalArgumentException("source must not be null"); @@ -748,17 +759,11 @@ public class SurfaceControl implements Parcelable { assignNativeObject(object); } - /** - * @hide - */ @Override public int describeContents() { return 0; } - /** - * @hide - */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(mName); @@ -791,9 +796,6 @@ public class SurfaceControl implements Parcelable { proto.end(token); } - /** - * @hide - */ public static final Creator<SurfaceControl> CREATOR = new Creator<SurfaceControl>() { public SurfaceControl createFromParcel(Parcel in) { @@ -823,10 +825,12 @@ public class SurfaceControl implements Parcelable { } /** - * Release the local reference to the server-side surface. - * Always call release() when you're done with a Surface. - * This will make the surface invalid. - * @hide + * Release the local reference to the server-side surface. The surface + * may continue to exist on-screen as long as its parent continues + * to exist. To explicitly remove a surface from the screen use + * {@link Transaction#reparent} with a null-parent. + * + * Always call release() when you're done with a SurfaceControl. */ public void release() { if (mNativeObject != 0) { @@ -866,7 +870,10 @@ public class SurfaceControl implements Parcelable { } /** - * @hide + * Check whether this instance points to a valid layer with the system-compositor. For + * example this may be false if construction failed, or the layer was released. + * + * @return Whether this SurfaceControl is valid. */ public boolean isValid() { return mNativeObject != 0; @@ -962,9 +969,9 @@ public class SurfaceControl implements Parcelable { /** * @hide */ - public void reparent(IBinder newParentHandle) { + public void reparent(SurfaceControl newParent) { synchronized(SurfaceControl.class) { - sGlobalTransaction.reparent(this, newParentHandle); + sGlobalTransaction.reparent(this, newParent); } } @@ -1270,9 +1277,6 @@ public class SurfaceControl implements Parcelable { } } - /** - * @hide - */ @Override public String toString() { return "Surface(name=" + mName + ")/@0x" + @@ -1286,6 +1290,7 @@ public class SurfaceControl implements Parcelable { /** * Describes the properties of a physical display known to surface flinger. + * @hide */ public static final class PhysicalDisplayInfo { /** @@ -1777,9 +1782,12 @@ public class SurfaceControl implements Parcelable { } /** - * @hide + * An atomic set of changes to a set of SurfaceControl. */ public static class Transaction implements Closeable { + /** + * @hide + */ public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( Transaction.class.getClassLoader(), nativeGetNativeTransactionFinalizer(), 512); @@ -1789,9 +1797,12 @@ public class SurfaceControl implements Parcelable { Runnable mFreeNativeResources; /** - * @hide + * Open a new transaction object. The transaction may be filed with commands to + * manipulate {@link SurfaceControl} instances, and then applied atomically with + * {@link #apply}. Eventually the user should invoke {@link #close}, when the object + * is no longer required. Note however that re-using a transaction after a call to apply + * is allowed as a convenience. */ - @UnsupportedAppUsage public Transaction() { mNativeObject = nativeCreateTransaction(); mFreeNativeResources @@ -1801,9 +1812,7 @@ public class SurfaceControl implements Parcelable { /** * Apply the transaction, clearing it's state, and making it usable * as a new transaction. - * @hide */ - @UnsupportedAppUsage public void apply() { apply(false); } @@ -1811,7 +1820,6 @@ public class SurfaceControl implements Parcelable { /** * Close the transaction, if the transaction was not already applied this will cancel the * transaction. - * @hide */ @Override public void close() { @@ -1841,6 +1849,27 @@ public class SurfaceControl implements Parcelable { } /** + * Toggle the visibility of a given Layer and it's sub-tree. + * + * @param sc The SurfaceControl for which to set the visibility + * @param visible The new visibility + * @return This transaction object. + */ + @NonNull + public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) { + sc.checkNotReleased(); + if (visible) { + return show(sc); + } else { + return hide(sc); + } + } + + /** + * Request that a given surface and it's sub-tree be shown. + * + * @param sc The surface to show. + * @return This transaction. * @hide */ @UnsupportedAppUsage @@ -1851,6 +1880,10 @@ public class SurfaceControl implements Parcelable { } /** + * Request that a given surface and it's sub-tree be hidden. + * + * @param sc The surface to hidden. + * @return This transaction. * @hide */ @UnsupportedAppUsage @@ -1871,10 +1904,17 @@ public class SurfaceControl implements Parcelable { } /** - * @hide + * Set the default buffer size for the SurfaceControl, if there is an + * {@link Surface} assosciated with the control, then + * this will be the default size for buffers dequeued from it. + * @param sc The surface to set the buffer size for. + * @param w The default width + * @param h The default height + * @return This Transaction */ - @UnsupportedAppUsage - public Transaction setBufferSize(SurfaceControl sc, int w, int h) { + @NonNull + public Transaction setBufferSize(@NonNull SurfaceControl sc, + @IntRange(from = 0) int w, @IntRange(from = 0) int h) { sc.checkNotReleased(); mResizedSurfaces.put(sc, new Point(w, h)); nativeSetSize(mNativeObject, sc.mNativeObject, w, h); @@ -1882,10 +1922,17 @@ public class SurfaceControl implements Parcelable { } /** - * @hide + * Set the Z-order for a given SurfaceControl, relative to it's siblings. + * If two siblings share the same Z order the ordering is undefined. Surfaces + * with a negative Z will be placed below the parent surface. + * + * @param sc The SurfaceControl to set the Z order on + * @param z The Z-order + * @return This Transaction. */ - @UnsupportedAppUsage - public Transaction setLayer(SurfaceControl sc, int z) { + @NonNull + public Transaction setLayer(@NonNull SurfaceControl sc, + @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) { sc.checkNotReleased(); nativeSetLayer(mNativeObject, sc.mNativeObject, z); return this; @@ -1912,10 +1959,15 @@ public class SurfaceControl implements Parcelable { } /** - * @hide + * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl + * will be blended with the Surfaces under it according to the specified ratio. + * + * @param sc The given SurfaceControl. + * @param alpha The alpha to set. */ - @UnsupportedAppUsage - public Transaction setAlpha(SurfaceControl sc, float alpha) { + @NonNull + public Transaction setAlpha(@NonNull SurfaceControl sc, + @FloatRange(from = 0.0, to = 1.0) float alpha) { sc.checkNotReleased(); nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha); return this; @@ -1947,6 +1999,25 @@ public class SurfaceControl implements Parcelable { } /** + * Specify how the buffer assosciated with this Surface is mapped in to the + * parent coordinate space. The source frame will be scaled to fit the destination + * frame, after being rotated according to the orientation parameter. + * + * @param sc The SurfaceControl to specify the geometry of + * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer. + * @param destFrame The destination rectangle in parent space. Or null for the source frame. + * @param orientation The buffer rotation + * @return This transaction object. + */ + @NonNull + public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop, + @Nullable Rect destFrame, @Surface.Rotation int orientation) { + sc.checkNotReleased(); + nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation); + return this; + } + + /** * @hide */ @UnsupportedAppUsage @@ -2023,20 +2094,20 @@ public class SurfaceControl implements Parcelable { return this; } - @UnsupportedAppUsage /** * @hide */ + @UnsupportedAppUsage public Transaction setLayerStack(SurfaceControl sc, int layerStack) { sc.checkNotReleased(); nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack); return this; } - @UnsupportedAppUsage /** * @hide */ + @UnsupportedAppUsage public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle, long frameNumber) { if (frameNumber < 0) { @@ -2047,10 +2118,10 @@ public class SurfaceControl implements Parcelable { return this; } - @UnsupportedAppUsage /** * @hide */ + @UnsupportedAppUsage public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface, long frameNumber) { if (frameNumber < 0) { @@ -2071,13 +2142,25 @@ public class SurfaceControl implements Parcelable { return this; } - /** Re-parents a specific child layer to a new parent - * @hide + /** + * Re-parents a given layer to a new parent. Children inherit transform (position, scaling) + * crop, visibility, and Z-ordering from their parents, as if the children were pixels within the + * parent Surface. + * + * @param sc The SurfaceControl to reparent + * @param newParent The new parent for the given control. + * @return This Transaction */ - public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) { + @NonNull + public Transaction reparent(@NonNull SurfaceControl sc, + @Nullable SurfaceControl newParent) { sc.checkNotReleased(); - nativeReparent(mNativeObject, sc.mNativeObject, - newParentHandle); + long otherObject = 0; + if (newParent != null) { + newParent.checkNotReleased(); + otherObject = newParent.mNativeObject; + } + nativeReparent(mNativeObject, sc.mNativeObject, otherObject); return this; } @@ -2245,9 +2328,12 @@ public class SurfaceControl implements Parcelable { /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. - * @hide + * + * @param other The transaction to merge in to this one. + * @return This transaction. */ - public Transaction merge(Transaction other) { + @NonNull + public Transaction merge(@NonNull Transaction other) { mResizedSurfaces.putAll(other.mResizedSurfaces); other.mResizedSurfaces.clear(); nativeMergeTransaction(mNativeObject, other.mNativeObject); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 61fb00d3fe59..45e6c50d9ada 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -120,10 +120,11 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb final Rect mScreenRect = new Rect(); SurfaceSession mSurfaceSession; - SurfaceControlWithBackground mSurfaceControl; + SurfaceControl mSurfaceControl; // In the case of format changes we switch out the surface in-place // we need to preserve the old one until the new one has drawn. SurfaceControl mDeferredDestroySurfaceControl; + SurfaceControl mBackgroundControl; final Rect mTmpRect = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -487,6 +488,29 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } } + private void updateBackgroundVisibilityInTransaction() { + if (mBackgroundControl == null) { + return; + } + if ((mSurfaceFlags & PixelFormat.OPAQUE) == 0) { + mBackgroundControl.show(); + mBackgroundControl.setLayer(Integer.MIN_VALUE); + } else { + mBackgroundControl.hide(); + } + } + + private void releaseSurfaces() { + if (mSurfaceControl != null) { + mSurfaceControl.destroy(); + mSurfaceControl = null; + } + if (mBackgroundControl != null) { + mBackgroundControl.destroy(); + mBackgroundControl = null; + } + } + /** @hide */ protected void updateSurface() { if (!mHaveFrame) { @@ -553,14 +577,21 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb updateOpaqueFlag(); final String name = "SurfaceView - " + viewRoot.getTitle().toString(); - mSurfaceControl = new SurfaceControlWithBackground( - name, - (mSurfaceFlags & SurfaceControl.OPAQUE) != 0, - new SurfaceControl.Builder(mSurfaceSession) - .setBufferSize(mSurfaceWidth, mSurfaceHeight) - .setFormat(mFormat) - .setParent(viewRoot.getSurfaceControl()) - .setFlags(mSurfaceFlags)); + mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) + .setName(name) + .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) + .setBufferSize(mSurfaceWidth, mSurfaceHeight) + .setFormat(mFormat) + .setParent(viewRoot.getSurfaceControl()) + .setFlags(mSurfaceFlags) + .build(); + mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession) + .setName("Background for -" + name) + .setOpaque(true) + .setColorLayer(true) + .setParent(mSurfaceControl) + .build(); + } else if (mSurfaceControl == null) { return; } @@ -577,11 +608,13 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb SurfaceControl.openTransaction(); try { mSurfaceControl.setLayer(mSubLayer); + if (mViewVisibility) { mSurfaceControl.show(); } else { mSurfaceControl.hide(); } + updateBackgroundVisibilityInTransaction(); // While creating the surface, we will set it's initial // geometry. Outside of that though, we should generally @@ -724,8 +757,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mSurfaceControl != null && !mSurfaceCreated) { mSurface.release(); - mSurfaceControl.destroy(); - mSurfaceControl = null; + releaseSurfaces(); } } } catch (Exception ex) { @@ -823,7 +855,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb final ViewRootImpl viewRoot = getViewRootImpl(); applySurfaceTransforms(mSurfaceControl, position, frameNumber); - applySurfaceTransforms(mSurfaceControl.mBackgroundControl, position, frameNumber); applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface, frameNumber); @@ -950,7 +981,19 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb * @hide */ public void setResizeBackgroundColor(int bgColor) { - mSurfaceControl.setBackgroundColor(bgColor); + if (mBackgroundControl == null) { + return; + } + + final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f, + Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f }; + + SurfaceControl.openTransaction(); + try { + mBackgroundControl.setColor(colorComponents); + } finally { + SurfaceControl.closeTransaction(); + } } @UnsupportedAppUsage @@ -1128,154 +1171,12 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb }; /** - * @hide + * Return a SurfaceControl which can be used for parenting Surfaces to + * this SurfaceView. + * + * @return The SurfaceControl for this SurfaceView. */ public SurfaceControl getSurfaceControl() { return mSurfaceControl; } - - class SurfaceControlWithBackground extends SurfaceControl { - SurfaceControl mBackgroundControl; - private boolean mOpaque = true; - public boolean mVisible = false; - - public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b) - throws Exception { - super(b.setName(name).build()); - - mBackgroundControl = b.setName("Background for -" + name) - .setFormat(OPAQUE) - // Unset the buffer size of the background color layer. - .setBufferSize(0, 0) - .setColorLayer(true) - .build(); - mOpaque = opaque; - } - - @Override - public void setAlpha(float alpha) { - super.setAlpha(alpha); - mBackgroundControl.setAlpha(alpha); - } - - @Override - public void setLayer(int zorder) { - super.setLayer(zorder); - // -3 is below all other child layers as SurfaceView never goes below -2 - mBackgroundControl.setLayer(-3); - } - - @Override - public void setPosition(float x, float y) { - super.setPosition(x, y); - mBackgroundControl.setPosition(x, y); - } - - @Override - public void setBufferSize(int w, int h) { - super.setBufferSize(w, h); - // The background surface is a color layer so we do not set a size. - } - - @Override - public void setWindowCrop(Rect crop) { - super.setWindowCrop(crop); - mBackgroundControl.setWindowCrop(crop); - } - - @Override - public void setWindowCrop(int width, int height) { - super.setWindowCrop(width, height); - mBackgroundControl.setWindowCrop(width, height); - } - - @Override - public void setLayerStack(int layerStack) { - super.setLayerStack(layerStack); - mBackgroundControl.setLayerStack(layerStack); - } - - @Override - public void setOpaque(boolean isOpaque) { - super.setOpaque(isOpaque); - mOpaque = isOpaque; - updateBackgroundVisibility(); - } - - @Override - public void setSecure(boolean isSecure) { - super.setSecure(isSecure); - } - - @Override - public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - super.setMatrix(dsdx, dtdx, dsdy, dtdy); - mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); - } - - @Override - public void hide() { - super.hide(); - mVisible = false; - updateBackgroundVisibility(); - } - - @Override - public void show() { - super.show(); - mVisible = true; - updateBackgroundVisibility(); - } - - @Override - public void destroy() { - super.destroy(); - mBackgroundControl.destroy(); - } - - @Override - public void release() { - super.release(); - mBackgroundControl.release(); - } - - @Override - public void setTransparentRegionHint(Region region) { - super.setTransparentRegionHint(region); - mBackgroundControl.setTransparentRegionHint(region); - } - - @Override - public void deferTransactionUntil(IBinder handle, long frame) { - super.deferTransactionUntil(handle, frame); - mBackgroundControl.deferTransactionUntil(handle, frame); - } - - @Override - public void deferTransactionUntil(Surface barrier, long frame) { - super.deferTransactionUntil(barrier, frame); - mBackgroundControl.deferTransactionUntil(barrier, frame); - } - - /** Set the color to fill the background with. */ - private void setBackgroundColor(int bgColor) { - final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f, - Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f }; - - SurfaceControl.openTransaction(); - try { - mBackgroundControl.setColor(colorComponents); - } finally { - SurfaceControl.closeTransaction(); - } - } - - void updateBackgroundVisibility() { - if (mOpaque && mVisible) { - mBackgroundControl.show(); - } else { - mBackgroundControl.hide(); - } - } - } } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 897427fd8787..0453195e6a1d 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -126,7 +126,12 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject, jint windowType, jint ownerUid) { ScopedUtfChars name(env, nameStr); - sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); + sp<SurfaceComposerClient> client; + if (sessionObj != NULL) { + client = android_view_SurfaceSession_getClient(env, sessionObj); + } else { + client = SurfaceComposerClient::getDefault(); + } SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject); sp<SurfaceControl> surface; status_t err = client->createSurfaceChecked( @@ -277,6 +282,21 @@ static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj, transaction->setPosition(ctrl, x, y); } +static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, + jobject sourceObj, jobject dstObj, jlong orientation) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + + Rect source, dst; + if (sourceObj != NULL) { + source = rectFromObj(env, sourceObj); + } + if (dstObj != NULL) { + dst = rectFromObj(env, dstObj); + } + transaction->setGeometry(ctrl, source, dst, orientation); +} + static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject) { @@ -868,13 +888,13 @@ static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionO static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject, - jobject newParentObject) { + jlong newParentObject) { auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); - sp<IBinder> parentHandle = ibinderForJavaObject(env, newParentObject); + auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject); { auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); - transaction->reparent(ctrl, parentHandle); + transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL); } } @@ -1063,7 +1083,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeDeferTransactionUntilSurface }, {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V", (void*)nativeReparentChildren } , - {"nativeReparent", "(JJLandroid/os/IBinder;)V", + {"nativeReparent", "(JJJ)V", (void*)nativeReparent }, {"nativeSeverChildren", "(JJ)V", (void*)nativeSeverChildren } , @@ -1087,6 +1107,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeGetDisplayedContentSample", "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;", (void*)nativeGetDisplayedContentSample }, + {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V", + (void*)nativeSetGeometry } }; int register_android_view_SurfaceControl(JNIEnv* env) diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 9361e7fc3116..750c5ca5922e 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -2404,7 +2404,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree @Override protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) { if (!mSurfaceAnimator.hasLeash()) { - t.reparent(mSurfaceControl, newParent.getHandle()); + t.reparent(mSurfaceControl, newParent); } } @@ -2450,7 +2450,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree t.setWindowCrop(mAnimationBoundsLayer, mTmpRect); // Reparent leash to animation bounds layer. - t.reparent(leash, mAnimationBoundsLayer.getHandle()); + t.reparent(leash, mAnimationBoundsLayer); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index ac1159a3272a..8fefd352e027 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -4588,7 +4588,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * Reparents the given surface to mOverlayLayer. */ void reparentToOverlay(Transaction transaction, SurfaceControl surface) { - transaction.reparent(surface, mOverlayLayer.getHandle()); + transaction.reparent(surface, mOverlayLayer); } void applyMagnificationSpec(MagnificationSpec spec) { @@ -4831,11 +4831,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * Re-parent the DisplayContent's top surfaces, {@link #mWindowingLayer} and * {@link #mOverlayLayer} to the specified surfaceControl. * - * @param surfaceControlHandle The handle for the new SurfaceControl, where the DisplayContent's + * @param surfaceControlHandle The new SurfaceControl, where the DisplayContent's * surfaces will be re-parented to. */ - void reparentDisplayContent(IBinder surfaceControlHandle) { - mPendingTransaction.reparent(mWindowingLayer, surfaceControlHandle) - .reparent(mOverlayLayer, surfaceControlHandle); + void reparentDisplayContent(SurfaceControl sc) { + mPendingTransaction.reparent(mWindowingLayer, sc) + .reparent(mOverlayLayer, sc); } } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 9d9b48a5b36a..1a8a9110c649 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -199,7 +199,7 @@ class SurfaceAnimator { * @see #setLayer */ void reparent(Transaction t, SurfaceControl newParent) { - t.reparent(mLeash != null ? mLeash : mAnimatable.getSurfaceControl(), newParent.getHandle()); + t.reparent(mLeash != null ? mLeash : mAnimatable.getSurfaceControl(), newParent); } /** @@ -228,8 +228,8 @@ class SurfaceAnimator { // Cancel source animation, but don't let animation runner cancel the animation. from.cancelAnimation(t, false /* restarting */, false /* forwardCancel */); - t.reparent(surface, mLeash.getHandle()); - t.reparent(mLeash, parent.getHandle()); + t.reparent(surface, mLeash); + t.reparent(mLeash, parent); mAnimatable.onAnimationLeashCreated(t, mLeash); mService.mAnimationTransferMap.put(mAnimation, this); } @@ -275,7 +275,7 @@ class SurfaceAnimator { final boolean destroy = mLeash != null && surface != null && parent != null; if (destroy) { if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to original parent"); - t.reparent(surface, parent.getHandle()); + t.reparent(surface, parent); scheduleAnim = true; } mService.mAnimationTransferMap.remove(mAnimation); @@ -308,7 +308,7 @@ class SurfaceAnimator { if (!hidden) { t.show(leash); } - t.reparent(surface, leash.getHandle()); + t.reparent(surface, leash); return leash; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c8c834f4f18e..c6679a9ad0d7 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7334,7 +7334,7 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void reparentDisplayContent(int displayId, IBinder surfaceControlHandle) { + public void reparentDisplayContent(int displayId, SurfaceControl sc) { final Display display = mDisplayManager.getDisplay(displayId); if (display == null) { throw new IllegalArgumentException( @@ -7351,7 +7351,7 @@ public class WindowManagerService extends IWindowManager.Stub long token = Binder.clearCallingIdentity(); try { DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); - displayContent.reparentDisplayContent(surfaceControlHandle); + displayContent.reparentDisplayContent(sc); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java index d0b9225715c4..ea5ab7bf0621 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java @@ -70,9 +70,9 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase { mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */); verify(mTransaction).reparent(eq(mToken.getSurfaceControl()), - eq(mToken.mSurfaceAnimator.mLeash.getHandle())); + eq(mToken.mSurfaceAnimator.mLeash)); verify(mTransaction).reparent(eq(mToken.mSurfaceAnimator.mLeash), - eq(mToken.mAnimationBoundsLayer.getHandle())); + eq(mToken.mAnimationBoundsLayer)); } @Test @@ -111,7 +111,7 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase { mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */); verify(mTransaction).reparent(eq(mToken.getSurfaceControl()), - eq(mToken.mSurfaceAnimator.mLeash.getHandle())); + eq(mToken.mSurfaceAnimator.mLeash)); assertThat(mToken.mAnimationBoundsLayer).isNull(); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java index ad80cd6ddfb7..9b84215a8f3b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java @@ -90,7 +90,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase { final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass( OnAnimationFinishedCallback.class); assertAnimating(mAnimatable); - verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash.getHandle())); + verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash)); verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture()); callbackCaptor.getValue().onAnimationFinished(mSpec); |