diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java index 8f364b448bf2d..026ea069419d6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java @@ -47,6 +47,8 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.InstanceId; +import com.android.launcher3.icons.BubbleBadgeIconFactory; +import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView; import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; import com.android.wm.shell.common.bubbles.BubbleInfo; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleBadgeIconFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleBadgeIconFactory.java deleted file mode 100644 index 56b13b8dcd462..0000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleBadgeIconFactory.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.bubbles; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Path; -import android.graphics.Rect; -import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.Drawable; - -import com.android.launcher3.icons.BaseIconFactory; -import com.android.launcher3.icons.BitmapInfo; -import com.android.wm.shell.R; - -/** - * Factory for creating app badge icons that are shown on bubbles. - */ -public class BubbleBadgeIconFactory extends BaseIconFactory { - - public BubbleBadgeIconFactory(Context context) { - super(context, context.getResources().getConfiguration().densityDpi, - context.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size)); - } - - /** - * 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(Drawable userBadgedAppIcon, boolean isImportantConversation) { - if (userBadgedAppIcon instanceof AdaptiveIconDrawable) { - AdaptiveIconDrawable ad = (AdaptiveIconDrawable) userBadgedAppIcon; - userBadgedAppIcon = new CircularAdaptiveIcon(ad.getBackground(), ad.getForeground()); - } - if (isImportantConversation) { - userBadgedAppIcon = new CircularRingDrawable(userBadgedAppIcon); - } - Bitmap userBadgedBitmap = createIconBitmap( - userBadgedAppIcon, 1, MODE_WITH_SHADOW); - return createIconBitmap(userBadgedBitmap); - } - - private class CircularRingDrawable extends CircularAdaptiveIcon { - - final int mImportantConversationColor; - final int mRingWidth; - final Rect mInnerBounds = new Rect(); - - final Drawable mDr; - - CircularRingDrawable(Drawable dr) { - super(null, null); - mDr = dr; - mImportantConversationColor = mContext.getResources().getColor( - R.color.important_conversation, null); - mRingWidth = mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.importance_ring_stroke_width); - } - - @Override - public void draw(Canvas canvas) { - int save = canvas.save(); - canvas.clipPath(getIconMask()); - canvas.drawColor(mImportantConversationColor); - mInnerBounds.set(getBounds()); - mInnerBounds.inset(mRingWidth, mRingWidth); - canvas.translate(mInnerBounds.left, mInnerBounds.top); - mDr.setBounds(0, 0, mInnerBounds.width(), mInnerBounds.height()); - mDr.draw(canvas); - canvas.restoreToCount(save); - } - } - - private static class CircularAdaptiveIcon extends AdaptiveIconDrawable { - - final Path mPath = new Path(); - - CircularAdaptiveIcon(Drawable bg, Drawable fg) { - super(bg, fg); - } - - @Override - public Path getIconMask() { - mPath.reset(); - Rect bounds = getBounds(); - mPath.addOval(bounds.left, bounds.top, bounds.right, bounds.bottom, Path.Direction.CW); - return mPath; - } - - @Override - public void draw(Canvas canvas) { - int save = canvas.save(); - canvas.clipPath(getIconMask()); - - Drawable d; - if ((d = getBackground()) != null) { - d.draw(canvas); - } - if ((d = getForeground()) != null) { - d.draw(canvas); - } - canvas.restoreToCount(save); - } - } -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index da8eb479a77b8..511b4109944c7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -89,6 +89,9 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; +import com.android.launcher3.icons.BubbleBadgeIconFactory; +import com.android.launcher3.icons.BubbleIconFactory; +import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; @@ -317,8 +320,13 @@ public class BubbleController implements ConfigurationChangeListener, mBubblePositioner = positioner; mBubbleData = data; mSavedUserBubbleData = new SparseArray<>(); - mBubbleIconFactory = new BubbleIconFactory(context); - mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(context); + mBubbleIconFactory = new BubbleIconFactory(context, + context.getResources().getDimensionPixelSize(R.dimen.bubble_size)); + mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(context, + context.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size), + context.getResources().getColor(R.color.important_conversation), + context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width)); mDisplayController = displayController; mTaskViewTransitions = taskViewTransitions; mOneHandedOptional = oneHandedOptional; @@ -927,8 +935,13 @@ public class BubbleController implements ConfigurationChangeListener, if (mStackView != null) { mStackView.onThemeChanged(); } - mBubbleIconFactory = new BubbleIconFactory(mContext); - mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(mContext); + mBubbleIconFactory = new BubbleIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size)); + mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size), + mContext.getResources().getColor(R.color.important_conversation), + mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width)); // Reload each bubble for (Bubble b : mBubbleData.getBubbles()) { @@ -964,8 +977,13 @@ public class BubbleController implements ConfigurationChangeListener, mDensityDpi = newConfig.densityDpi; mScreenBounds.set(newConfig.windowConfiguration.getBounds()); mBubbleData.onMaxBubblesChanged(); - mBubbleIconFactory = new BubbleIconFactory(mContext); - mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(mContext); + mBubbleIconFactory = new BubbleIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size)); + mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size), + mContext.getResources().getColor(R.color.important_conversation), + mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width)); mStackView.onDisplaySizeChanged(); } if (newConfig.fontScale != mFontScale) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java deleted file mode 100644 index 4ded3ea951e5d..0000000000000 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.wm.shell.bubbles; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.content.Intent; -import android.content.pm.LauncherApps; -import android.content.pm.ShortcutInfo; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; - -import androidx.annotation.VisibleForTesting; - -import com.android.launcher3.icons.BaseIconFactory; -import com.android.wm.shell.R; - -/** - * Factory for creating normalized bubble icons. - * We are not using Launcher's IconFactory because bubbles only runs on the UI thread, - * so there is no need to manage a pool across multiple threads. - */ -@VisibleForTesting -public class BubbleIconFactory extends BaseIconFactory { - - public BubbleIconFactory(Context context) { - super(context, context.getResources().getConfiguration().densityDpi, - context.getResources().getDimensionPixelSize(R.dimen.bubble_size)); - } - - /** - * Returns the drawable that the developer has provided to display in the bubble. - */ - Drawable getBubbleDrawable(@NonNull final Context context, - @Nullable final ShortcutInfo shortcutInfo, @Nullable final Icon ic) { - if (shortcutInfo != null) { - LauncherApps launcherApps = - (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE); - int density = context.getResources().getConfiguration().densityDpi; - return launcherApps.getShortcutIconDrawable(shortcutInfo, density); - } else { - if (ic != null) { - if (ic.getType() == Icon.TYPE_URI - || ic.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { - context.grantUriPermission(context.getPackageName(), - ic.getUri(), - Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - return ic.loadDrawable(context); - } - return null; - } - } - - /** - * Creates the bitmap for the provided drawable and returns the scale used for - * drawing the actual drawable. - */ - public Bitmap createIconBitmap(@NonNull Drawable icon, float[] outScale) { - if (outScale == null) { - outScale = new float[1]; - } - icon = normalizeAndWrapToAdaptiveIcon(icon, - true /* shrinkNonAdaptiveIcons */, - null /* outscale */, - outScale); - return createIconBitmap(icon, outScale[0], MODE_WITH_SHADOW); - } -} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt index 6cdb80b2bb93d..c2a05b715f44f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt @@ -28,6 +28,7 @@ import android.util.PathParser import android.util.TypedValue import android.view.LayoutInflater import android.widget.FrameLayout +import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.R import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView @@ -93,7 +94,8 @@ class BubbleOverflow( val shapeColor = res.getColor(android.R.color.system_accent1_1000) overflowBtn?.iconDrawable?.setTint(shapeColor) - val iconFactory = BubbleIconFactory(context) + val iconFactory = BubbleIconFactory(context, + context.getResources().getDimensionPixelSize(R.dimen.bubble_size)) // Update bitmap val fg = InsetDrawable(overflowBtn?.iconDrawable, overflowIconInset) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java index 1a97c0504b379..d1081de11f30b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java @@ -42,6 +42,8 @@ import android.view.LayoutInflater; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; import com.android.launcher3.icons.BitmapInfo; +import com.android.launcher3.icons.BubbleBadgeIconFactory; +import com.android.launcher3.icons.BubbleIconFactory; import com.android.wm.shell.R; import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView; import com.android.wm.shell.bubbles.bar.BubbleBarLayerView; diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 28bdca97552d5..e82456524012a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -85,6 +85,9 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; +import com.android.launcher3.icons.BubbleBadgeIconFactory; +import com.android.launcher3.icons.BubbleIconFactory; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; @@ -127,11 +130,9 @@ import com.android.systemui.statusbar.policy.ZenModeController; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.bubbles.Bubble; -import com.android.wm.shell.bubbles.BubbleBadgeIconFactory; import com.android.wm.shell.bubbles.BubbleData; import com.android.wm.shell.bubbles.BubbleDataRepository; import com.android.wm.shell.bubbles.BubbleEntry; -import com.android.wm.shell.bubbles.BubbleIconFactory; import com.android.wm.shell.bubbles.BubbleLogger; import com.android.wm.shell.bubbles.BubbleStackView; import com.android.wm.shell.bubbles.BubbleViewInfoTask; @@ -1225,8 +1226,13 @@ public class BubblesTest extends SysuiTestCase { BubbleViewInfoTask.BubbleViewInfo info = BubbleViewInfoTask.BubbleViewInfo.populate(context, mBubbleController, mBubbleController.getStackView(), - new BubbleIconFactory(mContext), - new BubbleBadgeIconFactory(mContext), + new BubbleIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size)), + new BubbleBadgeIconFactory(mContext, + mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size), + mContext.getResources().getColor(R.color.important_conversation), + mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width)), bubble, true /* skipInflation */); verify(userContext, times(1)).getPackageManager();