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

Commit 09fe96b9 authored by Jeremy Sim's avatar Jeremy Sim
Browse files

On disabled app pairs, set color tint instead of changing alpha

This CL changes the way disabled app pair icons are drawn: instead of setting alpha, it sets a color filter to indicate disabled status. This brings it in line with other apps icons and V's design specs.

Fixes: 326665140
Flag: ACONFIG com.android.wm.shell.enable_app_pairs TRUNKFOOD
Test: Manual
Change-Id: Ifc8ac694f321a6b28996ba9a42860dfc419d5901
parent 7e0703ec
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.launcher3.apppairs;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -94,17 +93,18 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
        icon.setOnClickListener(activity.getItemOnClickListener());
        icon.mInfo = appPairInfo;

        // TODO (b/326664798): Delete this check, instead check at launcher load time
        if (icon.mInfo.contents.size() != 2) {
            Log.wtf(TAG, "AppPair contents not 2, size: " + icon.mInfo.contents.size());
            return icon;
        }

        icon.checkScreenSize();

        // Set up icon drawable area
        icon.mIconGraphic = icon.findViewById(R.id.app_pair_icon_graphic);
        icon.mIconGraphic.init(activity.getDeviceProfile(), icon);

        icon.checkDisabledState();

        // Set up app pair title
        icon.mAppPairName = icon.findViewById(R.id.app_pair_icon_name);
        icon.mAppPairName.setCompoundDrawablePadding(0);
@@ -183,23 +183,20 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
    }

    /**
     * Checks if the app pair is launchable in the current device configuration.
     *
     * Updates the "disabled" state of the app pair in the current device configuration.
     * App pairs can be "disabled" in two ways:
     * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused
     * by the user or can't be launched).
     * by the user or can't be launched for some other reason).
     * 2) This specific instance of an app pair can't be launched due to screen size requirements.
     *
     * This method checks and updates #2. Both #1 and #2 are checked when app pairs are drawn
     * {@link AppPairIconGraphic#dispatchDraw(Canvas)} or clicked on
     * {@link com.android.launcher3.touch.ItemClickHandler#onClickAppPairIcon(View)}
     */
    public void checkScreenSize() {
    public void checkDisabledState() {
        DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
        // If user is on a small screen, we can't launch if either of the apps is non-resizeable
        mIsLaunchableAtScreenSize =
                dp.isTablet || getInfo().contents.stream().noneMatch(
                        wii -> wii.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE));
        // Call applyIcons to check and update icons
        mIconGraphic.applyIcons();
    }

    /**
@@ -209,7 +206,7 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
        // If either of the app pair icons return true on the predicate (i.e. in the list of
        // updated apps), redraw the icon graphic (icon background and both icons).
        if (getInfo().contents.stream().anyMatch(itemCheck)) {
            checkScreenSize();
            checkDisabledState();
            mIconGraphic.invalidate();
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -162,6 +162,6 @@ class AppPairIconBackground extends Drawable {

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        // Required by Drawable but not used.
        mBackgroundPaint.setColorFilter(colorFilter);
    }
}
+28 −35
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@ import android.view.Gravity
import android.widget.FrameLayout
import com.android.launcher3.DeviceProfile
import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.icons.PlaceHolderIconDrawable
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.icons.FastBitmapDrawable
import com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter
import com.android.launcher3.util.Themes

/**
@@ -46,9 +46,6 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
        private const val CENTER_CHANNEL_SCALE = 1 / 30f
        private const val BIG_RADIUS_SCALE = 1 / 5f
        private const val SMALL_RADIUS_SCALE = 1 / 15f
        // Disabled alpha is 38%, or 97/255
        private const val DISABLED_ALPHA = 97
        private const val ENABLED_ALPHA = 255
    }

    // App pair icons are slightly smaller than regular icons, so we pad the icon by this much on
@@ -71,8 +68,8 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr

    private lateinit var parentIcon: AppPairIcon
    private lateinit var appPairBackground: Drawable
    private var appIcon1: Drawable? = null
    private var appIcon2: Drawable? = null
    private lateinit var appIcon1: FastBitmapDrawable
    private lateinit var appIcon2: FastBitmapDrawable

    fun init(grid: DeviceProfile, icon: AppPairIcon) {
        // Calculate device-specific measurements
@@ -89,7 +86,8 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr

        appPairBackground = AppPairIconBackground(context, this)
        appPairBackground.setBounds(0, 0, backgroundSize.toInt(), backgroundSize.toInt())
        applyIcons(parentIcon.info.contents)

        applyIcons()

        // Center the drawable area in the larger icon canvas
        val lp: LayoutParams = layoutParams as LayoutParams
@@ -101,26 +99,29 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
    }

    /** Sets up app pair member icons for drawing. */
    private fun applyIcons(contents: ArrayList<WorkspaceItemInfo>) {
        // App pair should always contain 2 members; if not 2, return to avoid a crash loop
        if (contents.size != 2) {
            Log.wtf(TAG, "AppPair contents not 2, size: " + contents.size, Throwable())
    fun applyIcons() {
        val apps = parentIcon.info.contents

        // TODO (b/326664798): Delete this check, instead check at launcher load time
        if (apps.size != 2) {
            Log.wtf(TAG, "AppPair contents not 2, size: " + apps.size, Throwable())
            return
        }

        // Generate new icons, using themed flag if needed
        val flags = if (Themes.isThemedIconEnabled(context)) BitmapInfo.FLAG_THEMED else 0
        val newIcon1 = parentIcon.info.contents[0].newIcon(context, flags)
        val newIcon2 = parentIcon.info.contents[1].newIcon(context, flags)

        // If app icons did not draw fully last time, animate to full icon
        (appIcon1 as? PlaceHolderIconDrawable)?.animateIconUpdate(newIcon1)
        (appIcon2 as? PlaceHolderIconDrawable)?.animateIconUpdate(newIcon2)

        appIcon1 = newIcon1
        appIcon2 = newIcon2
        appIcon1?.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
        appIcon2?.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
        appIcon1 = apps[0].newIcon(context, flags)
        appIcon2 = apps[1].newIcon(context, flags)
        appIcon1.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
        appIcon2.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())

        // Check disabled state
        val shouldDrawAsDisabled =
            parentIcon.info.isDisabled || !parentIcon.isLaunchableAtScreenSize

        appPairBackground.colorFilter = if (shouldDrawAsDisabled) getDisabledColorFilter() else null
        appIcon1.setIsDisabled(shouldDrawAsDisabled)
        appIcon2.setIsDisabled(shouldDrawAsDisabled)
    }

    /** Gets this icon graphic's bounds, with respect to the parent icon's coordinate system. */
@@ -137,17 +138,9 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
    override fun dispatchDraw(canvas: Canvas) {
        super.dispatchDraw(canvas)

        val drawAlpha =
            if (!parentIcon.isLaunchableAtScreenSize || parentIcon.info.isDisabled) DISABLED_ALPHA
            else ENABLED_ALPHA

        // Draw background
        appPairBackground.alpha = drawAlpha
        appPairBackground.draw(canvas)

        // Make sure icons are loaded and fresh
        applyIcons(parentIcon.info.contents)

        // Draw first icon
        canvas.save()
        // The app icons are placed differently depending on device orientation.
@@ -156,8 +149,8 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
        } else {
            canvas.translate(width / 2f - memberIconSize / 2f, innerPadding)
        }
        appIcon1?.alpha = drawAlpha
        appIcon1?.draw(canvas)

        appIcon1.draw(canvas)
        canvas.restore()

        // Draw second icon
@@ -174,8 +167,8 @@ class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: Attr
                height - (innerPadding + memberIconSize)
            )
        }
        appIcon2?.alpha = drawAlpha
        appIcon2?.draw(canvas)

        appIcon2.draw(canvas)
        canvas.restore()
    }
}