Merge "Enable 'real bubbles' and fix our tests"

This commit is contained in:
Mady Mellor
2019-01-14 17:28:11 +00:00
committed by Android (Google) Code Review
4 changed files with 88 additions and 36 deletions

View File

@@ -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);
}
}
@@ -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) {

View File

@@ -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);
@@ -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());

View File

@@ -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(

View File

@@ -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);
}