Revert "Modify SurfaceView to use SurfaceFlinger child surfaces."

This reverts commit 693f3432ae77d1fcfaaf9d168de861192aacb4c4.

P0: When playing encrypted content the Fugu displays a blank screen.

Test: with topic "surfaceview-without-wm" reverted, encrypted playback
works on ToT oc-release. See repro steps in 35917840#12.

bug:35917840

Change-Id: I37fa1e427daff3a1c18ed1c92d035421d891f67c
(cherry picked from commit 3896db14751f16f4053e8fa4a82c3d6803054e5b)
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0ac16c1..b718696 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -95,11 +95,6 @@
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long nativeObject,
             IBinder handle, long frame);
-    private static native void nativeDeferTransactionUntilSurface(long nativeObject,
-            long surfaceObject, long frame);
-    private static native void nativeReparentChildren(long nativeObject,
-            IBinder handle);
-    private static native void nativeSeverChildren(long nativeObject);
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
@@ -426,18 +421,6 @@
         nativeDeferTransactionUntil(mNativeObject, handle, frame);
     }
 
-    public void deferTransactionUntil(Surface barrier, long frame) {
-        nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
-    }
-
-    public void reparentChildren(IBinder newParentHandle) {
-        nativeReparentChildren(mNativeObject, newParentHandle);
-    }
-
-    public void detachChildren() {
-        nativeSeverChildren(mNativeObject);
-    }
-
     public void setOverrideScalingMode(int scalingMode) {
         checkNotReleased();
         nativeSetOverrideScalingMode(mNativeObject, scalingMode);
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index b5912bc..3cf5af4 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -27,7 +27,6 @@
     private long mNativeClient; // SurfaceComposerClient*
 
     private static native long nativeCreate();
-    private static native long nativeCreateScoped(long surfacePtr);
     private static native void nativeDestroy(long ptr);
     private static native void nativeKill(long ptr);
 
@@ -36,10 +35,6 @@
         mNativeClient = nativeCreate();
     }
 
-    public SurfaceSession(Surface root) {
-        mNativeClient = nativeCreateScoped(root.mNativeObject);
-    }
-
     /* no user serviceable parts here ... */
     @Override
     protected void finalize() throws Throwable {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 6430633..d2577d4 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,10 +16,6 @@
 
 package android.view;
 
-import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
-import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
-import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
-
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
 import android.content.res.Configuration;
@@ -30,12 +26,16 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
 
+import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.SurfaceCallbackHelper;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -92,8 +92,8 @@
  * positioned asynchronously.</p>
  */
 public class SurfaceView extends View {
-    private static final String TAG = "SurfaceView";
-    private static final boolean DEBUG = false;
+    static private final String TAG = "SurfaceView";
+    static private final boolean DEBUG = false;
 
     final ArrayList<SurfaceHolder.Callback> mCallbacks
             = new ArrayList<SurfaceHolder.Callback>();
@@ -102,23 +102,28 @@
 
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     final Surface mSurface = new Surface();       // Current surface in use
+    final Surface mNewSurface = new Surface();    // New surface we are switching to
     boolean mDrawingStopped = true;
-    // We use this to track if the application has produced a frame
-    // in to the Surface. Up until that point, we should be careful not to punch
-    // holes.
-    boolean mDrawFinished = false;
 
-    final Rect mScreenRect = new Rect();
-    SurfaceSession mSurfaceSession;
-
-    SurfaceControl mSurfaceControl;
+    final WindowManager.LayoutParams mLayout
+            = new WindowManager.LayoutParams();
+    IWindowSession mSession;
+    MyWindow mWindow;
+    final Rect mVisibleInsets = new Rect();
+    final Rect mWinFrame = new Rect();
+    final Rect mOverscanInsets = new Rect();
+    final Rect mContentInsets = new Rect();
+    final Rect mStableInsets = new Rect();
+    final Rect mOutsets = new Rect();
+    final Rect mBackdropFrame = new Rect();
     final Rect mTmpRect = new Rect();
     final Configuration mConfiguration = new Configuration();
 
     static final int KEEP_SCREEN_ON_MSG = 1;
-    static final int DRAW_FINISHED_MSG = 2;
+    static final int GET_NEW_SURFACE_MSG = 2;
+    static final int UPDATE_WINDOW_MSG = 3;
 
-    int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
+    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
@@ -130,9 +135,11 @@
                 case KEEP_SCREEN_ON_MSG: {
                     setKeepScreenOn(msg.arg1 != 0);
                 } break;
-                case DRAW_FINISHED_MSG: {
-                    mDrawFinished = true;
-                    invalidate();
+                case GET_NEW_SURFACE_MSG: {
+                    handleGetNewSurface();
+                } break;
+                case UPDATE_WINDOW_MSG: {
+                    updateWindow();
                 } break;
             }
         }
@@ -142,7 +149,7 @@
             = new ViewTreeObserver.OnScrollChangedListener() {
                     @Override
                     public void onScrollChanged() {
-                        updateSurface();
+                        updateWindow();
                     }
             };
 
@@ -152,14 +159,13 @@
                 public boolean onPreDraw() {
                     // reposition ourselves where the surface is
                     mHaveFrame = getWidth() > 0 && getHeight() > 0;
-                    updateSurface();
+                    updateWindow();
                     return true;
                 }
             };
 
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
-    boolean mLastWindowVisibility = false;
     boolean mViewVisibility = false;
     int mRequestedWidth = -1;
     int mRequestedHeight = -1;
@@ -175,17 +181,19 @@
     boolean mVisible = false;
     int mWindowSpaceLeft = -1;
     int mWindowSpaceTop = -1;
-    int mSurfaceWidth = -1;
-    int mSurfaceHeight = -1;
+    int mWindowSpaceWidth = -1;
+    int mWindowSpaceHeight = -1;
     int mFormat = -1;
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
+    boolean mUpdateWindowNeeded;
+    boolean mReportDrawNeeded;
     private Translator mTranslator;
+    private int mWindowInsetLeft;
+    private int mWindowInsetTop;
 
     private boolean mGlobalListenersAdded;
 
-    private int mSurfaceFlags = SurfaceControl.HIDDEN;
-
     public SurfaceView(Context context) {
         this(context, null);
     }
@@ -219,8 +227,11 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mParent.requestTransparentRegion(this);
+        mSession = getWindowSession();
+        mLayout.token = getWindowToken();
+        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
+        mLayout.packageName = mContext.getOpPackageName();
         mViewVisibility = getVisibility() == VISIBLE;
-        mRequestedVisible = mViewVisibility && mWindowVisibility;
 
         if (!mGlobalListenersAdded) {
             ViewTreeObserver observer = getViewTreeObserver();
@@ -235,7 +246,7 @@
         super.onWindowVisibilityChanged(visibility);
         mWindowVisibility = visibility == VISIBLE;
         mRequestedVisible = mWindowVisibility && mViewVisibility;
-        updateSurface();
+        updateWindow();
     }
 
     @Override
@@ -253,7 +264,7 @@
             requestLayout();
         }
         mRequestedVisible = newRequestedVisible;
-        updateSurface();
+        updateWindow();
     }
 
     @Override
@@ -266,14 +277,19 @@
         }
 
         mRequestedVisible = false;
-
-        updateSurface();
-        if (mSurfaceControl != null) {
-            mSurfaceControl.destroy();
-        }
-        mSurfaceControl = null;
-
+        updateWindow();
         mHaveFrame = false;
+        if (mWindow != null) {
+            try {
+                mSession.remove(mWindow);
+            } catch (RemoteException ex) {
+                // Not much we can do here...
+            }
+            mWindow = null;
+        }
+        mSession = null;
+        mLayout.token = null;
+
         super.onDetachedFromWindow();
     }
 
@@ -292,13 +308,13 @@
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
         boolean result = super.setFrame(left, top, right, bottom);
-        updateSurface();
+        updateWindow();
         return result;
     }
 
     @Override
     public boolean gatherTransparentRegion(Region region) {
-        if (isAboveParent()) {
+        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
             return super.gatherTransparentRegion(region);
         }
 
@@ -325,7 +341,7 @@
 
     @Override
     public void draw(Canvas canvas) {
-        if (mDrawFinished && !isAboveParent()) {
+        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
             // draw() is not called when SKIP_DRAW is set
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
                 // punch a whole in the view-hierarchy below us
@@ -337,8 +353,8 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        if (mDrawFinished && !isAboveParent()) {
-            // draw() is not called when SKIP_DRAW is set
+        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+            // if SKIP_DRAW is cleared, draw() has already punched a hole
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                 // punch a whole in the view-hierarchy below us
                 canvas.drawColor(0, PorterDuff.Mode.CLEAR);
@@ -359,8 +375,9 @@
      * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
      */
     public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-        mSubLayer = isMediaOverlay
-            ? APPLICATION_MEDIA_OVERLAY_SUBLAYER : APPLICATION_MEDIA_SUBLAYER;
+        mWindowType = isMediaOverlay
+                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
+                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
     }
 
     /**
@@ -378,9 +395,12 @@
      */
     public void setZOrderOnTop(boolean onTop) {
         if (onTop) {
-            mSubLayer = APPLICATION_PANEL_SUBLAYER;
+            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+            // ensures the surface is placed below the IME
+            mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         } else {
-            mSubLayer = APPLICATION_MEDIA_SUBLAYER;
+            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         }
     }
 
@@ -398,23 +418,31 @@
      */
     public void setSecure(boolean isSecure) {
         if (isSecure) {
-            mSurfaceFlags |= SurfaceControl.SECURE;
+            mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE;
         } else {
-            mSurfaceFlags &= ~SurfaceControl.SECURE;
+            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE;
         }
     }
 
+    /**
+     * Hack to allow special layering of windows.  The type is one of the
+     * types in WindowManager.LayoutParams.  This is a hack so:
+     * @hide
+     */
+    public void setWindowType(int type) {
+        mWindowType = type;
+    }
+
     /** @hide */
-    protected void updateSurface() {
+    protected void updateWindow() {
         if (!mHaveFrame) {
             return;
         }
         ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
-            return;
+        if (viewRoot != null) {
+            mTranslator = viewRoot.mTranslator;
         }
 
-        mTranslator = viewRoot.mTranslator;
         if (mTranslator != null) {
             mSurface.setCompatibilityTranslator(mTranslator);
         }
@@ -424,15 +452,17 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
+        final boolean creating = mWindow == null;
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean creating = (mSurfaceControl == null || formatChanged)
-                && mRequestedVisible;
-        final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
+        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
         final boolean visibleChanged = mVisible != mRequestedVisible;
-        final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
+        final boolean layoutSizeChanged = getWidth() != mLayout.width
+                || getHeight() != mLayout.height;
+
         boolean redrawNeeded = false;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
+        if (creating || formatChanged || sizeChanged || visibleChanged
+            || mUpdateWindowNeeded || mReportDrawNeeded) {
             getLocationInWindow(mLocation);
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -446,74 +476,93 @@
                 final boolean visible = mVisible = mRequestedVisible;
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                mSurfaceWidth = myWidth;
-                mSurfaceHeight = myHeight;
+                mWindowSpaceWidth = myWidth;
+                mWindowSpaceHeight = myHeight;
                 mFormat = mRequestedFormat;
-                mLastWindowVisibility = mWindowVisibility;
 
-                mScreenRect.left = mWindowSpaceLeft;
-                mScreenRect.top = mWindowSpaceTop;
-                mScreenRect.right = mWindowSpaceLeft + getWidth();
-                mScreenRect.bottom = mWindowSpaceTop + getHeight();
+                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
+
+                // Places the window relative
+                mLayout.x = mWindowSpaceLeft;
+                mLayout.y = mWindowSpaceTop;
+                mLayout.width = getWidth();
+                mLayout.height = getHeight();
                 if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
                 }
 
-                if (creating) {
-                    mSurfaceSession = new SurfaceSession(viewRoot.mSurface);
-                    mSurfaceControl = new SurfaceControl(mSurfaceSession,
-                            "SurfaceView - " + viewRoot.getTitle().toString(),
-                            mSurfaceWidth, mSurfaceHeight, mFormat,
-                            mSurfaceFlags);
+                mLayout.format = mRequestedFormat;
+                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                              | WindowManager.LayoutParams.FLAG_SCALED
+                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                              ;
+                if (!creating && !sizeChanged) {
+                    mLayout.privateFlags |=
+                            WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
+                } else {
+                    mLayout.privateFlags &=
+                            ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
                 }
 
-                boolean realSizeChanged = false;
+                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
+                    mLayout.privateFlags |=
+                            WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+                }
+                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+                    | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
+
+                if (mWindow == null) {
+                    Display display = getDisplay();
+                    mWindow = new MyWindow(this);
+                    mLayout.type = mWindowType;
+                    mLayout.gravity = Gravity.START|Gravity.TOP;
+                    mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
+                            mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets,
+                            mStableInsets);
+                }
+
+                boolean realSizeChanged;
+                boolean reportDrawNeeded;
+
+                int relayoutResult;
 
                 mSurfaceLock.lock();
                 try {
+                    mUpdateWindowNeeded = false;
+                    reportDrawNeeded = mReportDrawNeeded;
+                    mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
 
                     if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                             + "Cur surface: " + mSurface);
 
-                    SurfaceControl.openTransaction();
-                    try {
-                        mSurfaceControl.setLayer(mSubLayer);
-                        if (mViewVisibility) {
-                            mSurfaceControl.show();
-                        } else {
-                            mSurfaceControl.hide();
-                        }
-
-                        // While creating the surface, we will set it's initial
-                        // geometry. Outside of that though, we should generally
-                        // leave it to the RenderThread.
-                        if (creating || !mRtHandlingPositionUpdates) {
-                            mSurfaceControl.setPosition(mScreenRect.left, mScreenRect.top);
-                            mSurfaceControl.setMatrix(mScreenRect.width() / (float) mSurfaceWidth,
-                                    0.0f, 0.0f,
-                                    mScreenRect.height() / (float) mSurfaceHeight);
-                        }
-                        if (sizeChanged) {
-                            mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight);
-                        }
-                    } finally {
-                        SurfaceControl.closeTransaction();
+                    relayoutResult = mSession.relayout(
+                        mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight,
+                            visible ? VISIBLE : GONE,
+                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
+                            mWinFrame, mOverscanInsets, mContentInsets,
+                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
+                            mConfiguration, mNewSurface);
+                    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
+                        reportDrawNeeded = true;
                     }
 
-                    if (sizeChanged || creating) {
-                        redrawNeeded = true;
-                    }
+                    if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+                            + "New surface: " + mNewSurface
+                            + ", vis=" + visible + ", frame=" + mWinFrame);
 
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
                     if (mTranslator == null) {
-                        mSurfaceFrame.right = mSurfaceWidth;
-                        mSurfaceFrame.bottom = mSurfaceHeight;
+                        mSurfaceFrame.right = mWinFrame.width();
+                        mSurfaceFrame.bottom = mWinFrame.height();
                     } else {
                         float appInvertedScale = mTranslator.applicationInvertedScale;
-                        mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
-                        mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
+                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
+                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
                     }
 
                     final int surfaceWidth = mSurfaceFrame.right;
@@ -527,11 +576,12 @@
                 }
 
                 try {
-                    redrawNeeded |= visible && !mDrawFinished;
+                    redrawNeeded |= creating | reportDrawNeeded;
 
                     SurfaceHolder.Callback callbacks[] = null;
 
-                    final boolean surfaceChanged = creating;
+                    final boolean surfaceChanged = (relayoutResult
+                            & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0;
                     if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
                         mSurfaceCreated = false;
                         if (mSurface.isValid()) {
@@ -558,10 +608,7 @@
                         }
                     }
 
-                    if (creating) {
-                        mSurface.copyFrom(mSurfaceControl);
-                    }
-
+                    mSurface.transferFrom(mNewSurface);
                     if (visible && mSurface.isValid()) {
                         if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
                             mSurfaceCreated = true;
@@ -594,57 +641,53 @@
                                 callbacks = getSurfaceCallbacks();
                             }
                             SurfaceCallbackHelper sch =
-                                    new SurfaceCallbackHelper(this::onDrawFinished);
+                                    new SurfaceCallbackHelper(mSession, mWindow);
                             sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                         }
                     }
                 } finally {
                     mIsCreating = false;
-                    if (mSurfaceControl != null && !mSurfaceCreated) {
-                        mSurfaceControl.destroy();
-                        mSurfaceControl = null;
-                    }
+                    mSession.performDeferredDestroy(mWindow);
                 }
-            } catch (Exception ex) {
+            } catch (RemoteException ex) {
                 Log.e(TAG, "Exception from relayout", ex);
             }
             if (DEBUG) Log.v(
-                TAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top
-                + " w=" + mScreenRect.width() + " h=" + mScreenRect.height()
-                + ", frame=" + mSurfaceFrame);
+                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
+                " w=" + mLayout.width + " h=" + mLayout.height +
+                ", frame=" + mSurfaceFrame);
         } else {
             // Calculate the window position in case RT loses the window
             // and we need to fallback to a UI-thread driven position update
             getLocationInWindow(mLocation);
             final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
                     || mWindowSpaceTop != mLocation[1];
-            final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
-                    || getHeight() != mScreenRect.height();
             if (positionChanged || layoutSizeChanged) { // Only the position has changed
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                // For our size changed check, we keep mScreenRect.width() and mScreenRect.height()
+                // For our size changed check, we keep mLayout.width and mLayout.height
                 // in view local space.
-                mLocation[0] = getWidth();
-                mLocation[1] = getHeight();
+                mLocation[0] = mLayout.width = getWidth();
+                mLocation[1] = mLayout.height = getHeight();
 
                 transformFromViewToWindowSpace(mLocation);
 
-                mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
+                mTmpRect.set(mWindowSpaceLeft, mWindowSpaceTop,
                         mLocation[0], mLocation[1]);
 
                 if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                    mTranslator.translateRectInAppWindowToScreen(mTmpRect);
                 }
 
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
-                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
+                        if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " +
                                 "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                                mScreenRect.left, mScreenRect.top,
-                                mScreenRect.right, mScreenRect.bottom));
-                        setParentSpaceRectangle(mScreenRect, -1);
-                    } catch (Exception ex) {
+                                mTmpRect.left, mTmpRect.top,
+                                mTmpRect.right, mTmpRect.bottom));
+                        mSession.repositionChild(mWindow, mTmpRect.left, mTmpRect.top,
+                                mTmpRect.right, mTmpRect.bottom, -1, mTmpRect);
+                    } catch (RemoteException ex) {
                         Log.e(TAG, "Exception from relayout", ex);
                     }
                 }
@@ -652,40 +695,18 @@
         }
     }
 
-    private void onDrawFinished() {
-        if (DEBUG) {
-            Log.i(TAG, System.identityHashCode(this) + " "
-                    + "finishedDrawing");
-        }
-        mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
-    }
-
-    private void setParentSpaceRectangle(Rect position, long frameNumber) {
-        ViewRootImpl viewRoot = getViewRootImpl();
-
-        SurfaceControl.openTransaction();
-        try {
-            if (frameNumber > 0) {
-                mSurfaceControl.deferTransactionUntil(viewRoot.mSurface, frameNumber);
-            }
-            mSurfaceControl.setPosition(position.left, position.top);
-            mSurfaceControl.setMatrix(position.width() / (float) mSurfaceWidth,
-                    0.0f, 0.0f,
-                    position.height() / (float) mSurfaceHeight);
-        } finally {
-            SurfaceControl.closeTransaction();
-        }
-    }
-
     private Rect mRTLastReportedPosition = new Rect();
 
     /**
      * Called by native by a Rendering Worker thread to update the window position
      * @hide
      */
-    public final void updateSurfacePosition_renderWorker(long frameNumber,
+    public final void updateWindowPosition_renderWorker(long frameNumber,
             int left, int top, int right, int bottom) {
-        if (mSurfaceControl == null) {
+        IWindowSession session = mSession;
+        MyWindow window = mWindow;
+        if (session == null || window == null) {
+            // Guess we got detached, that sucks
             return;
         }
         // TODO: This is teensy bit racey in that a brand new SurfaceView moving on
@@ -705,29 +726,35 @@
         }
         try {
             if (DEBUG) {
-                Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " +
+                Log.d(TAG, String.format("%d updateWindowPosition RenderWorker, frameNr = %d, " +
                         "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
                         frameNumber, left, top, right, bottom));
             }
-            mRTLastReportedPosition.set(left, top, right, bottom);
-            setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
+            // Just using mRTLastReportedPosition as a dummy rect here
+            session.repositionChild(window, left, top, right, bottom,
+                    frameNumber,
+                    mRTLastReportedPosition);
             // Now overwrite mRTLastReportedPosition with our values
-        } catch (Exception ex) {
+            mRTLastReportedPosition.set(left, top, right, bottom);
+        } catch (RemoteException ex) {
             Log.e(TAG, "Exception from repositionChild", ex);
         }
     }
 
     /**
-     * Called by native on RenderThread to notify that the view is no longer in the
+     * Called by native on RenderThread to notify that the window is no longer in the
      * draw tree. UI thread is blocked at this point.
      * @hide
      */
-    public final void surfacePositionLost_uiRtSync(long frameNumber) {
+    public final void windowPositionLost_uiRtSync(long frameNumber) {
         if (DEBUG) {
             Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
                     System.identityHashCode(this), frameNumber));
         }
-        if (mSurfaceControl == null) {
+        IWindowSession session = mSession;
+        MyWindow window = mWindow;
+        if (session == null || window == null) {
+            // We got detached prior to receiving this, abort
             return;
         }
         if (mRtHandlingPositionUpdates) {
@@ -736,14 +763,19 @@
             // safely access other member variables at this time.
             // So do what the UI thread would have done if RT wasn't handling position
             // updates.
-            if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
+            mTmpRect.set(mLayout.x, mLayout.y,
+                    mLayout.x + mLayout.width,
+                    mLayout.y + mLayout.height);
+
+            if (!mTmpRect.isEmpty() && !mTmpRect.equals(mRTLastReportedPosition)) {
                 try {
-                    if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " +
+                    if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " +
                             "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                            mScreenRect.left, mScreenRect.top,
-                            mScreenRect.right, mScreenRect.bottom));
-                    setParentSpaceRectangle(mScreenRect, frameNumber);
-                } catch (Exception ex) {
+                            mTmpRect.left, mTmpRect.top,
+                            mTmpRect.right, mTmpRect.bottom));
+                    session.repositionChild(window, mTmpRect.left, mTmpRect.top,
+                            mTmpRect.right, mTmpRect.bottom, frameNumber, mWinFrame);
+                } catch (RemoteException ex) {
                     Log.e(TAG, "Exception from relayout", ex);
                 }
             }
@@ -760,6 +792,10 @@
         return callbacks;
     }
 
+    void handleGetNewSurface() {
+        updateWindow();
+    }
+
     /**
      * Check to see if the surface has fixed size dimensions or if the surface's
      * dimensions are dimensions are dependent on its current layout.
@@ -771,8 +807,65 @@
         return (mRequestedWidth != -1 || mRequestedHeight != -1);
     }
 
-    private boolean isAboveParent() {
-        return mSubLayer >= 0;
+    private static class MyWindow extends BaseIWindow {
+        private final WeakReference<SurfaceView> mSurfaceView;
+
+        public MyWindow(SurfaceView surfaceView) {
+            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
+        }
+
+        @Override
+        public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
+                Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
+                Configuration newConfig, Rect backDropRect, boolean forceLayout,
+                boolean alwaysConsumeNavBar, int displayId) {
+            SurfaceView surfaceView = mSurfaceView.get();
+            if (surfaceView != null) {
+                if (DEBUG) Log.v(TAG, surfaceView + " got resized: w=" + frame.width()
+                        + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight);
+                surfaceView.mSurfaceLock.lock();
+                try {
+                    if (reportDraw) {
+                        surfaceView.mUpdateWindowNeeded = true;
+                        surfaceView.mReportDrawNeeded = true;
+                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
+                    } else if (surfaceView.mWinFrame.width() != frame.width()
+                            || surfaceView.mWinFrame.height() != frame.height()
+                            || forceLayout) {
+                        surfaceView.mUpdateWindowNeeded = true;
+                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
+                    }
+                } finally {
+                    surfaceView.mSurfaceLock.unlock();
+                }
+            }
+        }
+
+        @Override
+        public void dispatchAppVisibility(boolean visible) {
+            // The point of SurfaceView is to let the app control the surface.
+        }
+
+        @Override
+        public void dispatchGetNewSurface() {
+            SurfaceView surfaceView = mSurfaceView.get();
+            if (surfaceView != null) {
+                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
+                surfaceView.mHandler.sendMessage(msg);
+            }
+        }
+
+        @Override
+        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
+            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
+        }
+
+        @Override
+        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
+        }
+
+        int mCurWidth = -1;
+        int mCurHeight = -1;
     }
 
     private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
@@ -820,14 +913,15 @@
 
         @Override
         public void setFormat(int format) {
+
             // for backward compatibility reason, OPAQUE always
             // means 565 for SurfaceView
             if (format == PixelFormat.OPAQUE)
                 format = PixelFormat.RGB_565;
 
             mRequestedFormat = format;
-            if (mSurfaceControl != null) {
-                updateSurface();
+            if (mWindow != null) {
+                updateWindow();
             }
         }
 
@@ -888,10 +982,10 @@
             mSurfaceLock.lock();
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped="
-                    + mDrawingStopped + ", surfaceControl=" + mSurfaceControl);
+                    + mDrawingStopped + ", win=" + mWindow);
 
             Canvas c = null;
-            if (!mDrawingStopped && mSurfaceControl != null) {
+            if (!mDrawingStopped && mWindow != null) {
                 try {
                     if (hardware) {
                         c = mSurface.lockHardwareCanvas();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f9863b0..20d960f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2632,14 +2632,6 @@
         }
     }
 
-    private void onDrawFinished() {
-        try {
-            mWindowSession.finishDrawing(mWindow);
-        } catch (RemoteException e) {
-            // Have fun!
-        }
-    }
-
     private void performDraw() {
         if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
             return;
@@ -2690,7 +2682,7 @@
             }
 
             if (mSurfaceHolder != null && mSurface.isValid()) {
-                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished);
+                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(mWindowSession, mWindow);
                 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
 
                 sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
diff --git a/core/java/com/android/internal/view/SurfaceCallbackHelper.java b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
index 507b673..5b6a82c 100644
--- a/core/java/com/android/internal/view/SurfaceCallbackHelper.java
+++ b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
@@ -17,11 +17,14 @@
 package com.android.internal.view;
 
 import android.os.RemoteException;
+import android.view.IWindow;
+import android.view.IWindowSession;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
 public class SurfaceCallbackHelper {
-    Runnable mRunnable;
+    IWindowSession mSession;
+    IWindow.Stub mWindow;
 
     int mFinishDrawingCollected = 0;
     int mFinishDrawingExpected = 0;
@@ -34,18 +37,26 @@
                     if (mFinishDrawingCollected < mFinishDrawingExpected) {
                         return;
                     }
-                    mRunnable.run();
+                    try {
+                        mSession.finishDrawing(mWindow);
+                    } catch (RemoteException e) {
+                    }
                 }
             }
     };
 
-    public SurfaceCallbackHelper(Runnable callbacksCollected) {
-        mRunnable = callbacksCollected;
+    public SurfaceCallbackHelper(IWindowSession session,
+            IWindow.Stub window) {
+        mSession = session;
+        mWindow = window;
     }
 
     public void dispatchSurfaceRedrawNeededAsync(SurfaceHolder holder, SurfaceHolder.Callback callbacks[]) {
         if (callbacks == null || callbacks.length == 0) {
-            mRunnable.run();
+            try {
+                mSession.finishDrawing(mWindow);
+            } catch (RemoteException e) {
+            }
             return;
         }
 
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index edcbb3f..f221392 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -627,9 +627,9 @@
 int register_android_view_RenderNode(JNIEnv* env) {
     jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
     gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
-            "updateSurfacePosition_renderWorker", "(JIIII)V");
+            "updateWindowPosition_renderWorker", "(JIIII)V");
     gSurfaceViewPositionLostMethod = GetMethodIDOrDie(env, clazz,
-            "surfacePositionLost_uiRtSync", "(J)V");
+            "windowPositionLost_uiRtSync", "(J)V");
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index be86f5c..a81901d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -693,6 +693,7 @@
     return JNI_TRUE;
 }
 
+
 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
         jobject handleObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -701,27 +702,6 @@
     ctrl->deferTransactionUntil(handle, frameNumber);
 }
 
-static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong nativeObject,
-        jobject surfaceObject, jlong frameNumber) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
-
-    ctrl->deferTransactionUntil(barrier, frameNumber);
-}
-
-static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong nativeObject,
-        jobject newParentObject) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
-
-    ctrl->reparentChildren(handle);
-}
-
-static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong nativeObject) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    ctrl->detachChildren();
-}
-
 static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
         jint scalingMode) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -844,12 +824,6 @@
             (void*)nativeSetDisplayPowerMode },
     {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
-    {"nativeDeferTransactionUntilSurface", "(JJJ)V",
-            (void*)nativeDeferTransactionUntilSurface },
-    {"nativeReparentChildren", "(JLandroid/os/IBinder;)V",
-            (void*)nativeReparentChildren } ,
-    {"nativeSeverChildren", "(J)V",
-            (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp
index 508d897..dad6958 100644
--- a/core/jni/android_view_SurfaceSession.cpp
+++ b/core/jni/android_view_SurfaceSession.cpp
@@ -24,7 +24,6 @@
 #include <utils/RefBase.h>
 
 #include <gui/SurfaceComposerClient.h>
-#include <gui/Surface.h>
 
 namespace android {
 
@@ -46,13 +45,6 @@
     return reinterpret_cast<jlong>(client);
 }
 
-static jlong nativeCreateScoped(JNIEnv* env, jclass clazz, jlong surfaceObject) {
-    Surface *parent = reinterpret_cast<Surface*>(surfaceObject);
-    SurfaceComposerClient* client = new SurfaceComposerClient(parent->getIGraphicBufferProducer());
-    client->incStrong((void*)nativeCreate);
-    return reinterpret_cast<jlong>(client);
-}
-
 static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
     SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr);
     client->decStrong((void*)nativeCreate);
@@ -63,12 +55,11 @@
     client->dispose();
 }
 
+
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
     { "nativeCreate", "()J",
             (void*)nativeCreate },
-    { "nativeCreateScoped", "(J)J",
-            (void*)nativeCreateScoped },
     { "nativeDestroy", "(J)V",
             (void*)nativeDestroy },
     { "nativeKill", "(J)V",
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index e5af357..aee9d38e 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -776,8 +776,8 @@
         mSurface = null;
         mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
             @Override
-            protected void updateSurface() {
-                super.updateSurface();
+            protected void updateWindow() {
+                super.updateWindow();
                 relayoutSessionOverlayView();
             }};
         // The surface view's content should be treated as secure all the time.
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 994f38d..f5ccf08 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -795,16 +795,6 @@
         if (canFreezeBounds()) {
             freezeBounds();
         }
-
-        // In the process of tearing down before relaunching, the app will
-        // try and clean up it's child surfaces. We need to prevent this from
-        // happening, so we sever the children, transfering their ownership
-        // from the client it-self to the parent surface (owned by us).
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final WindowState w = mChildren.get(i);
-            w.mWinAnimator.detachChildren();
-        }
-
         mPendingRelaunchCount++;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index eb3a2d1..e339329 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2199,15 +2199,6 @@
         if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
             mAccessibilityController.onWindowTransitionLocked(win, transit);
         }
-
-        // When we start the exit animation we take the Surface from the client
-        // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger
-        // side child surfaces, so they will remain preserved in their current state
-        // (rather than be cleaned up immediately by the app code).
-        SurfaceControl.openTransaction();
-        winAnimator.detachChildren();
-        SurfaceControl.closeTransaction();
-
         return focusMayChange;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4b71338..98598e1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -566,20 +566,6 @@
         if (!mDestroyPreservedSurfaceUponRedraw) {
             return;
         }
-        if (mSurfaceController != null) {
-            if (mPendingDestroySurface != null) {
-                // If we are preserving a surface but we aren't relaunching that means
-                // we are just doing an in-place switch. In that case any SurfaceFlinger side
-                // child layers need to be reparented to the new surface to make this
-                // transparent to the app.
-                if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
-                    SurfaceControl.openTransaction();
-                    mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
-                    SurfaceControl.closeTransaction();
-                }
-            }
-        }
-
         destroyDeferredSurfaceLocked();
         mDestroyPreservedSurfaceUponRedraw = false;
     }
@@ -1979,10 +1965,4 @@
         }
         return mForceScaleUntilResize;
     }
-
-    void detachChildren() {
-        if (mSurfaceController != null) {
-            mSurfaceController.detachChildren();
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f7d3343..f8e7428 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -135,20 +135,6 @@
         }
     }
 
-    void reparentChildrenInTransaction(WindowSurfaceController other) {
-        if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
-        if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
-            mSurfaceControl.reparentChildren(other.getHandle());
-        }
-    }
-
-    void detachChildren() {
-        if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
-        if (mSurfaceControl != null) {
-            mSurfaceControl.detachChildren();
-        }
-    }
-
     void hideInTransaction(String reason) {
         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
         mHiddenForOtherReasons = true;