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

Commit decfc412 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Workaround to not use the hidden SyncRtSurfaceTransactionApplier"

parents 000e9572 b6eba5ee
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);