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

Commit 496b4cbb authored by Vadim Caen's avatar Vadim Caen
Browse files

Do not draw icon background if it shouldn't be seen

Test: atest CtsWindowManagerDeviceTestCases:SplashscreenTests
Bug: 193608336
Change-Id: I824137e67eaa0133337fcaf55c44fca46bac8010
parent c97285ab
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -3176,7 +3176,6 @@ package android.window {

  public final class SplashScreenView extends android.widget.FrameLayout {
    method @Nullable public android.view.View getBrandingView();
    method @ColorInt public int getIconBackgroundColor();
  }

  public final class StartingWindowInfo implements android.os.Parcelable {
+45 −38
Original line number Diff line number Diff line
@@ -89,11 +89,11 @@ public final class SplashScreenView extends FrameLayout {
    private boolean mNotCopyable;
    private boolean mIsCopied;
    private int mInitBackgroundColor;
    private int mInitIconBackgroundColor;
    private View mIconView;
    private Bitmap mParceledIconBitmap;
    private View mBrandingImageView;
    private Bitmap mParceledBrandingBitmap;
    private Bitmap mParceledIconBackgroundBitmap;
    private Duration mIconAnimationDuration;
    private Instant mIconAnimationStart;

@@ -130,11 +130,12 @@ public final class SplashScreenView extends FrameLayout {
        private final Context mContext;
        private int mIconSize;
        private @ColorInt int mBackgroundColor;
        private @ColorInt int mIconBackground;
        private Bitmap mParceledIconBitmap;
        private Bitmap mParceledIconBackgroundBitmap;
        private Drawable mIconDrawable;
        // It is only set for legacy splash screen which won't be sent across processes.
        private Drawable mOverlayDrawable;
        private Drawable mIconBackground;
        private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
        private RemoteCallback mClientCallback;
        private int mBrandingImageWidth;
@@ -155,7 +156,6 @@ public final class SplashScreenView extends FrameLayout {
        public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
            mIconSize = parcelable.getIconSize();
            mBackgroundColor = parcelable.getBackgroundColor();
            mIconBackground = parcelable.getIconBackground();
            mSurfacePackage = parcelable.mSurfacePackage;
            if (mSurfacePackage == null && parcelable.mIconBitmap != null) {
                // We only create a Bitmap copies of immobile icons since animated icon are using
@@ -163,6 +163,11 @@ public final class SplashScreenView extends FrameLayout {
                mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
                mParceledIconBitmap = parcelable.mIconBitmap;
            }
            if (parcelable.mIconBackground != null) {
                mIconBackground = new BitmapDrawable(mContext.getResources(),
                        parcelable.mIconBackground);
                mParceledIconBackgroundBitmap = parcelable.mIconBackground;
            }
            if (parcelable.mBrandingBitmap != null) {
                setBrandingDrawable(new BitmapDrawable(mContext.getResources(),
                                parcelable.mBrandingBitmap), parcelable.mBrandingWidth,
@@ -213,8 +218,8 @@ public final class SplashScreenView extends FrameLayout {
        /**
         * Set the background color for the icon.
         */
        public Builder setIconBackground(int color) {
            mIconBackground = color;
        public Builder setIconBackground(Drawable iconBackground) {
            mIconBackground = iconBackground;
            return this;
        }

@@ -245,7 +250,6 @@ public final class SplashScreenView extends FrameLayout {
            final SplashScreenView view = (SplashScreenView)
                    layoutInflater.inflate(R.layout.splash_screen_view, null, false);
            view.mInitBackgroundColor = mBackgroundColor;
            view.mInitIconBackgroundColor = mIconBackground;
            if (mOverlayDrawable != null) {
                view.setBackground(mOverlayDrawable);
            } else {
@@ -263,25 +267,29 @@ public final class SplashScreenView extends FrameLayout {
                        mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
                view.mIconAnimationStart = mIconAnimationStart;
                view.mIconAnimationDuration = mIconAnimationDuration;
            } else {
                view.mIconView = view.findViewById(R.id.splashscreen_icon_view);
                if (mIconSize != 0) {
                    final ViewGroup.LayoutParams params = view.mIconView.getLayoutParams();
            } else if (mIconSize != 0) {
                ImageView imageView = view.findViewById(R.id.splashscreen_icon_view);
                assert imageView != null;

                final ViewGroup.LayoutParams params = imageView.getLayoutParams();
                params.width = mIconSize;
                params.height = mIconSize;
                    view.mIconView.setLayoutParams(params);
                imageView.setLayoutParams(params);
                if (mIconDrawable != null) {
                        view.mIconView.setBackground(mIconDrawable);
                    imageView.setImageDrawable(mIconDrawable);
                }
                if (mIconBackground != null) {
                    imageView.setBackground(mIconBackground);
                }
                view.mIconView = imageView;
            }
            if (mOverlayDrawable != null || mIconDrawable == null) {
                view.setNotCopyable();
            }

            if (mParceledIconBitmap != null) {
            view.mParceledIconBackgroundBitmap = mParceledIconBackgroundBitmap;
            view.mParceledIconBitmap = mParceledIconBitmap;
            }

            // branding image
            if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) {
                final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
@@ -310,6 +318,7 @@ public final class SplashScreenView extends FrameLayout {
        private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
            final SurfaceView surfaceView = new SurfaceView(view.getContext());
            surfaceView.setPadding(0, 0, 0, 0);
            surfaceView.setBackground(mIconBackground);
            if (mSurfacePackage == null) {
                if (DEBUG) {
                    Log.d(TAG,
@@ -475,7 +484,11 @@ public final class SplashScreenView extends FrameLayout {
        }
        setVisibility(GONE);
        if (mParceledIconBitmap != null) {
            if (mIconView instanceof ImageView) {
                ((ImageView) mIconView).setImageDrawable(null);
            } else if (mIconView != null) {
                mIconView.setBackground(null);
            }
            mParceledIconBitmap.recycle();
            mParceledIconBitmap = null;
        }
@@ -484,6 +497,13 @@ public final class SplashScreenView extends FrameLayout {
            mParceledBrandingBitmap.recycle();
            mParceledBrandingBitmap = null;
        }
        if (mParceledIconBackgroundBitmap != null) {
            if (mIconView != null) {
                mIconView.setBackground(null);
            }
            mParceledIconBackgroundBitmap.recycle();
            mParceledIconBackgroundBitmap = null;
        }
        if (mWindow != null) {
            final DecorView decorView = (DecorView) mWindow.peekDecorView();
            if (DEBUG) {
@@ -599,15 +619,6 @@ public final class SplashScreenView extends FrameLayout {
        return mBrandingImageView;
    }

    /**
     * Get the icon background color
     * @hide
     */
    @TestApi
    public @ColorInt int getIconBackgroundColor() {
        return mInitIconBackgroundColor;
    }

    /**
     * Get the initial background color of this view.
     * @hide
@@ -637,7 +648,7 @@ public final class SplashScreenView extends FrameLayout {
    public static class SplashScreenViewParcelable implements Parcelable {
        private int mIconSize;
        private int mBackgroundColor;
        private int mIconBackground;
        private Bitmap mIconBackground;

        private Bitmap mIconBitmap = null;
        private int mBrandingWidth;
@@ -653,11 +664,11 @@ public final class SplashScreenView extends FrameLayout {
        public SplashScreenViewParcelable(SplashScreenView view) {
            mIconSize = view.mIconView.getWidth();
            mBackgroundColor = view.getInitBackgroundColor();
            mIconBackground = view.getIconBackgroundColor();
            mIconBackground = copyDrawable(view.getIconView().getBackground());
            mSurfacePackage = view.mSurfacePackageCopy;
            if (mSurfacePackage == null) {
                // We only need to copy the drawable if we are not using a SurfaceView
                mIconBitmap = copyDrawable(view.getIconView().getBackground());
                mIconBitmap = copyDrawable(((ImageView) view.getIconView()).getDrawable());
            }
            mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());

@@ -703,7 +714,7 @@ public final class SplashScreenView extends FrameLayout {
            mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
            mIconAnimationStartMillis = source.readLong();
            mIconAnimationDurationMillis = source.readLong();
            mIconBackground = source.readInt();
            mIconBackground = source.readTypedObject(Bitmap.CREATOR);
            mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
            mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
        }
@@ -723,7 +734,7 @@ public final class SplashScreenView extends FrameLayout {
            dest.writeTypedObject(mBrandingBitmap, flags);
            dest.writeLong(mIconAnimationStartMillis);
            dest.writeLong(mIconAnimationDurationMillis);
            dest.writeInt(mIconBackground);
            dest.writeTypedObject(mIconBackground, flags);
            dest.writeTypedObject(mSurfacePackage, flags);
            dest.writeTypedObject(mClientCallback, flags);
        }
@@ -760,10 +771,6 @@ public final class SplashScreenView extends FrameLayout {
            return mBackgroundColor;
        }

        int getIconBackground() {
            return mIconBackground;
        }

        /**
         * Sets the {@link RemoteCallback} that will be called by the client to notify the shell
         * of the removal of the {@link SplashScreenView}.
+1 −2
Original line number Diff line number Diff line
@@ -21,12 +21,11 @@
    android:padding="0dp"
    android:orientation="vertical">

    <View android:id="@+id/splashscreen_icon_view"
    <ImageView android:id="@+id/splashscreen_icon_view"
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:layout_gravity="center"
          android:padding="0dp"
          android:background="@null"
          android:contentDescription="@string/splash_screen_view_icon_description"/>

    <View android:id="@+id/splashscreen_branding_view"
+24 −17
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCRE

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -314,7 +315,7 @@ public class SplashscreenContentDrawer {
        private Drawable mOverlayDrawable;
        private int mSuggestType;
        private int mThemeColor;
        private Drawable mFinalIconDrawable;
        private Drawable[] mFinalIconDrawables;
        private int mFinalIconSize = mIconSize;

        StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
@@ -346,12 +347,13 @@ public class SplashscreenContentDrawer {
                animationDuration = 0;
                mFinalIconSize = 0;
            } else if (mTmpAttrs.mSplashScreenIcon != null) {
                // replaced icon, don't process
                // Using the windowSplashScreenAnimatedIcon attribute
                iconDrawable = mTmpAttrs.mSplashScreenIcon;
                animationDuration = mTmpAttrs.mAnimationDuration;

                // There is no background below the icon, so scale the icon up
                if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT) {
                if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
                        || mTmpAttrs.mIconBgColor == mThemeColor) {
                    mFinalIconSize *= NO_BACKGROUND_SCALE;
                }
                createIconDrawable(iconDrawable, false);
@@ -382,7 +384,7 @@ public class SplashscreenContentDrawer {
                animationDuration = 0;
            }

            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawable, animationDuration);
            return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration);
        }

        private class ShapeIconFactory extends BaseIconFactory {
@@ -393,12 +395,11 @@ public class SplashscreenContentDrawer {

        private void createIconDrawable(Drawable iconDrawable, boolean legacy) {
            if (legacy) {
                mFinalIconDrawable = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
                mFinalIconDrawables = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
                        iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
            } else {
                mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
                        mTmpAttrs.mIconBgColor != Color.TRANSPARENT
                                ? mTmpAttrs.mIconBgColor : mThemeColor,
                mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
                        mTmpAttrs.mIconBgColor, mThemeColor,
                        iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
            }
        }
@@ -459,18 +460,24 @@ public class SplashscreenContentDrawer {
            return true;
        }

        private SplashScreenView fillViewWithIcon(int iconSize, Drawable iconDrawable,
        private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
                int animationDuration) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
            final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext);
            builder.setBackgroundColor(mThemeColor);
            builder.setOverlayDrawable(mOverlayDrawable);
            Drawable foreground = null;
            Drawable background = null;
            if (iconDrawable != null) {
                builder.setIconSize(iconSize)
                        .setIconBackground(mTmpAttrs.mIconBgColor)
                        .setCenterViewDrawable(iconDrawable)
                        .setAnimationDurationMillis(animationDuration);
                foreground = iconDrawable.length > 0 ? iconDrawable[0] : null;
                background = iconDrawable.length > 1 ? iconDrawable[1] : null;
            }

            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
            final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext)
                    .setBackgroundColor(mThemeColor)
                    .setOverlayDrawable(mOverlayDrawable)
                    .setIconSize(iconSize)
                    .setIconBackground(background)
                    .setCenterViewDrawable(foreground)
                    .setAnimationDurationMillis(animationDuration);

            if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
                    && mTmpAttrs.mBrandingImage != null) {
                builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
+103 −57
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -33,7 +35,6 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Trace;
@@ -44,32 +45,55 @@ import com.android.internal.R;

/**
 * Creating a lightweight Drawable object used for splash screen.
 *
 * @hide
 */
public class SplashscreenIconDrawableFactory {

    static Drawable makeIconDrawable(@ColorInt int backgroundColor,
    /**
     * @return An array containing the foreground drawable at index 0 and if needed a background
     * drawable at index 1.
     */
    static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
            @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
            Handler splashscreenWorkerHandler) {
        Drawable foreground;
        Drawable background = null;
        boolean drawBackground =
                backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;

        if (foregroundDrawable instanceof Animatable) {
            return new AnimatableIconAnimateListener(backgroundColor, foregroundDrawable);
            foreground = new AnimatableIconAnimateListener(foregroundDrawable);
        } else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
            return new ImmobileIconDrawable(foregroundDrawable,
            // If the icon is Adaptive, we already use the icon background.
            drawBackground = false;
            foreground = new ImmobileIconDrawable(foregroundDrawable,
                    srcIconSize, iconSize, splashscreenWorkerHandler);
        } else {
            // single layer icon
            return new ImmobileIconDrawable(new AdaptiveIconDrawable(
                    new ColorDrawable(backgroundColor), foregroundDrawable),
            // Adaptive icon don't handle transparency so we draw the background of the adaptive
            // icon with the same color as the window background color instead of using two layers
            foreground = new ImmobileIconDrawable(
                    new AdaptiveForegroundDrawable(foregroundDrawable),
                    srcIconSize, iconSize, splashscreenWorkerHandler);
        }

        if (drawBackground) {
            background = new MaskBackgroundDrawable(backgroundColor);
        }

        return new Drawable[]{foreground, background};
    }

    static Drawable makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
    static Drawable[] makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
            int iconSize, Handler splashscreenWorkerHandler) {
        return new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
                splashscreenWorkerHandler);
        return new Drawable[]{new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
                splashscreenWorkerHandler)};
    }

    /**
     * Drawable pre-drawing the scaled icon in a separate thread to increase the speed of the
     * final drawing.
     */
    private static class ImmobileIconDrawable extends Drawable {
        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
                | Paint.FILTER_BITMAP_FLAG);
@@ -121,8 +145,10 @@ public class SplashscreenIconDrawableFactory {
        }
    }

    // Base class the draw the circle background
    private abstract static class MaskBackgroundDrawable extends Drawable {
    /**
     * Base class the draw a background clipped by the system mask.
     */
    public static class MaskBackgroundDrawable extends Drawable {
        private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE;
        private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
        static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
@@ -132,17 +158,24 @@ public class SplashscreenIconDrawableFactory {
        private static Path sMask;
        private final Path mMaskScaleOnly;
        private final Matrix mMaskMatrix;
        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
                | Paint.FILTER_BITMAP_FLAG);

        MaskBackgroundDrawable(@ColorInt int backgroundColor) {
        @Nullable
        private final Paint mBackgroundPaint;

        public MaskBackgroundDrawable(@ColorInt int backgroundColor) {
            final Resources r = Resources.getSystem();
            sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
            Path mask = new Path(sMask);
            mMaskScaleOnly = new Path(mask);
            mMaskMatrix = new Matrix();
            mPaint.setColor(backgroundColor);
            mPaint.setStyle(Paint.Style.FILL);
            if (backgroundColor != Color.TRANSPARENT) {
                mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
                        | Paint.FILTER_BITMAP_FLAG);
                mBackgroundPaint.setColor(backgroundColor);
                mBackgroundPaint.setStyle(Paint.Style.FILL);
            } else {
                mBackgroundPaint = null;
            }
        }

        @Override
@@ -162,41 +195,81 @@ public class SplashscreenIconDrawableFactory {
        @Override
        public void draw(Canvas canvas) {
            canvas.clipPath(mMaskScaleOnly);
            if (mMaskScaleOnly != null) {
                canvas.drawPath(mMaskScaleOnly, mPaint);
            if (mBackgroundPaint != null) {
                canvas.drawPath(mMaskScaleOnly, mBackgroundPaint);
            }
        }

        @Override
        public void setAlpha(int alpha) {
            mPaint.setAlpha(alpha);
            if (mBackgroundPaint != null) {
                mBackgroundPaint.setAlpha(alpha);
            }
        }

        @Override
        public int getOpacity() {
            return PixelFormat.RGBA_8888;
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {
        }
    }

    private static class AdaptiveForegroundDrawable extends MaskBackgroundDrawable {

        @NonNull
        protected final Drawable mForegroundDrawable;
        private final Rect mTmpOutRect = new Rect();

        AdaptiveForegroundDrawable(@NonNull Drawable foregroundDrawable) {
            super(Color.TRANSPARENT);
            mForegroundDrawable = foregroundDrawable;
        }

        @Override
        protected void updateLayerBounds(Rect bounds) {
            super.updateLayerBounds(bounds);
            int cX = bounds.width() / 2;
            int cY = bounds.height() / 2;

            int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
            int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
            final Rect outRect = mTmpOutRect;
            outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
            if (mForegroundDrawable != null) {
                mForegroundDrawable.setBounds(outRect);
            }
            invalidateSelf();
        }

        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            mForegroundDrawable.draw(canvas);
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {
            mForegroundDrawable.setColorFilter(colorFilter);
        }
    }

    /**
     * A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this
     * drawable masked by config_icon_mask.
     */
    private static class AnimatableIconAnimateListener extends MaskBackgroundDrawable
    private static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
            implements SplashScreenView.IconAnimateListener {
        private final Drawable mForegroundDrawable;
        private Animatable mAnimatableIcon;
        private Animator mIconAnimator;
        private boolean mAnimationTriggered;
        private final Rect mTmpOutRect = new Rect();

        AnimatableIconAnimateListener(@ColorInt int backgroundColor, Drawable foregroundDrawable) {
            super(backgroundColor);
            mForegroundDrawable = foregroundDrawable;
            if (mForegroundDrawable != null) {
        AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
            super(foregroundDrawable);
            mForegroundDrawable.setCallback(mCallback);
        }
        }

        @Override
        public boolean prepareAnimate(long duration, Runnable startListener) {
@@ -231,22 +304,6 @@ public class SplashscreenIconDrawableFactory {
            return true;
        }

        @Override
        protected void updateLayerBounds(Rect bounds) {
            super.updateLayerBounds(bounds);
            int cX = bounds.width() / 2;
            int cY = bounds.height() / 2;

            int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
            int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
            final Rect outRect = mTmpOutRect;
            outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
            if (mForegroundDrawable != null) {
                mForegroundDrawable.setBounds(outRect);
            }
            invalidateSelf();
        }

        private final Callback mCallback = new Callback() {
            @Override
            public void invalidateDrawable(@NonNull Drawable who) {
@@ -276,19 +333,8 @@ public class SplashscreenIconDrawableFactory {

        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            if (mForegroundDrawable != null) {
            ensureAnimationStarted();
                mForegroundDrawable.draw(canvas);
            }
        }

        @Override
        public void setColorFilter(ColorFilter colorFilter) {
            if (mForegroundDrawable != null) {
                mForegroundDrawable.setColorFilter(colorFilter);
            }
            super.draw(canvas);
        }
    }

}