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

This commit is contained in:
Winson Chung
2021-02-12 01:26:33 +00:00
committed by Android (Google) Code Review
4 changed files with 81 additions and 103 deletions

View File

@@ -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)) {
if (canLaunchInActivityView(mContext, e)) {
updateBubble(e, true /* suppressFlyout */, false /* showInShade */);
}
}
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,17 +927,20 @@ 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());
if (entry != null) {
// Updating the entry to be a bubble will trigger our normal update flow
setIsBubble(entry, isBubble, b.shouldAutoExpand());
} else if (isBubble) {
// If bubble doesn't exist, it's a persisted bubble so we need to add it to the
// stack ourselves
Bubble bubble = mBubbleData.getOrCreateBubble(null, b /* persistedBubble */);
inflateAndAdd(bubble, bubble.shouldAutoExpand() /* suppressFlyout */,
!bubble.shouldAutoExpand() /* showInShade */);
}
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());
} else if (isBubble) {
// If bubble doesn't exist, it's a persisted bubble so we need to add it to the
// stack ourselves
Bubble bubble = mBubbleData.getOrCreateBubble(null, b /* persistedBubble */);
inflateAndAdd(bubble, bubble.shouldAutoExpand() /* suppressFlyout */,
!bubble.shouldAutoExpand() /* showInShade */);
}
});
});
}
@SuppressWarnings("FieldCanBeLocal")
@@ -992,14 +1003,17 @@ public class BubbleController {
}
}
final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(bubble.getKey());
if (entry != null) {
final String groupKey = entry.getStatusBarNotification().getGroupKey();
if (getBubblesInGroup(groupKey).isEmpty()) {
// Time to potentially remove the summary
mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey());
}
}
mSysuiProxy.getPendingOrActiveEntry(bubble.getKey(), (entry) -> {
mMainExecutor.execute(() -> {
if (entry != null) {
final String groupKey = entry.getStatusBarNotification().getGroupKey();
if (getBubblesInGroup(groupKey).isEmpty()) {
// Time to potentially remove the summary
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);
});
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
/**