Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +44 −46 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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()); Loading @@ -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") Loading Loading @@ -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()) { Loading @@ -1000,6 +1012,8 @@ public class BubbleController { mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey()); mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey()); } } } } }); }); } } mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository); mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository); Loading Loading @@ -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; Loading Loading @@ -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); }); }); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +9 −8 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +26 −48 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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 Loading Loading @@ -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); } } /** /** Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +44 −46 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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()); Loading @@ -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") Loading Loading @@ -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()) { Loading @@ -1000,6 +1012,8 @@ public class BubbleController { mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey()); mSysuiProxy.notifyMaybeCancelSummary(bubble.getKey()); } } } } }); }); } } mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository); mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository); Loading Loading @@ -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; Loading Loading @@ -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); }); }); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +9 −8 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +26 −48 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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 Loading Loading @@ -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); } } /** /** Loading