summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java71
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java4
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);
}