summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/Surface.java39
-rw-r--r--core/java/android/view/SurfaceView.java10
-rw-r--r--core/jni/android_view_Surface.cpp12
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",