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

Commit 7a337fac authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Remove some blocking calls in BubbleManager" into sc-dev

parents f53b7111 6d4d8ed1
Loading
Loading
Loading
Loading
+44 −46
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -586,11 +587,15 @@ public class BubbleController {
            // There were no bubbles saved for this used.
            return;
        }
        for (BubbleEntry e : mSysuiProxy.getShouldRestoredEntries(savedBubbleKeys)) {
        mSysuiProxy.getShouldRestoredEntries(savedBubbleKeys, (entries) -> {
            mMainExecutor.execute(() -> {
                for (BubbleEntry e : entries) {
                    if (canLaunchInActivityView(mContext, e)) {
                        updateBubble(e, true /* suppressFlyout */, false /* showInShade */);
                    }
                }
            });
        });
        // Finally, remove the entries for this user now that bubbles are restored.
        mSavedBubbleKeysPerUser.remove(mCurrentUserId);
    }
@@ -856,21 +861,24 @@ public class BubbleController {
        }
    }

    private void onRankingUpdated(RankingMap rankingMap) {
    private void onRankingUpdated(RankingMap rankingMap,
            HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey) {
        if (mTmpRanking == null) {
            mTmpRanking = new NotificationListenerService.Ranking();
        }
        String[] orderedKeys = rankingMap.getOrderedKeys();
        for (int i = 0; i < orderedKeys.length; i++) {
            String key = orderedKeys[i];
            BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(key);
            Pair<BubbleEntry, Boolean> entryData = entryDataByKey.get(key);
            BubbleEntry entry = entryData.first;
            boolean shouldBubbleUp = entryData.second;
            rankingMap.getRanking(key, mTmpRanking);
            boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
            if (isActiveBubble && !mTmpRanking.canBubble()) {
                // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason.
                // This means that the app or channel's ability to bubble has been revoked.
                mBubbleData.dismissBubbleWithKey(key, DISMISS_BLOCKED);
            } else if (isActiveBubble && !mSysuiProxy.shouldBubbleUp(key)) {
            } else if (isActiveBubble && !shouldBubbleUp) {
                // If this entry is allowed to bubble, but cannot currently bubble up, dismiss it.
                // This happens when DND is enabled and configured to hide bubbles. Dismissing with
                // the reason DISMISS_NO_BUBBLE_UP will retain the underlying notification, so that
@@ -919,7 +927,8 @@ public class BubbleController {
    private void setIsBubble(@NonNull final Bubble b, final boolean isBubble) {
        Objects.requireNonNull(b);
        b.setIsBubble(isBubble);
        final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(b.getKey());
        mSysuiProxy.getPendingOrActiveEntry(b.getKey(), (entry) -> {
            mMainExecutor.execute(() -> {
                if (entry != null) {
                    // Updating the entry to be a bubble will trigger our normal update flow
                    setIsBubble(entry, isBubble, b.shouldAutoExpand());
@@ -930,6 +939,8 @@ public class BubbleController {
                    inflateAndAdd(bubble, bubble.shouldAutoExpand() /* suppressFlyout */,
                            !bubble.shouldAutoExpand() /* showInShade */);
                }
            });
        });
    }

    @SuppressWarnings("FieldCanBeLocal")
@@ -992,7 +1003,8 @@ public class BubbleController {
                    }

                }
                final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(bubble.getKey());
                mSysuiProxy.getPendingOrActiveEntry(bubble.getKey(), (entry) -> {
                    mMainExecutor.execute(() -> {
                        if (entry != null) {
                            final String groupKey = entry.getStatusBarNotification().getGroupKey();
                            if (getBubblesInGroup(groupKey).isEmpty()) {
@@ -1000,6 +1012,8 @@ public class BubbleController {
                                mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey());
                            }
                        }
                    });
                });
            }
            mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository);

@@ -1121,23 +1135,6 @@ public class BubbleController {
        mStackView.updateContentDescription();
    }

    /**
     * The task id of the expanded view, if the stack is expanded and not occluded by the
     * status bar, otherwise returns {@link ActivityTaskManager#INVALID_TASK_ID}.
     */
    private int getExpandedTaskId() {
        if (mStackView == null) {
            return INVALID_TASK_ID;
        }
        final BubbleViewProvider expandedViewProvider = mStackView.getExpandedBubble();
        if (expandedViewProvider != null && isStackExpanded()
                && !mStackView.isExpansionAnimating()
                && !mSysuiProxy.isNotificationShadeExpand()) {
            return expandedViewProvider.getTaskId();
        }
        return INVALID_TASK_ID;
    }

    @VisibleForTesting
    public BubbleStackView getStackView() {
        return mStackView;
@@ -1343,9 +1340,10 @@ public class BubbleController {
        }

        @Override
        public void onRankingUpdated(RankingMap rankingMap) {
        public void onRankingUpdated(RankingMap rankingMap,
                HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey) {
            mMainExecutor.execute(() -> {
                BubbleController.this.onRankingUpdated(rankingMap);
                BubbleController.this.onRankingUpdated(rankingMap, entryDataByKey);
            });
        }

+9 −8
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Bundle;
import android.os.Looper;
import android.service.notification.NotificationListenerService.RankingMap;
import android.util.ArraySet;
import android.util.Pair;
import android.view.View;

import androidx.annotation.IntDef;
@@ -37,6 +38,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
@@ -182,8 +184,11 @@ public interface Bubbles {
     * permissions on the notification channel or the global setting.
     *
     * @param rankingMap the updated ranking map from NotificationListenerService
     * @param entryDataByKey a map of ranking key to bubble entry and whether the entry should
     *                       bubble up
     */
    void onRankingUpdated(RankingMap rankingMap);
    void onRankingUpdated(RankingMap rankingMap,
            HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey);

    /**
     * Called when the status bar has become visible or invisible (either permanently or
@@ -243,14 +248,10 @@ public interface Bubbles {

    /** Callback to tell SysUi components execute some methods. */
    interface SysuiProxy {
        @Nullable
        BubbleEntry getPendingOrActiveEntry(String key);
        void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback);

        List<BubbleEntry> getShouldRestoredEntries(ArraySet<String> savedBubbleKeys);

        boolean isNotificationShadeExpand();

        boolean shouldBubbleUp(String key);
        void getShouldRestoredEntries(ArraySet<String> savedBubbleKeys,
                Consumer<List<BubbleEntry>> callback);

        void setNotificationInterruption(String key);

+2 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_AT
import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.getNavigationBarRect;

import android.annotation.BinderThread;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
@@ -498,7 +499,7 @@ public class TaskSnapshotWindow {
        }
    }

    @ExternalThread
    @BinderThread
    static class Window extends BaseIWindow {
        private TaskSnapshotWindow mOuter;

+26 −48
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.ZenModeConfig;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import android.view.View;

import androidx.annotation.NonNull;
@@ -86,10 +87,12 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.function.Supplier;

@@ -248,38 +251,19 @@ public class BubblesManager implements Dumpable {
                });

        mSysuiProxy = new Bubbles.SysuiProxy() {
            private <T> T executeBlockingForResult(Supplier<T> runnable, Executor executor,
                    Class clazz) {
                if (Looper.myLooper() == Looper.getMainLooper()) {
                    return runnable.get();
                }
                final T[] result = (T[]) Array.newInstance(clazz, 1);
                final CountDownLatch latch = new CountDownLatch(1);
                executor.execute(() -> {
                    result[0] = runnable.get();
                    latch.countDown();
                });
                try {
                    latch.await();
                    return result[0];
                } catch (InterruptedException e) {
                    return null;
                }
            }

            @Override
            @Nullable
            public BubbleEntry getPendingOrActiveEntry(String key) {
                return executeBlockingForResult(() -> {
            public void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback) {
                sysuiMainExecutor.execute(() -> {
                    NotificationEntry entry =
                            mNotificationEntryManager.getPendingOrActiveNotif(key);
                    return entry == null ? null : notifToBubbleEntry(entry);
                }, sysuiMainExecutor, BubbleEntry.class);
                    callback.accept(entry == null ? null : notifToBubbleEntry(entry));
                });
            }

            @Override
            public List<BubbleEntry> getShouldRestoredEntries(ArraySet<String> savedBubbleKeys) {
                return executeBlockingForResult(() -> {
            public void getShouldRestoredEntries(ArraySet<String> savedBubbleKeys,
                    Consumer<List<BubbleEntry>> callback) {
                sysuiMainExecutor.execute(() -> {
                    List<BubbleEntry> result = new ArrayList<>();
                    List<NotificationEntry> activeEntries =
                            mNotificationEntryManager.getActiveNotificationsForCurrentUser();
@@ -291,27 +275,8 @@ public class BubblesManager implements Dumpable {
                            result.add(notifToBubbleEntry(entry));
                        }
                    }
                    return result;
                }, sysuiMainExecutor, List.class);
            }

            @Override
            public boolean isNotificationShadeExpand() {
                return executeBlockingForResult(() -> {
                    return mNotificationShadeWindowController.getPanelExpanded();
                }, sysuiMainExecutor, Boolean.class);
            }

            @Override
            public boolean shouldBubbleUp(String key) {
                return executeBlockingForResult(() -> {
                    final NotificationEntry entry =
                            mNotificationEntryManager.getPendingOrActiveNotif(key);
                    if (entry != null) {
                        return mNotificationInterruptStateProvider.shouldBubbleUp(entry);
                    }
                    return false;
                }, sysuiMainExecutor, Boolean.class);
                    callback.accept(result);
                });
            }

            @Override
@@ -587,7 +552,20 @@ public class BubblesManager implements Dumpable {
    }

    void onRankingUpdate(RankingMap rankingMap) {
        mBubbles.onRankingUpdated(rankingMap);
        String[] orderedKeys = rankingMap.getOrderedKeys();
        HashMap<String, Pair<BubbleEntry, Boolean>> pendingOrActiveNotif = new HashMap<>();
        for (int i = 0; i < orderedKeys.length; i++) {
            String key = orderedKeys[i];
            NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(key);
            BubbleEntry bubbleEntry = entry != null
                    ? notifToBubbleEntry(entry)
                    : null;
            boolean shouldBubbleUp = entry != null
                    ? mNotificationInterruptStateProvider.shouldBubbleUp(entry)
                    : false;
            pendingOrActiveNotif.put(key, new Pair<>(bubbleEntry, shouldBubbleUp));
        }
        mBubbles.onRankingUpdated(rankingMap, pendingOrActiveNotif);
    }

    /**