Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a04c1b56 authored by Cicely Lambright's avatar Cicely Lambright
Browse files

Allow blurred background to be seen behind notification badge icon

This will change the badge ring from a flat color to a transparent
cutout showing the blurred notification background.

Test: Tested on the device
Fixes: b/409346132
Flag: com.android.internal.widget.flags.notification_transparent_badge_ring
Change-Id: Ic82b038530a80ea7dbc2aadc4b99ab559ffd6f58
parent 0883e019
Loading
Loading
Loading
Loading
+16 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.internal.widget;
package com.android.internal.widget;


import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing;

import android.annotation.AttrRes;
import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
@@ -28,6 +30,7 @@ import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.view.RemotableViewMethod;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.RemoteViews;


@@ -87,7 +90,18 @@ public class CallLayout extends FrameLayout {
        // When the small icon is gone, hide the rest of the badge
        // When the small icon is gone, hide the rest of the badge
        mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
        mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
            mPeopleHelper.animateViewForceHidden(mConversationIconBadgeBg, 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
    @NonNull
@@ -127,7 +141,8 @@ public class CallLayout extends FrameLayout {
     */
     */
    @RemotableViewMethod
    @RemotableViewMethod
    public void setNotificationBackgroundColor(int color) {
    public void setNotificationBackgroundColor(int color) {
        mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf(color));
        mConversationIconBadgeBg.setImageTintList(ColorStateList.valueOf(
                notificationTransparentBadgeRing() ? android.R.color.transparent : color));
    }
    }


    /**
    /**
+4 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.internal.widget;
package com.android.internal.widget;


import static com.android.internal.widget.flags.Flags.notificationTransparentBadgeRing;

import android.app.Notification;
import android.app.Notification;
import android.app.Notification.MessagingStyle;
import android.app.Notification.MessagingStyle;
import android.app.Person;
import android.app.Person;
@@ -119,7 +121,8 @@ public class CompactMessagingLayout extends FrameLayout {
     */
     */
    @RemotableViewMethod
    @RemotableViewMethod
    public void setNotificationBackgroundColor(int color) {
    public void setNotificationBackgroundColor(int color) {
        mNotificationBackgroundColor = color;
        mNotificationBackgroundColor =
                notificationTransparentBadgeRing() ? android.R.color.transparent : color;
    }
    }


    /**
    /**
+24 −2
Original line number Original line Diff line number Diff line
@@ -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_EXTERNAL;
import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;
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.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorListenerAdapter;
@@ -215,6 +216,17 @@ public class ConversationLayout extends FrameLayout
        mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
        mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
        mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
        mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
        mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
        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()) {
        if (notificationsRedesignTemplates()) {
            // The left_icon in the header has the default rounded square background. Make sure
            // The left_icon in the header has the default rounded square background. Make sure
            // we're using the circular background instead.
            // we're using the circular background instead.
@@ -255,6 +267,11 @@ public class ConversationLayout extends FrameLayout
                mConversationIconBadge.animate().cancel();
                mConversationIconBadge.animate().cancel();
                mConversationIconBadge.setVisibility(visibility);
                mConversationIconBadge.setVisibility(visibility);
            }
            }

            if (transparentBadgeRingEnabled()) {
                mConversationIconView.setClipToOutline(true);
                mConversationFacePile.setClipToOutline(true);
            }
        });
        });
        // When the small icon is gone, hide the rest of the badge
        // When the small icon is gone, hide the rest of the badge
        mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
        mIcon.setOnForceHiddenChangedListener((forceHidden) -> {
@@ -302,7 +319,6 @@ public class ConversationLayout extends FrameLayout
                R.dimen.conversation_badge_protrusion_group_expanded);
                R.dimen.conversation_badge_protrusion_group_expanded);
        mExpandedGroupBadgeProtrusionFacePile = getResources().getDimensionPixelSize(
        mExpandedGroupBadgeProtrusionFacePile = getResources().getDimensionPixelSize(
                R.dimen.conversation_badge_protrusion_group_expanded_face_pile);
                R.dimen.conversation_badge_protrusion_group_expanded_face_pile);
        mConversationFacePile = findViewById(R.id.conversation_face_pile);
        mFacePileAvatarSize = getResources().getDimensionPixelSize(
        mFacePileAvatarSize = getResources().getDimensionPixelSize(
                R.dimen.conversation_face_pile_avatar_size);
                R.dimen.conversation_face_pile_avatar_size);
        mFacePileAvatarSizeExpandedGroup = getResources().getDimensionPixelSize(
        mFacePileAvatarSizeExpandedGroup = getResources().getDimensionPixelSize(
@@ -1146,7 +1162,9 @@ public class ConversationLayout extends FrameLayout
    }
    }


    private void applyNotificationBackgroundColor(ImageView view) {
    private void applyNotificationBackgroundColor(ImageView view) {
        view.setImageTintList(ColorStateList.valueOf(mNotificationBackgroundColor));
        view.setImageTintList(ColorStateList.valueOf(
                transparentBadgeRingEnabled() ? android.R.color.transparent
                        : mNotificationBackgroundColor));
    }
    }


    @RemotableViewMethod
    @RemotableViewMethod
@@ -1752,6 +1770,10 @@ public class ConversationLayout extends FrameLayout
        return mConversationHeaderData;
        return mConversationHeaderData;
    }
    }


    private static boolean transparentBadgeRingEnabled() {
        return notificationsRedesignTemplates() && notificationTransparentBadgeRing();
    }

    private static class TouchDelegateComposite extends TouchDelegate {
    private static class TouchDelegateComposite extends TouchDelegate {
        private final ArrayList<TouchDelegate> mDelegates = new ArrayList<>();
        private final ArrayList<TouchDelegate> mDelegates = new ArrayList<>();


+51 −0
Original line number Original line Diff line number Diff line
@@ -28,11 +28,14 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Icon;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.view.View;
import android.view.View;
import android.view.ViewOutlineProvider;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.graphics.ColorUtils;
@@ -302,4 +305,52 @@ public class PeopleHelper {
            messagingGroup.setCanHideSenderIfFirst(canHide);
            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;
            }
        };
    }
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -24,3 +24,10 @@ flag {
        purpose: PURPOSE_BUGFIX
        purpose: PURPOSE_BUGFIX
    }
    }
}
}

flag {
    name: "notification_transparent_badge_ring"
    namespace: "systemui"
    description: "Makes the ring around for the notification badge transparent"
    bug: "409346132"
}