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

Commit 42f19b61 authored by Galia Peycheva's avatar Galia Peycheva
Browse files

Make BackgroundBlurDrawable a SystemApi

Bug: 177524486
Test: check that using the drawable in the PermissionController works

Change-Id: I0b881ec6e9a41c5aed3ca17589a6d66ced0539bf
parent e463ad6d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2578,6 +2578,18 @@ package android.debug {
}
package android.graphics.drawable {
  public final class BackgroundBlurDrawable extends android.graphics.drawable.Drawable {
    ctor @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR) public BackgroundBlurDrawable();
    method public void setBlurRadius(int);
    method public void setColor(@ColorInt int);
    method public void setCornerRadius(float);
    method public void setCornerRadius(float, float, float, float);
  }
}
package android.hardware {
  public final class Sensor {
+20 −0
Original line number Diff line number Diff line
@@ -9802,6 +9802,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    private void notifyAttachForDrawables() {
        if (mBackground != null) mBackground.onAttached(this);
        if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
            mForegroundInfo.mDrawable.onAttached(this);
        }
    }
    private void notifyDetachForDrawables() {
        if (mBackground != null) mBackground.onDetached(this);
        if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
            mForegroundInfo.mDrawable.onDetached(this);
        }
    }
    private void setNotifiedContentCaptureAppeared() {
        mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
        mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
@@ -20653,6 +20667,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        notifyEnterOrExitForAutoFillIfNeeded(true);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
        notifyAttachForDrawables();
    }
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
@@ -20702,6 +20717,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        notifyEnterOrExitForAutoFillIfNeeded(false);
        notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
        notifyDetachForDrawables();
    }
    /**
@@ -23830,6 +23846,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mBackground != null) {
            if (isAttachedToWindow()) {
                mBackground.setVisible(false, false);
                mBackground.onDetached(this);
            }
            mBackground.setCallback(null);
            unscheduleDrawable(mBackground);
@@ -23879,6 +23896,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                background.setState(getDrawableState());
            }
            if (isAttachedToWindow()) {
                background.onAttached(this);
                background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
            }
@@ -24111,6 +24129,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mForegroundInfo.mDrawable != null) {
            if (isAttachedToWindow()) {
                mForegroundInfo.mDrawable.setVisible(false, false);
                mForegroundInfo.mDrawable.onDetached(this);
            }
            mForegroundInfo.mDrawable.setCallback(null);
            unscheduleDrawable(mForegroundInfo.mDrawable);
@@ -24128,6 +24147,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            }
            applyForegroundTint();
            if (isAttachedToWindow()) {
                foreground.onAttached(this);
                foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
            }
            // Set callback last, since the view may still be initializing.
+9 −8
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.RenderNode;
import android.graphics.drawable.BackgroundBlurDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.hardware.display.DisplayManager;
@@ -188,7 +189,6 @@ import android.window.ClientWindowFrames;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.SomeArgs;
@@ -671,6 +671,14 @@ public final class ViewRootImpl implements ViewParent,
    private final BackgroundBlurDrawable.Aggregator mBlurRegionAggregator =
            new BackgroundBlurDrawable.Aggregator(this);

    /**
     * @return {@link BackgroundBlurDrawable.Aggregator} for this instance.
     */
    @NonNull
    public BackgroundBlurDrawable.Aggregator getBlurRegionAggregator() {
        return mBlurRegionAggregator;
    }

    /**
     * @return {@link ImeFocusController} for this instance.
     */
@@ -10048,13 +10056,6 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    /**
     * Creates a background blur drawable for the backing {@link Surface}.
     */
    public BackgroundBlurDrawable createBackgroundBlurDrawable() {
        return mBlurRegionAggregator.createBackgroundBlurDrawable(mContext);
    }

    @Override
    public void onDescendantUnbufferedRequested() {
        mUnbufferedInputSource = mView.mUnbufferedInputSource;
+80 −27
Original line number Diff line number Diff line
@@ -14,12 +14,13 @@
 * limitations under the License.
 */

package com.android.internal.graphics.drawable;
package android.graphics.drawable;

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -30,59 +31,71 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
import android.util.ArrayMap;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;

import com.android.internal.R;

/**
 * A drawable that keeps track of a blur region, pokes a hole under it, and propagates its state
 * to SurfaceFlinger.
 *
 * @hide
 */
@SystemApi
public final class BackgroundBlurDrawable extends Drawable {

    private static final String TAG = BackgroundBlurDrawable.class.getSimpleName();
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final Aggregator mAggregator;
    private final RenderNode mRenderNode;
    private final Paint mPaint = new Paint();
    private final Path mRectPath = new Path();
    private final float[] mTmpRadii = new float[8];
    private final SurfaceControl.BlurRegion mBlurRegion = new SurfaceControl.BlurRegion();

    private Aggregator mAggregator;

    // This will be called from a thread pool.
    private final RenderNode.PositionUpdateListener mPositionUpdateListener =
            new RenderNode.PositionUpdateListener() {
            @Override
            public void positionChanged(long frameNumber, int left, int top, int right,
                    int bottom) {
                if (mAggregator == null) {
                    mBlurRegion.rect.set(left, top, right, bottom);
                } else {
                    synchronized (mAggregator) {
                        mBlurRegion.rect.set(left, top, right, bottom);
                        mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion);
                    }
                }
            }

            @Override
            public void positionLost(long frameNumber) {
                if (mAggregator == null) {
                    mBlurRegion.rect.setEmpty();
                } else {
                    synchronized (mAggregator) {
                        mBlurRegion.rect.setEmpty();
                        mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion);
                    }
                }
            }
        };

    private BackgroundBlurDrawable(Aggregator aggregator) {
        mAggregator = aggregator;
    @RequiresPermission(android.Manifest.permission.USE_BACKGROUND_BLUR)
    public BackgroundBlurDrawable() {
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
        mPaint.setColor(Color.TRANSPARENT);
        mRenderNode = new RenderNode("BackgroundBlurDrawable");
        mRenderNode.addPositionUpdateListener(mPositionUpdateListener);
    }

    /**
     * @hide
     */
    @Override
    public void draw(@NonNull Canvas canvas) {
        if (mRectPath.isEmpty() || !isVisible() || getAlpha() == 0) {
@@ -100,6 +113,9 @@ public final class BackgroundBlurDrawable extends Drawable {
        mPaint.setColor(color);
    }

    /**
     * @hide
     */
    @Override
    public boolean setVisible(boolean visible, boolean restart) {
        boolean changed = super.setVisible(visible, restart);
@@ -109,6 +125,9 @@ public final class BackgroundBlurDrawable extends Drawable {
        return changed;
    }

    /**
     * @hide
     */
    @Override
    public void setAlpha(int alpha) {
        mBlurRegion.alpha = alpha / 255f;
@@ -139,12 +158,12 @@ public final class BackgroundBlurDrawable extends Drawable {
     */
    public void setCornerRadius(float cornerRadiusTL, float cornerRadiusTR, float cornerRadiusBL,
            float cornerRadiusBR) {
        synchronized (mAggregator) {
        maybeRunSynchronized(() -> {
            mBlurRegion.cornerRadiusTL = cornerRadiusTL;
            mBlurRegion.cornerRadiusTR = cornerRadiusTR;
            mBlurRegion.cornerRadiusBL = cornerRadiusBL;
            mBlurRegion.cornerRadiusBR = cornerRadiusBR;
        }
        });
        updatePath();
        invalidateSelf();
    }
@@ -157,12 +176,13 @@ public final class BackgroundBlurDrawable extends Drawable {
    }

    private void updatePath() {
        synchronized (mAggregator) {
        maybeRunSynchronized(() -> {
            mTmpRadii[0] = mTmpRadii[1] = mBlurRegion.cornerRadiusTL;
            mTmpRadii[2] = mTmpRadii[3] = mBlurRegion.cornerRadiusTR;
            mTmpRadii[4] = mTmpRadii[5] = mBlurRegion.cornerRadiusBL;
            mTmpRadii[6] = mTmpRadii[7] = mBlurRegion.cornerRadiusBR;
        }
        });

        mRectPath.reset();
        if (getAlpha() == 0 || !isVisible()) {
            return;
@@ -172,19 +192,62 @@ public final class BackgroundBlurDrawable extends Drawable {
                Path.Direction.CW);
    }

    /**
     * @hide
     */
    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        throw new IllegalArgumentException("not implemented");
    }

    /**
     * @hide
     */
    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    /**
     *  @hide
     */
    @Override
    public void onAttached(@NonNull View v) {
        super.onAttached(v);
        mAggregator = v.getViewRootImpl().getBlurRegionAggregator();
    }

    /**
     *  @hide
     */
    @Override
    public void onDetached(@NonNull View v) {
        super.onDetached(v);
        mAggregator = null;
    }

    /**
     * The Aggregator is called from the RenderThread to aggregate all blur regions and send them
     * to SurfaceFlinger. Since the BackgroundBlurDrawable could be updated at any time from the
     * main thread, we need to synchronize the two threads. The BackgroundBlurDrawable may be
     * instantiated before the ViewRootImpl is created, i.e. before the Aggregator is created.
     * In that case, updates are not synchronized.
     */
    private void maybeRunSynchronized(Runnable r) {
        if (mAggregator == null) {
            r.run();
        } else {
            synchronized (mAggregator) {
                r.run();
            }
        }
    }

    /**
     * Responsible for keeping track of all blur regions of a {@link ViewRootImpl} and posting a
     * message when it's time to propagate them.
     *
     * @hide
     */
    public static final class Aggregator {

@@ -198,16 +261,6 @@ public final class BackgroundBlurDrawable extends Drawable {
            mViewRoot = viewRoot;
        }

        /**
         * Creates a blur region with default radius.
         */
        public BackgroundBlurDrawable createBackgroundBlurDrawable(Context context) {
            BackgroundBlurDrawable drawable = new BackgroundBlurDrawable(this);
            drawable.setBlurRadius(context.getResources().getDimensionPixelSize(
                    R.dimen.default_background_blur_radius));
            return drawable;
        }

        /**
         * Called from RenderThread only, already locked.
         * @param drawable
+18 −0
Original line number Diff line number Diff line
@@ -1464,6 +1464,24 @@ public abstract class Drawable {
        mVisible = attrs.getBoolean(visibleAttr, mVisible);
    }

    /**
     * Notifies the drawable that it has been attached.
     *
     * @param v The view that it is attached to
     * @hide
     */
    public void onAttached(View v) {
    }

    /**
     * Notifies the drawable that it has been detached.
     *
     * @param v The view that it is detached from
     * @hide
     */
    public void onDetached(View v) {
    }

    /**
     * Sets the source override density for this Drawable. If non-zero, this density is to be used
     * for any calls to {@link Resources#getDrawableForDensity(int, int, Theme)} or