Let NoMan know when something is no longer a bubble

This is needed for some of the notification group summary stuff to work.

More importantly, this is needed so that we can properly report to apps
if their notification is bubbled or not, e.g. if the user dismisses the
bubble & the notification is in the shade, that shouldn't be reported as
'FLAG_BUBBLE' as that notification is not actually being shown as a bubble.

* Adds onBubbleNotificationChanged to NotificationDelegate to pipe through
  changes in bubble state, currently we only ever change it to 'false' but
  this CL includes ability to flip it to 'true' (and also checks if the
  notif should actually be able to bubble)
* Factors code that indicates something is approved to bubble into own
  method
* Adds way to set BubbleMetadata on a notification (hidden !!)

Bug: 130250809
Test: atest NotificationManagerServiceTest
Change-Id: I8df4cc1231ed5d078ce4d50a70d2631f82fd2306
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 744f88d..ef383ad 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -32,7 +32,6 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
-import android.app.INotificationManager;
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
@@ -52,6 +51,7 @@
 import androidx.annotation.MainThread;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -131,8 +131,7 @@
     private StatusBarStateListener mStatusBarStateListener;
 
     private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
-
-    private INotificationManager mNotificationManagerService;
+    private IStatusBarService mBarService;
 
     // Used for determining view rect for touch interaction
     private Rect mTempRect = new Rect();
@@ -207,13 +206,6 @@
         mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
         mNotificationEntryManager.addNotificationEntryListener(mEntryListener);
 
-        try {
-            mNotificationManagerService = INotificationManager.Stub.asInterface(
-                    ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE));
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            e.printStackTrace();
-        }
-
         mStatusBarWindowController = statusBarWindowController;
         mStatusBarStateListener = new StatusBarStateListener();
         Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
@@ -231,6 +223,9 @@
         mBubbleData = data;
         mBubbleData.setListener(mBubbleDataListener);
         mSurfaceSynchronizer = synchronizer;
+
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
     }
 
     /**
@@ -462,6 +457,18 @@
             if (mStackView != null) {
                 mStackView.removeBubble(bubble);
             }
+            if (!bubble.entry.showInShadeWhenBubble()) {
+                // The notification is gone & bubble is gone, time to actually remove it
+                mNotificationEntryManager.performRemoveNotification(bubble.entry.notification);
+            } else {
+                // The notification is still in the shade but we've removed the bubble so
+                // lets make sure NoMan knows it's not a bubble anymore
+                try {
+                    mBarService.onNotificationBubbleChanged(bubble.getKey(), false /* isBubble */);
+                } catch (RemoteException e) {
+                    // Bad things have happened
+                }
+            }
         }
 
         public void onBubbleUpdated(Bubble bubble) {