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

Commit e0b39197 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixing alpha flag is not retained for fullbleed icons" into main

parents bbdbfaa7 a966ce15
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -178,12 +178,16 @@ constructor(
        }
        if (options.wrapNonAdaptiveIcon) tempIcon = wrapToAdaptiveIcon(tempIcon, options)

        val bitmap = drawableToBitmap(tempIcon, options)
        val drawFullBleed = options.drawFullBleed ?: drawFullBleedIcons
        val bitmap = drawableToBitmap(tempIcon, drawFullBleed, options)
        icon.bounds = oldBounds

        val color = options.extractedColor ?: findDominantColorByHue(bitmap)
        var flagOp = getBitmapFlagOp(options)
        if (drawFullBleedIcons) flagOp = flagOp.addFlag(BitmapInfo.FLAG_FULL_BLEED)
        if (drawFullBleed) {
            flagOp = flagOp.addFlag(BitmapInfo.FLAG_FULL_BLEED)
            bitmap.setHasAlpha(false)
        }

        var info =
            BitmapInfo(
@@ -273,14 +277,16 @@ constructor(
                )
                .apply { setBounds(0, 0, 1, 1) }

    private fun drawableToBitmap(icon: Drawable, options: IconOptions): Bitmap {
        val isFullBleedEnabled = options.drawFullBleed ?: drawFullBleedIcons

    private fun drawableToBitmap(
        icon: Drawable,
        drawFullBleed: Boolean,
        options: IconOptions,
    ): Bitmap {
        if (icon is AdaptiveIconDrawable) {
            // We are ignoring KEY_SHADOW_DISTANCE because regular icons ignore this at the
            // moment b/298203449
            val offset =
                if (isFullBleedEnabled) 0
                if (drawFullBleed) 0
                else
                    max(
                        (ceil(BLUR_FACTOR * iconBitmapSize)).toInt(),
@@ -292,11 +298,11 @@ constructor(
            return createBitmap(options) { canvas, _ ->
                canvas.transformed {
                    translate(offset.toFloat(), offset.toFloat())
                    if (options.addShadows && !isFullBleedEnabled)
                    if (options.addShadows && !drawFullBleed)
                        shadowGenerator.addPathShadow(icon.iconMask, canvas)
                    if (icon is Extender) icon.drawForPersistence()

                    if (isFullBleedEnabled) {
                    if (drawFullBleed) {
                        drawColor(Color.BLACK)
                        icon.background?.draw(canvas)
                        icon.foreground?.draw(canvas)
@@ -316,9 +322,10 @@ constructor(
            iconToDraw.setBounds(0, 0, iconBitmapSize, iconBitmapSize)

            return createBitmap(options) { canvas, bitmap ->
                if (drawFullBleed) canvas.drawColor(Color.BLACK)
                iconToDraw.draw(canvas)

                if (options.addShadows && bitmap != null) {
                if (options.addShadows && bitmap != null && !drawFullBleed) {
                    // Shadow extraction only works in software mode
                    shadowGenerator.drawShadow(bitmap, canvas)

+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3.icons

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.ColorDrawable
import androidx.test.core.app.ApplicationProvider
import com.android.launcher3.icons.BaseIconFactory.IconOptions
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class BaseIconFactoryTest {

    private val context: Context = ApplicationProvider.getApplicationContext()

    @Test
    fun fullBleed_has_no_alpha() {
        val info =
            factory(drawFullBleedIcons = true)
                .createBadgedIconBitmap(AdaptiveIconDrawable(ColorDrawable(Color.RED), null))

        assertFalse(info.icon.hasAlpha())
        assertEquals(BitmapInfo.FLAG_FULL_BLEED, info.flags and BitmapInfo.FLAG_FULL_BLEED)
    }

    @Test
    fun non_fullBleed_has_alpha() {
        val info =
            factory(drawFullBleedIcons = false)
                .createBadgedIconBitmap(AdaptiveIconDrawable(ColorDrawable(Color.RED), null))
        assertTrue(info.icon.hasAlpha())
        assertEquals(0, info.flags and BitmapInfo.FLAG_FULL_BLEED)
    }

    @Test
    fun icon_options_overrides_fullBleed() {
        val info =
            factory(drawFullBleedIcons = false)
                .createBadgedIconBitmap(
                    AdaptiveIconDrawable(ColorDrawable(Color.RED), null),
                    IconOptions().setDrawFullBleed(true),
                )
        assertFalse(info.icon.hasAlpha())
        assertEquals(BitmapInfo.FLAG_FULL_BLEED, info.flags and BitmapInfo.FLAG_FULL_BLEED)

        val info2 =
            factory(drawFullBleedIcons = true)
                .createBadgedIconBitmap(
                    AdaptiveIconDrawable(ColorDrawable(Color.RED), null),
                    IconOptions().setDrawFullBleed(false),
                )
        assertTrue(info2.icon.hasAlpha())
        assertEquals(0, info2.flags and BitmapInfo.FLAG_FULL_BLEED)
    }

    private fun factory(
        fullResIconDpi: Int = context.resources.displayMetrics.densityDpi,
        iconBitmapSize: Int = 64,
        drawFullBleedIcons: Boolean = false,
        themeController: IconThemeController? = null,
    ) =
        BaseIconFactory(
            context = context,
            fullResIconDpi = fullResIconDpi,
            iconBitmapSize = iconBitmapSize,
            drawFullBleedIcons = drawFullBleedIcons,
            themeController = themeController,
        )
}