Workaround to not use the hidden SyncRtSurfaceTransactionApplier

Test: unbundled branch builds
Change-Id: I32838cbfbeadab223e9402ece1ffb3325230271b
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index c0a1d89..e6acfbe 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -16,14 +16,10 @@
 
 package com.android.systemui.shared.system;
 
+import android.graphics.HardwareRenderer;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.SurfaceControl.Transaction;
-import android.view.SyncRtSurfaceTransactionApplier;
-import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
-import android.view.ThreadedRenderer;
 import android.view.View;
 import android.view.ViewRootImpl;
 
@@ -31,20 +27,21 @@
 
 /**
  * Helper class to apply surface transactions in sync with RenderThread.
+ *
+ * NOTE: This is a modification of {@link android.view.SyncRtSurfaceTransactionApplier}, we can't 
+ *       currently reference that class from the shared lib as it is hidden.
  */
 public class SyncRtSurfaceTransactionApplierCompat {
 
-    private final SyncRtSurfaceTransactionApplier mApplier;
+    private final Surface mTargetSurface;
+    private final ViewRootImpl mTargetViewRootImpl;
 
     /**
      * @param targetView The view in the surface that acts as synchronization anchor.
      */
     public SyncRtSurfaceTransactionApplierCompat(View targetView) {
-        mApplier = new SyncRtSurfaceTransactionApplier(targetView);
-    }
-
-    private SyncRtSurfaceTransactionApplierCompat(SyncRtSurfaceTransactionApplier applier) {
-        mApplier = applier;
+        mTargetViewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
+        mTargetSurface = mTargetViewRootImpl != null ? mTargetViewRootImpl.mSurface : null;
     }
 
     /**
@@ -53,38 +50,74 @@
      * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
      *               this method to avoid synchronization issues.
      */
-    public void scheduleApply(final SurfaceParams... params) {
-        mApplier.scheduleApply(convert(params));
-    }
-
-    private SyncRtSurfaceTransactionApplier.SurfaceParams[] convert(SurfaceParams[] params) {
-        SyncRtSurfaceTransactionApplier.SurfaceParams[] result =
-                new SyncRtSurfaceTransactionApplier.SurfaceParams[params.length];
-        for (int i = 0; i < params.length; i++) {
-            result[i] = params[i].mParams;
+    public void scheduleApply(final SyncRtSurfaceTransactionApplierCompat.SurfaceParams... params) {
+        if (mTargetViewRootImpl == null) {
+            return;
         }
-        return result;
+        mTargetViewRootImpl.registerRtFrameCallback(new HardwareRenderer.FrameDrawingCallback() {
+            @Override
+            public void onFrameDraw(long frame) {
+                if (mTargetSurface == null || !mTargetSurface.isValid()) {
+                    return;
+                }
+                TransactionCompat t = new TransactionCompat();
+                for (int i = params.length - 1; i >= 0; i--) {
+                    SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
+                            params[i];
+                    SurfaceControlCompat surface = surfaceParams.surface;
+                    t.deferTransactionUntil(surface, mTargetSurface, frame);
+                    applyParams(t, surfaceParams);
+                }
+                t.setEarlyWakeup();
+                t.apply();
+            }
+        });
+
+        // Make sure a frame gets scheduled.
+        mTargetViewRootImpl.getView().invalidate();
     }
 
-    public static void applyParams(TransactionCompat t, SurfaceParams params) {
-        SyncRtSurfaceTransactionApplier.applyParams(t.mTransaction, params.mParams, t.mTmpValues);
+    public static void applyParams(TransactionCompat t,
+            SyncRtSurfaceTransactionApplierCompat.SurfaceParams params) {
+        t.setMatrix(params.surface, params.matrix);
+        t.setWindowCrop(params.surface, params.windowCrop);
+        t.setAlpha(params.surface, params.alpha);
+        t.setLayer(params.surface, params.layer);
+        t.setCornerRadius(params.surface, params.cornerRadius);
+        t.show(params.surface);
     }
 
+    /**
+     * Creates an instance of SyncRtSurfaceTransactionApplier, deferring until the target view is
+     * attached if necessary.
+     */
     public static void create(final View targetView,
             final Consumer<SyncRtSurfaceTransactionApplierCompat> callback) {
-        SyncRtSurfaceTransactionApplier.create(targetView,
-                new Consumer<SyncRtSurfaceTransactionApplier>() {
-                    @Override
-                    public void accept(SyncRtSurfaceTransactionApplier applier) {
-                        callback.accept(new SyncRtSurfaceTransactionApplierCompat(applier));
-                    }
-                });
+        if (targetView == null) {
+            // No target view, no applier
+            callback.accept(null);
+        } else if (targetView.getViewRootImpl() != null) {
+            // Already attached, we're good to go
+            callback.accept(new SyncRtSurfaceTransactionApplierCompat(targetView));
+        } else {
+            // Haven't been attached before we can get the view root
+            targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    targetView.removeOnAttachStateChangeListener(this);
+                    callback.accept(new SyncRtSurfaceTransactionApplierCompat(targetView));
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    // Do nothing
+                }
+            });
+        }
     }
 
     public static class SurfaceParams {
 
-        private final SyncRtSurfaceTransactionApplier.SurfaceParams mParams;
-
         /**
          * Constructs surface parameters to be applied when the current view state gets pushed to
          * RenderThread.
@@ -96,8 +129,19 @@
          */
         public SurfaceParams(SurfaceControlCompat surface, float alpha, Matrix matrix,
                 Rect windowCrop, int layer, float cornerRadius) {
-            mParams = new SyncRtSurfaceTransactionApplier.SurfaceParams(surface.mSurfaceControl,
-                    alpha, matrix, windowCrop, layer, cornerRadius);
+            this.surface = surface;
+            this.alpha = alpha;
+            this.matrix = new Matrix(matrix);
+            this.windowCrop = new Rect(windowCrop);
+            this.layer = layer;
+            this.cornerRadius = cornerRadius;
         }
+
+        public final SurfaceControlCompat surface;
+        public final float alpha;
+        final float cornerRadius;
+        public final Matrix matrix;
+        public final Rect windowCrop;
+        public final int layer;
     }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
index 2aba3fa..af32f48 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -82,6 +82,11 @@
         return this;
     }
 
+    public TransactionCompat setCornerRadius(SurfaceControlCompat surfaceControl, float radius) {
+        mTransaction.setCornerRadius(surfaceControl.mSurfaceControl, radius);
+        return this;
+    }
+
     public TransactionCompat deferTransactionUntil(SurfaceControlCompat surfaceControl,
             IBinder handle, long frameNumber) {
         mTransaction.deferTransactionUntil(surfaceControl.mSurfaceControl, handle, frameNumber);