summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Notification.java17
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java129
5 files changed, 60 insertions, 95 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index efb9f6bb88f1..47118a81632e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -17,7 +17,6 @@
package android.app;
import static android.annotation.Dimension.DP;
-import static android.graphics.drawable.Icon.TYPE_BITMAP;
import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
@@ -8741,26 +8740,20 @@ public class Notification implements Parcelable
* If your app produces multiple bubbles, the image should be unique for each of them.
* </p>
*
- * <p>The shape of a bubble icon is adaptive and can match the device theme.
+ * <p>The shape of a bubble icon is adaptive and will match the device theme.
*
- * If your icon is bitmap-based, you should create it using
- * {@link Icon#createWithAdaptiveBitmap(Bitmap)}, otherwise this method will throw.
- *
- * If your icon is not bitmap-based, you should expect that the icon will be tinted.
+ * Ideally your icon should be constructed via
+ * {@link Icon#createWithAdaptiveBitmap(Bitmap)}, otherwise, the icon will be shrunk
+ * and placed on an adaptive shape.
* </p>
*
- * @throws IllegalArgumentException if icon is null or a non-adaptive bitmap
+ * @throws IllegalArgumentException if icon is null.
*/
@NonNull
public BubbleMetadata.Builder setIcon(@NonNull Icon icon) {
if (icon == null) {
throw new IllegalArgumentException("Bubbles require non-null icon");
}
- if (icon.getType() == TYPE_BITMAP) {
- throw new IllegalArgumentException("When using bitmap based icons, Bubbles "
- + "require TYPE_ADAPTIVE_BITMAP, please use"
- + " Icon#createWithAdaptiveBitmap instead");
- }
mIcon = icon;
return this;
}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 14371fe4b41b..64b2892efc9a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1120,8 +1120,6 @@
<dimen name="bubble_touch_padding">12dp</dimen>
<!-- Size of the circle around the bubbles when they're in the dismiss target. -->
<dimen name="bubble_dismiss_encircle_size">52dp</dimen>
- <!-- How much to inset the icon in the circle -->
- <dimen name="bubble_icon_inset">16dp</dimen>
<!-- Padding around the view displayed when the bubble is expanded -->
<dimen name="bubble_expanded_view_padding">4dp</dimen>
<!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 7600b2f3ed7a..f8e45d4c8b63 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -134,6 +134,10 @@ class Bubble {
return mAppName;
}
+ public Drawable getUserBadgedAppIcon() {
+ return mUserBadgedAppIcon;
+ }
+
boolean isInflated() {
return mInflated;
}
@@ -165,7 +169,6 @@ class Bubble {
mIconView = (BubbleView) inflater.inflate(
R.layout.bubble_view, stackView, false /* attachToRoot */);
mIconView.setBubble(this);
- mIconView.setAppIcon(mUserBadgedAppIcon);
mExpandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index e5af3897dff2..4a1bbe48efb0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -1459,7 +1459,7 @@ public class BubbleStackView extends FrameLayout {
mFlyout.setupFlyoutStartingAsDot(
updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
mStackAnimationController.isStackOnLeftSide(),
- bubble.getIconView().getBadgeColor() /* dotColor */,
+ bubble.getIconView().getDotColor() /* dotColor */,
expandFlyoutAfterDelay /* onLayoutComplete */,
mFlyoutOnHide,
bubble.getIconView().getDotCenter());
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index fe4fa90a272d..35657d38df0c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -24,17 +24,16 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Path;
-import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
-import android.graphics.drawable.InsetDrawable;
import android.util.AttributeSet;
import android.util.PathParser;
import android.widget.FrameLayout;
import com.android.internal.graphics.ColorUtils;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.ColorExtractor;
import com.android.launcher3.icons.ShadowGenerator;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -45,17 +44,13 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
*/
public class BubbleView extends FrameLayout {
- private static final int DARK_ICON_ALPHA = 180;
- private static final double ICON_MIN_CONTRAST = 4.1;
- private static final int DEFAULT_BACKGROUND_COLOR = Color.LTGRAY;
// Same value as Launcher3 badge code
private static final float WHITE_SCRIM_ALPHA = 0.54f;
private Context mContext;
private BadgedImageView mBadgedImageView;
- private int mBadgeColor;
- private int mIconInset;
- private Drawable mUserBadgedAppIcon;
+ private int mDotColor;
+ private ColorExtractor mColorExtractor;
// mBubbleIconFactory cannot be static because it depends on Context.
private BubbleIconFactory mBubbleIconFactory;
@@ -79,13 +74,13 @@ public class BubbleView extends FrameLayout {
public BubbleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
- mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mBadgedImageView = findViewById(R.id.bubble_image);
+ mColorExtractor = new ColorExtractor();
}
@Override
@@ -106,6 +101,13 @@ public class BubbleView extends FrameLayout {
}
/**
+ * @param factory Factory for creating normalized bubble icons.
+ */
+ public void setBubbleIconFactory(BubbleIconFactory factory) {
+ mBubbleIconFactory = factory;
+ }
+
+ /**
* The {@link NotificationEntry} associated with this view, if one exists.
*/
@Nullable
@@ -129,17 +131,6 @@ public class BubbleView extends FrameLayout {
updateViews();
}
- /**
- * @param factory Factory for creating normalized bubble icons.
- */
- public void setBubbleIconFactory(BubbleIconFactory factory) {
- mBubbleIconFactory = factory;
- }
-
- public void setAppIcon(Drawable appIcon) {
- mUserBadgedAppIcon = appIcon;
- }
-
/** Changes the dot's visibility to match the bubble view's state. */
void updateDotVisibility(boolean animate) {
updateDotVisibility(animate, null /* after */);
@@ -154,9 +145,17 @@ public class BubbleView extends FrameLayout {
updateDotVisibility(animate);
}
+ boolean isDotShowing() {
+ return mBubble.showBubbleDot() && !mSuppressDot;
+ }
+
+ int getDotColor() {
+ return mDotColor;
+ }
+
/** Sets the position of the 'new' dot, animating it out and back in if requested. */
void setDotPosition(boolean onLeft, boolean animate) {
- if (animate && onLeft != mBadgedImageView.getDotOnLeft() && shouldShowDot()) {
+ if (animate && onLeft != mBadgedImageView.getDotOnLeft() && isDotShowing()) {
animateDot(false /* showDot */, () -> {
mBadgedImageView.setDotOnLeft(onLeft);
animateDot(true /* showDot */, null);
@@ -180,7 +179,7 @@ public class BubbleView extends FrameLayout {
* after animation if requested.
*/
private void updateDotVisibility(boolean animate, Runnable after) {
- final boolean showDot = shouldShowDot();
+ final boolean showDot = isDotShowing();
if (animate) {
animateDot(showDot, after);
} else {
@@ -218,42 +217,21 @@ public class BubbleView extends FrameLayout {
if (mBubble == null || mBubbleIconFactory == null) {
return;
}
- // Update icon.
- Notification.BubbleMetadata metadata = mBubble.getEntry().getBubbleMetadata();
- Notification n = mBubble.getEntry().getSbn().getNotification();
- Icon ic = metadata.getIcon();
- boolean needsTint = ic.getType() != Icon.TYPE_ADAPTIVE_BITMAP;
-
- Drawable iconDrawable = ic.loadDrawable(mContext);
- if (needsTint) {
- iconDrawable = buildIconWithTint(iconDrawable, n.color);
- }
- Bitmap bubbleIcon = mBubbleIconFactory.createBadgedIconBitmap(iconDrawable,
- null /* user */,
- true /* shrinkNonAdaptiveIcons */).icon;
-
- // Give it a shadow
- Bitmap userBadgedBitmap = mBubbleIconFactory.createIconBitmap(mUserBadgedAppIcon,
- 1f, mBubbleIconFactory.getBadgeSize());
- Canvas c = new Canvas();
- ShadowGenerator shadowGenerator = new ShadowGenerator(mBubbleIconFactory.getBadgeSize());
- c.setBitmap(userBadgedBitmap);
- shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
- mBubbleIconFactory.badgeWithDrawable(bubbleIcon,
- new BitmapDrawable(mContext.getResources(), userBadgedBitmap));
- mBadgedImageView.setImageBitmap(bubbleIcon);
+ Drawable bubbleDrawable = getBubbleDrawable(mContext);
+ BitmapInfo badgeBitmapInfo = getBadgedBitmap();
+ BitmapInfo bubbleBitmapInfo = getBubbleBitmap(bubbleDrawable, badgeBitmapInfo);
+ mBadgedImageView.setImageBitmap(bubbleBitmapInfo.icon);
// Update badge.
- int badgeColor = determineDominateColor(iconDrawable, n.color);
- mBadgeColor = badgeColor;
- mBadgedImageView.setDotColor(badgeColor);
+ mDotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, Color.WHITE, WHITE_SCRIM_ALPHA);
+ mBadgedImageView.setDotColor(mDotColor);
// Update dot.
Path iconPath = PathParser.createPathFromPathData(
getResources().getString(com.android.internal.R.string.config_icon_mask));
Matrix matrix = new Matrix();
- float scale = mBubbleIconFactory.getNormalizer().getScale(iconDrawable,
+ float scale = mBubbleIconFactory.getNormalizer().getScale(bubbleDrawable,
null /* outBounds */, null /* path */, null /* outMaskShape */);
float radius = BadgedImageView.DEFAULT_PATH_SIZE / 2f;
matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
@@ -261,41 +239,34 @@ public class BubbleView extends FrameLayout {
iconPath.transform(matrix);
mBadgedImageView.drawDot(iconPath);
- animateDot(shouldShowDot(), null /* after */);
+ animateDot(isDotShowing(), null /* after */);
}
- boolean shouldShowDot() {
- return mBubble.showBubbleDot() && !mSuppressDot;
+ Drawable getBubbleDrawable(Context context) {
+ Notification.BubbleMetadata metadata = getEntry().getBubbleMetadata();
+ Icon ic = metadata.getIcon();
+ return ic.loadDrawable(context);
}
- int getBadgeColor() {
- return mBadgeColor;
- }
+ BitmapInfo getBadgedBitmap() {
+ Bitmap userBadgedBitmap = mBubbleIconFactory.createIconBitmap(
+ mBubble.getUserBadgedAppIcon(), 1f, mBubbleIconFactory.getBadgeSize());
- private AdaptiveIconDrawable buildIconWithTint(Drawable iconDrawable, int backgroundColor) {
- iconDrawable = checkTint(iconDrawable, backgroundColor);
- InsetDrawable foreground = new InsetDrawable(iconDrawable, mIconInset);
- ColorDrawable background = new ColorDrawable(backgroundColor);
- return new AdaptiveIconDrawable(background, foreground);
+ Canvas c = new Canvas();
+ ShadowGenerator shadowGenerator = new ShadowGenerator(mBubbleIconFactory.getBadgeSize());
+ c.setBitmap(userBadgedBitmap);
+ shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
+ BitmapInfo bitmapInfo = mBubbleIconFactory.createIconBitmap(userBadgedBitmap);
+ return bitmapInfo;
}
- private Drawable checkTint(Drawable iconDrawable, int backgroundColor) {
- backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, 255 /* alpha */);
- if (backgroundColor == Color.TRANSPARENT) {
- // ColorUtils throws exception when background is translucent.
- backgroundColor = DEFAULT_BACKGROUND_COLOR;
- }
- iconDrawable.setTint(Color.WHITE);
- double contrastRatio = ColorUtils.calculateContrast(Color.WHITE, backgroundColor);
- if (contrastRatio < ICON_MIN_CONTRAST) {
- int dark = ColorUtils.setAlphaComponent(Color.BLACK, DARK_ICON_ALPHA);
- iconDrawable.setTint(dark);
- }
- return iconDrawable;
- }
+ BitmapInfo getBubbleBitmap(Drawable bubble, BitmapInfo badge) {
+ BitmapInfo bubbleIconInfo = mBubbleIconFactory.createBadgedIconBitmap(bubble,
+ null /* user */,
+ true /* shrinkNonAdaptiveIcons */);
- private int determineDominateColor(Drawable d, int defaultTint) {
- // XXX: should we pull from the drawable, app icon, notif tint?
- return ColorUtils.blendARGB(defaultTint, Color.WHITE, WHITE_SCRIM_ALPHA);
+ mBubbleIconFactory.badgeWithDrawable(bubbleIconInfo.icon,
+ new BitmapDrawable(mContext.getResources(), badge.icon));
+ return bubbleIconInfo;
}
}