Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6eba5ee authored by Winson Chung's avatar Winson Chung
Browse files

Workaround to not use the hidden SyncRtSurfaceTransactionApplier

Test: unbundled branch builds
Change-Id: I32838cbfbeadab223e9402ece1ffb3325230271b
parent 4fd1f355
Loading
Loading
Loading
Loading
+78 −34
Original line number Diff line number Diff line
@@ -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 @@ import java.util.function.Consumer;

/**
 * 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 @@ public class SyncRtSurfaceTransactionApplierCompat {
     * @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));
    public void scheduleApply(final SyncRtSurfaceTransactionApplierCompat.SurfaceParams... params) {
        if (mTargetViewRootImpl == null) {
            return;
        }

    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;
        mTargetViewRootImpl.registerRtFrameCallback(new HardwareRenderer.FrameDrawingCallback() {
            @Override
            public void onFrameDraw(long frame) {
                if (mTargetSurface == null || !mTargetSurface.isValid()) {
                    return;
                }
        return result;
                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>() {
        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 accept(SyncRtSurfaceTransactionApplier applier) {
                        callback.accept(new SyncRtSurfaceTransactionApplierCompat(applier));
                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 class SyncRtSurfaceTransactionApplierCompat {
         */
        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;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -82,6 +82,11 @@ public class TransactionCompat {
        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);