Cleanup to make loading bubble info in background easier
* Moved all the image creation code into BubbleIconFactory & document it
possibly this is where image caching logic will occur in the future
* BubbleController owns BubbleIconFactory now
* Simplifies some logic in BubbleExpandedView
Test: atest SystemUITests
Bug: 144719337
Change-Id: I91656478e2e542fa943ca00535091ada227ee8ef
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index a6a3ce0..6e03441 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -16,16 +16,13 @@
package com.android.systemui.bubbles;
import android.annotation.Nullable;
-import android.app.Notification;
import android.content.Context;
-import android.content.pm.LauncherApps;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
import android.util.AttributeSet;
import android.util.PathParser;
import android.widget.ImageView;
@@ -283,8 +280,8 @@
return;
}
- Drawable bubbleDrawable = getBubbleDrawable(mContext);
- BitmapInfo badgeBitmapInfo = mBubbleIconFactory.getBadgedBitmap(mBubble);
+ Drawable bubbleDrawable = mBubbleIconFactory.getBubbleDrawable(mBubble, mContext);
+ BitmapInfo badgeBitmapInfo = mBubbleIconFactory.getBadgeBitmap(mBubble);
BitmapInfo bubbleBitmapInfo = mBubbleIconFactory.getBubbleBitmap(bubbleDrawable,
badgeBitmapInfo);
setImageBitmap(bubbleBitmapInfo.icon);
@@ -307,17 +304,4 @@
animateDot();
}
-
- Drawable getBubbleDrawable(Context context) {
- if (mBubble.getShortcutInfo() != null && mBubble.usingShortcutInfo()) {
- LauncherApps launcherApps =
- (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
- int density = getContext().getResources().getConfiguration().densityDpi;
- return launcherApps.getShortcutIconDrawable(mBubble.getShortcutInfo(), density);
- } else {
- Notification.BubbleMetadata metadata = mBubble.getEntry().getBubbleMetadata();
- Icon ic = metadata.getIcon();
- return ic.loadDrawable(context);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 1277736..85a3959 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -103,7 +103,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -151,6 +150,7 @@
private BubbleData mBubbleData;
@Nullable private BubbleStackView mStackView;
+ private BubbleIconFactory mBubbleIconFactory;
// Tracks the id of the current (foreground) user.
private int mCurrentUserId;
@@ -353,6 +353,7 @@
mUserBlockedBubbles = new HashSet<>();
mScreenshotHelper = new ScreenshotHelper(context);
+ mBubbleIconFactory = new BubbleIconFactory(context);
}
/**
@@ -416,13 +417,21 @@
@Override
public void onUiModeChanged() {
- if (mStackView != null) {
- mStackView.onThemeChanged();
- }
+ updateForThemeChanges();
}
@Override
public void onOverlayChanged() {
+ updateForThemeChanges();
+ }
+
+ private void updateForThemeChanges() {
+ mBubbleIconFactory = new BubbleIconFactory(mContext);
+ for (Bubble b: mBubbleData.getBubbles()) {
+ b.getIconView().setBubbleIconFactory(mBubbleIconFactory);
+ b.getIconView().updateViews();
+ b.getExpandedView().applyThemeAttrs();
+ }
if (mStackView != null) {
mStackView.onThemeChanged();
}
@@ -509,14 +518,10 @@
return (isSummary && isSuppressedSummary) || isBubbleAndSuppressed;
}
- void selectBubble(Bubble bubble) {
- mBubbleData.setSelectedBubble(bubble);
- }
-
@VisibleForTesting
void selectBubble(String key) {
Bubble bubble = mBubbleData.getBubbleWithKey(key);
- selectBubble(bubble);
+ mBubbleData.setSelectedBubble(bubble);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 63d036d..c1705db 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -99,7 +99,6 @@
private int mExpandedViewTouchSlop;
private Bubble mBubble;
- private String mAppName;
private BubbleController mBubbleController = Dependency.get(BubbleController.class);
private WindowManager mWindowManager;
@@ -339,26 +338,41 @@
}
}
- /**
- * Sets the bubble used to populate this view.
- */
- public void setBubble(Bubble bubble, BubbleStackView stackView) {
- if (DEBUG_BUBBLE_EXPANDED_VIEW) {
- Log.d(TAG, "setBubble: bubble=" + (bubble != null ? bubble.getKey() : "null"));
- }
+ void setStackView(BubbleStackView stackView) {
mStackView = stackView;
- mBubble = bubble;
- mAppName = bubble.getAppName();
-
- applyThemeAttrs();
- showSettingsIcon();
- updateExpandedView();
}
/**
- * Lets activity view know it should be shown / populated.
+ * Sets the bubble used to populate this view.
*/
- public void populateExpandedView() {
+ void update(Bubble bubble) {
+ if (DEBUG_BUBBLE_EXPANDED_VIEW) {
+ Log.d(TAG, "update: bubble=" + (bubble != null ? bubble.getKey() : "null"));
+ }
+ boolean isNew = mBubble == null;
+ if (isNew || bubble.getKey().equals(mBubble.getKey())) {
+ mBubble = bubble;
+ mSettingsIcon.setContentDescription(getResources().getString(
+ R.string.bubbles_settings_button_description, bubble.getAppName()));
+
+ if (isNew) {
+ mBubbleIntent = mBubble.getBubbleIntent();
+ if (mBubbleIntent != null) {
+ setContentVisibility(false);
+ mActivityView.setVisibility(VISIBLE);
+ }
+ }
+ applyThemeAttrs();
+ } else {
+ Log.w(TAG, "Trying to update entry with different key, new bubble: "
+ + bubble.getKey() + " old bubble: " + bubble.getKey());
+ }
+ }
+
+ /**
+ * Lets activity view know it should be shown / populated with activity content.
+ */
+ void populateExpandedView() {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
Log.d(TAG, "populateExpandedView: "
+ "bubble=" + getBubbleKey());
@@ -371,38 +385,6 @@
}
}
- /**
- * Updates the bubble backing this view. This will not re-populate ActivityView, it will
- * only update the deep-links in the title, and the height of the view.
- */
- public void update(Bubble bubble) {
- if (DEBUG_BUBBLE_EXPANDED_VIEW) {
- Log.d(TAG, "update: bubble=" + (bubble != null ? bubble.getKey() : "null"));
- }
- if (bubble.getKey().equals(mBubble.getKey())) {
- mBubble = bubble;
- updateSettingsContentDescription();
- updateHeight();
- } else {
- Log.w(TAG, "Trying to update entry with different key, new bubble: "
- + bubble.getKey() + " old bubble: " + bubble.getKey());
- }
- }
-
- private void updateExpandedView() {
- if (DEBUG_BUBBLE_EXPANDED_VIEW) {
- Log.d(TAG, "updateExpandedView: bubble="
- + getBubbleKey());
- }
-
- mBubbleIntent = mBubble.getBubbleIntent();
- if (mBubbleIntent != null) {
- setContentVisibility(false);
- mActivityView.setVisibility(VISIBLE);
- }
- updateView();
- }
-
boolean performBackPressIfNeeded() {
if (!usingActivityView()) {
return false;
@@ -490,16 +472,6 @@
}
}
- private void updateSettingsContentDescription() {
- mSettingsIcon.setContentDescription(getResources().getString(
- R.string.bubbles_settings_button_description, mAppName));
- }
-
- void showSettingsIcon() {
- updateSettingsContentDescription();
- mSettingsIcon.setVisibility(VISIBLE);
- }
-
/**
* Update appearance of the expanded view being displayed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
index 9ff033c..093fd0d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleIconFactory.java
@@ -15,11 +15,14 @@
*/
package com.android.systemui.bubbles;
+import android.app.Notification;
import android.content.Context;
+import android.content.pm.LauncherApps;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.BitmapInfo;
@@ -42,8 +45,27 @@
return mContext.getResources().getDimensionPixelSize(
com.android.launcher3.icons.R.dimen.profile_badge_size);
}
+ /**
+ * Returns the drawable that the developer has provided to display in the bubble.
+ */
+ Drawable getBubbleDrawable(Bubble b, Context context) {
+ if (b.getShortcutInfo() != null && b.usingShortcutInfo()) {
+ LauncherApps launcherApps =
+ (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
+ int density = context.getResources().getConfiguration().densityDpi;
+ return launcherApps.getShortcutIconDrawable(b.getShortcutInfo(), density);
+ } else {
+ Notification.BubbleMetadata metadata = b.getEntry().getBubbleMetadata();
+ Icon ic = metadata.getIcon();
+ return ic.loadDrawable(context);
+ }
+ }
- BitmapInfo getBadgedBitmap(Bubble b) {
+ /**
+ * Returns a {@link BitmapInfo} for the app-badge that is shown on top of each bubble. This
+ * will include the workprofile indicator on the badge if appropriate.
+ */
+ BitmapInfo getBadgeBitmap(Bubble b) {
Bitmap userBadgedBitmap = createIconBitmap(
b.getUserBadgedAppIcon(), 1f, getBadgeSize());
@@ -51,10 +73,12 @@
ShadowGenerator shadowGenerator = new ShadowGenerator(getBadgeSize());
c.setBitmap(userBadgedBitmap);
shadowGenerator.recreateIcon(Bitmap.createBitmap(userBadgedBitmap), c);
- BitmapInfo bitmapInfo = createIconBitmap(userBadgedBitmap);
- return bitmapInfo;
+ return createIconBitmap(userBadgedBitmap);
}
+ /**
+ * Returns a {@link BitmapInfo} for the entire bubble icon including the badge.
+ */
BitmapInfo getBubbleBitmap(Drawable bubble, BitmapInfo badge) {
BitmapInfo bubbleIconInfo = createBadgedIconBitmap(bubble,
null /* user */,
@@ -64,5 +88,4 @@
new BitmapDrawable(mContext.getResources(), badge.icon));
return bubbleIconInfo;
}
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 245b232..8987683 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -516,14 +516,7 @@
* Handle theme changes.
*/
public void onThemeChanged() {
- // Recreate icon factory to update default adaptive icon scale.
- mBubbleIconFactory = new BubbleIconFactory(mContext);
setUpFlyout();
- for (Bubble b: mBubbleData.getBubbles()) {
- b.getIconView().setBubbleIconFactory(mBubbleIconFactory);
- b.getIconView().updateViews();
- b.getExpandedView().applyThemeAttrs();
- }
}
/** Respond to the phone being rotated by repositioning the stack and hiding any flyouts. */
@@ -749,10 +742,6 @@
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
}
- bubble.setBubbleIconFactory(mBubbleIconFactory);
- bubble.inflate(mInflater, this);
- bubble.getIconView().updateViews();
-
// Set the dot position to the opposite of the side the stack is resting on, since the stack
// resting slightly off-screen would result in the dot also being off-screen.
bubble.getIconView().setDotPosition(
@@ -1567,9 +1556,6 @@
mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
if (mIsExpanded) {
- // First update the view so that it calculates a new height (ensuring the y position
- // calculation is correct)
- mExpandedBubble.getExpandedView().updateView();
final float y = getExpandedViewY();
if (!mExpandedViewYAnim.isRunning()) {
// We're not animating so set the value