Use new SurfaceFlinger transaction API.

For now we reimplement global transactions in the Java side
JNI layer.

Bug: 64815723
Bug: 64816140
Bug: 64815766
Test: Existing tests pass. go/wm-smoke
Change-Id: I6c0a7b5e65b1b6cc844ac61f3269629af60a4244
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 6526123..d1af71d 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -260,9 +260,9 @@
     sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
             dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
 
-    SurfaceComposerClient::openGlobalTransaction();
-    control->setLayer(0x40000000);
-    SurfaceComposerClient::closeGlobalTransaction();
+    SurfaceComposerClient::Transaction t;
+    t.setLayer(control, 0x40000000)
+        .apply();
 
     sp<Surface> s = control->getSurface();
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 31daeff..5482589 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -21,15 +21,22 @@
 import android.annotation.Size;
 import android.graphics.Bitmap;
 import android.graphics.GraphicBuffer;
+import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
+import android.os.Debug;
 import android.os.IBinder;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 
 import dalvik.system.CloseGuard;
 
+import java.io.Closeable;
+
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * SurfaceControl
  *  @hide
@@ -54,25 +61,34 @@
             Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
             boolean allLayers, boolean useIdentityTransform);
 
-    private static native void nativeOpenTransaction();
-    private static native void nativeCloseTransaction(boolean sync);
-    private static native void nativeSetAnimationTransaction();
+    private static native long nativeCreateTransaction();
+    private static native long nativeGetNativeTransactionFinalizer();
+    private static native void nativeApplyTransaction(long transactionObj, boolean sync);
+    private static native void nativeSetAnimationTransaction(long transactionObj);
 
-    private static native void nativeSetLayer(long nativeObject, int zorder);
-    private static native void nativeSetRelativeLayer(long nativeObject, IBinder relativeTo,
-            int zorder);
-    private static native void nativeSetPosition(long nativeObject, float x, float y);
-    private static native void nativeSetGeometryAppliesWithResize(long nativeObject);
-    private static native void nativeSetSize(long nativeObject, int w, int h);
-    private static native void nativeSetTransparentRegionHint(long nativeObject, Region region);
-    private static native void nativeSetAlpha(long nativeObject, float alpha);
-    private static native void nativeSetColor(long nativeObject, float[] color);
-    private static native void nativeSetMatrix(long nativeObject, float dsdx, float dtdx,
+    private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
+    private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
+            IBinder relativeTo, int zorder);
+    private static native void nativeSetPosition(long transactionObj, long nativeObject,
+            float x, float y);
+    private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
+            long nativeObject);
+    private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h);
+    private static native void nativeSetTransparentRegionHint(long transactionObj,
+            long nativeObject, Region region);
+    private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha);
+    private static native void nativeSetMatrix(long transactionObj, long nativeObject,
+            float dsdx, float dtdx,
             float dtdy, float dsdy);
-    private static native void nativeSetFlags(long nativeObject, int flags, int mask);
-    private static native void nativeSetWindowCrop(long nativeObject, int l, int t, int r, int b);
-    private static native void nativeSetFinalCrop(long nativeObject, int l, int t, int r, int b);
-    private static native void nativeSetLayerStack(long nativeObject, int layerStack);
+    private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
+    private static native void nativeSetFlags(long transactionObj, long nativeObject,
+            int flags, int mask);
+    private static native void nativeSetWindowCrop(long transactionObj, long nativeObject,
+            int l, int t, int r, int b);
+    private static native void nativeSetFinalCrop(long transactionObj, long nativeObject,
+            int l, int t, int r, int b);
+    private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
+            int layerStack);
 
     private static native boolean nativeClearContentFrameStats(long nativeObject);
     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
@@ -82,15 +98,16 @@
     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
     private static native IBinder nativeCreateDisplay(String name, boolean secure);
     private static native void nativeDestroyDisplay(IBinder displayToken);
-    private static native void nativeSetDisplaySurface(
+    private static native void nativeSetDisplaySurface(long transactionObj,
             IBinder displayToken, long nativeSurfaceObject);
-    private static native void nativeSetDisplayLayerStack(
+    private static native void nativeSetDisplayLayerStack(long transactionObj,
             IBinder displayToken, int layerStack);
-    private static native void nativeSetDisplayProjection(
+    private static native void nativeSetDisplayProjection(long transactionObj,
             IBinder displayToken, int orientation,
             int l, int t, int r, int b,
             int L, int T, int R, int B);
-    private static native void nativeSetDisplaySize(IBinder displayToken, int width, int height);
+    private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
+            int width, int height);
     private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
             IBinder displayToken);
     private static native int nativeGetActiveConfig(IBinder displayToken);
@@ -101,16 +118,17 @@
             int colorMode);
     private static native void nativeSetDisplayPowerMode(
             IBinder displayToken, int mode);
-    private static native void nativeDeferTransactionUntil(long nativeObject,
+    private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
             IBinder handle, long frame);
-    private static native void nativeDeferTransactionUntilSurface(long nativeObject,
+    private static native void nativeDeferTransactionUntilSurface(long transactionObj,
+            long nativeObject,
             long surfaceObject, long frame);
-    private static native void nativeReparentChildren(long nativeObject,
+    private static native void nativeReparentChildren(long transactionObj, long nativeObject,
             IBinder handle);
-    private static native void nativeReparent(long nativeObject,
+    private static native void nativeReparent(long transactionObj, long nativeObject,
             IBinder parentHandle);
-    private static native void nativeSeverChildren(long nativeObject);
-    private static native void nativeSetOverrideScalingMode(long nativeObject,
+    private static native void nativeSeverChildren(long transactionObj, long nativeObject);
+    private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
     private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
@@ -122,6 +140,9 @@
     private final String mName;
     long mNativeObject; // package visibility only for Surface.java access
 
+    static Transaction sGlobalTransaction;
+    static long sTransactionNestCount = 0;
+
     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
 
     /**
@@ -377,11 +398,6 @@
         }
     }
 
-    @Override
-    public String toString() {
-        return "Surface(name=" + mName + ")";
-    }
-
     /**
      * Release the local reference to the server-side surface.
      * Always call release() when you're done with a Surface.
@@ -429,102 +445,141 @@
 
     /** start a transaction */
     public static void openTransaction() {
-        nativeOpenTransaction();
+        synchronized (SurfaceControl.class) {
+            if (sGlobalTransaction == null) {
+                sGlobalTransaction = new Transaction();
+            }
+            synchronized(SurfaceControl.class) {
+                sTransactionNestCount++;
+            }
+        }
+    }
+
+    private static void closeTransaction(boolean sync) {
+        synchronized(SurfaceControl.class) {
+            if (sTransactionNestCount == 0) {
+                Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction");
+            } else if (--sTransactionNestCount > 0) {
+                return;
+            }
+            sGlobalTransaction.apply(sync);
+        }
     }
 
     /** end a transaction */
     public static void closeTransaction() {
-        nativeCloseTransaction(false);
+        closeTransaction(false);
     }
 
     public static void closeTransactionSync() {
-        nativeCloseTransaction(true);
+        closeTransaction(true);
     }
 
     public void deferTransactionUntil(IBinder handle, long frame) {
         if (frame > 0) {
-            nativeDeferTransactionUntil(mNativeObject, handle, frame);
+            synchronized(SurfaceControl.class) {
+                sGlobalTransaction.deferTransactionUntil(this, handle, frame);
+            }
         }
     }
 
     public void deferTransactionUntil(Surface barrier, long frame) {
         if (frame > 0) {
-            nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
+            synchronized(SurfaceControl.class) {
+                sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame);
+            }
         }
     }
 
     public void reparentChildren(IBinder newParentHandle) {
-        nativeReparentChildren(mNativeObject, newParentHandle);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.reparentChildren(this, newParentHandle);
+        }
     }
 
-    /** Re-parents this layer to a new parent. */
     public void reparent(IBinder newParentHandle) {
-        nativeReparent(mNativeObject, newParentHandle);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.reparent(this, newParentHandle);
+        }
     }
 
     public void detachChildren() {
-        nativeSeverChildren(mNativeObject);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.detachChildren(this);
+        }
     }
 
     public void setOverrideScalingMode(int scalingMode) {
         checkNotReleased();
-        nativeSetOverrideScalingMode(mNativeObject, scalingMode);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setOverrideScalingMode(this, scalingMode);
+        }
     }
 
     public IBinder getHandle() {
         return nativeGetHandle(mNativeObject);
     }
 
-    /** flag the transaction as an animation */
     public static void setAnimationTransaction() {
-        nativeSetAnimationTransaction();
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setAnimationTransaction();
+        }
     }
 
     public void setLayer(int zorder) {
         checkNotReleased();
-        nativeSetLayer(mNativeObject, zorder);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setLayer(this, zorder);
+        }
     }
 
     public void setRelativeLayer(IBinder relativeTo, int zorder) {
         checkNotReleased();
-        nativeSetRelativeLayer(mNativeObject, relativeTo, zorder);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setRelativeLayer(this, relativeTo, zorder);
+        }
     }
 
     public void setPosition(float x, float y) {
         checkNotReleased();
-        nativeSetPosition(mNativeObject, x, y);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setPosition(this, x, y);
+        }
     }
 
-    /**
-     * If the buffer size changes in this transaction, position and crop updates specified
-     * in this transaction will not complete until a buffer of the new size
-     * arrives. As transform matrix and size are already frozen in this fashion,
-     * this enables totally freezing the surface until the resize has completed
-     * (at which point the geometry influencing aspects of this transaction will then occur)
-     */
     public void setGeometryAppliesWithResize() {
         checkNotReleased();
-        nativeSetGeometryAppliesWithResize(mNativeObject);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setGeometryAppliesWithResize(this);
+        }
     }
 
     public void setSize(int w, int h) {
         checkNotReleased();
-        nativeSetSize(mNativeObject, w, h);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setSize(this, w, h);
+        }
     }
 
     public void hide() {
         checkNotReleased();
-        nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.hide(this);
+        }
     }
 
     public void show() {
         checkNotReleased();
-        nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.show(this);
+        }
     }
 
     public void setTransparentRegionHint(Region region) {
         checkNotReleased();
-        nativeSetTransparentRegionHint(mNativeObject, region);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setTransparentRegionHint(this, region);
+        }
     }
 
     public boolean clearContentFrameStats() {
@@ -545,80 +600,70 @@
         return nativeGetAnimationFrameStats(outStats);
     }
 
-    /**
-     * Sets an alpha value for the entire Surface.  This value is combined with the
-     * per-pixel alpha.  It may be used with opaque Surfaces.
-     */
     public void setAlpha(float alpha) {
         checkNotReleased();
-        nativeSetAlpha(mNativeObject, alpha);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setAlpha(this, alpha);
+        }
     }
 
-    /**
-     * Sets a color for the Surface.
-     * @param color A float array with three values to represent r, g, b in range [0..1]
-     */
     public void setColor(@Size(3) float[] color) {
         checkNotReleased();
-        nativeSetColor(mNativeObject, color);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setColor(this, color);
+        }
     }
 
     public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
         checkNotReleased();
-        nativeSetMatrix(mNativeObject, dsdx, dtdx, dtdy, dsdy);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setMatrix(this, dsdx, dtdx, dtdy, dsdy);
+        }
     }
 
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
-        if (crop != null) {
-            nativeSetWindowCrop(mNativeObject,
-                crop.left, crop.top, crop.right, crop.bottom);
-        } else {
-            nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setWindowCrop(this, crop);
         }
     }
 
     public void setFinalCrop(Rect crop) {
         checkNotReleased();
-        if (crop != null) {
-            nativeSetFinalCrop(mNativeObject,
-                crop.left, crop.top, crop.right, crop.bottom);
-        } else {
-            nativeSetFinalCrop(mNativeObject, 0, 0, 0, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setFinalCrop(this, crop);
         }
     }
 
     public void setLayerStack(int layerStack) {
         checkNotReleased();
-        nativeSetLayerStack(mNativeObject, layerStack);
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.setLayerStack(this, layerStack);
+        }
     }
 
-    /**
-     * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
-     * Surface with the {@link #OPAQUE} flag.
-     */
     public void setOpaque(boolean isOpaque) {
         checkNotReleased();
-        if (isOpaque) {
-            nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE);
-        } else {
-            nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE);
+
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setOpaque(this, isOpaque);
         }
     }
 
-    /**
-     * Sets the security of the surface.  Setting the flag is equivalent to creating the
-     * Surface with the {@link #SECURE} flag.
-     */
     public void setSecure(boolean isSecure) {
         checkNotReleased();
-        if (isSecure) {
-            nativeSetFlags(mNativeObject, SECURE, SECURE);
-        } else {
-            nativeSetFlags(mNativeObject, 0, SECURE);
+
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setSecure(this, isSecure);
         }
     }
 
+    @Override
+    public String toString() {
+        return "Surface(name=" + mName + ")/@0x" +
+                Integer.toHexString(System.identityHashCode(this));
+    }
+
     /*
      * set display parameters.
      * needs to be inside open/closeTransaction block
@@ -741,50 +786,28 @@
 
     public static void setDisplayProjection(IBinder displayToken,
             int orientation, Rect layerStackRect, Rect displayRect) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplayProjection(displayToken, orientation,
+                    layerStackRect, displayRect);
         }
-        if (layerStackRect == null) {
-            throw new IllegalArgumentException("layerStackRect must not be null");
-        }
-        if (displayRect == null) {
-            throw new IllegalArgumentException("displayRect must not be null");
-        }
-        nativeSetDisplayProjection(displayToken, orientation,
-                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
-                displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
     }
 
     public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack);
         }
-        nativeSetDisplayLayerStack(displayToken, layerStack);
     }
 
     public static void setDisplaySurface(IBinder displayToken, Surface surface) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
-        }
-
-        if (surface != null) {
-            synchronized (surface.mLock) {
-                nativeSetDisplaySurface(displayToken, surface.mNativeObject);
-            }
-        } else {
-            nativeSetDisplaySurface(displayToken, 0);
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplaySurface(displayToken, surface);
         }
     }
 
     public static void setDisplaySize(IBinder displayToken, int width, int height) {
-        if (displayToken == null) {
-            throw new IllegalArgumentException("displayToken must not be null");
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setDisplaySize(displayToken, width, height);
         }
-        if (width <= 0 || height <= 0) {
-            throw new IllegalArgumentException("width and height must be positive");
-        }
-
-        nativeSetDisplaySize(displayToken, width, height);
     }
 
     public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
@@ -946,4 +969,261 @@
         nativeScreenshot(display, consumer, sourceCrop, width, height,
                 minLayer, maxLayer, allLayers, useIdentityTransform);
     }
+
+    public static class Transaction implements Closeable {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                Transaction.class.getClassLoader(),
+                nativeGetNativeTransactionFinalizer(), 512);
+        private long mNativeObject;
+
+        Runnable mFreeNativeResources;
+
+        public Transaction() {
+            mNativeObject = nativeCreateTransaction();
+            mFreeNativeResources
+                = sRegistry.registerNativeAllocation(this, mNativeObject);
+        }
+
+        /**
+         * Apply the transaction, clearing it's state, and making it usable
+         * as a new transaction.
+         */
+        public void apply() {
+            apply(false);
+        }
+
+        /**
+         * Close the transaction, if the transaction was not already applied this will cancel the
+         * transaction.
+         */
+        @Override
+        public void close() {
+            mFreeNativeResources.run();
+            mNativeObject = 0;
+        }
+
+        /**
+         * Jankier version of apply. Avoid use (b/28068298).
+         */
+        public void apply(boolean sync) {
+            nativeApplyTransaction(mNativeObject, sync);
+        }
+
+        public Transaction show(SurfaceControl sc) {
+            nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN);
+            return this;
+        }
+
+        public Transaction hide(SurfaceControl sc) {
+            nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
+            return this;
+        }
+
+        public Transaction setPosition(SurfaceControl sc, float x, float y) {
+            nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
+            return this;
+        }
+
+        public Transaction setSize(SurfaceControl sc, int w, int h) {
+            nativeSetSize(mNativeObject, sc.mNativeObject,
+                    w, h);
+            return this;
+        }
+
+        public Transaction setLayer(SurfaceControl sc, int z) {
+            nativeSetLayer(mNativeObject, sc.mNativeObject, z);
+            return this;
+        }
+
+        public Transaction setRelativeLayer(SurfaceControl sc, IBinder relativeTo, int z) {
+            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject,
+                    relativeTo, z);
+            return this;
+        }
+
+        public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) {
+            nativeSetTransparentRegionHint(mNativeObject,
+                    sc.mNativeObject, transparentRegion);
+            return this;
+        }
+
+        public Transaction setAlpha(SurfaceControl sc, float alpha) {
+            nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
+            return this;
+        }
+
+        public Transaction setMatrix(SurfaceControl sc,
+                float dsdx, float dtdx, float dtdy, float dsdy) {
+            nativeSetMatrix(mNativeObject, sc.mNativeObject,
+                    dsdx, dtdx, dtdy, dsdy);
+            return this;
+        }
+
+        public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
+            if (crop != null) {
+                nativeSetWindowCrop(mNativeObject, sc.mNativeObject,
+                        crop.left, crop.top, crop.right, crop.bottom);
+            } else {
+                nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
+            }
+
+            return this;
+        }
+
+        public Transaction setFinalCrop(SurfaceControl sc, Rect crop) {
+            if (crop != null) {
+                nativeSetFinalCrop(mNativeObject, sc.mNativeObject,
+                        crop.left, crop.top, crop.right, crop.bottom);
+            } else {
+                nativeSetFinalCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0);
+            }
+
+            return this;
+        }
+
+        public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
+            nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
+            return this;
+        }
+
+        public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle, long frameNumber) {
+            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
+            return this;
+        }
+
+        public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
+                long frameNumber) {
+            nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
+                    barrierSurface.mNativeObject, frameNumber);
+            return this;
+        }
+
+        public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
+            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle);
+            return this;
+        }
+
+        /** Re-parents a specific child layer to a new parent */
+        public Transaction reparent(SurfaceControl sc, IBinder newParentHandle) {
+            nativeReparent(mNativeObject, sc.mNativeObject,
+                    newParentHandle);
+            return this;
+        }
+
+        public Transaction detachChildren(SurfaceControl sc) {
+            nativeSeverChildren(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
+        public Transaction setOverrideScalingMode(SurfaceControl sc, int overrideScalingMode) {
+            nativeSetOverrideScalingMode(mNativeObject, sc.mNativeObject,
+                    overrideScalingMode);
+            return this;
+        }
+
+        /**
+         * Sets a color for the Surface.
+         * @param color A float array with three values to represent r, g, b in range [0..1]
+         */
+        public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) {
+            nativeSetColor(mNativeObject, sc.mNativeObject, color);
+            return this;
+        }
+
+        /**
+         * If the buffer size changes in this transaction, position and crop updates specified
+         * in this transaction will not complete until a buffer of the new size
+         * arrives. As transform matrix and size are already frozen in this fashion,
+         * this enables totally freezing the surface until the resize has completed
+         * (at which point the geometry influencing aspects of this transaction will then occur)
+         */
+        public Transaction setGeometryAppliesWithResize(SurfaceControl sc) {
+            nativeSetGeometryAppliesWithResize(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
+        /**
+         * Sets the security of the surface.  Setting the flag is equivalent to creating the
+         * Surface with the {@link #SECURE} flag.
+         */
+        Transaction setSecure(SurfaceControl sc, boolean isSecure) {
+            if (isSecure) {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE);
+            } else {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the opacity of the surface.  Setting the flag is equivalent to creating the
+         * Surface with the {@link #OPAQUE} flag.
+         */
+        public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) {
+            if (isOpaque) {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, OPAQUE, OPAQUE);
+            } else {
+                nativeSetFlags(mNativeObject, sc.mNativeObject, 0, OPAQUE);
+            }
+            return this;
+        }
+
+        public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+
+            if (surface != null) {
+                synchronized (surface.mLock) {
+                    nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject);
+                }
+            } else {
+                nativeSetDisplaySurface(mNativeObject, displayToken, 0);
+            }
+            return this;
+        }
+
+        public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack);
+            return this;
+        }
+
+        public Transaction setDisplayProjection(IBinder displayToken,
+                int orientation, Rect layerStackRect, Rect displayRect) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            if (layerStackRect == null) {
+                throw new IllegalArgumentException("layerStackRect must not be null");
+            }
+            if (displayRect == null) {
+                throw new IllegalArgumentException("displayRect must not be null");
+            }
+            nativeSetDisplayProjection(mNativeObject, displayToken, orientation,
+                    layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
+                    displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
+            return this;
+        }
+
+        public Transaction setDisplaySize(IBinder displayToken, int width, int height) {
+            if (displayToken == null) {
+                throw new IllegalArgumentException("displayToken must not be null");
+            }
+            if (width <= 0 || height <= 0) {
+                throw new IllegalArgumentException("width and height must be positive");
+            }
+
+            nativeSetDisplaySize(mNativeObject, displayToken, width, height);
+            return this;
+        }
+
+        /** flag the transaction as an animation */
+        public Transaction setAnimationTransaction() {
+            nativeSetAnimationTransaction(mNativeObject);
+            return this;
+        }
+    }
 }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a9b849e..8ae9ada 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -98,6 +98,18 @@
 
 // ----------------------------------------------------------------------------
 
+static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
+    return reinterpret_cast<jlong>(new SurfaceComposerClient::Transaction);
+}
+
+static void releaseTransaction(SurfaceComposerClient::Transaction* t) {
+    delete t;
+}
+
+static jlong nativeGetNativeTransactionFinalizer(JNIEnv* env, jclass clazz) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseTransaction));
+}
+
 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) {
@@ -278,69 +290,72 @@
     }
 }
 
-static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
-    SurfaceComposerClient::openGlobalTransaction();
+static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->apply(sync);
 }
 
-
-static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
-    SurfaceComposerClient::closeGlobalTransaction(sync);
+static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz, jlong transactionObj) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->setAnimationTransaction();
 }
 
-static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
-    SurfaceComposerClient::setAnimationTransaction();
-}
+static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint zorder) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setLayer(zorder);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setLayer(ctrl, zorder);
 }
 
-static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject relativeTo, jint zorder) {
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);
 
-    ctrl->setRelativeLayer(handle, zorder);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setRelativeLayer(ctrl, handle, zorder);
+    }
 }
 
-static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat x, jfloat y) {
+static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloat x, jfloat y) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setPosition(x, y);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setPosition(ctrl, x, y);
 }
 
 static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
+jlong transactionObj,
         jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setGeometryAppliesWithResize();
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setGeometryAppliesWithResize(ctrl);
 }
 
-static void nativeSetSize(JNIEnv* env, jclass clazz, jlong nativeObject, jint w, jint h) {
+static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint w, jint h) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setSize(w, h);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setSize(ctrl, w, h);
 }
 
-static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong nativeObject, jint flags, jint mask) {
+static void nativeSetFlags(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint flags, jint mask) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setFlags(flags, mask);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setFlags(ctrl, flags, mask);
 }
 
-static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) {
+static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jobject regionObj) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
     if (!region) {
@@ -359,65 +374,65 @@
         }
     }
 
-    status_t err = ctrl->setTransparentRegionHint(reg);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setTransparentRegionHint(ctrl, reg);
     }
 }
 
-static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat alpha) {
+static void nativeSetAlpha(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloat alpha) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setAlpha(alpha);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setAlpha(ctrl, alpha);
 }
 
-static void nativeSetColor(JNIEnv* env, jclass clazz, jlong nativeObject, jfloatArray fColor) {
+static void nativeSetColor(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloatArray fColor) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+
     float* floatColors = env->GetFloatArrayElements(fColor, 0);
     half3 color(floatColors[0], floatColors[1], floatColors[2]);
-    status_t err = ctrl->setColor(color);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setColor(ctrl, color);
 }
 
-static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setMatrix(dsdx, dtdx, dtdy, dsdy);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
 }
 
-static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint l, jint t, jint r, jint b) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     Rect crop(l, t, r, b);
-    status_t err = ctrl->setCrop(crop);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setCrop(ctrl, crop);
 }
 
-static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint l, jint t, jint r, jint b) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     Rect crop(l, t, r, b);
-    status_t err = ctrl->setFinalCrop(crop);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setFinalCrop(ctrl, crop);
 }
 
-static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong nativeObject, jint layerStack) {
+static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jint layerStack) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t err = ctrl->setLayerStack(layerStack);
-    if (err < 0 && err != NO_INIT) {
-        doThrowIAE(env);
-    }
+    transaction->setLayerStack(ctrl, layerStack);
 }
 
 static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
@@ -440,6 +455,7 @@
 }
 
 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jlong nativeSurfaceObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
@@ -448,8 +464,14 @@
     if (sur != NULL) {
         bufferProducer = sur->getIGraphicBufferProducer();
     }
-    status_t err = SurfaceComposerClient::setDisplaySurface(token,
-            bufferProducer);
+
+
+    status_t err = NO_ERROR;
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        err = transaction->setDisplaySurface(token,
+                bufferProducer);
+    }
     if (err != NO_ERROR) {
         doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this"
                 " Surface created with singleBufferMode?");
@@ -457,14 +479,20 @@
 }
 
 static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint layerStack) {
+
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
 
-    SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplayLayerStack(token, layerStack);
+    }
 }
 
 static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint orientation,
         jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
         jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
@@ -472,14 +500,23 @@
     if (token == NULL) return;
     Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
     Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
-    SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplayProjection(token, orientation, layerStackRect, displayRect);
+    }
 }
 
 static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
+        jlong transactionObj,
         jobject tokenObj, jint width, jint height) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
     if (token == NULL) return;
-    SurfaceComposerClient::setDisplaySize(token, width, height);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->setDisplaySize(token, width, height);
+    }
 }
 
 static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
@@ -722,52 +759,73 @@
     return JNI_TRUE;
 }
 
-static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject handleObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
 
-    ctrl->deferTransactionUntil(handle, frameNumber);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->deferTransactionUntil(ctrl, handle, frameNumber);
+    }
 }
 
-static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jlong surfaceObject, jlong frameNumber) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
 
-    ctrl->deferTransactionUntil(barrier, frameNumber);
+    transaction->deferTransactionUntil(ctrl, barrier, frameNumber);
 }
 
-static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject newParentObject) {
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
 
-    ctrl->reparentChildren(handle);
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->reparentChildren(ctrl, handle);
+    }
 }
 
-static void nativeReparent(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jobject newParentObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     sp<IBinder> parentHandle = ibinderForJavaObject(env, newParentObject);
-    ctrl->reparent(parentHandle);
+
+    {
+        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+        transaction->reparent(ctrl, parentHandle);
+    }
 }
 
-static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong nativeObject) {
+static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    ctrl->detachChildren();
+    transaction->detachChildren(ctrl);
 }
 
-static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
+static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject,
         jint scalingMode) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-    ctrl->setOverrideScalingMode(scalingMode);
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    transaction->setOverrideScalingMode(ctrl, scalingMode);
 }
 
 static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-
     return javaObjectForIBinder(env, ctrl->getHandle());
 }
 
@@ -802,37 +860,39 @@
             (void*)nativeScreenshotBitmap },
     {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
             (void*)nativeScreenshot },
-    {"nativeOpenTransaction", "()V",
-            (void*)nativeOpenTransaction },
-    {"nativeCloseTransaction", "(Z)V",
-            (void*)nativeCloseTransaction },
-    {"nativeSetAnimationTransaction", "()V",
+    {"nativeCreateTransaction", "()J",
+            (void*)nativeCreateTransaction },
+    {"nativeApplyTransaction", "(JZ)V",
+            (void*)nativeApplyTransaction },
+    {"nativeGetNativeTransactionFinalizer", "()J",
+            (void*)nativeGetNativeTransactionFinalizer },
+    {"nativeSetAnimationTransaction", "(J)V",
             (void*)nativeSetAnimationTransaction },
-    {"nativeSetLayer", "(JI)V",
+    {"nativeSetLayer", "(JJI)V",
             (void*)nativeSetLayer },
-    {"nativeSetRelativeLayer", "(JLandroid/os/IBinder;I)V",
+    {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V",
             (void*)nativeSetRelativeLayer },
-    {"nativeSetPosition", "(JFF)V",
+    {"nativeSetPosition", "(JJFF)V",
             (void*)nativeSetPosition },
-    {"nativeSetGeometryAppliesWithResize", "(J)V",
+    {"nativeSetGeometryAppliesWithResize", "(JJ)V",
             (void*)nativeSetGeometryAppliesWithResize },
-    {"nativeSetSize", "(JII)V",
+    {"nativeSetSize", "(JJII)V",
             (void*)nativeSetSize },
-    {"nativeSetTransparentRegionHint", "(JLandroid/graphics/Region;)V",
+    {"nativeSetTransparentRegionHint", "(JJLandroid/graphics/Region;)V",
             (void*)nativeSetTransparentRegionHint },
-    {"nativeSetAlpha", "(JF)V",
+    {"nativeSetAlpha", "(JJF)V",
             (void*)nativeSetAlpha },
-    {"nativeSetColor", "(J[F)V",
+    {"nativeSetColor", "(JJ[F)V",
             (void*)nativeSetColor },
-    {"nativeSetMatrix", "(JFFFF)V",
+    {"nativeSetMatrix", "(JJFFFF)V",
             (void*)nativeSetMatrix },
-    {"nativeSetFlags", "(JII)V",
+    {"nativeSetFlags", "(JJII)V",
             (void*)nativeSetFlags },
-    {"nativeSetWindowCrop", "(JIIII)V",
+    {"nativeSetWindowCrop", "(JJIIII)V",
             (void*)nativeSetWindowCrop },
-    {"nativeSetFinalCrop", "(JIIII)V",
+    {"nativeSetFinalCrop", "(JJIIII)V",
             (void*)nativeSetFinalCrop },
-    {"nativeSetLayerStack", "(JI)V",
+    {"nativeSetLayerStack", "(JJI)V",
             (void*)nativeSetLayerStack },
     {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
             (void*)nativeGetBuiltInDisplay },
@@ -840,13 +900,13 @@
             (void*)nativeCreateDisplay },
     {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
             (void*)nativeDestroyDisplay },
-    {"nativeSetDisplaySurface", "(Landroid/os/IBinder;J)V",
+    {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
             (void*)nativeSetDisplaySurface },
-    {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
+    {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
             (void*)nativeSetDisplayLayerStack },
-    {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
+    {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V",
             (void*)nativeSetDisplayProjection },
-    {"nativeSetDisplaySize", "(Landroid/os/IBinder;II)V",
+    {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
             (void*)nativeSetDisplaySize },
     {"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
             (void*)nativeGetDisplayConfigs },
@@ -872,17 +932,17 @@
             (void*)nativeGetAnimationFrameStats },
     {"nativeSetDisplayPowerMode", "(Landroid/os/IBinder;I)V",
             (void*)nativeSetDisplayPowerMode },
-    {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
+    {"nativeDeferTransactionUntil", "(JJLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
-    {"nativeDeferTransactionUntilSurface", "(JJJ)V",
+    {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
             (void*)nativeDeferTransactionUntilSurface },
-    {"nativeReparentChildren", "(JLandroid/os/IBinder;)V",
+    {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V",
             (void*)nativeReparentChildren } ,
-    {"nativeReparent", "(JLandroid/os/IBinder;)V",
+    {"nativeReparent", "(JJLandroid/os/IBinder;)V",
             (void*)nativeReparent },
-    {"nativeSeverChildren", "(J)V",
+    {"nativeSeverChildren", "(JJ)V",
             (void*)nativeSeverChildren } ,
-    {"nativeSetOverrideScalingMode", "(JI)V",
+    {"nativeSetOverrideScalingMode", "(JJI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
diff --git a/libs/hwui/tests/common/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
index c1ca1e7..1e30d23 100644
--- a/libs/hwui/tests/common/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -81,10 +81,10 @@
     mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"),
             gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888);
 
-    SurfaceComposerClient::openGlobalTransaction();
-    mSurfaceControl->setLayer(0x7FFFFFF);
-    mSurfaceControl->show();
-    SurfaceComposerClient::closeGlobalTransaction();
+    SurfaceComposerClient::Transaction t;
+    t.setLayer(mSurfaceControl, 0x7FFFFFF)
+            .show(mSurfaceControl)
+            .apply();
     mSurface = mSurfaceControl->getSurface();
 }
 
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index ed31b12..173cd50 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -148,8 +148,9 @@
         }
     }
 
-    // Resize sprites if needed, inside a global transaction.
-    bool haveGlobalTransaction = false;
+    // Resize sprites if needed.
+    SurfaceComposerClient::Transaction t;
+    bool needApplyTransaction = false;
     for (size_t i = 0; i < numSprites; i++) {
         SpriteUpdate& update = updates.editItemAt(i);
 
@@ -158,36 +159,24 @@
             int32_t desiredHeight = update.state.icon.bitmap.height();
             if (update.state.surfaceWidth < desiredWidth
                     || update.state.surfaceHeight < desiredHeight) {
-                if (!haveGlobalTransaction) {
-                    SurfaceComposerClient::openGlobalTransaction();
-                    haveGlobalTransaction = true;
-                }
+                needApplyTransaction = true;
 
-                status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);
-                if (status) {
-                    ALOGE("Error %d resizing sprite surface from %dx%d to %dx%d",
-                            status, update.state.surfaceWidth, update.state.surfaceHeight,
-                            desiredWidth, desiredHeight);
-                } else {
-                    update.state.surfaceWidth = desiredWidth;
-                    update.state.surfaceHeight = desiredHeight;
-                    update.state.surfaceDrawn = false;
-                    update.surfaceChanged = surfaceChanged = true;
+                t.setSize(update.state.surfaceControl,
+                        desiredWidth, desiredHeight);
+                update.state.surfaceWidth = desiredWidth;
+                update.state.surfaceHeight = desiredHeight;
+                update.state.surfaceDrawn = false;
+                update.surfaceChanged = surfaceChanged = true;
 
-                    if (update.state.surfaceVisible) {
-                        status = update.state.surfaceControl->hide();
-                        if (status) {
-                            ALOGE("Error %d hiding sprite surface after resize.", status);
-                        } else {
-                            update.state.surfaceVisible = false;
-                        }
-                    }
+                if (update.state.surfaceVisible) {
+                    t.hide(update.state.surfaceControl);
+                    update.state.surfaceVisible = false;
                 }
             }
         }
     }
-    if (haveGlobalTransaction) {
-        SurfaceComposerClient::closeGlobalTransaction();
+    if (needApplyTransaction) {
+        t.apply();
     }
 
     // Redraw sprites if needed.
@@ -240,8 +229,7 @@
         }
     }
 
-    // Set sprite surface properties and make them visible.
-    bool haveTransaction = false;
+    needApplyTransaction = false;
     for (size_t i = 0; i < numSprites; i++) {
         SpriteUpdate& update = updates.editItemAt(i);
 
@@ -253,75 +241,59 @@
                 || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
                         | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
                         | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
-            status_t status;
-            if (!haveTransaction) {
-                SurfaceComposerClient::openGlobalTransaction();
-                haveTransaction = true;
-            }
+            needApplyTransaction = true;
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {
-                status = update.state.surfaceControl->setAlpha(update.state.alpha);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface alpha.", status);
-                }
+                t.setAlpha(update.state.surfaceControl,
+                        update.state.alpha);
             }
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & (DIRTY_POSITION
                             | DIRTY_HOTSPOT)))) {
-                status = update.state.surfaceControl->setPosition(
+                t.setPosition(
+                        update.state.surfaceControl,
                         update.state.positionX - update.state.icon.hotSpotX,
                         update.state.positionY - update.state.icon.hotSpotY);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface position.", status);
-                }
             }
 
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible
                             || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {
-                status = update.state.surfaceControl->setMatrix(
+                t.setMatrix(
+                        update.state.surfaceControl,
                         update.state.transformationMatrix.dsdx,
                         update.state.transformationMatrix.dtdx,
                         update.state.transformationMatrix.dsdy,
                         update.state.transformationMatrix.dtdy);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface transformation matrix.", status);
-                }
             }
 
             int32_t surfaceLayer = mOverlayLayer + update.state.layer;
             if (wantSurfaceVisibleAndDrawn
                     && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {
-                status = update.state.surfaceControl->setLayer(surfaceLayer);
-                if (status) {
-                    ALOGE("Error %d setting sprite surface layer.", status);
-                }
+                t.setLayer(update.state.surfaceControl, surfaceLayer);
             }
 
             if (becomingVisible) {
-                status = update.state.surfaceControl->show();
-                if (status) {
-                    ALOGE("Error %d showing sprite surface.", status);
-                } else {
-                    update.state.surfaceVisible = true;
-                    update.surfaceChanged = surfaceChanged = true;
-                }
+                t.show(update.state.surfaceControl);
+
+                update.state.surfaceVisible = true;
+                update.surfaceChanged = surfaceChanged = true;
             } else if (becomingHidden) {
-                status = update.state.surfaceControl->hide();
-                if (status) {
-                    ALOGE("Error %d hiding sprite surface.", status);
-                } else {
-                    update.state.surfaceVisible = false;
-                    update.surfaceChanged = surfaceChanged = true;
-                }
+                t.hide(update.state.surfaceControl);
+
+                update.state.surfaceVisible = false;
+                update.surfaceChanged = surfaceChanged = true;
             }
         }
     }
 
-    if (haveTransaction) {
-        SurfaceComposerClient::closeGlobalTransaction();
+    if (needApplyTransaction) {
+        status_t status = t.apply();
+        if (status) {
+            ALOGE("Error applying Surface transaction");
+        }
     }
 
     // If any surfaces were changed, write back the new surface properties to the sprites.
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 5c29a0a..d206554 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -18,7 +18,6 @@
 
 import static android.graphics.PixelFormat.OPAQUE;
 import static android.view.SurfaceControl.FX_SURFACE_DIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -51,14 +50,8 @@
             int w = r-l;
             int h = b-t;
 
-            if (DEBUG_SURFACE_TRACE) {
-                surface = new WindowSurfaceController.SurfaceTrace(session, "BlackSurface("
-                        + l + ", " + t + ")",
-                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            } else {
-                surface = new SurfaceControl(session, "BlackSurface",
-                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            }
+            surface = new SurfaceControl(session, "BlackSurface",
+                    w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
 
             surface.setAlpha(1);
             surface.setLayerStack(layerStack);
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index ae41541..85f468b 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -67,14 +66,9 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowSurfaceController.SurfaceTrace(session, "CircularDisplayMask",
-                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
-                        SurfaceControl.HIDDEN);
-            } else {
-                ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x,
-                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-            }
+            ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x,
+                    mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setLayer(zOrder);
             ctrl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 708973d..48181d3 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DIM_LAYER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -105,16 +104,10 @@
     private void constructSurface(WindowManagerService service) {
         service.openSurfaceTransaction();
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                mDimSurface = new WindowSurfaceController.SurfaceTrace(service.mFxSession,
-                    "DimSurface",
+            mDimSurface = new SurfaceControl(service.mFxSession, mName,
                     16, 16, PixelFormat.OPAQUE,
                     SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            } else {
-                mDimSurface = new SurfaceControl(service.mFxSession, mName,
-                    16, 16, PixelFormat.OPAQUE,
-                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
-            }
+
             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
                     "  DIM " + mDimSurface + ": CREATE");
             mDimSurface.setLayerStack(mDisplayId);
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 3186d3d..19bd8e9 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -57,14 +56,8 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (DEBUG_SURFACE_TRACE) {
-                ctrl = new WindowSurfaceController.SurfaceTrace(session, "EmulatorDisplayOverlay",
-                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
-                        SurfaceControl.HIDDEN);
-            } else {
-                ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
-                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-            }
+            ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
+                    mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
             ctrl.setLayerStack(display.getLayerStack());
             ctrl.setLayer(zOrder);
             ctrl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index d5b6d24..8e99be8 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -24,7 +23,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
-import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
 import static com.android.server.wm.proto.ScreenRotationAnimationProto.ANIMATION_RUNNING;
 import static com.android.server.wm.proto.ScreenRotationAnimationProto.STARTED;
 
@@ -276,17 +274,10 @@
                     flags |= SurfaceControl.SECURE;
                 }
 
-                if (DEBUG_SURFACE_TRACE) {
-                    mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
-                            mWidth, mHeight,
-                            PixelFormat.OPAQUE, flags);
-                    Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
-                            + mOriginalDisplayRect.toShortString());
-                } else {
-                    mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
-                            mWidth, mHeight,
-                            PixelFormat.OPAQUE, flags);
-                }
+                mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
+                        mWidth, mHeight,
+                        PixelFormat.OPAQUE, flags);
+
                 // capture a screenshot into the surface we just created
                 Surface sur = new Surface();
                 sur.copyFrom(mSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 6d5673e..9d9805a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -60,7 +60,6 @@
     static final boolean DEBUG_SCREENSHOT = false;
     static final boolean DEBUG_BOOT = false;
     static final boolean DEBUG_LAYOUT_REPEATS = false;
-    static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
     static final boolean DEBUG_TASK_POSITIONING = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1fb2188..bc6ab9e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6898,11 +6898,6 @@
                     dumpSessionsLocked(pw, true);
                 }
                 return;
-            } else if ("surfaces".equals(cmd)) {
-                synchronized(mWindowMap) {
-                    WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, null);
-                }
-                return;
             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
                 synchronized(mWindowMap) {
                     mRoot.dumpDisplayContents(pw);
@@ -6967,10 +6962,6 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            WindowSurfaceController.SurfaceTrace.dumpAllSurfaces(pw, dumpAll ?
-                    "-------------------------------------------------------------------------------"
-                    : null);
-            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4ff0f39..01a1977 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -83,7 +83,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -1210,7 +1209,7 @@
             // application when it has finished drawing.
             if (getOrientationChanging() || dragResizingChanged
                     || isResizedWhileNotDragResizing()) {
-                if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
+                if (DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
                     Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                             + ", mDrawState=DRAW_PENDING in " + this
                             + ", surfaceController " + winAnimator.mSurfaceController);
@@ -3695,7 +3694,7 @@
 
         // Force the show in the next prepareSurfaceLocked() call.
         mWinAnimator.mLastAlpha = -1;
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) Slog.v(TAG,
+        if (DEBUG_ANIM) Slog.v(TAG,
                 "performShowLocked: mDrawState=HAS_DRAWN in " + this);
         mWinAnimator.mDrawState = HAS_DRAWN;
         mService.scheduleAnimationLocked();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1b7e527..e12b339 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -31,7 +31,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
@@ -509,7 +508,7 @@
         boolean layoutNeeded = false;
 
         if (mDrawState == DRAW_PENDING) {
-            if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
+            if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
                         + mSurfaceController);
             if (DEBUG_STARTING_WINDOW && startingWindow) {
@@ -532,7 +531,7 @@
         if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
             return false;
         }
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
+        if (DEBUG_ANIM) {
             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
         }
         mDrawState = READY_TO_SHOW;
@@ -1033,7 +1032,7 @@
                 //Slog.i(TAG_WM, "Not applying alpha transform");
             }
 
-            if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
+            if ((DEBUG_ANIM || WindowManagerService.localLOGV)
                     && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
                     TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
                     + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 2e1e3f7..d56df55 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -22,7 +22,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -565,262 +564,4 @@
     public String toString() {
         return mSurfaceControl.toString();
     }
-
-    static class SurfaceTrace extends SurfaceControl {
-        private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
-        private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
-        final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
-
-        private float mSurfaceTraceAlpha = 0;
-        private int mLayer;
-        private final PointF mPosition = new PointF();
-        private final Point mSize = new Point();
-        private final Rect mWindowCrop = new Rect();
-        private final Rect mFinalCrop = new Rect();
-        private boolean mShown = false;
-        private int mLayerStack;
-        private boolean mIsOpaque;
-        private float mDsdx, mDtdx, mDsdy, mDtdy;
-        private final String mName;
-
-        public SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags,
-                        int windowType, int ownerUid)
-                    throws OutOfResourcesException {
-            super(s, name, w, h, format, flags, windowType, ownerUid);
-            mName = name != null ? name : "Not named";
-            mSize.set(w, h);
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.add(0, this);
-            }
-        }
-
-        public SurfaceTrace(SurfaceSession s,
-                        String name, int w, int h, int format, int flags) {
-            super(s, name, w, h, format, flags);
-            mName = name != null ? name : "Not named";
-            mSize.set(w, h);
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.add(0, this);
-            }
-        }
-
-        @Override
-        public void setAlpha(float alpha) {
-            if (mSurfaceTraceAlpha != alpha) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
-                        ". Called by " + Debug.getCallers(3));
-                mSurfaceTraceAlpha = alpha;
-            }
-            super.setAlpha(alpha);
-        }
-
-        @Override
-        public void setLayer(int zorder) {
-            if (zorder != mLayer) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
-                        + ". Called by " + Debug.getCallers(3));
-                mLayer = zorder;
-            }
-            super.setLayer(zorder);
-
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-                int i;
-                for (i = sSurfaces.size() - 1; i >= 0; i--) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    if (s.mLayer < zorder) {
-                        break;
-                    }
-                }
-                sSurfaces.add(i + 1, this);
-            }
-        }
-
-        @Override
-        public void setPosition(float x, float y) {
-            if (x != mPosition.x || y != mPosition.y) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mPosition.set(x, y);
-            }
-            super.setPosition(x, y);
-        }
-
-        @Override
-        public void setGeometryAppliesWithResize() {
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: "
-                    + this + ". Called by" + Debug.getCallers(3));
-            super.setGeometryAppliesWithResize();
-        }
-
-        @Override
-        public void setSize(int w, int h) {
-            if (w != mSize.x || h != mSize.y) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mSize.set(w, h);
-            }
-            super.setSize(w, h);
-        }
-
-        @Override
-        public void setWindowCrop(Rect crop) {
-            if (crop != null) {
-                if (!crop.equals(mWindowCrop)) {
-                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
-                            + crop.toShortString() + "): OLD:" + this + ". Called by "
-                            + Debug.getCallers(3));
-                    mWindowCrop.set(crop);
-                }
-            }
-            super.setWindowCrop(crop);
-        }
-
-        @Override
-        public void setFinalCrop(Rect crop) {
-            if (crop != null) {
-                if (!crop.equals(mFinalCrop)) {
-                    if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
-                            + crop.toShortString() + "): OLD:" + this + ". Called by "
-                            + Debug.getCallers(3));
-                    mFinalCrop.set(crop);
-                }
-            }
-            super.setFinalCrop(crop);
-        }
-
-        @Override
-        public void setLayerStack(int layerStack) {
-            if (layerStack != mLayerStack) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mLayerStack = layerStack;
-            }
-            super.setLayerStack(layerStack);
-        }
-
-        @Override
-        public void setOpaque(boolean isOpaque) {
-            if (isOpaque != mIsOpaque) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
-                        + this + ". Called by " + Debug.getCallers(3));
-                mIsOpaque = isOpaque;
-            }
-            super.setOpaque(isOpaque);
-        }
-
-        @Override
-        public void setSecure(boolean isSecure) {
-            super.setSecure(isSecure);
-        }
-
-        @Override
-        public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-            if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
-                        + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mDsdx = dsdx;
-                mDtdx = dtdx;
-                mDsdy = dsdy;
-                mDtdy = dtdy;
-            }
-            super.setMatrix(dsdx, dtdx, dsdy, dtdy);
-        }
-
-        @Override
-        public void hide() {
-            if (mShown) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = false;
-            }
-            super.hide();
-        }
-
-        @Override
-        public void show() {
-            if (!mShown) {
-                if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
-                        + Debug.getCallers(3));
-                mShown = true;
-            }
-            super.show();
-        }
-
-        @Override
-        public void destroy() {
-            super.destroy();
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        @Override
-        public void release() {
-            super.release();
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
-                    + Debug.getCallers(3));
-            synchronized (sSurfaces) {
-                sSurfaces.remove(this);
-            }
-        }
-
-        @Override
-        public void setTransparentRegionHint(Region region) {
-            if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region
-                    + "): OLD: " + this + " . Called by " + Debug.getCallers(3));
-            super.setTransparentRegionHint(region);
-        }
-
-        static void dumpAllSurfaces(PrintWriter pw, String header) {
-            synchronized (sSurfaces) {
-                final int N = sSurfaces.size();
-                if (N <= 0) {
-                    return;
-                }
-                if (header != null) {
-                    pw.println(header);
-                }
-                pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
-                for (int i = 0; i < N; i++) {
-                    SurfaceTrace s = sSurfaces.get(i);
-                    pw.print("  Surface #"); pw.print(i); pw.print(": #");
-                            pw.print(Integer.toHexString(System.identityHashCode(s)));
-                            pw.print(" "); pw.println(s.mName);
-                    pw.print("    mLayerStack="); pw.print(s.mLayerStack);
-                            pw.print(" mLayer="); pw.println(s.mLayer);
-                    pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
-                            pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
-                            pw.println(s.mIsOpaque);
-                    pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
-                            pw.print(s.mPosition.y);
-                            pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
-                            pw.println(s.mSize.y);
-                    pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
-                    pw.print("    mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
-                    pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
-                            pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
-                            pw.print(", "); pw.print(s.mDtdy); pw.println(")");
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
-                    + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
-                    + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
-                    + " " + mSize.x + "x" + mSize.y
-                    + " crop=" + mWindowCrop.toShortString()
-                    + " opaque=" + mIsOpaque
-                    + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
-        }
-    }
 }