diff options
4 files changed, 88 insertions, 36 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 9f3ff782211d..79ee4b85f887 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -22,12 +22,16 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static com.android.systemui.bubbles.BubbleMovementHelper.EDGE_OVERLAP; +import android.annotation.Nullable; +import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; +import android.os.RemoteException; +import android.os.ServiceManager; import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.Log; @@ -35,8 +39,6 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.widget.FrameLayout; -import androidx.annotation.Nullable; - import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -88,6 +90,8 @@ public class BubbleController { // Bubbles get added to the status bar view private final StatusBarWindowController mStatusBarWindowController; + private INotificationManager mNotificationManagerService; + // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); @@ -124,6 +128,13 @@ public class BubbleController { mStatusBarWindowController = statusBarWindowController; mNotificationEntryManager.addNotificationEntryListener(mEntryListener); + + try { + mNotificationManagerService = INotificationManager.Stub.asInterface( + ServiceManager.getServiceOrThrow(Context.NOTIFICATION_SERVICE)); + } catch (ServiceManager.ServiceNotFoundException e) { + e.printStackTrace(); + } } /** @@ -268,7 +279,7 @@ public class BubbleController { private final NotificationEntryListener mEntryListener = new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { - if (shouldAutoBubble(mContext, entry)) { + if (shouldAutoBubble(mContext, entry) || shouldBubble(entry)) { entry.setIsBubble(true); } } @@ -368,18 +379,37 @@ public class BubbleController { } /** + * Whether the notification has been developer configured to bubble and is allowed by the user. + */ + private boolean shouldBubble(NotificationEntry entry) { + StatusBarNotification n = entry.notification; + boolean canAppOverlay = false; + try { + canAppOverlay = mNotificationManagerService.areAppOverlaysAllowedForPackage( + n.getPackageName(), n.getUid()); + } catch (RemoteException e) { + Log.w(TAG, "Error calling NoMan to determine if app can overlay", e); + } + + boolean canChannelOverlay = mNotificationEntryManager.getNotificationData().getChannel( + entry.key).canOverlayApps(); + boolean hasOverlayIntent = n.getNotification().getAppOverlayIntent() != null; + return hasOverlayIntent && canChannelOverlay && canAppOverlay; + } + + /** * Whether the notification should bubble or not. */ - private static boolean shouldAutoBubble(Context context, NotificationEntry entry) { + private boolean shouldAutoBubble(Context context, NotificationEntry entry) { if (entry.isBubbleDismissed()) { return false; } + StatusBarNotification n = entry.notification; boolean autoBubbleMessages = shouldAutoBubbleMessages(context) || DEBUG_ENABLE_AUTO_BUBBLE; boolean autoBubbleOngoing = shouldAutoBubbleOngoing(context) || DEBUG_ENABLE_AUTO_BUBBLE; boolean autoBubbleAll = shouldAutoBubbleAll(context) || DEBUG_ENABLE_AUTO_BUBBLE; - StatusBarNotification n = entry.notification; boolean hasRemoteInput = false; if (n.getNotification().actions != null) { for (Notification.Action action : n.getNotification().actions) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 21d3652adca7..702a64131ca1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -74,7 +74,8 @@ public class BubbleControllerTest extends SysuiTestCase { private ExpandableNotificationRow mRow; private ExpandableNotificationRow mRow2; - private final NotificationData mNotificationData = new NotificationData(); + @Mock + private NotificationData mNotificationData; @Before public void setUp() throws Exception { @@ -93,6 +94,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Return non-null notification data from the NEM when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData); + when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel); mBubbleController = new TestableBubbleController(mContext, mStatusBarWindowController); @@ -103,11 +105,6 @@ public class BubbleControllerTest extends SysuiTestCase { } @Test - public void testIsBubble() { - assertTrue(mRow.getEntry().isBubble()); - } - - @Test public void testAddBubble() { mBubbleController.addBubble(mRow.getEntry()); assertTrue(mBubbleController.hasBubbles()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java index 529da8251c57..2b13f864b9a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java @@ -17,13 +17,16 @@ package com.android.systemui.statusbar; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; +import static android.app.NotificationManager.IMPORTANCE_HIGH; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.Instrumentation; import android.app.Notification; import android.app.NotificationChannel; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.test.InstrumentationRegistry; @@ -86,8 +89,7 @@ public class NotificationTestHelper { * @throws Exception */ public ExpandableNotificationRow createRow(String pkg, int uid) throws Exception { - return createRow(pkg, uid, false /* isGroupSummary */, null /* groupKey */, - false /* isBubble */); + return createRow(pkg, uid, false /* isGroupSummary */, null /* groupKey */); } /** @@ -98,8 +100,7 @@ public class NotificationTestHelper { * @throws Exception */ public ExpandableNotificationRow createRow(Notification notification) throws Exception { - return generateRow(notification, PKG, UID, 0 /* extraInflationFlags */, - false /* isBubble */); + return generateRow(notification, PKG, UID, 0 /* extraInflationFlags */); } /** @@ -112,8 +113,7 @@ public class NotificationTestHelper { */ public ExpandableNotificationRow createRow(@InflationFlag int extraInflationFlags) throws Exception { - return generateRow(createNotification(), PKG, UID, extraInflationFlags, - false /* isBubble */); + return generateRow(createNotification(), PKG, UID, extraInflationFlags); } /** @@ -134,20 +134,21 @@ public class NotificationTestHelper { return createGroup(2); } - /** - * Retursn an {@link ExpandableNotificationRow} that should be a bubble. - */ - public ExpandableNotificationRow createBubble() throws Exception { - return createRow(PKG, UID, false /* isGroupSummary */, null /* groupKey */, - true /* isBubble */); - } - private ExpandableNotificationRow createGroupSummary(String groupkey) throws Exception { - return createRow(PKG, UID, true /* isGroupSummary */, groupkey, false); + return createRow(PKG, UID, true /* isGroupSummary */, groupkey); } private ExpandableNotificationRow createGroupChild(String groupkey) throws Exception { - return createRow(PKG, UID, false /* isGroupSummary */, groupkey, false); + return createRow(PKG, UID, false /* isGroupSummary */, groupkey); + } + + /** + * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble. + */ + public ExpandableNotificationRow createBubble() throws Exception { + Notification n = createNotification(false /* isGroupSummary */, + null /* groupKey */, true /* isBubble */); + return generateRow(n, PKG, UID, 0 /* extraInflationFlags */, IMPORTANCE_HIGH); } /** @@ -157,7 +158,6 @@ public class NotificationTestHelper { * @param uid uid used for creating a {@link StatusBarNotification} * @param isGroupSummary whether the notification row is a group summary * @param groupKey the group key for the notification group used across notifications - * @param isBubble * @return a row with that's either a standalone notification or a group notification if the * groupKey is non-null * @throws Exception @@ -166,10 +166,10 @@ public class NotificationTestHelper { String pkg, int uid, boolean isGroupSummary, - @Nullable String groupKey, boolean isBubble) + @Nullable String groupKey) throws Exception { Notification notif = createNotification(isGroupSummary, groupKey); - return generateRow(notif, pkg, uid, 0 /* inflationFlags */, isBubble); + return generateRow(notif, pkg, uid, 0 /* inflationFlags */); } /** @@ -188,8 +188,20 @@ public class NotificationTestHelper { * @param groupKey the group key for the notification group used across notifications * @return a notification that is in the group specified or standalone if unspecified */ + private Notification createNotification(boolean isGroupSummary, @Nullable String groupKey) { + return createNotification(isGroupSummary, groupKey, false /* isBubble */); + } + + /** + * Creates a notification with the given parameters. + * + * @param isGroupSummary whether the notification is a group summary + * @param groupKey the group key for the notification group used across notifications + * @param isBubble whether this notification should bubble + * @return a notification that is in the group specified or standalone if unspecified + */ private Notification createNotification(boolean isGroupSummary, - @Nullable String groupKey) { + @Nullable String groupKey, boolean isBubble) { Notification publicVersion = new Notification.Builder(mContext).setSmallIcon( R.drawable.ic_person) .setCustomContentView(new RemoteViews(mContext.getPackageName(), @@ -207,6 +219,10 @@ public class NotificationTestHelper { if (!TextUtils.isEmpty(groupKey)) { notificationBuilder.setGroup(groupKey); } + if (isBubble) { + PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0); + notificationBuilder.setAppOverlayIntent(bubbleIntent); + } return notificationBuilder.build(); } @@ -214,7 +230,17 @@ public class NotificationTestHelper { Notification notification, String pkg, int uid, - @InflationFlag int extraInflationFlags, boolean isBubble) + @InflationFlag int extraInflationFlags) + throws Exception { + return generateRow(notification, pkg, uid, extraInflationFlags, IMPORTANCE_DEFAULT); + } + + private ExpandableNotificationRow generateRow( + Notification notification, + String pkg, + int uid, + @InflationFlag int extraInflationFlags, + int importance) throws Exception { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( mContext.LAYOUT_INFLATER_SERVICE); @@ -242,9 +268,8 @@ public class NotificationTestHelper { entry.setRow(row); entry.createIcons(mContext, sbn); entry.channel = new NotificationChannel( - notification.getChannelId(), notification.getChannelId(), IMPORTANCE_DEFAULT); + notification.getChannelId(), notification.getChannelId(), importance); entry.channel.setBlockableSystem(true); - entry.setIsBubble(isBubble); row.setEntry(entry); row.getNotificationInflater().addInflationFlags(extraInflationFlags); NotificationInflaterTest.runThenWaitForInflation( diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c68e0f98325e..2d977269207c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2313,8 +2313,8 @@ public class NotificationManagerService extends SystemService { @Override public boolean areAppOverlaysAllowedForPackage(String pkg, int uid) { - checkCallerIsSystemOrSameApp(pkg); - + enforceSystemOrSystemUIOrSamePackage("Caller not system or systemui or same package", + pkg); return mPreferencesHelper.areAppOverlaysAllowed(pkg, uid); } |