diff options
| -rw-r--r-- | core/java/android/view/Surface.java | 39 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 10 | ||||
| -rw-r--r-- | core/jni/android_view_Surface.cpp | 12 |
3 files changed, 60 insertions, 1 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 8bb3fa988a45..4f9dbd5ad7a0 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -52,7 +52,9 @@ public class Surface implements Parcelable { private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) throws OutOfResourcesException; + private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject); + private static native long nativeGetFromSurfaceControl(long surfaceControlNativeObject); private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty) throws OutOfResourcesException; @@ -410,6 +412,9 @@ public class Surface implements Parcelable { * back from a client, converting it from the representation being managed * by the window manager to the representation the client uses to draw * in to it. + * + * @param other {@link SurfaceControl} to copy from. + * * @hide */ public void copyFrom(SurfaceControl other) { @@ -420,7 +425,39 @@ public class Surface implements Parcelable { long surfaceControlPtr = other.mNativeObject; if (surfaceControlPtr == 0) { throw new NullPointerException( - "SurfaceControl native object is null. Are you using a released SurfaceControl?"); + "null SurfaceControl native object. Are you using a released SurfaceControl?"); + } + long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr); + + synchronized (mLock) { + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + } + setNativeObjectLocked(newNativeObject); + } + } + + /** + * Gets a reference a surface created from this one. This surface now holds a reference + * to the same data as the original surface, and is -not- the owner. + * This is for use by the window manager when returning a window surface + * back from a client, converting it from the representation being managed + * by the window manager to the representation the client uses to draw + * in to it. + * + * @param other {@link SurfaceControl} to create surface from. + * + * @hide + */ + public void createFrom(SurfaceControl other) { + if (other == null) { + throw new IllegalArgumentException("other must not be null"); + } + + long surfaceControlPtr = other.mNativeObject; + if (surfaceControlPtr == 0) { + throw new NullPointerException( + "null SurfaceControl native object. Are you using a released SurfaceControl?"); } long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 679a9cd92bc2..34ceeb7bcc0d 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -641,6 +641,16 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mSurface.copyFrom(mSurfaceControl); } + if (getContext().getApplicationInfo().targetSdkVersion + < Build.VERSION_CODES.O) { + // Some legacy applications use the underlying native {@link Surface} object + // as a key to whether anything has changed. In these cases, updates to the + // existing {@link Surface} will be ignored when the size changes. + // Therefore, we must explicitly recreate the {@link Surface} in these + // cases. + mSurface.createFrom(mSurfaceControl); + } + if (visible && mSurface.isValid()) { if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) { mSurfaceCreated = true; diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index bde913487e8a..494e266dabcd 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -400,6 +400,16 @@ static void nativeAllocateBuffers(JNIEnv* /* env */ , jclass /* clazz */, static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) { + sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj)); + sp<Surface> surface(ctrl->createSurface()); + if (surface != NULL) { + surface->incStrong(&sRefBaseOwner); + } + return reinterpret_cast<jlong>(surface.get()); +} + +static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, + jlong surfaceControlNativeObj) { /* * This is used by the WindowManagerService just after constructing * a Surface and is necessary for returning the Surface reference to @@ -596,6 +606,8 @@ static const JNINativeMethod gSurfaceMethods[] = { (void*)nativeAllocateBuffers }, {"nativeCreateFromSurfaceControl", "(J)J", (void*)nativeCreateFromSurfaceControl }, + {"nativeGetFromSurfaceControl", "(J)J", + (void*)nativeGetFromSurfaceControl }, {"nativeReadFromParcel", "(JLandroid/os/Parcel;)J", (void*)nativeReadFromParcel }, {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", |