Merge "Bubbles Policy: remove phonecalls" into rvc-dev am: ef7b53424b

Change-Id: I183dc3c12d66273d2a28d76a7b1d2831c85cda97
This commit is contained in:
Mady Mellor
2020-03-24 20:23:24 +00:00
committed by Automerger Merge Worker
3 changed files with 3 additions and 244 deletions

View File

@@ -15,9 +15,7 @@
*/
package com.android.server.notification;
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
@@ -25,7 +23,6 @@ import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR
import android.app.ActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -34,8 +31,6 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import java.util.ArrayList;
/**
* Determines whether a bubble can be shown for this notification
*/
@@ -152,41 +147,13 @@ public class BubbleExtractor implements NotificationSignalExtractor {
return false;
}
// At this point the bubble must fulfill communication policy
// Communication always needs a person
ArrayList<Person> peopleList = notification.extras != null
? notification.extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST)
: null;
// Message style requires a person & it's not included in the list
boolean isMessageStyle = Notification.MessagingStyle.class.equals(
notification.getNotificationStyle());
if (!isMessageStyle && (peopleList == null || peopleList.isEmpty())) {
logBubbleError(r.getKey(), "Must have a person and be "
+ "Notification.MessageStyle or Notification.CATEGORY_CALL");
if (!isMessageStyle) {
logBubbleError(r.getKey(), "must be Notification.MessageStyle");
return false;
}
// Communication is a message or a call
boolean isCall = CATEGORY_CALL.equals(notification.category);
boolean hasForegroundService = (notification.flags & FLAG_FOREGROUND_SERVICE) != 0;
if (hasForegroundService && !isCall) {
logBubbleError(r.getKey(),
"foreground services must be Notification.CATEGORY_CALL to bubble");
return false;
}
if (isMessageStyle) {
return true;
} else if (isCall) {
if (hasForegroundService) {
return true;
}
logBubbleError(r.getKey(), "calls require foreground service");
return false;
}
logBubbleError(r.getKey(), "Must be "
+ "Notification.MessageStyle or Notification.CATEGORY_CALL");
return false;
return true;
}
/**

View File

@@ -243,7 +243,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FunctionalUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.TriPredicate;

View File

@@ -18,7 +18,6 @@ package com.android.server.notification;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.FLAG_AUTO_CANCEL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
@@ -5236,141 +5235,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nr.getSbn().getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_flag_phonecall() throws RemoteException {
// Bubbles are allowed!
setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Give it a person
Person person = new Person.Builder()
.setName("bubblebot")
.build();
// Make it a phone call
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.setCategory(CATEGORY_CALL)
.addPerson(person)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
"testFlagBubbleNotifs_flag_phonecall", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
// yes phone call, yes person, yes foreground service, yes bubble
assertTrue(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_phonecall_noForegroundService() throws RemoteException {
// Bubbles are allowed!
setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Give it a person
Person person = new Person.Builder()
.setName("bubblebot")
.build();
// Make it a phone call
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.setCategory(CATEGORY_CALL)
.addPerson(person)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
// yes phone call, yes person, NO foreground service, no bubble
assertFalse(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_phonecall_noPerson() throws RemoteException {
// Bubbles are allowed!
setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Make it a phone call
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.setCategory(CATEGORY_CALL)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
"testFlagBubbleNotifs_noFlag_phonecall_noPerson", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
// yes phone call, yes foreground service, BUT NO person, no bubble
assertFalse(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_phonecall_noCategory() throws RemoteException {
// Bubbles are allowed!
setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Give it a person
Person person = new Person.Builder()
.setName("bubblebot")
.build();
// No category
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.addPerson(person)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
"testFlagBubbleNotifs_noFlag_phonecall_noCategory", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
// yes person, yes foreground service, BUT NO call, no bubble
assertFalse(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_messaging_appNotAllowed() throws RemoteException {
// Bubbles are NOT allowed!
@@ -5431,77 +5295,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
nr.getSbn().getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_phonecall_notAllowed() throws RemoteException {
// Bubbles are not allowed!
setUpPrefsForBubbles(PKG, mUid, false /* global */, true /* app */, true /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Give it a person
Person person = new Person.Builder()
.setName("bubblebot")
.build();
// Make it a phone call
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.setCategory(CATEGORY_CALL)
.addPerson(person)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
"testFlagBubbleNotifs_noFlag_phonecall_notAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
sbn.getId(), sbn.getNotification(), sbn.getUserId());
waitForIdle();
// yes phone call, yes person, yes foreground service, but not allowed, no bubble
assertFalse(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testFlagBubbleNotifs_noFlag_phonecall_channelNotAllowed() throws RemoteException {
// Bubbles are allowed, but not on channel.
setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, false /* channel */);
// Give it bubble metadata
Notification.BubbleMetadata data = getBubbleMetadataBuilder().build();
// Give it a person
Person person = new Person.Builder()
.setName("bubblebot")
.build();
// Make it a phone call
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.setCategory(CATEGORY_CALL)
.addPerson(person)
.setContentTitle("foo")
.setBubbleMetadata(data)
.setSmallIcon(android.R.drawable.sym_def_app_icon);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
"testFlagBubbleNotifs_noFlag_phonecall_channelNotAllowed", mUid, 0,
nb.build(), new UserHandle(mUid), null, 0);
// Make sure it has foreground service
sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
waitForIdle();
// yes phone call, yes person, yes foreground service, but channel not allowed, no bubble
assertFalse(mService.getNotificationRecord(
sbn.getKey()).getNotification().isBubbleNotification());
}
@Test
public void testCancelNotificationsFromApp_cancelsBubbles() throws Exception {
final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);