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 Original line Diff line number Diff line
@@ -86,6 +86,7 @@ import com.android.wm.shell.pip.PinnedStackListenerForwarder;
import java.io.FileDescriptor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
@@ -586,11 +587,15 @@ public class BubbleController {
            // There were no bubbles saved for this used.
            // There were no bubbles saved for this used.
            return;
            return;
        }
        }
        for (BubbleEntry e : mSysuiProxy.getShouldRestoredEntries(savedBubbleKeys)) {
        mSysuiProxy.getShouldRestoredEntries(savedBubbleKeys, (entries) -> {
            mMainExecutor.execute(() -> {
                for (BubbleEntry e : entries) {
                    if (canLaunchInActivityView(mContext, e)) {
                    if (canLaunchInActivityView(mContext, e)) {
                        updateBubble(e, true /* suppressFlyout */, false /* showInShade */);
                        updateBubble(e, true /* suppressFlyout */, false /* showInShade */);
                    }
                    }
                }
                }
            });
        });
        // Finally, remove the entries for this user now that bubbles are restored.
        // Finally, remove the entries for this user now that bubbles are restored.
        mSavedBubbleKeysPerUser.remove(mCurrentUserId);
        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) {
        if (mTmpRanking == null) {
            mTmpRanking = new NotificationListenerService.Ranking();
            mTmpRanking = new NotificationListenerService.Ranking();
        }
        }
        String[] orderedKeys = rankingMap.getOrderedKeys();
        String[] orderedKeys = rankingMap.getOrderedKeys();
        for (int i = 0; i < orderedKeys.length; i++) {
        for (int i = 0; i < orderedKeys.length; i++) {
            String key = orderedKeys[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);
            rankingMap.getRanking(key, mTmpRanking);
            boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
            boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
            if (isActiveBubble && !mTmpRanking.canBubble()) {
            if (isActiveBubble && !mTmpRanking.canBubble()) {
                // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason.
                // 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.
                // This means that the app or channel's ability to bubble has been revoked.
                mBubbleData.dismissBubbleWithKey(key, DISMISS_BLOCKED);
                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.
                // 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
                // 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
                // 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) {
    private void setIsBubble(@NonNull final Bubble b, final boolean isBubble) {
        Objects.requireNonNull(b);
        Objects.requireNonNull(b);
        b.setIsBubble(isBubble);
        b.setIsBubble(isBubble);
        final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(b.getKey());
        mSysuiProxy.getPendingOrActiveEntry(b.getKey(), (entry) -> {
            mMainExecutor.execute(() -> {
                if (entry != null) {
                if (entry != null) {
                    // Updating the entry to be a bubble will trigger our normal update flow
                    // Updating the entry to be a bubble will trigger our normal update flow
                    setIsBubble(entry, isBubble, b.shouldAutoExpand());
                    setIsBubble(entry, isBubble, b.shouldAutoExpand());
@@ -930,6 +939,8 @@ public class BubbleController {
                    inflateAndAdd(bubble, bubble.shouldAutoExpand() /* suppressFlyout */,
                    inflateAndAdd(bubble, bubble.shouldAutoExpand() /* suppressFlyout */,
                            !bubble.shouldAutoExpand() /* showInShade */);
                            !bubble.shouldAutoExpand() /* showInShade */);
                }
                }
            });
        });
    }
    }


    @SuppressWarnings("FieldCanBeLocal")
    @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) {
                        if (entry != null) {
                            final String groupKey = entry.getStatusBarNotification().getGroupKey();
                            final String groupKey = entry.getStatusBarNotification().getGroupKey();
                            if (getBubblesInGroup(groupKey).isEmpty()) {
                            if (getBubblesInGroup(groupKey).isEmpty()) {
@@ -1000,6 +1012,8 @@ public class BubbleController {
                                mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey());
                                mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey());
                            }
                            }
                        }
                        }
                    });
                });
            }
            }
            mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository);
            mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository);


@@ -1121,23 +1135,6 @@ public class BubbleController {
        mStackView.updateContentDescription();
        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
    @VisibleForTesting
    public BubbleStackView getStackView() {
    public BubbleStackView getStackView() {
        return mStackView;
        return mStackView;
@@ -1343,9 +1340,10 @@ public class BubbleController {
        }
        }


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


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


import androidx.annotation.IntDef;
import androidx.annotation.IntDef;
@@ -37,6 +38,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.BiConsumer;
@@ -182,8 +184,11 @@ public interface Bubbles {
     * permissions on the notification channel or the global setting.
     * permissions on the notification channel or the global setting.
     *
     *
     * @param rankingMap the updated ranking map from NotificationListenerService
     * @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
     * 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. */
    /** Callback to tell SysUi components execute some methods. */
    interface SysuiProxy {
    interface SysuiProxy {
        @Nullable
        void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback);
        BubbleEntry getPendingOrActiveEntry(String key);


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

                Consumer<List<BubbleEntry>> callback);
        boolean isNotificationShadeExpand();

        boolean shouldBubbleUp(String key);


        void setNotificationInterruption(String key);
        void setNotificationInterruption(String key);


+2 −1
Original line number Original line 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.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
import static com.android.internal.policy.DecorView.getNavigationBarRect;


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


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


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


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


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


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


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


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


    void onRankingUpdate(RankingMap rankingMap) {
    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);
    }
    }


    /**
    /**