diff options
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;      }  }  |