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
diff --git a/src/com/android/launcher3/apppairs/AppPairIcon.java b/src/com/android/launcher3/apppairs/AppPairIcon.java
index 48d0fbd..c11193a 100644
--- a/src/com/android/launcher3/apppairs/AppPairIcon.java
+++ b/src/com/android/launcher3/apppairs/AppPairIcon.java
@@ -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 @@
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 @@
}
/**
- * 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 @@
// 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();
}
}
diff --git a/src/com/android/launcher3/apppairs/AppPairIconBackground.java b/src/com/android/launcher3/apppairs/AppPairIconBackground.java
index b5011f1..187541f 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconBackground.java
+++ b/src/com/android/launcher3/apppairs/AppPairIconBackground.java
@@ -162,6 +162,6 @@
@Override
public void setColorFilter(ColorFilter colorFilter) {
- // Required by Drawable but not used.
+ mBackgroundPaint.setColorFilter(colorFilter);
}
}
diff --git a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
index 365edf8..c12aa0c 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
+++ b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
@@ -26,8 +26,8 @@
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 @@
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 @@
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 @@
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 @@
}
/** 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)
+ 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())
- // If app icons did not draw fully last time, animate to full icon
- (appIcon1 as? PlaceHolderIconDrawable)?.animateIconUpdate(newIcon1)
- (appIcon2 as? PlaceHolderIconDrawable)?.animateIconUpdate(newIcon2)
+ // Check disabled state
+ val shouldDrawAsDisabled =
+ parentIcon.info.isDisabled || !parentIcon.isLaunchableAtScreenSize
- appIcon1 = newIcon1
- appIcon2 = newIcon2
- appIcon1?.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
- appIcon2?.setBounds(0, 0, memberIconSize.toInt(), memberIconSize.toInt())
+ 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 @@
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 @@
} 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 @@
height - (innerPadding + memberIconSize)
)
}
- appIcon2?.alpha = drawAlpha
- appIcon2?.draw(canvas)
+
+ appIcon2.draw(canvas)
canvas.restore()
}
}