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

Commit 925ae859 authored by Neil Fuller's avatar Neil Fuller Committed by Automerger Merge Worker
Browse files

Merge "Revert "Persists bubbles to disk (part 4)"" into rvc-dev am: a5cc646a...

Merge "Revert "Persists bubbles to disk (part 4)"" into rvc-dev am: a5cc646a am: 7c0341e6 am: 4461aa8f

Change-Id: I0b16f7fa272b7a6a0cc7a32d48f22304ce0074d0
parents 554f9178 4461aa8f
Loading
Loading
Loading
Loading
+11 −108
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.systemui.bubbles;
package com.android.systemui.bubbles;




import static android.app.Notification.FLAG_BUBBLE;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.FINISHED;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;


@@ -28,7 +27,6 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutInfo;
@@ -57,11 +55,6 @@ import java.util.Objects;
class Bubble implements BubbleViewProvider {
class Bubble implements BubbleViewProvider {
    private static final String TAG = "Bubble";
    private static final String TAG = "Bubble";


    /**
     * NotificationEntry associated with the bubble. A null value implies this bubble is loaded
     * from disk.
     */
    @Nullable
    private NotificationEntry mEntry;
    private NotificationEntry mEntry;
    private final String mKey;
    private final String mKey;
    private final String mGroupId;
    private final String mGroupId;
@@ -102,56 +95,18 @@ class Bubble implements BubbleViewProvider {
    private Bitmap mBadgedImage;
    private Bitmap mBadgedImage;
    private int mDotColor;
    private int mDotColor;
    private Path mDotPath;
    private Path mDotPath;
    private int mFlags;


    /**

     * Extract GroupId from {@link NotificationEntry}. See also {@link #groupId(ShortcutInfo)}.
     */
    public static String groupId(NotificationEntry entry) {
    public static String groupId(NotificationEntry entry) {
        UserHandle user = entry.getSbn().getUser();
        UserHandle user = entry.getSbn().getUser();
        return user.getIdentifier() + "|" + entry.getSbn().getPackageName();
        return user.getIdentifier() + "|" + entry.getSbn().getPackageName();
    }
    }


    /**
    // TODO: Decouple Bubble from NotificationEntry and transform ShortcutInfo into Bubble
     * Extract GroupId from {@link ShortcutInfo}. This should match the one generated from
     * {@link NotificationEntry}. See also {@link #groupId(NotificationEntry)}.
     */
    @NonNull
    public static String groupId(@NonNull final ShortcutInfo shortcutInfo) {
        return shortcutInfo.getUserId() + "|" + shortcutInfo.getPackage();
    }

    /**
     * Generate a unique identifier for this bubble based on given {@link NotificationEntry}. If
     * {@link ShortcutInfo} was found in the notification entry, the identifier would be generated
     * from {@link ShortcutInfo} instead. See also {@link #key(ShortcutInfo)}.
     */
    @NonNull
    public static String key(@NonNull final NotificationEntry entry) {
        final ShortcutInfo shortcutInfo = entry.getRanking().getShortcutInfo();
        if (shortcutInfo != null) return key(shortcutInfo);
        return entry.getKey();
    }

    /**
     * Generate a unique identifier for this bubble based on given {@link ShortcutInfo}.
     * See also {@link #key(NotificationEntry)}.
     */
    @NonNull
    public static String key(@NonNull final ShortcutInfo shortcutInfo) {
        return shortcutInfo.getUserId() + "|" + shortcutInfo.getPackage() + "|"
                + shortcutInfo.getId();
    }

    /**
     * Create a bubble with limited information based on given {@link ShortcutInfo}.
     * Note: Currently this is only being used when the bubble is persisted to disk.
     */
    Bubble(ShortcutInfo shortcutInfo) {
    Bubble(ShortcutInfo shortcutInfo) {
        mShortcutInfo = shortcutInfo;
        mShortcutInfo = shortcutInfo;
        mKey = key(shortcutInfo);
        mKey = shortcutInfo.getId();
        mGroupId = groupId(shortcutInfo);
        mGroupId = shortcutInfo.getId();
        mFlags = 0;
    }
    }


    /** Used in tests when no UI is required. */
    /** Used in tests when no UI is required. */
@@ -159,11 +114,10 @@ class Bubble implements BubbleViewProvider {
    Bubble(NotificationEntry e,
    Bubble(NotificationEntry e,
            BubbleController.NotificationSuppressionChangedListener listener) {
            BubbleController.NotificationSuppressionChangedListener listener) {
        mEntry = e;
        mEntry = e;
        mKey = key(e);
        mKey = e.getKey();
        mLastUpdated = e.getSbn().getPostTime();
        mLastUpdated = e.getSbn().getPostTime();
        mGroupId = groupId(e);
        mGroupId = groupId(e);
        mSuppressionListener = listener;
        mSuppressionListener = listener;
        mFlags = e.getSbn().getNotification().flags;
    }
    }


    @Override
    @Override
@@ -171,26 +125,16 @@ class Bubble implements BubbleViewProvider {
        return mKey;
        return mKey;
    }
    }


    @Nullable
    public NotificationEntry getEntry() {
    public NotificationEntry getEntry() {
        return mEntry;
        return mEntry;
    }
    }


    @Nullable
    public UserHandle getUser() {
        if (mEntry != null) return mEntry.getSbn().getUser();
        if (mShortcutInfo != null) return mShortcutInfo.getUserHandle();
        return null;
    }

    public String getGroupId() {
    public String getGroupId() {
        return mGroupId;
        return mGroupId;
    }
    }


    public String getPackageName() {
    public String getPackageName() {
        return mEntry == null
        return mEntry.getSbn().getPackageName();
                ? mShortcutInfo == null ? null : mShortcutInfo.getPackage()
                : mEntry.getSbn().getPackageName();
    }
    }


    @Override
    @Override
@@ -274,8 +218,7 @@ class Bubble implements BubbleViewProvider {
    void inflate(BubbleViewInfoTask.Callback callback,
    void inflate(BubbleViewInfoTask.Callback callback,
            Context context,
            Context context,
            BubbleStackView stackView,
            BubbleStackView stackView,
            BubbleIconFactory iconFactory,
            BubbleIconFactory iconFactory) {
            boolean skipInflation) {
        if (isBubbleLoading()) {
        if (isBubbleLoading()) {
            mInflationTask.cancel(true /* mayInterruptIfRunning */);
            mInflationTask.cancel(true /* mayInterruptIfRunning */);
        }
        }
@@ -283,7 +226,6 @@ class Bubble implements BubbleViewProvider {
                context,
                context,
                stackView,
                stackView,
                iconFactory,
                iconFactory,
                skipInflation,
                callback);
                callback);
        if (mInflateSynchronously) {
        if (mInflateSynchronously) {
            mInflationTask.onPostExecute(mInflationTask.doInBackground());
            mInflationTask.onPostExecute(mInflationTask.doInBackground());
@@ -403,7 +345,6 @@ class Bubble implements BubbleViewProvider {
     * Whether this notification should be shown in the shade.
     * Whether this notification should be shown in the shade.
     */
     */
    boolean showInShade() {
    boolean showInShade() {
        if (mEntry == null) return false;
        return !shouldSuppressNotification() || !mEntry.isClearable();
        return !shouldSuppressNotification() || !mEntry.isClearable();
    }
    }


@@ -411,8 +352,8 @@ class Bubble implements BubbleViewProvider {
     * Sets whether this notification should be suppressed in the shade.
     * Sets whether this notification should be suppressed in the shade.
     */
     */
    void setSuppressNotification(boolean suppressNotification) {
    void setSuppressNotification(boolean suppressNotification) {
        if (mEntry == null) return;
        boolean prevShowInShade = showInShade();
        boolean prevShowInShade = showInShade();

        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        int flags = data.getFlags();
        int flags = data.getFlags();
        if (suppressNotification) {
        if (suppressNotification) {
@@ -443,7 +384,6 @@ class Bubble implements BubbleViewProvider {
     */
     */
    @Override
    @Override
    public boolean showDot() {
    public boolean showDot() {
        if (mEntry == null) return false;
        return mShowBubbleUpdateDot
        return mShowBubbleUpdateDot
                && !mEntry.shouldSuppressNotificationDot()
                && !mEntry.shouldSuppressNotificationDot()
                && !shouldSuppressNotification();
                && !shouldSuppressNotification();
@@ -453,7 +393,6 @@ class Bubble implements BubbleViewProvider {
     * Whether the flyout for the bubble should be shown.
     * Whether the flyout for the bubble should be shown.
     */
     */
    boolean showFlyout() {
    boolean showFlyout() {
        if (mEntry == null) return false;
        return !mSuppressFlyout && !mEntry.shouldSuppressPeek()
        return !mSuppressFlyout && !mEntry.shouldSuppressPeek()
                && !shouldSuppressNotification()
                && !shouldSuppressNotification()
                && !mEntry.shouldSuppressNotificationList();
                && !mEntry.shouldSuppressNotificationList();
@@ -477,13 +416,11 @@ class Bubble implements BubbleViewProvider {
     * is an ongoing bubble.
     * is an ongoing bubble.
     */
     */
    boolean isOngoing() {
    boolean isOngoing() {
        if (mEntry == null) return false;
        int flags = mEntry.getSbn().getNotification().flags;
        int flags = mEntry.getSbn().getNotification().flags;
        return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
        return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
    }
    }


    float getDesiredHeight(Context context) {
    float getDesiredHeight(Context context) {
        if (mEntry == null) return 0;
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        boolean useRes = data.getDesiredHeightResId() != 0;
        boolean useRes = data.getDesiredHeightResId() != 0;
        if (useRes) {
        if (useRes) {
@@ -497,7 +434,6 @@ class Bubble implements BubbleViewProvider {
    }
    }


    String getDesiredHeightString() {
    String getDesiredHeightString() {
        if (mEntry == null) return String.valueOf(0);
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        boolean useRes = data.getDesiredHeightResId() != 0;
        boolean useRes = data.getDesiredHeightResId() != 0;
        if (useRes) {
        if (useRes) {
@@ -514,13 +450,11 @@ class Bubble implements BubbleViewProvider {
     * To populate the icon use {@link LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)}.
     * To populate the icon use {@link LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)}.
     */
     */
    boolean usingShortcutInfo() {
    boolean usingShortcutInfo() {
        return mEntry != null && mEntry.getBubbleMetadata().getShortcutId() != null
        return mEntry.getBubbleMetadata().getShortcutId() != null;
                || mShortcutInfo != null;
    }
    }


    @Nullable
    @Nullable
    PendingIntent getBubbleIntent() {
    PendingIntent getBubbleIntent() {
        if (mEntry == null) return null;
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        if (data != null) {
        if (data != null) {
            return data.getIntent();
            return data.getIntent();
@@ -528,32 +462,16 @@ class Bubble implements BubbleViewProvider {
        return null;
        return null;
    }
    }


    Intent getSettingsIntent(final Context context) {
    Intent getSettingsIntent() {
        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
        final int uid = getUid(context);
        intent.putExtra(Settings.EXTRA_APP_UID, mEntry.getSbn().getUid());
        if (uid != -1) {
            intent.putExtra(Settings.EXTRA_APP_UID, uid);
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        return intent;
        return intent;
    }
    }


    private int getUid(final Context context) {
        if (mEntry != null) return mEntry.getSbn().getUid();
        final PackageManager pm = context.getPackageManager();
        if (pm == null) return -1;
        try {
            final ApplicationInfo info = pm.getApplicationInfo(mShortcutInfo.getPackage(), 0);
            return info.uid;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "cannot find uid", e);
        }
        return -1;
    }

    private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) {
    private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) {
        PackageManager pm = context.getPackageManager();
        PackageManager pm = context.getPackageManager();
        Resources r;
        Resources r;
@@ -575,30 +493,15 @@ class Bubble implements BubbleViewProvider {
    }
    }


    private boolean shouldSuppressNotification() {
    private boolean shouldSuppressNotification() {
        if (mEntry == null) return false;
        return mEntry.getBubbleMetadata() != null
        return mEntry.getBubbleMetadata() != null
                && mEntry.getBubbleMetadata().isNotificationSuppressed();
                && mEntry.getBubbleMetadata().isNotificationSuppressed();
    }
    }


    boolean shouldAutoExpand() {
    boolean shouldAutoExpand() {
        if (mEntry == null) return false;
        Notification.BubbleMetadata metadata = mEntry.getBubbleMetadata();
        Notification.BubbleMetadata metadata = mEntry.getBubbleMetadata();
        return metadata != null && metadata.getAutoExpandBubble();
        return metadata != null && metadata.getAutoExpandBubble();
    }
    }


    public boolean isBubble() {
        if (mEntry == null) return (mFlags & FLAG_BUBBLE) != 0;
        return (mEntry.getSbn().getNotification().flags & FLAG_BUBBLE) != 0;
    }

    public void enable(int option) {
        mFlags |= option;
    }

    public void disable(int option) {
        mFlags &= ~option;
    }

    @Override
    @Override
    public String toString() {
    public String toString() {
        return "Bubble{" + mKey + '}';
        return "Bubble{" + mKey + '}';
+29 −69
Original line number Original line Diff line number Diff line
@@ -42,7 +42,6 @@ import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import static java.lang.annotation.RetentionPolicy.SOURCE;


import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.annotation.UserIdInt;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.INotificationManager;
import android.app.INotificationManager;
@@ -243,7 +242,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
         * This can happen when an app cancels a bubbled notification or when the user dismisses a
         * This can happen when an app cancels a bubbled notification or when the user dismisses a
         * bubble.
         * bubble.
         */
         */
        void removeNotification(@NonNull NotificationEntry entry, int reason);
        void removeNotification(NotificationEntry entry, int reason);


        /**
        /**
         * Called when a bubbled notification has changed whether it should be
         * Called when a bubbled notification has changed whether it should be
@@ -259,7 +258,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
         * removes all remnants of the group's summary from the notification pipeline.
         * removes all remnants of the group's summary from the notification pipeline.
         * TODO: (b/145659174) Only old pipeline needs this - delete post-migration.
         * TODO: (b/145659174) Only old pipeline needs this - delete post-migration.
         */
         */
        void maybeCancelSummary(@NonNull NotificationEntry entry);
        void maybeCancelSummary(NotificationEntry entry);
    }
    }


    /**
    /**
@@ -482,7 +481,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi


        addNotifCallback(new NotifCallback() {
        addNotifCallback(new NotifCallback() {
            @Override
            @Override
            public void removeNotification(@NonNull final NotificationEntry entry, int reason) {
            public void removeNotification(NotificationEntry entry, int reason) {
                mNotificationEntryManager.performRemoveNotification(entry.getSbn(),
                mNotificationEntryManager.performRemoveNotification(entry.getSbn(),
                        reason);
                        reason);
            }
            }
@@ -493,7 +492,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            }
            }


            @Override
            @Override
            public void maybeCancelSummary(@NonNull final NotificationEntry entry) {
            public void maybeCancelSummary(NotificationEntry entry) {
                // Check if removed bubble has an associated suppressed group summary that needs
                // Check if removed bubble has an associated suppressed group summary that needs
                // to be removed now.
                // to be removed now.
                final String groupKey = entry.getSbn().getGroupKey();
                final String groupKey = entry.getSbn().getGroupKey();
@@ -702,12 +701,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
        mBubbleIconFactory = new BubbleIconFactory(mContext);
        mBubbleIconFactory = new BubbleIconFactory(mContext);
        // Reload each bubble
        // Reload each bubble
        for (Bubble b: mBubbleData.getBubbles()) {
        for (Bubble b: mBubbleData.getBubbles()) {
            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory,
            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
                    false /* skipInflation */);
        }
        }
        for (Bubble b: mBubbleData.getOverflowBubbles()) {
        for (Bubble b: mBubbleData.getOverflowBubbles()) {
            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory,
            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
                    false /* skipInflation */);
        }
        }
    }
    }


@@ -806,7 +803,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            if (bubble != null) {
            if (bubble != null) {
                mBubbleData.promoteBubbleFromOverflow(bubble, mStackView, mBubbleIconFactory);
                mBubbleData.promoteBubbleFromOverflow(bubble, mStackView, mBubbleIconFactory);
            }
            }
        } else if (bubble.isBubble()) {
        } else if (bubble.getEntry().isBubble()){
            mBubbleData.setSelectedBubble(bubble);
            mBubbleData.setSelectedBubble(bubble);
        }
        }
        mBubbleData.setExpanded(true);
        mBubbleData.setExpanded(true);
@@ -835,33 +832,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
        updateBubble(notif, suppressFlyout, true /* showInShade */);
        updateBubble(notif, suppressFlyout, true /* showInShade */);
    }
    }


    /**
     * Fills the overflow bubbles by loading them from disk.
     */
    void loadOverflowBubblesFromDisk() {
        if (!mBubbleData.getOverflowBubbles().isEmpty()) {
            // we don't need to load overflow bubbles from disk if it is already in memory
            return;
        }
        mDataRepository.loadBubbles((bubbles) -> {
            bubbles.forEach(bubble -> {
                if (mBubbleData.getBubbles().contains(bubble)) {
                    // if the bubble is already active, there's no need to push it to overflow
                    return;
                }
                bubble.inflate((b) -> mBubbleData.overflowBubble(DISMISS_AGED, bubble),
                        mContext, mStackView, mBubbleIconFactory, true /* skipInflation */);
            });
            return null;
        });
    }

    void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) {
    void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) {
        if (mStackView == null) {
        if (mStackView == null) {
            // Lazy init stack view when a bubble is created
            // Lazy init stack view when a bubble is created
            ensureStackViewCreated();
            ensureStackViewCreated();
            // Lazy load overflow bubbles from disk
            loadOverflowBubblesFromDisk();
        }
        }
        // If this is an interruptive notif, mark that it's interrupted
        // If this is an interruptive notif, mark that it's interrupted
        if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
        if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
@@ -881,11 +855,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                            return;
                            return;
                        }
                        }
                        mHandler.post(
                        mHandler.post(
                                () -> removeBubble(bubble.getKey(),
                                () -> removeBubble(bubble.getEntry(),
                                        BubbleController.DISMISS_INVALID_INTENT));
                                        BubbleController.DISMISS_INVALID_INTENT));
                    });
                    });
                },
                },
                mContext, mStackView, mBubbleIconFactory, false /* skipInflation */);
                mContext, mStackView, mBubbleIconFactory);
    }
    }


    /**
    /**
@@ -897,10 +871,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
     * @param entry the notification to change bubble state for.
     * @param entry the notification to change bubble state for.
     * @param shouldBubble whether the notification should show as a bubble or not.
     * @param shouldBubble whether the notification should show as a bubble or not.
     */
     */
    public void onUserChangedBubble(@Nullable final NotificationEntry entry, boolean shouldBubble) {
    public void onUserChangedBubble(NotificationEntry entry, boolean shouldBubble) {
        if (entry == null) {
            return;
        }
        NotificationChannel channel = entry.getChannel();
        NotificationChannel channel = entry.getChannel();
        final String appPkg = entry.getSbn().getPackageName();
        final String appPkg = entry.getSbn().getPackageName();
        final int appUid = entry.getSbn().getUid();
        final int appUid = entry.getSbn().getUid();
@@ -939,14 +910,14 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
    }
    }


    /**
    /**
     * Removes the bubble with the given key.
     * Removes the bubble with the given NotificationEntry.
     * <p>
     * <p>
     * Must be called from the main thread.
     * Must be called from the main thread.
     */
     */
    @MainThread
    @MainThread
    void removeBubble(String key, int reason) {
    void removeBubble(NotificationEntry entry, int reason) {
        if (mBubbleData.hasAnyBubbleWithKey(key)) {
        if (mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
            mBubbleData.notificationEntryRemoved(key, reason);
            mBubbleData.notificationEntryRemoved(entry, reason);
        }
        }
    }
    }


@@ -962,7 +933,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                && canLaunchInActivityView(mContext, entry);
                && canLaunchInActivityView(mContext, entry);
        if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
        if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
            // It was previously a bubble but no longer a bubble -- lets remove it
            // It was previously a bubble but no longer a bubble -- lets remove it
            removeBubble(entry.getKey(), DISMISS_NO_LONGER_BUBBLE);
            removeBubble(entry, DISMISS_NO_LONGER_BUBBLE);
        } else if (shouldBubble) {
        } else if (shouldBubble) {
            updateBubble(entry);
            updateBubble(entry);
        }
        }
@@ -976,10 +947,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            // Remove any associated bubble children with the summary
            // Remove any associated bubble children with the summary
            final List<Bubble> bubbleChildren = mBubbleData.getBubblesInGroup(groupKey);
            final List<Bubble> bubbleChildren = mBubbleData.getBubblesInGroup(groupKey);
            for (int i = 0; i < bubbleChildren.size(); i++) {
            for (int i = 0; i < bubbleChildren.size(); i++) {
                removeBubble(bubbleChildren.get(i).getKey(), DISMISS_GROUP_CANCELLED);
                removeBubble(bubbleChildren.get(i).getEntry(), DISMISS_GROUP_CANCELLED);
            }
            }
        } else {
        } else {
            removeBubble(entry.getKey(), DISMISS_NOTIF_CANCEL);
            removeBubble(entry, DISMISS_NOTIF_CANCEL);
        }
        }
    }
    }


@@ -1001,8 +972,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
            rankingMap.getRanking(key, mTmpRanking);
            rankingMap.getRanking(key, mTmpRanking);
            boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
            boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
            if (isActiveBubble && !mTmpRanking.canBubble()) {
            if (isActiveBubble && !mTmpRanking.canBubble()) {
                mBubbleData.notificationEntryRemoved(entry.getKey(),
                mBubbleData.notificationEntryRemoved(entry, BubbleController.DISMISS_BLOCKED);
                        BubbleController.DISMISS_BLOCKED);
            } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
            } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
                entry.setFlagBubble(true);
                entry.setFlagBubble(true);
                onEntryUpdated(entry);
                onEntryUpdated(entry);
@@ -1012,16 +982,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi


    private void setIsBubble(Bubble b, boolean isBubble) {
    private void setIsBubble(Bubble b, boolean isBubble) {
        if (isBubble) {
        if (isBubble) {
            if (b.getEntry() != null) {
            b.getEntry().getSbn().getNotification().flags |= FLAG_BUBBLE;
            b.getEntry().getSbn().getNotification().flags |= FLAG_BUBBLE;
            }
            b.enable(FLAG_BUBBLE);
        } else {
        } else {
            if (b.getEntry() != null) {
            b.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
            b.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
        }
        }
            b.disable(FLAG_BUBBLE);
        }
        try {
        try {
            mBarService.onNotificationBubbleChanged(b.getKey(), isBubble, 0);
            mBarService.onNotificationBubbleChanged(b.getKey(), isBubble, 0);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -1068,21 +1032,18 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                        // The bubble is now gone & the notification is hidden from the shade, so
                        // The bubble is now gone & the notification is hidden from the shade, so
                        // time to actually remove it
                        // time to actually remove it
                        for (NotifCallback cb : mCallbacks) {
                        for (NotifCallback cb : mCallbacks) {
                            if (bubble.getEntry() != null) {
                            cb.removeNotification(bubble.getEntry(), REASON_CANCEL);
                            cb.removeNotification(bubble.getEntry(), REASON_CANCEL);
                        }
                        }
                        }
                    } else {
                    } else {
                        if (bubble.isBubble() && bubble.showInShade()) {
                        if (bubble.getEntry().isBubble() && bubble.showInShade()) {
                            setIsBubble(bubble, /* isBubble */ false);
                            setIsBubble(bubble, /* isBubble */ false);
                        }
                        }
                        if (bubble.getEntry() != null && bubble.getEntry().getRow() != null) {
                        if (bubble.getEntry().getRow() != null) {
                            bubble.getEntry().getRow().updateBubbleButton();
                            bubble.getEntry().getRow().updateBubbleButton();
                        }
                        }
                    }
                    }


                }
                }
                if (bubble.getEntry() != null) {
                final String groupKey = bubble.getEntry().getSbn().getGroupKey();
                final String groupKey = bubble.getEntry().getSbn().getGroupKey();
                if (mBubbleData.getBubblesInGroup(groupKey).isEmpty()) {
                if (mBubbleData.getBubblesInGroup(groupKey).isEmpty()) {
                    // Time to potentially remove the summary
                    // Time to potentially remove the summary
@@ -1091,7 +1052,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                    }
                    }
                }
                }
            }
            }
            }
            mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository);
            mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository);


            if (update.addedBubble != null) {
            if (update.addedBubble != null) {
@@ -1113,7 +1073,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi


            if (update.selectionChanged) {
            if (update.selectionChanged) {
                mStackView.setSelectedBubble(update.selectedBubble);
                mStackView.setSelectedBubble(update.selectedBubble);
                if (update.selectedBubble != null && update.selectedBubble.getEntry() != null) {
                if (update.selectedBubble != null) {
                    mNotificationGroupManager.updateSuppression(
                    mNotificationGroupManager.updateSuppression(
                            update.selectedBubble.getEntry());
                            update.selectedBubble.getEntry());
                }
                }
+8 −16
Original line number Original line Diff line number Diff line
@@ -23,7 +23,6 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME


import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toList;


import android.annotation.NonNull;
import android.app.Notification;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Context;
@@ -224,7 +223,7 @@ public class BubbleData {
                            false, /* showInShade */ true);
                            false, /* showInShade */ true);
                    setSelectedBubble(bubble);
                    setSelectedBubble(bubble);
                },
                },
                mContext, stack, factory, false /* skipInflation */);
                mContext, stack, factory);
        dispatchPendingChanges();
        dispatchPendingChanges();
    }
    }


@@ -279,8 +278,7 @@ public class BubbleData {
        }
        }
        mPendingBubbles.remove(bubble); // No longer pending once we're here
        mPendingBubbles.remove(bubble); // No longer pending once we're here
        Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey());
        Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey());
        suppressFlyout |= bubble.getEntry() == null
        suppressFlyout |= !bubble.getEntry().getRanking().visuallyInterruptive();
                || !bubble.getEntry().getRanking().visuallyInterruptive();


        if (prevBubble == null) {
        if (prevBubble == null) {
            // Create a new bubble
            // Create a new bubble
@@ -309,14 +307,11 @@ public class BubbleData {
        dispatchPendingChanges();
        dispatchPendingChanges();
    }
    }


    /**
    public void notificationEntryRemoved(NotificationEntry entry, @DismissReason int reason) {
     * Called when a notification associated with a bubble is removed.
     */
    public void notificationEntryRemoved(String key, @DismissReason int reason) {
        if (DEBUG_BUBBLE_DATA) {
        if (DEBUG_BUBBLE_DATA) {
            Log.d(TAG, "notificationEntryRemoved: key=" + key + " reason=" + reason);
            Log.d(TAG, "notificationEntryRemoved: entry=" + entry + " reason=" + reason);
        }
        }
        doRemove(key, reason);
        doRemove(entry.getKey(), reason);
        dispatchPendingChanges();
        dispatchPendingChanges();
    }
    }


@@ -364,7 +359,7 @@ public class BubbleData {
            return bubbleChildren;
            return bubbleChildren;
        }
        }
        for (Bubble b : mBubbles) {
        for (Bubble b : mBubbles) {
            if (b.getEntry() != null && groupKey.equals(b.getEntry().getSbn().getGroupKey())) {
            if (groupKey.equals(b.getEntry().getSbn().getGroupKey())) {
                bubbleChildren.add(b);
                bubbleChildren.add(b);
            }
            }
        }
        }
@@ -475,10 +470,8 @@ public class BubbleData {
            Bubble newSelected = mBubbles.get(newIndex);
            Bubble newSelected = mBubbles.get(newIndex);
            setSelectedBubbleInternal(newSelected);
            setSelectedBubbleInternal(newSelected);
        }
        }
        if (bubbleToRemove.getEntry() != null) {
        maybeSendDeleteIntent(reason, bubbleToRemove.getEntry());
        maybeSendDeleteIntent(reason, bubbleToRemove.getEntry());
    }
    }
    }


    void overflowBubble(@DismissReason int reason, Bubble bubble) {
    void overflowBubble(@DismissReason int reason, Bubble bubble) {
        if (bubble.getPendingIntentCanceled()
        if (bubble.getPendingIntentCanceled()
@@ -751,8 +744,7 @@ public class BubbleData {
        return true;
        return true;
    }
    }


    private void maybeSendDeleteIntent(@DismissReason int reason,
    private void maybeSendDeleteIntent(@DismissReason int reason, NotificationEntry entry) {
            @NonNull final NotificationEntry entry) {
        if (reason == BubbleController.DISMISS_USER_GESTURE) {
        if (reason == BubbleController.DISMISS_USER_GESTURE) {
            Notification.BubbleMetadata bubbleMetadata = entry.getBubbleMetadata();
            Notification.BubbleMetadata bubbleMetadata = entry.getBubbleMetadata();
            PendingIntent deleteIntent = bubbleMetadata != null
            PendingIntent deleteIntent = bubbleMetadata != null
+2 −4
Original line number Original line Diff line number Diff line
@@ -74,10 +74,7 @@ internal class BubbleDataRepository @Inject constructor(


    private fun transform(userId: Int, bubbles: List<Bubble>): List<BubbleEntity> {
    private fun transform(userId: Int, bubbles: List<Bubble>): List<BubbleEntity> {
        return bubbles.mapNotNull { b ->
        return bubbles.mapNotNull { b ->
            var shortcutId = b.shortcutInfo?.id
            val shortcutId = b.shortcutInfo?.id ?: return@mapNotNull null
            if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId
            if (shortcutId == null) shortcutId = b.entry?.ranking?.shortcutInfo?.id
            if (shortcutId == null) return@mapNotNull null
            BubbleEntity(userId, b.packageName, shortcutId)
            BubbleEntity(userId, b.packageName, shortcutId)
        }
        }
    }
    }
@@ -111,6 +108,7 @@ internal class BubbleDataRepository @Inject constructor(
    /**
    /**
     * Load bubbles from disk.
     * Load bubbles from disk.
     */
     */
    // TODO: call this method from BubbleController and update UI
    @SuppressLint("WrongConstant")
    @SuppressLint("WrongConstant")
    fun loadBubbles(cb: (List<Bubble>) -> Unit) = ioScope.launch {
    fun loadBubbles(cb: (List<Bubble>) -> Unit) = ioScope.launch {
        /**
        /**
+7 −2
Original line number Original line Diff line number Diff line
@@ -65,6 +65,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.recents.TriangleShape;
import com.android.systemui.recents.TriangleShape;
import com.android.systemui.statusbar.AlphaOptimizedButton;
import com.android.systemui.statusbar.AlphaOptimizedButton;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;


/**
/**
 * Container for the expanded bubble view, handles rendering the caret and settings icon.
 * Container for the expanded bubble view, handles rendering the caret and settings icon.
@@ -160,7 +161,7 @@ public class BubbleExpandedView extends LinearLayout {
                            // the bubble again so we'll just remove it.
                            // the bubble again so we'll just remove it.
                            Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
                            Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
                                    + ", " + e.getMessage() + "; removing bubble");
                                    + ", " + e.getMessage() + "; removing bubble");
                            mBubbleController.removeBubble(getBubbleKey(),
                            mBubbleController.removeBubble(getBubbleEntry(),
                                    BubbleController.DISMISS_INVALID_INTENT);
                                    BubbleController.DISMISS_INVALID_INTENT);
                        }
                        }
                    });
                    });
@@ -204,7 +205,7 @@ public class BubbleExpandedView extends LinearLayout {
            }
            }
            if (mBubble != null) {
            if (mBubble != null) {
                // Must post because this is called from a binder thread.
                // Must post because this is called from a binder thread.
                post(() -> mBubbleController.removeBubble(mBubble.getKey(),
                post(() -> mBubbleController.removeBubble(mBubble.getEntry(),
                        BubbleController.DISMISS_TASK_FINISHED));
                        BubbleController.DISMISS_TASK_FINISHED));
            }
            }
        }
        }
@@ -291,6 +292,10 @@ public class BubbleExpandedView extends LinearLayout {
        return mBubble != null ? mBubble.getKey() : "null";
        return mBubble != null ? mBubble.getKey() : "null";
    }
    }


    private NotificationEntry getBubbleEntry() {
        return mBubble != null ? mBubble.getEntry() : null;
    }

    void setManageClickListener(OnClickListener manageClickListener) {
    void setManageClickListener(OnClickListener manageClickListener) {
        findViewById(R.id.settings_button).setOnClickListener(manageClickListener);
        findViewById(R.id.settings_button).setOnClickListener(manageClickListener);
    }
    }
Loading