Loading quickstep/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -363,6 +363,7 @@ <dimen name="bubblebar_icon_size">50dp</dimen> <dimen name="bubblebar_badge_size">24dp</dimen> <dimen name="bubblebar_icon_overlap">12dp</dimen> <dimen name="bubblebar_overflow_inset">24dp</dimen> <dimen name="bubblebar_icon_spacing">3dp</dimen> <dimen name="bubblebar_icon_elevation">1dp</dimen> Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +52 −3 Original line number Diff line number Diff line Loading @@ -38,11 +38,15 @@ import android.content.pm.ApplicationInfo; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; import android.os.Bundle; import android.os.SystemProperties; import android.os.UserHandle; Loading @@ -51,6 +55,8 @@ import android.util.Log; import android.util.PathParser; import android.view.LayoutInflater; import androidx.appcompat.content.res.AppCompatResources; import com.android.internal.graphics.ColorUtils; import com.android.launcher3.R; import com.android.launcher3.icons.BitmapInfo; Loading Loading @@ -113,7 +119,8 @@ public class BubbleBarController extends IBubblesListener.Stub { private final LauncherApps mLauncherApps; private final BubbleIconFactory mIconFactory; private BubbleBarBubble mSelectedBubble; private BubbleBarItem mSelectedBubble; private BubbleBarOverflow mOverflowBubble; private BubbleBarViewController mBubbleBarViewController; private BubbleStashController mBubbleStashController; Loading Loading @@ -178,6 +185,16 @@ public class BubbleBarController extends IBubblesListener.Stub { mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); }); BUBBLE_STATE_EXECUTOR.execute(() -> { if (mOverflowBubble == null) { BubbleBarOverflow overflow = createOverflow(mContext); mMainExecutor.execute(() -> { mBubbleBarViewController.addBubble(overflow); mOverflowBubble = overflow; }); } }); } /** Loading Loading @@ -329,7 +346,7 @@ public class BubbleBarController extends IBubblesListener.Stub { * WMShell that the selection has changed, that should go through * {@link SystemUiProxy#showBubble}. */ public void setSelectedBubble(BubbleBarBubble b) { public void setSelectedBubble(BubbleBarItem b) { if (!Objects.equals(b, mSelectedBubble)) { if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey()); mSelectedBubble = b; Loading Loading @@ -424,7 +441,6 @@ public class BubbleBarController extends IBubblesListener.Stub { dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, Color.WHITE, WHITE_SCRIM_ALPHA); LayoutInflater inflater = LayoutInflater.from(context); BubbleView bubbleView = (BubbleView) inflater.inflate( R.layout.bubblebar_item_view, bbv, false /* attachToRoot */); Loading @@ -434,4 +450,37 @@ public class BubbleBarController extends IBubblesListener.Stub { bubbleView.setBubble(bubble); return bubble; } private BubbleBarOverflow createOverflow(Context context) { Bitmap bitmap = createOverflowBitmap(context); LayoutInflater inflater = LayoutInflater.from(context); BubbleView bubbleView = (BubbleView) inflater.inflate( R.layout.bubblebar_item_view, mBarView, false /* attachToRoot */); BubbleBarOverflow overflow = new BubbleBarOverflow(bubbleView); bubbleView.setOverflow(overflow, bitmap); return overflow; } private Bitmap createOverflowBitmap(Context context) { Drawable iconDrawable = AppCompatResources.getDrawable(mContext, R.drawable.bubble_ic_overflow_button); final TypedArray ta = mContext.obtainStyledAttributes( new int[]{ com.android.internal.R.attr.materialColorOnPrimaryFixed, com.android.internal.R.attr.materialColorPrimaryFixed }); int overflowIconColor = ta.getColor(0, Color.WHITE); int overflowBackgroundColor = ta.getColor(1, Color.BLACK); ta.recycle(); iconDrawable.setTint(overflowIconColor); int inset = context.getResources().getDimensionPixelSize(R.dimen.bubblebar_overflow_inset); Drawable foreground = new InsetDrawable(iconDrawable, inset); Drawable drawable = new AdaptiveIconDrawable(new ColorDrawable(overflowBackgroundColor), foreground); return mIconFactory.createBadgedIconBitmap(drawable).icon; } } quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBubble.kt→quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarItem.kt +7 −4 Original line number Diff line number Diff line Loading @@ -19,16 +19,19 @@ import android.graphics.Bitmap import android.graphics.Path import com.android.wm.shell.common.bubbles.BubbleInfo /** An entity in the bubble bar. */ sealed class BubbleBarItem(open val key: String, open val view: BubbleView) /** Contains state info about a bubble in the bubble bar as well as presentation information. */ data class BubbleBarBubble( val info: BubbleInfo, val view: BubbleView, override val view: BubbleView, val badge: Bitmap, val icon: Bitmap, val dotColor: Int, val dotPath: Path, val appName: String ) { ) : BubbleBarItem(info.key, view) val key: String = info.key } /** Represents the overflow bubble in the bubble bar. */ data class BubbleBarOverflow(override val view: BubbleView) : BubbleBarItem("overflow", view) quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +4 −4 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ public class BubbleBarViewController { } private void onBubbleClicked(View v) { BubbleBarBubble bubble = ((BubbleView) v).getBubble(); BubbleBarItem bubble = ((BubbleView) v).getBubble(); if (bubble == null) { Log.e(TAG, "bubble click listener, bubble was null"); } Loading Loading @@ -236,7 +236,7 @@ public class BubbleBarViewController { /** * Removes the provided bubble from the bubble bar. */ public void removeBubble(BubbleBarBubble b) { public void removeBubble(BubbleBarItem b) { if (b != null) { mBarView.removeView(b.getView()); } else { Loading @@ -247,7 +247,7 @@ public class BubbleBarViewController { /** * Adds the provided bubble to the bubble bar. */ public void addBubble(BubbleBarBubble b) { public void addBubble(BubbleBarItem b) { if (b != null) { mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize)); b.getView().setOnClickListener(mBubbleClickListener); Loading @@ -268,7 +268,7 @@ public class BubbleBarViewController { /** * Updates the selected bubble. */ public void updateSelectedBubble(BubbleBarBubble newlySelected) { public void updateSelectedBubble(BubbleBarItem newlySelected) { mBarView.setSelectedBubble(newlySelected.getView()); } Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java +17 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.launcher3.icons.IconNormalizer; // TODO: (b/276978250) This is will be similar to WMShell's BadgedImageView, it'd be nice to share. // TODO: (b/269670235) currently this doesn't show the 'update dot' /** * View that displays a bubble icon, along with an app badge on either the left or * right side of the view. Loading @@ -48,7 +49,7 @@ public class BubbleView extends ConstraintLayout { // TODO: (b/273310265) handle RTL private boolean mOnLeft = false; private BubbleBarBubble mBubble; private BubbleBarItem mBubble; public BubbleView(Context context) { this(context, null); Loading Loading @@ -97,15 +98,27 @@ public class BubbleView extends ConstraintLayout { mAppIcon.setImageBitmap(bubble.getBadge()); } void setOverflow(BubbleBarOverflow overflow, Bitmap bitmap) { mBubble = overflow; mBubbleIcon.setImageBitmap(bitmap); hideBadge(); } /** Returns the bubble being rendered in this view. */ @Nullable BubbleBarBubble getBubble() { BubbleBarItem getBubble() { return mBubble; } /** Shows the app badge on this bubble. */ void showBadge() { Bitmap appBadgeBitmap = mBubble.getBadge(); if (mBubble instanceof BubbleBarOverflow) { // The overflow bubble does not have a badge, so just bail. return; } BubbleBarBubble bubble = (BubbleBarBubble) mBubble; Bitmap appBadgeBitmap = bubble.getBadge(); if (appBadgeBitmap == null) { mAppIcon.setVisibility(GONE); return; Loading @@ -113,7 +126,7 @@ public class BubbleView extends ConstraintLayout { int translationX; if (mOnLeft) { translationX = -(mBubble.getIcon().getWidth() - appBadgeBitmap.getWidth()); translationX = -(bubble.getIcon().getWidth() - appBadgeBitmap.getWidth()); } else { translationX = 0; } Loading Loading
quickstep/res/values/dimens.xml +1 −0 Original line number Diff line number Diff line Loading @@ -363,6 +363,7 @@ <dimen name="bubblebar_icon_size">50dp</dimen> <dimen name="bubblebar_badge_size">24dp</dimen> <dimen name="bubblebar_icon_overlap">12dp</dimen> <dimen name="bubblebar_overflow_inset">24dp</dimen> <dimen name="bubblebar_icon_spacing">3dp</dimen> <dimen name="bubblebar_icon_elevation">1dp</dimen> Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +52 −3 Original line number Diff line number Diff line Loading @@ -38,11 +38,15 @@ import android.content.pm.ApplicationInfo; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; import android.os.Bundle; import android.os.SystemProperties; import android.os.UserHandle; Loading @@ -51,6 +55,8 @@ import android.util.Log; import android.util.PathParser; import android.view.LayoutInflater; import androidx.appcompat.content.res.AppCompatResources; import com.android.internal.graphics.ColorUtils; import com.android.launcher3.R; import com.android.launcher3.icons.BitmapInfo; Loading Loading @@ -113,7 +119,8 @@ public class BubbleBarController extends IBubblesListener.Stub { private final LauncherApps mLauncherApps; private final BubbleIconFactory mIconFactory; private BubbleBarBubble mSelectedBubble; private BubbleBarItem mSelectedBubble; private BubbleBarOverflow mOverflowBubble; private BubbleBarViewController mBubbleBarViewController; private BubbleStashController mBubbleStashController; Loading Loading @@ -178,6 +185,16 @@ public class BubbleBarController extends IBubblesListener.Stub { mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED); }); BUBBLE_STATE_EXECUTOR.execute(() -> { if (mOverflowBubble == null) { BubbleBarOverflow overflow = createOverflow(mContext); mMainExecutor.execute(() -> { mBubbleBarViewController.addBubble(overflow); mOverflowBubble = overflow; }); } }); } /** Loading Loading @@ -329,7 +346,7 @@ public class BubbleBarController extends IBubblesListener.Stub { * WMShell that the selection has changed, that should go through * {@link SystemUiProxy#showBubble}. */ public void setSelectedBubble(BubbleBarBubble b) { public void setSelectedBubble(BubbleBarItem b) { if (!Objects.equals(b, mSelectedBubble)) { if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey()); mSelectedBubble = b; Loading Loading @@ -424,7 +441,6 @@ public class BubbleBarController extends IBubblesListener.Stub { dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color, Color.WHITE, WHITE_SCRIM_ALPHA); LayoutInflater inflater = LayoutInflater.from(context); BubbleView bubbleView = (BubbleView) inflater.inflate( R.layout.bubblebar_item_view, bbv, false /* attachToRoot */); Loading @@ -434,4 +450,37 @@ public class BubbleBarController extends IBubblesListener.Stub { bubbleView.setBubble(bubble); return bubble; } private BubbleBarOverflow createOverflow(Context context) { Bitmap bitmap = createOverflowBitmap(context); LayoutInflater inflater = LayoutInflater.from(context); BubbleView bubbleView = (BubbleView) inflater.inflate( R.layout.bubblebar_item_view, mBarView, false /* attachToRoot */); BubbleBarOverflow overflow = new BubbleBarOverflow(bubbleView); bubbleView.setOverflow(overflow, bitmap); return overflow; } private Bitmap createOverflowBitmap(Context context) { Drawable iconDrawable = AppCompatResources.getDrawable(mContext, R.drawable.bubble_ic_overflow_button); final TypedArray ta = mContext.obtainStyledAttributes( new int[]{ com.android.internal.R.attr.materialColorOnPrimaryFixed, com.android.internal.R.attr.materialColorPrimaryFixed }); int overflowIconColor = ta.getColor(0, Color.WHITE); int overflowBackgroundColor = ta.getColor(1, Color.BLACK); ta.recycle(); iconDrawable.setTint(overflowIconColor); int inset = context.getResources().getDimensionPixelSize(R.dimen.bubblebar_overflow_inset); Drawable foreground = new InsetDrawable(iconDrawable, inset); Drawable drawable = new AdaptiveIconDrawable(new ColorDrawable(overflowBackgroundColor), foreground); return mIconFactory.createBadgedIconBitmap(drawable).icon; } }
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBubble.kt→quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarItem.kt +7 −4 Original line number Diff line number Diff line Loading @@ -19,16 +19,19 @@ import android.graphics.Bitmap import android.graphics.Path import com.android.wm.shell.common.bubbles.BubbleInfo /** An entity in the bubble bar. */ sealed class BubbleBarItem(open val key: String, open val view: BubbleView) /** Contains state info about a bubble in the bubble bar as well as presentation information. */ data class BubbleBarBubble( val info: BubbleInfo, val view: BubbleView, override val view: BubbleView, val badge: Bitmap, val icon: Bitmap, val dotColor: Int, val dotPath: Path, val appName: String ) { ) : BubbleBarItem(info.key, view) val key: String = info.key } /** Represents the overflow bubble in the bubble bar. */ data class BubbleBarOverflow(override val view: BubbleView) : BubbleBarItem("overflow", view)
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +4 −4 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ public class BubbleBarViewController { } private void onBubbleClicked(View v) { BubbleBarBubble bubble = ((BubbleView) v).getBubble(); BubbleBarItem bubble = ((BubbleView) v).getBubble(); if (bubble == null) { Log.e(TAG, "bubble click listener, bubble was null"); } Loading Loading @@ -236,7 +236,7 @@ public class BubbleBarViewController { /** * Removes the provided bubble from the bubble bar. */ public void removeBubble(BubbleBarBubble b) { public void removeBubble(BubbleBarItem b) { if (b != null) { mBarView.removeView(b.getView()); } else { Loading @@ -247,7 +247,7 @@ public class BubbleBarViewController { /** * Adds the provided bubble to the bubble bar. */ public void addBubble(BubbleBarBubble b) { public void addBubble(BubbleBarItem b) { if (b != null) { mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize)); b.getView().setOnClickListener(mBubbleClickListener); Loading @@ -268,7 +268,7 @@ public class BubbleBarViewController { /** * Updates the selected bubble. */ public void updateSelectedBubble(BubbleBarBubble newlySelected) { public void updateSelectedBubble(BubbleBarItem newlySelected) { mBarView.setSelectedBubble(newlySelected.getView()); } Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java +17 −4 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.launcher3.icons.IconNormalizer; // TODO: (b/276978250) This is will be similar to WMShell's BadgedImageView, it'd be nice to share. // TODO: (b/269670235) currently this doesn't show the 'update dot' /** * View that displays a bubble icon, along with an app badge on either the left or * right side of the view. Loading @@ -48,7 +49,7 @@ public class BubbleView extends ConstraintLayout { // TODO: (b/273310265) handle RTL private boolean mOnLeft = false; private BubbleBarBubble mBubble; private BubbleBarItem mBubble; public BubbleView(Context context) { this(context, null); Loading Loading @@ -97,15 +98,27 @@ public class BubbleView extends ConstraintLayout { mAppIcon.setImageBitmap(bubble.getBadge()); } void setOverflow(BubbleBarOverflow overflow, Bitmap bitmap) { mBubble = overflow; mBubbleIcon.setImageBitmap(bitmap); hideBadge(); } /** Returns the bubble being rendered in this view. */ @Nullable BubbleBarBubble getBubble() { BubbleBarItem getBubble() { return mBubble; } /** Shows the app badge on this bubble. */ void showBadge() { Bitmap appBadgeBitmap = mBubble.getBadge(); if (mBubble instanceof BubbleBarOverflow) { // The overflow bubble does not have a badge, so just bail. return; } BubbleBarBubble bubble = (BubbleBarBubble) mBubble; Bitmap appBadgeBitmap = bubble.getBadge(); if (appBadgeBitmap == null) { mAppIcon.setVisibility(GONE); return; Loading @@ -113,7 +126,7 @@ public class BubbleView extends ConstraintLayout { int translationX; if (mOnLeft) { translationX = -(mBubble.getIcon().getWidth() - appBadgeBitmap.getWidth()); translationX = -(bubble.getIcon().getWidth() - appBadgeBitmap.getWidth()); } else { translationX = 0; } Loading