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

Unverified Commit c95400c1 authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-13.0.0_r35' into staging/lineage-20.0_merge-android-13.0.0_r35

Android 13.0.0 release 35

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZA9jvwAKCRDorT+BmrEO
# eNxVAJ9S29jQpxUc8/MmD5KTd1TPHApvNgCeO7F2Q0o7mEy8KS2YHXarFPeoovA=
# =6tgo
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon Mar 13 19:56:15 2023 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [marginal]
# gpg: initial-contribution@android.com: Verified 1579 signatures in the past
#      16 months.  Encrypted 4 messages in the past 14 months.
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 4340 D135 70EF 945E 8381  0964 E8AD 3F81 9AB1 0E78

# By Johannes Gallmann (6) and others
# Via Android Build Coastguard Worker (16) and others
* tag 'android-13.0.0_r35':
  Fixing different prtobug version across projects
  Add more documentation to the ViewCapture code.
  Adding support for overriding monochrome icon logic
  add section header LayoutType
  Adding support for overriding extracted color in IconOptions
  Fix MotionToolLib race condition in Tests
  Change Photos -> IMAGE
  Change SCREENSHOT -> PHOTOS  and added VIDEOS and SYSTEMPOINTER result type
  [Toast] Add a new layout type for rich answers.
  Add NO_FULFILLMENT and EDUCARD to ResultType
  MotionToolManager and ViewCapture cleanups
  Implement MotionTool Library using ViewCapture library
  Add Tests to ViewCapture Library
  Add Choreographer timestamp to ViewCapture
  Extracting ViewCapture into common Library
  Add layout type
  Optmizing shadow bitmap creation to avoid additional bitmap generation when using AdaptiveIconDrawable

Change-Id: I79bab1a55cdeb69aa0c97c62ca638c061a64710a
parents a538ee36 66f8bc86
Loading
Loading
Loading
Loading
+97 −62
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT;
import static com.android.launcher3.icons.BitmapInfo.FLAG_WORK;
import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
@@ -31,12 +33,15 @@ import android.os.Build;
import android.os.UserHandle;
import android.util.SparseBooleanArray;

import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.launcher3.icons.BitmapInfo.Extender;
import com.android.launcher3.util.FlagOp;

import java.lang.annotation.Retention;
import java.util.Objects;

/**
@@ -47,9 +52,15 @@ public class BaseIconFactory implements AutoCloseable {

    private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;

    protected static final int BITMAP_GENERATION_MODE_DEFAULT = 0;
    protected static final int BITMAP_GENERATION_MODE_ALPHA = 1;
    protected static final int BITMAP_GENERATION_MODE_WITH_SHADOW = 2;
    public static final int MODE_DEFAULT = 0;
    public static final int MODE_ALPHA = 1;
    public static final int MODE_WITH_SHADOW = 2;
    public static final int MODE_HARDWARE = 3;
    public static final int MODE_HARDWARE_WITH_SHADOW = 4;

    @Retention(SOURCE)
    @IntDef({MODE_DEFAULT, MODE_ALPHA, MODE_WITH_SHADOW, MODE_HARDWARE_WITH_SHADOW, MODE_HARDWARE})
    @interface BitmapGenerationMode {}

    private static final float ICON_BADGE_SCALE = 0.444f;

@@ -71,8 +82,6 @@ public class BaseIconFactory implements AutoCloseable {
    @NonNull
    private final ColorExtractor mColorExtractor;

    private boolean mDisableColorExtractor;

    protected final int mFillResIconDpi;
    protected final int mIconBitmapSize;

@@ -115,7 +124,6 @@ public class BaseIconFactory implements AutoCloseable {

    protected void clear() {
        mWrapperBackgroundColor = DEFAULT_WRAPPER_BACKGROUND;
        mDisableColorExtractor = false;
    }

    @NonNull
@@ -169,7 +177,7 @@ public class BaseIconFactory implements AutoCloseable {
            icon = createIconBitmap(new BitmapDrawable(mContext.getResources(), icon), 1f);
        }

        return BitmapInfo.of(icon, extractColor(icon));
        return BitmapInfo.of(icon, mColorExtractor.findDominantColorByHue(icon));
    }

    /**
@@ -204,27 +212,39 @@ public class BaseIconFactory implements AutoCloseable {
        boolean shrinkNonAdaptiveIcons = options == null || options.mShrinkNonAdaptiveIcons;
        float[] scale = new float[1];
        icon = normalizeAndWrapToAdaptiveIcon(icon, shrinkNonAdaptiveIcons, null, scale);
        Bitmap bitmap = createIconBitmap(icon, scale[0], BITMAP_GENERATION_MODE_WITH_SHADOW);
        Bitmap bitmap = createIconBitmap(icon, scale[0], MODE_WITH_SHADOW);

        int color = extractColor(bitmap);
        int color = (options != null && options.mExtractedColor != null)
                ? options.mExtractedColor : mColorExtractor.findDominantColorByHue(bitmap);
        BitmapInfo info = BitmapInfo.of(bitmap, color);

        if (icon instanceof BitmapInfo.Extender) {
            info = ((BitmapInfo.Extender) icon).getExtendedInfo(bitmap, color, this, scale[0]);
        } else if (mMonoIconEnabled && IconProvider.ATLEAST_T
                && icon instanceof AdaptiveIconDrawable) {
            Drawable mono = ((AdaptiveIconDrawable) icon).getMonochrome();
        } else if (IconProvider.ATLEAST_T && mMonoIconEnabled) {
            Drawable mono = getMonochromeDrawable(icon);
            if (mono != null) {
                // Convert mono drawable to bitmap
                Drawable paddedMono = new ClippedMonoDrawable(mono);
                info.setMonoIcon(
                        createIconBitmap(paddedMono, scale[0], BITMAP_GENERATION_MODE_ALPHA), this);
                info.setMonoIcon(createIconBitmap(mono, scale[0], MODE_ALPHA), this);
            }
        }
        info = info.withFlags(getBitmapFlagOp(options));
        return info;
    }

    /**
     * Returns a monochromatic version of the given drawable or null, if it is not supported
     * @param base the original icon
     */
    @TargetApi(Build.VERSION_CODES.TIRAMISU)
    protected Drawable getMonochromeDrawable(Drawable base) {
        if (base instanceof AdaptiveIconDrawable) {
            Drawable mono = ((AdaptiveIconDrawable) base).getMonochrome();
            if (mono != null) {
                return new ClippedMonoDrawable(mono);
            }
        }
        return null;
    }

    @NonNull
    public FlagOp getBitmapFlagOp(@Nullable IconOptions options) {
        FlagOp op = FlagOp.NO_OP;
@@ -251,31 +271,23 @@ public class BaseIconFactory implements AutoCloseable {
        return op;
    }

    /** package private */
    @NonNull
    Bitmap getWhiteShadowLayer() {
    public Bitmap getWhiteShadowLayer() {
        if (mWhiteShadowLayer == null) {
            mWhiteShadowLayer = createScaledBitmapWithShadow(
                    new AdaptiveIconDrawable(new ColorDrawable(Color.WHITE), null));
            mWhiteShadowLayer = createScaledBitmap(
                    new AdaptiveIconDrawable(new ColorDrawable(Color.WHITE), null),
                    MODE_HARDWARE_WITH_SHADOW);
        }
        return mWhiteShadowLayer;
    }

    @NonNull
    public Bitmap createScaledBitmapWithShadow(@NonNull final Drawable d) {
        float scale = getNormalizer().getScale(d, null, null, null);
        Bitmap bitmap = createIconBitmap(d, scale);
        return BitmapRenderer.createHardwareBitmap(bitmap.getWidth(), bitmap.getHeight(),
                canvas -> getShadowGenerator().recreateIcon(bitmap, canvas));
    }

    @NonNull
    public Bitmap createScaledBitmapWithoutShadow(@Nullable Drawable icon) {
    public Bitmap createScaledBitmap(@NonNull Drawable icon, @BitmapGenerationMode int mode) {
        RectF iconBounds = new RectF();
        float[] scale = new float[1];
        icon = normalizeAndWrapToAdaptiveIcon(icon, true, iconBounds, scale);
        return createIconBitmap(icon,
                Math.min(scale[0], ShadowGenerator.getScaleForBounds(iconBounds)));
                Math.min(scale[0], ShadowGenerator.getScaleForBounds(iconBounds)), mode);
    }

    /**
@@ -285,13 +297,6 @@ public class BaseIconFactory implements AutoCloseable {
        mWrapperBackgroundColor = (Color.alpha(color) < 255) ? DEFAULT_WRAPPER_BACKGROUND : color;
    }

    /**
     * Disables the dominant color extraction for all icons loaded.
     */
    public void disableColorExtraction() {
        mDisableColorExtractor = true;
    }

    @Nullable
    protected Drawable normalizeAndWrapToAdaptiveIcon(@Nullable Drawable icon,
            final boolean shrinkNonAdaptiveIcons, @Nullable final RectF outIconBounds,
@@ -328,20 +333,24 @@ public class BaseIconFactory implements AutoCloseable {

    @NonNull
    protected Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale) {
        return createIconBitmap(icon, scale, BITMAP_GENERATION_MODE_DEFAULT);
        return createIconBitmap(icon, scale, MODE_DEFAULT);
    }

    @NonNull
    protected Bitmap createIconBitmap(@Nullable final Drawable icon, final float scale,
            final int bitmapGenerationMode) {
            @BitmapGenerationMode int bitmapGenerationMode) {
        final int size = mIconBitmapSize;

        final Bitmap bitmap;
        switch (bitmapGenerationMode) {
            case BITMAP_GENERATION_MODE_ALPHA:
            case MODE_ALPHA:
                bitmap = Bitmap.createBitmap(size, size, Config.ALPHA_8);
                break;
            case BITMAP_GENERATION_MODE_WITH_SHADOW:
            case MODE_HARDWARE:
            case MODE_HARDWARE_WITH_SHADOW: {
                return BitmapRenderer.createHardwareBitmap(size, size, canvas ->
                        drawIconBitmap(canvas, icon, scale, bitmapGenerationMode, null));
            }
            case MODE_WITH_SHADOW:
            default:
                bitmap = Bitmap.createBitmap(size, size, Config.ARGB_8888);
                break;
@@ -350,6 +359,15 @@ public class BaseIconFactory implements AutoCloseable {
            return bitmap;
        }
        mCanvas.setBitmap(bitmap);
        drawIconBitmap(mCanvas, icon, scale, bitmapGenerationMode, bitmap);
        mCanvas.setBitmap(null);
        return bitmap;
    }

    private void drawIconBitmap(@NonNull Canvas canvas, @Nullable final Drawable icon,
            final float scale, @BitmapGenerationMode int bitmapGenerationMode,
            @Nullable Bitmap targetBitmap) {
        final int size = mIconBitmapSize;
        mOldBounds.set(icon.getBounds());

        if (icon instanceof AdaptiveIconDrawable) {
@@ -357,19 +375,20 @@ public class BaseIconFactory implements AutoCloseable {
                    Math.round(size * (1 - scale) / 2));
            // b/211896569: AdaptiveIconDrawable do not work properly for non top-left bounds
            icon.setBounds(0, 0, size - offset - offset, size - offset - offset);
            int count = mCanvas.save();
            mCanvas.translate(offset, offset);
            if (bitmapGenerationMode == BITMAP_GENERATION_MODE_WITH_SHADOW) {
            int count = canvas.save();
            canvas.translate(offset, offset);
            if (bitmapGenerationMode == MODE_WITH_SHADOW
                    || bitmapGenerationMode == MODE_HARDWARE_WITH_SHADOW) {
                getShadowGenerator().addPathShadow(
                        ((AdaptiveIconDrawable) icon).getIconMask(), mCanvas);
                        ((AdaptiveIconDrawable) icon).getIconMask(), canvas);
            }

            if (icon instanceof BitmapInfo.Extender) {
                ((Extender) icon).drawForPersistence(mCanvas);
                ((Extender) icon).drawForPersistence(canvas);
            } else {
                icon.draw(mCanvas);
                icon.draw(canvas);
            }
            mCanvas.restoreToCount(count);
            canvas.restoreToCount(count);
        } else {
            if (icon instanceof BitmapDrawable) {
                BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
@@ -395,15 +414,24 @@ public class BaseIconFactory implements AutoCloseable {
            final int left = (size - width) / 2;
            final int top = (size - height) / 2;
            icon.setBounds(left, top, left + width, top + height);
            mCanvas.save();
            mCanvas.scale(scale, scale, size / 2, size / 2);
            icon.draw(mCanvas);
            mCanvas.restore();

            canvas.save();
            canvas.scale(scale, scale, size / 2, size / 2);
            icon.draw(canvas);
            canvas.restore();

            if (bitmapGenerationMode == MODE_WITH_SHADOW && targetBitmap != null) {
                // Shadow extraction only works in software mode
                getShadowGenerator().drawShadow(targetBitmap, canvas);

                // Draw the icon again on top:
                canvas.save();
                canvas.scale(scale, scale, size / 2, size / 2);
                icon.draw(canvas);
                canvas.restore();
            }
        }
        icon.setBounds(mOldBounds);
        mCanvas.setBitmap(null);
        return bitmap;
    }

    @Override
@@ -422,10 +450,6 @@ public class BaseIconFactory implements AutoCloseable {
                android.R.drawable.sym_def_app_icon, iconDpi));
    }

    private int extractColor(@NonNull final Bitmap bitmap) {
        return mDisableColorExtractor ? 0 : mColorExtractor.findDominantColorByHue(bitmap);
    }

    /**
     * Returns the correct badge size given an icon size
     */
@@ -439,8 +463,10 @@ public class BaseIconFactory implements AutoCloseable {

        boolean mIsInstantApp;

        @Nullable
        UserHandle mUserHandle;
        @Nullable UserHandle mUserHandle;

        @ColorInt
        @Nullable Integer mExtractedColor;

        /**
         * Set to false if non-adaptive icons should not be treated
@@ -468,6 +494,15 @@ public class BaseIconFactory implements AutoCloseable {
            mIsInstantApp = instantApp;
            return this;
        }

        /**
         * Disables auto color extraction and overrides the color to the provided value
         */
        @NonNull
        public IconOptions setExtractedColor(@ColorInt int color) {
            mExtractedColor = color;
            return this;
        }
    }

    /**
@@ -504,7 +539,7 @@ public class BaseIconFactory implements AutoCloseable {
        }
    }

    private static class ClippedMonoDrawable extends InsetDrawable {
    protected static class ClippedMonoDrawable extends InsetDrawable {

        @NonNull
        private final AdaptiveIconDrawable mCrop;
+2 −1
Original line number Diff line number Diff line
@@ -214,7 +214,8 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap
            BaseIconFactory iconFactory, float normalizationScale) {
        AdaptiveIconDrawable background = new AdaptiveIconDrawable(
                getBackground().getConstantState().newDrawable(), null);
        Bitmap flattenBG = iconFactory.createScaledBitmapWithShadow(background);
        Bitmap flattenBG = iconFactory.createScaledBitmap(background,
                BaseIconFactory.MODE_HARDWARE_WITH_SHADOW);

        // Only pass theme info if mono-icon is enabled
        AnimationInfo themeInfo = iconFactory.mMonoIconEnabled ? mThemeInfo : null;
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ public class ColorExtractor {
     * This picks a dominant color, looking for high-saturation, high-value, repeated hues.
     * @param bitmap The bitmap to scan
     */
    public int findDominantColorByHue(@NonNull final Bitmap bitmap, final int samples) {
    protected int findDominantColorByHue(@NonNull final Bitmap bitmap, final int samples) {
        final int height = bitmap.getHeight();
        final int width = bitmap.getWidth();
        int sampleStride = (int) Math.sqrt((height * width) / samples);
+1 −5
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ public class ShadowGenerator {
        mDefaultBlurMaskFilter = new BlurMaskFilter(mIconSize * BLUR_FACTOR, Blur.NORMAL);
    }

    public synchronized void recreateIcon(Bitmap icon, Canvas out) {
    public synchronized void drawShadow(Bitmap icon, Canvas out) {
        if (ENABLE_SHADOWS) {
            int[] offset = new int[2];
            mBlurPaint.setMaskFilter(mDefaultBlurMaskFilter);
@@ -73,10 +73,6 @@ public class ShadowGenerator {
            out.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize,
                    mDrawPaint);
        }

        // Draw the icon
        mDrawPaint.setAlpha(255);
        out.drawBitmap(icon, 0, 0, mDrawPaint);
    }

    /** package private **/
+13 −0
Original line number Diff line number Diff line
*.iml
.project
.classpath
.project.properties
gen/
bin/
.idea/
.gradle/
local.properties
gradle/
build/
gradlew*
.DS_Store
Loading