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

Commit e5d0b517 authored by Winson Chung's avatar Winson Chung Committed by Automerger Merge Worker
Browse files

Merge "Remove some blocking calls in BubbleManager" into sc-dev am: 7a337fac

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13551670

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I21f7626cb4b9bfe2adf26e088a58b2a163684451
parents 45187d42 7a337fac
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);
    }

    /**