Loading core/java/com/android/internal/widget/CallLayout.java +16 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -28,6 +30,7 @@ import android.graphics.drawable.Icon; import android.os.Bundle; import android.util.AttributeSet; import android.view.RemotableViewMethod; import android.view.View; import android.widget.FrameLayout; import android.widget.RemoteViews; Loading Loading @@ -87,7 +90,18 @@ public class CallLayout extends FrameLayout { // When the small icon is gone, hide the rest of the badge mIcon.setOnForceHiddenChangedListener((forceHidden) -> { mPeopleHelper.animateViewForceHidden(mConversationIconBadgeBg, forceHidden); if (notificationTransparentBadgeRing()) { mConversationIconView.setClipToOutline(true); } }); if (notificationTransparentBadgeRing()) { View conversationIconBadge = findViewById(R.id.conversation_icon_badge); mConversationIconView.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationIconView, conversationIconBadge)); } } @NonNull Loading Loading @@ -127,7 +141,8 @@ public class CallLayout extends FrameLayout { */ @RemotableViewMethod public void setNotificationBackgroundColor(int color) { mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf(color)); mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf( notificationTransparentBadgeRing() ? android.R.color.transparent : color)); } /** Loading core/java/com/android/internal/widget/CompactMessagingLayout.java +4 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.app.Notification; import android.app.Notification.MessagingStyle; import android.app.Person; Loading Loading @@ -119,7 +121,8 @@ public class CompactMessagingLayout extends FrameLayout { */ @RemotableViewMethod public void setNotificationBackgroundColor(int color) { mNotificationBackgroundColor = color; mNotificationBackgroundColor = notificationTransparentBadgeRing() ? android.R.color.transparent : color; } /** Loading core/java/com/android/internal/widget/ConversationLayout.java +24 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.Flags.notificationsRedesignTemplates; import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL; import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; Loading Loading @@ -215,6 +216,17 @@ public class ConversationLayout extends FrameLayout mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring); mConversationIconBadge = findViewById(R.id.conversation_icon_badge); mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg); mConversationFacePile = findViewById(R.id.conversation_face_pile); if (transparentBadgeRingEnabled()) { mConversationIconView.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationIconView, mConversationIconBadge)); mConversationFacePile.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationFacePile, mConversationIconBadge)); } if (notificationsRedesignTemplates()) { // The left_icon in the header has the default rounded square background. Make sure // we're using the circular background instead. Loading Loading @@ -255,6 +267,11 @@ public class ConversationLayout extends FrameLayout mConversationIconBadge.animate().cancel(); mConversationIconBadge.setVisibility(visibility); } if (transparentBadgeRingEnabled()) { mConversationIconView.setClipToOutline(true); mConversationFacePile.setClipToOutline(true); } }); // When the small icon is gone, hide the rest of the badge mIcon.setOnForceHiddenChangedListener((forceHidden) -> { Loading Loading @@ -302,7 +319,6 @@ public class ConversationLayout extends FrameLayout R.dimen.conversation_badge_protrusion_group_expanded); mExpandedGroupBadgeProtrusionFacePile = getResources().getDimensionPixelSize( R.dimen.conversation_badge_protrusion_group_expanded_face_pile); mConversationFacePile = findViewById(R.id.conversation_face_pile); mFacePileAvatarSize = getResources().getDimensionPixelSize( R.dimen.conversation_face_pile_avatar_size); mFacePileAvatarSizeExpandedGroup = getResources().getDimensionPixelSize( Loading Loading @@ -1146,7 +1162,9 @@ public class ConversationLayout extends FrameLayout } private void applyNotificationBackgroundColor(ImageView view) { view.setImageTintList(ColorStateList.valueOf(mNotificationBackgroundColor)); view.setImageTintList(ColorStateList.valueOf( transparentBadgeRingEnabled() ? android.R.color.transparent : mNotificationBackgroundColor)); } @RemotableViewMethod Loading Loading @@ -1752,6 +1770,10 @@ public class ConversationLayout extends FrameLayout return mConversationHeaderData; } private static boolean transparentBadgeRingEnabled() { return notificationsRedesignTemplates() && notificationTransparentBadgeRing(); } private static class TouchDelegateComposite extends TouchDelegate { private final ArrayList<TouchDelegate> mDelegates = new ArrayList<>(); Loading core/java/com/android/internal/widget/PeopleHelper.java +51 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,14 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.drawable.Icon; import android.text.TextUtils; import android.util.ArrayMap; import android.view.View; import android.view.ViewOutlineProvider; import com.android.internal.R; import com.android.internal.graphics.ColorUtils; Loading Loading @@ -302,4 +305,52 @@ public class PeopleHelper { messagingGroup.setCanHideSenderIfFirst(canHide); } } /** * Builds a {@link ViewOutlineProvider} that provides a circular path or a circular path with a * smaller circle cut out of the shape. This is primarily for cutting out a shape for the icon * badge ring. * * @param baseView - View used to provide the larger outline's size. * @param cutoutView - View used to determine the size of the cutout. This view must be a direct * child of the base view, * otherwise positional getters on the view (eg. {@link View#getBottom}) will * not return the correct value. * @return A {@link ViewOutlineProvider} that sets the correct outline based on state and size. */ public static ViewOutlineProvider getBadgeCutoutOutlineProvider(View baseView, View cutoutView) { if (baseView == null || cutoutView == null) { return ViewOutlineProvider.BACKGROUND; } return new ViewOutlineProvider() { private View mBase = baseView; private View mCutout = cutoutView; @Override public void getOutline(View view, Outline outline) { outline.setPath( mCutout.getVisibility() == View.GONE ? getBasePath() : getCutoutPath()); } private Path getBasePath() { Path basePath = new Path(); basePath.addOval(mBase.getLeft(), mBase.getTop(), mBase.getRight(), mBase.getBottom(), Path.Direction.CW); return basePath; } private Path getCutoutPath() { Path clippedShape = new Path(); clippedShape.addOval(mCutout.getLeft(), mCutout.getTop(), mCutout.getRight(), mCutout.getBottom(), Path.Direction.CW); Path cutoutPath = new Path(getBasePath()); cutoutPath.op(clippedShape, Path.Op.DIFFERENCE); return cutoutPath; } }; } } core/java/com/android/internal/widget/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -24,3 +24,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "notification_transparent_badge_ring" namespace: "systemui" description: "Makes the ring around for the notification badge transparent" bug: "409346132" } Loading
core/java/com/android/internal/widget/CallLayout.java +16 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.annotation.AttrRes; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -28,6 +30,7 @@ import android.graphics.drawable.Icon; import android.os.Bundle; import android.util.AttributeSet; import android.view.RemotableViewMethod; import android.view.View; import android.widget.FrameLayout; import android.widget.RemoteViews; Loading Loading @@ -87,7 +90,18 @@ public class CallLayout extends FrameLayout { // When the small icon is gone, hide the rest of the badge mIcon.setOnForceHiddenChangedListener((forceHidden) -> { mPeopleHelper.animateViewForceHidden(mConversationIconBadgeBg, forceHidden); if (notificationTransparentBadgeRing()) { mConversationIconView.setClipToOutline(true); } }); if (notificationTransparentBadgeRing()) { View conversationIconBadge = findViewById(R.id.conversation_icon_badge); mConversationIconView.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationIconView, conversationIconBadge)); } } @NonNull Loading Loading @@ -127,7 +141,8 @@ public class CallLayout extends FrameLayout { */ @RemotableViewMethod public void setNotificationBackgroundColor(int color) { mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf(color)); mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf( notificationTransparentBadgeRing() ? android.R.color.transparent : color)); } /** Loading
core/java/com/android/internal/widget/CompactMessagingLayout.java +4 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.app.Notification; import android.app.Notification.MessagingStyle; import android.app.Person; Loading Loading @@ -119,7 +121,8 @@ public class CompactMessagingLayout extends FrameLayout { */ @RemotableViewMethod public void setNotificationBackgroundColor(int color) { mNotificationBackgroundColor = color; mNotificationBackgroundColor = notificationTransparentBadgeRing() ? android.R.color.transparent : color; } /** Loading
core/java/com/android/internal/widget/ConversationLayout.java +24 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.Flags.notificationsRedesignTemplates; import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL; import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE; import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; Loading Loading @@ -215,6 +216,17 @@ public class ConversationLayout extends FrameLayout mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring); mConversationIconBadge = findViewById(R.id.conversation_icon_badge); mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg); mConversationFacePile = findViewById(R.id.conversation_face_pile); if (transparentBadgeRingEnabled()) { mConversationIconView.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationIconView, mConversationIconBadge)); mConversationFacePile.setOutlineProvider( PeopleHelper.getBadgeCutoutOutlineProvider(mConversationFacePile, mConversationIconBadge)); } if (notificationsRedesignTemplates()) { // The left_icon in the header has the default rounded square background. Make sure // we're using the circular background instead. Loading Loading @@ -255,6 +267,11 @@ public class ConversationLayout extends FrameLayout mConversationIconBadge.animate().cancel(); mConversationIconBadge.setVisibility(visibility); } if (transparentBadgeRingEnabled()) { mConversationIconView.setClipToOutline(true); mConversationFacePile.setClipToOutline(true); } }); // When the small icon is gone, hide the rest of the badge mIcon.setOnForceHiddenChangedListener((forceHidden) -> { Loading Loading @@ -302,7 +319,6 @@ public class ConversationLayout extends FrameLayout R.dimen.conversation_badge_protrusion_group_expanded); mExpandedGroupBadgeProtrusionFacePile = getResources().getDimensionPixelSize( R.dimen.conversation_badge_protrusion_group_expanded_face_pile); mConversationFacePile = findViewById(R.id.conversation_face_pile); mFacePileAvatarSize = getResources().getDimensionPixelSize( R.dimen.conversation_face_pile_avatar_size); mFacePileAvatarSizeExpandedGroup = getResources().getDimensionPixelSize( Loading Loading @@ -1146,7 +1162,9 @@ public class ConversationLayout extends FrameLayout } private void applyNotificationBackgroundColor(ImageView view) { view.setImageTintList(ColorStateList.valueOf(mNotificationBackgroundColor)); view.setImageTintList(ColorStateList.valueOf( transparentBadgeRingEnabled() ? android.R.color.transparent : mNotificationBackgroundColor)); } @RemotableViewMethod Loading Loading @@ -1752,6 +1770,10 @@ public class ConversationLayout extends FrameLayout return mConversationHeaderData; } private static boolean transparentBadgeRingEnabled() { return notificationsRedesignTemplates() && notificationTransparentBadgeRing(); } private static class TouchDelegateComposite extends TouchDelegate { private final ArrayList<TouchDelegate> mDelegates = new ArrayList<>(); Loading
core/java/com/android/internal/widget/PeopleHelper.java +51 −0 Original line number Diff line number Diff line Loading @@ -28,11 +28,14 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.drawable.Icon; import android.text.TextUtils; import android.util.ArrayMap; import android.view.View; import android.view.ViewOutlineProvider; import com.android.internal.R; import com.android.internal.graphics.ColorUtils; Loading Loading @@ -302,4 +305,52 @@ public class PeopleHelper { messagingGroup.setCanHideSenderIfFirst(canHide); } } /** * Builds a {@link ViewOutlineProvider} that provides a circular path or a circular path with a * smaller circle cut out of the shape. This is primarily for cutting out a shape for the icon * badge ring. * * @param baseView - View used to provide the larger outline's size. * @param cutoutView - View used to determine the size of the cutout. This view must be a direct * child of the base view, * otherwise positional getters on the view (eg. {@link View#getBottom}) will * not return the correct value. * @return A {@link ViewOutlineProvider} that sets the correct outline based on state and size. */ public static ViewOutlineProvider getBadgeCutoutOutlineProvider(View baseView, View cutoutView) { if (baseView == null || cutoutView == null) { return ViewOutlineProvider.BACKGROUND; } return new ViewOutlineProvider() { private View mBase = baseView; private View mCutout = cutoutView; @Override public void getOutline(View view, Outline outline) { outline.setPath( mCutout.getVisibility() == View.GONE ? getBasePath() : getCutoutPath()); } private Path getBasePath() { Path basePath = new Path(); basePath.addOval(mBase.getLeft(), mBase.getTop(), mBase.getRight(), mBase.getBottom(), Path.Direction.CW); return basePath; } private Path getCutoutPath() { Path clippedShape = new Path(); clippedShape.addOval(mCutout.getLeft(), mCutout.getTop(), mCutout.getRight(), mCutout.getBottom(), Path.Direction.CW); Path cutoutPath = new Path(getBasePath()); cutoutPath.op(clippedShape, Path.Op.DIFFERENCE); return cutoutPath; } }; } }
core/java/com/android/internal/widget/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -24,3 +24,10 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "notification_transparent_badge_ring" namespace: "systemui" description: "Makes the ring around for the notification badge transparent" bug: "409346132" }