Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +35 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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(); } } /** Loading Loading @@ -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); } } Loading Loading @@ -367,19 +378,38 @@ public class BubbleController { return new Point(EDGE_OVERLAP, size); } /** * 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) { Loading packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +3 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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); Loading @@ -102,11 +104,6 @@ public class BubbleControllerTest extends SysuiTestCase { mEntryListener = mEntryListenerCaptor.getValue(); } @Test public void testIsBubble() { assertTrue(mRow.getEntry().isBubble()); } @Test public void testAddBubble() { mBubbleController.addBubble(mRow.getEntry()); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +48 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */); } /** Loading @@ -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 */); } /** Loading @@ -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); } /** Loading @@ -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); } /** Loading @@ -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 Loading @@ -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 */); } /** Loading @@ -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(), Loading @@ -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(); } Loading @@ -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); Loading Loading @@ -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( Loading services/core/java/com/android/server/notification/NotificationManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -2317,8 +2317,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); } Loading Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +35 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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(); } } /** Loading Loading @@ -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); } } Loading Loading @@ -367,19 +378,38 @@ public class BubbleController { return new Point(EDGE_OVERLAP, size); } /** * 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) { Loading
packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +3 −6 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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); Loading @@ -102,11 +104,6 @@ public class BubbleControllerTest extends SysuiTestCase { mEntryListener = mEntryListenerCaptor.getValue(); } @Test public void testIsBubble() { assertTrue(mRow.getEntry().isBubble()); } @Test public void testAddBubble() { mBubbleController.addBubble(mRow.getEntry()); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +48 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 */); } /** Loading @@ -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 */); } /** Loading @@ -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); } /** Loading @@ -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); } /** Loading @@ -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 Loading @@ -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 */); } /** Loading @@ -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(), Loading @@ -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(); } Loading @@ -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); Loading Loading @@ -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( Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -2317,8 +2317,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); } Loading