Merge "Remove onBeforeNotificationAdded call"

This commit is contained in:
Beverly Tai
2019-10-25 13:16:54 +00:00
committed by Android (Google) Code Review
12 changed files with 214 additions and 285 deletions

View File

@@ -21,10 +21,13 @@ import android.util.ArraySet;
import android.util.SparseArray;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Tracks state of foreground services and notifications related to foreground services per user.
*/
@@ -33,9 +36,11 @@ public class ForegroundServiceController {
private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
private final Object mMutex = new Object();
private final NotificationEntryManager mEntryManager;
@Inject
public ForegroundServiceController() {
public ForegroundServiceController(NotificationEntryManager entryManager) {
mEntryManager = entryManager;
}
/**
@@ -90,11 +95,18 @@ public class ForegroundServiceController {
}
/**
* Records active app ops. App Ops are stored in FSC in addition to NotificationData in
* case they change before we have a notification to tag.
* Records active app ops and updates the app op for the pending or visible notifications
* with the given parameters.
* App Ops are stored in FSC in addition to NotificationEntry in case they change before we
* have a notification to tag.
* @param appOpCode code for appOp to add/remove
* @param uid of user the notification is sent to
* @param packageName package that created the notification
* @param active whether the appOpCode is active or not
*/
public void onAppOpChanged(int code, int uid, String packageName, boolean active) {
public void onAppOpChanged(int appOpCode, int uid, String packageName, boolean active) {
int userId = UserHandle.getUserId(uid);
// Record active app ops
synchronized (mMutex) {
ForegroundServicesUserState userServices = mUserServices.get(userId);
if (userServices == null) {
@@ -102,9 +114,30 @@ public class ForegroundServiceController {
mUserServices.put(userId, userServices);
}
if (active) {
userServices.addOp(packageName, code);
userServices.addOp(packageName, appOpCode);
} else {
userServices.removeOp(packageName, code);
userServices.removeOp(packageName, appOpCode);
}
}
// Update appOp if there's an associated pending or visible notification:
final String foregroundKey = getStandardLayoutKey(userId, packageName);
if (foregroundKey != null) {
final NotificationEntry entry = mEntryManager.getPendingOrCurrentNotif(foregroundKey);
if (entry != null
&& uid == entry.getSbn().getUid()
&& packageName.equals(entry.getSbn().getPackageName())) {
boolean changed;
synchronized (entry.mActiveAppOps) {
if (active) {
changed = entry.mActiveAppOps.add(appOpCode);
} else {
changed = entry.mActiveAppOps.remove(appOpCode);
}
}
if (changed) {
mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
}
}
}
}

View File

@@ -21,6 +21,7 @@ import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.Log;
import com.android.internal.statusbar.NotificationVisibility;
@@ -40,6 +41,7 @@ public class ForegroundServiceNotificationListener {
private final Context mContext;
private final ForegroundServiceController mForegroundServiceController;
private final NotificationEntryManager mEntryManager;
@Inject
public ForegroundServiceNotificationListener(Context context,
@@ -47,15 +49,16 @@ public class ForegroundServiceNotificationListener {
NotificationEntryManager notificationEntryManager) {
mContext = context;
mForegroundServiceController = foregroundServiceController;
notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
mEntryManager = notificationEntryManager;
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
addNotification(entry.getSbn(), entry.getImportance());
addNotification(entry, entry.getImportance());
}
@Override
public void onPostEntryUpdated(NotificationEntry entry) {
updateNotification(entry.getSbn(), entry.getImportance());
public void onPreEntryUpdated(NotificationEntry entry) {
updateNotification(entry, entry.getImportance());
}
@Override
@@ -67,15 +70,14 @@ public class ForegroundServiceNotificationListener {
}
});
notificationEntryManager.addNotificationLifetimeExtender(
new ForegroundServiceLifetimeExtender());
mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender());
}
/**
* @param sbn notification that was just posted
* @param entry notification that was just posted
*/
private void addNotification(StatusBarNotification sbn, int importance) {
updateNotification(sbn, importance);
private void addNotification(NotificationEntry entry, int importance) {
updateNotification(entry, importance);
}
/**
@@ -113,9 +115,10 @@ public class ForegroundServiceNotificationListener {
}
/**
* @param sbn notification that was just changed in some way
* @param entry notification that was just changed in some way
*/
private void updateNotification(StatusBarNotification sbn, int newImportance) {
private void updateNotification(NotificationEntry entry, int newImportance) {
final StatusBarNotification sbn = entry.getSbn();
mForegroundServiceController.updateUserState(
sbn.getUserId(),
userState -> {
@@ -143,8 +146,22 @@ public class ForegroundServiceNotificationListener {
}
}
}
tagForeground(entry);
return true;
},
true /* create if not found */);
}
private void tagForeground(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
sbn.getUserId(),
sbn.getPackageName());
if (activeOps != null) {
synchronized (entry.mActiveAppOps) {
entry.mActiveAppOps.clear();
entry.mActiveAppOps.addAll(activeOps);
}
}
}
}

View File

@@ -20,12 +20,12 @@ import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import androidx.annotation.NonNull;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
import androidx.annotation.NonNull;
/**
* Listener interface for changes sent by NotificationEntryManager.
*/
@@ -37,13 +37,6 @@ public interface NotificationEntryListener {
default void onPendingEntryAdded(NotificationEntry entry) {
}
// TODO: Combine this with onPreEntryUpdated into "onBeforeEntryFiltered" or similar
/**
* Called when a new entry is created but before it has been filtered or displayed to the user.
*/
default void onBeforeNotificationAdded(NotificationEntry entry) {
}
/**
* Called when a new entry is created.
*/

View File

@@ -262,9 +262,6 @@ public class NotificationEntryManager implements
listener.onEntryInflated(entry, inflatedFlags);
}
mNotificationData.add(entry);
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onBeforeNotificationAdded(entry);
}
updateNotifications("onAsyncInflationFinished");
for (NotificationEntryListener listener : mNotificationEntryListeners) {
listener.onNotificationAdded(entry);
@@ -563,6 +560,18 @@ public class NotificationEntryManager implements
return mPendingNotifications.values();
}
/**
* Gets the pending or visible notification entry with the given key. Returns null if
* notification doesn't exist.
*/
public NotificationEntry getPendingOrCurrentNotif(String key) {
if (mPendingNotifications.containsKey(key)) {
return mPendingNotifications.get(key);
} else {
return mNotificationData.get(key);
}
}
private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) {
NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry);
if (activeExtender != null && activeExtender != extender) {

View File

@@ -18,10 +18,6 @@ package com.android.systemui.statusbar.notification;
import static com.android.internal.util.Preconditions.checkNotNull;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -70,11 +66,6 @@ public class NotificationListController {
boolean removedByUser) {
mListContainer.cleanUpViewStateForEntry(entry);
}
@Override
public void onBeforeNotificationAdded(NotificationEntry entry) {
tagForeground(entry.getSbn());
}
};
private final DeviceProvisionedListener mDeviceProvisionedListener =
@@ -84,29 +75,4 @@ public class NotificationListController {
mEntryManager.updateNotifications("device provisioned changed");
}
};
// TODO: This method is horrifically inefficient
private void tagForeground(StatusBarNotification notification) {
ArraySet<Integer> activeOps =
mForegroundServiceController.getAppOps(
notification.getUserId(), notification.getPackageName());
if (activeOps != null) {
int len = activeOps.size();
for (int i = 0; i < len; i++) {
updateNotificationsForAppOp(activeOps.valueAt(i), notification.getUid(),
notification.getPackageName(), true);
}
}
}
/** When an app op changes, propagate that change to notifications. */
public void updateNotificationsForAppOp(int appOp, int uid, String pkg, boolean showIcon) {
String foregroundKey =
mForegroundServiceController.getStandardLayoutKey(UserHandle.getUserId(uid), pkg);
if (foregroundKey != null) {
mEntryManager
.getNotificationData().updateAppOp(appOp, uid, pkg, foregroundKey, showIcon);
mEntryManager.updateNotifications("app opp changed pkg=" + pkg);
}
}
}

View File

@@ -225,24 +225,6 @@ public class NotificationData {
updateRankingAndSort(ranking, reason);
}
public void updateAppOp(int appOp, int uid, String pkg, String key, boolean showIcon) {
synchronized (mEntries) {
final int len = mEntries.size();
for (int i = 0; i < len; i++) {
NotificationEntry entry = mEntries.valueAt(i);
if (uid == entry.getSbn().getUid()
&& pkg.equals(entry.getSbn().getPackageName())
&& key.equals(entry.getKey())) {
if (showIcon) {
entry.mActiveAppOps.add(appOp);
} else {
entry.mActiveAppOps.remove(appOp);
}
}
}
}
}
/**
* Returns true if this notification should be displayed in the high-priority notifications
* section

View File

@@ -130,7 +130,7 @@ public final class NotificationEntry {
private Throwable mDebugThrowable;
public CharSequence remoteInputTextWhenReset;
public long lastRemoteInputSent = NOT_LAUNCHED_YET;
public ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
public final ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
public CharSequence headsUpStatusBarText;
public CharSequence headsUpStatusBarTextPublic;

View File

@@ -617,7 +617,6 @@ public class StatusBar extends SystemUI implements DemoMode,
public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
Dependency.get(MAIN_HANDLER).post(() -> {
mForegroundServiceController.onAppOpChanged(code, uid, packageName, active);
mNotificationListController.updateNotificationsForAppOp(code, uid, packageName, active);
});
}

View File

@@ -21,11 +21,15 @@ import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
@@ -42,6 +46,8 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,26 +56,103 @@ import org.mockito.ArgumentCaptor;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ForegroundServiceControllerTest extends SysuiTestCase {
@UserIdInt private static final int USERID_ONE = 10; // UserManagerService.MIN_USER_ID;
@UserIdInt private static final int USERID_TWO = USERID_ONE + 1;
private ForegroundServiceController mFsc;
private ForegroundServiceNotificationListener mListener;
private NotificationEntryListener mEntryListener;
private NotificationEntryManager mEntryManager;
@Before
public void setUp() throws Exception {
mFsc = new ForegroundServiceController();
NotificationEntryManager notificationEntryManager = mock(NotificationEntryManager.class);
mEntryManager = mock(NotificationEntryManager.class);
mFsc = new ForegroundServiceController(mEntryManager);
mListener = new ForegroundServiceNotificationListener(
mContext, mFsc, notificationEntryManager);
mContext, mFsc, mEntryManager);
ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
ArgumentCaptor.forClass(NotificationEntryListener.class);
verify(notificationEntryManager).addNotificationEntryListener(
verify(mEntryManager).addNotificationEntryListener(
entryListenerCaptor.capture());
mEntryListener = entryListenerCaptor.getValue();
}
@Test
public void testAppOps_appOpChangedBeforeNotificationExists() {
// GIVEN app op exists, but notification doesn't exist in NEM yet
NotificationEntry entry = createFgEntry();
mFsc.onAppOpChanged(
AppOpsManager.OP_CAMERA,
entry.getSbn().getUid(),
entry.getSbn().getPackageName(),
true);
assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
// WHEN the notification is added
mEntryListener.onPendingEntryAdded(entry);
// THEN the app op is added to the entry
Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
}
@Test
public void testAppOps_appOpAddedToForegroundNotif() {
// GIVEN a notification associated with a foreground service
NotificationEntry entry = addFgEntry();
when(mEntryManager.getPendingOrCurrentNotif(entry.getKey())).thenReturn(entry);
// WHEN we are notified of a new app op for this notification
mFsc.onAppOpChanged(
AppOpsManager.OP_CAMERA,
entry.getSbn().getUid(),
entry.getSbn().getPackageName(),
true);
// THEN the app op is added to the entry
Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
// THEN notification views are updated since the notification is visible
verify(mEntryManager, times(1)).updateNotifications(anyString());
}
@Test
public void testAppOpsAlreadyAdded() {
// GIVEN a foreground service associated notification that already has the correct app op
NotificationEntry entry = addFgEntry();
entry.mActiveAppOps.add(AppOpsManager.OP_CAMERA);
when(mEntryManager.getPendingOrCurrentNotif(entry.getKey())).thenReturn(entry);
// WHEN we are notified of the same app op for this notification
mFsc.onAppOpChanged(
AppOpsManager.OP_CAMERA,
entry.getSbn().getUid(),
entry.getSbn().getPackageName(),
true);
// THEN the app op still exists in the notification entry
Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
// THEN notification views aren't updated since nothing changed
verify(mEntryManager, never()).updateNotifications(anyString());
}
@Test
public void testAppOps_appOpNotAddedToUnrelatedNotif() {
// GIVEN no notification entries correspond to the newly updated appOp
NotificationEntry entry = addFgEntry();
when(mEntryManager.getPendingOrCurrentNotif(entry.getKey())).thenReturn(null);
// WHEN a new app op is detected
mFsc.onAppOpChanged(
AppOpsManager.OP_CAMERA,
entry.getSbn().getUid(),
entry.getSbn().getPackageName(),
true);
// THEN we won't see appOps on the entry
Assert.assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
// THEN notification views aren't updated since nothing changed
verify(mEntryManager, never()).updateNotifications(anyString());
}
@Test
public void testAppOpsCRUD() {
// no crash on remove that doesn't exist
@@ -339,12 +422,12 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
assertTrue(mFsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
}
private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
private StatusBarNotification makeMockSBN(int userId, String pkg, int id, String tag,
int flags) {
final Notification n = mock(Notification.class);
n.extras = new Bundle();
n.flags = flags;
return makeMockSBN(userid, pkg, id, tag, n);
return makeMockSBN(userId, pkg, id, tag, n);
}
private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
@@ -360,10 +443,10 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
return sbn;
}
private StatusBarNotification makeMockFgSBN(int userid, String pkg, int id,
private StatusBarNotification makeMockFgSBN(int uid, String pkg, int id,
boolean usesStdLayout) {
StatusBarNotification sbn =
makeMockSBN(userid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE);
makeMockSBN(uid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE);
if (usesStdLayout) {
sbn.getNotification().contentView = null;
sbn.getNotification().headsUpContentView = null;
@@ -374,8 +457,8 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
return sbn;
}
private StatusBarNotification makeMockFgSBN(int userid, String pkg) {
return makeMockSBN(userid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE);
private StatusBarNotification makeMockFgSBN(int uid, String pkg) {
return makeMockSBN(uid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE);
}
private StatusBarNotification makeMockDisclosure(int userid, String[] pkgs) {
@@ -392,6 +475,19 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
return sbn;
}
private NotificationEntry addFgEntry() {
NotificationEntry entry = createFgEntry();
mEntryListener.onPendingEntryAdded(entry);
return entry;
}
private NotificationEntry createFgEntry() {
return new NotificationEntryBuilder()
.setSbn(makeMockFgSBN(0, TEST_PACKAGE_NAME, 1000, true))
.setImportance(NotificationManager.IMPORTANCE_DEFAULT)
.build();
}
private void entryRemoved(StatusBarNotification notification) {
mEntryListener.onEntryRemoved(
new NotificationEntryBuilder()
@@ -414,6 +510,10 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
.setSbn(notification)
.setImportance(importance)
.build();
mEntryListener.onPostEntryUpdated(entry);
mEntryListener.onPreEntryUpdated(entry);
}
@UserIdInt private static final int USERID_ONE = 10; // UserManagerService.MIN_USER_ID;
@UserIdInt private static final int USERID_TWO = USERID_ONE + 1;
private static final String TEST_PACKAGE_NAME = "test";
}

View File

@@ -140,6 +140,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
@Mock private RowInflaterTask mAsyncInflationTask;
@Mock private NotificationRowBinder mMockedRowBinder;
private int mId;
private NotificationEntry mEntry;
private StatusBarNotification mSbn;
private TestableNotificationEntryManager mEntryManager;
@@ -243,18 +244,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
when(mListContainer.getViewParentForNotification(any())).thenReturn(
new FrameLayout(mContext));
Notification.Builder n = new Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
.setContentTitle("Title")
.setContentText("Text");
mEntry = new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME)
.setOpPkg(TEST_PACKAGE_NAME)
.setUid(TEST_UID)
.setNotification(n.build())
.setUser(new UserHandle(ActivityManager.getCurrentUser()))
.build();
mEntry = createNotification();
mSbn = mEntry.getSbn();
mEntry.expandedIcon = mock(StatusBarIconView.class);
@@ -607,6 +597,22 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
any(NotificationVisibility.class), anyBoolean());
}
private NotificationEntry createNotification() {
Notification.Builder n = new Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
.setContentTitle("Title")
.setContentText("Text");
return new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME)
.setOpPkg(TEST_PACKAGE_NAME)
.setUid(TEST_UID)
.setId(mId++)
.setNotification(n.build())
.setUser(new UserHandle(ActivityManager.getCurrentUser()))
.build();
}
private Notification.Action createAction() {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),

View File

@@ -16,24 +16,16 @@
package com.android.systemui.statusbar.notification;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.Notification;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
@@ -123,107 +115,6 @@ public class NotificationListControllerTest extends SysuiTestCase {
verify(mEntryManager).updateNotifications(anyString());
}
@Test
public void testAppOps_appOpAddedToForegroundNotif() {
// GIVEN a notification associated with a foreground service
final NotificationEntry entry = buildEntry();
mNotificationData.add(entry);
when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
.thenReturn(entry.getKey());
// WHEN we are notified of a new app op
mController.updateNotificationsForAppOp(
AppOpsManager.OP_CAMERA,
entry.getSbn().getUid(),
entry.getSbn().getPackageName(),
true);
// THEN the app op is added to the entry
assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
// THEN updateNotifications(TEST) is called
verify(mEntryManager, times(1)).updateNotifications(anyString());
}
@Test
public void testAppOps_appOpAddedToUnrelatedNotif() {
// GIVEN No current foreground notifs
when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
.thenReturn(null);
// WHEN An unrelated notification gets a new app op
mController.updateNotificationsForAppOp(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
// THEN We never call updateNotifications(TEST)
verify(mEntryManager, never()).updateNotifications(anyString());
}
@Test
public void testAppOps_addNotificationWithExistingAppOps() {
// GIVEN a notification with three associated app ops that is associated with a foreground
// service
final NotificationEntry entry = buildEntry();
mNotificationData.add(entry);
ArraySet<Integer> expected = new ArraySet<>();
expected.add(3);
expected.add(235);
expected.add(1);
when(mForegroundServiceController.getStandardLayoutKey(
entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn(entry.getKey());
when(mForegroundServiceController.getAppOps(entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn(expected);
// WHEN the notification is added
mEntryListener.onBeforeNotificationAdded(entry);
// THEN the entry is tagged with all three app ops
assertEquals(expected.size(), entry.mActiveAppOps.size());
for (int op : expected) {
assertTrue("Entry missing op " + op, entry.mActiveAppOps.contains(op));
}
}
@Test
public void testAdd_addNotificationWithNoExistingAppOps() {
// GIVEN a notification with NO associated app ops
final NotificationEntry entry = buildEntry();
mNotificationData.add(entry);
when(mForegroundServiceController.getStandardLayoutKey(
entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn(entry.getKey());
when(mForegroundServiceController.getAppOps(entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn(null);
// WHEN the notification is added
mEntryListener.onBeforeNotificationAdded(entry);
// THEN the entry doesn't have any app ops associated with it
assertEquals(0, entry.mActiveAppOps.size());
}
@Test
public void testAdd_addNonForegroundNotificationWithExistingAppOps() {
// GIVEN a notification with app ops that isn't associated with a foreground service
final NotificationEntry entry = buildEntry();
mNotificationData.add(entry);
ArraySet<Integer> ops = new ArraySet<>();
ops.add(3);
ops.add(235);
ops.add(1);
when(mForegroundServiceController.getAppOps(entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn(ops);
when(mForegroundServiceController.getStandardLayoutKey(
entry.getSbn().getUserId(),
entry.getSbn().getPackageName())).thenReturn("something else");
// WHEN the notification is added
mEntryListener.onBeforeNotificationAdded(entry);
// THEN the entry doesn't have any app ops associated with it
assertEquals(0, entry.mActiveAppOps.size());
}
private NotificationEntry buildEntry() {
mNextNotifId++;

View File

@@ -16,8 +16,6 @@
package com.android.systemui.statusbar.notification.collection;
import static android.app.AppOpsManager.OP_ACCEPT_HANDOVER;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.Notification.CATEGORY_ALARM;
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
@@ -56,7 +54,6 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.Process;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
@@ -64,7 +61,6 @@ import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
@@ -159,69 +155,6 @@ public class NotificationDataTest extends SysuiTestCase {
assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().getChannel());
}
@Test
public void testAllRelevantNotisTaggedWithAppOps() throws Exception {
mNotificationData.add(mRow.getEntry());
ExpandableNotificationRow row2 = new NotificationTestHelper(getContext(), mDependency)
.createRow();
mNotificationData.add(row2.getEntry());
ExpandableNotificationRow diffPkg =
new NotificationTestHelper(getContext(), mDependency).createRow("pkg", 4000,
Process.myUserHandle());
mNotificationData.add(diffPkg.getEntry());
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
expectedOps.add(OP_ACCEPT_HANDOVER);
for (int op : expectedOps) {
mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
NotificationTestHelper.PKG, mRow.getEntry().getKey(), true);
mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
NotificationTestHelper.PKG, row2.getEntry().getKey(), true);
}
for (int op : expectedOps) {
assertTrue(mRow.getEntry().getKey() + " doesn't have op " + op,
mNotificationData.get(mRow.getEntry().getKey()).mActiveAppOps.contains(op));
assertTrue(row2.getEntry().getKey() + " doesn't have op " + op,
mNotificationData.get(row2.getEntry().getKey()).mActiveAppOps.contains(op));
assertFalse(diffPkg.getEntry().getKey() + " has op " + op,
mNotificationData.get(diffPkg.getEntry().getKey()).mActiveAppOps.contains(op));
}
}
@Test
public void testAppOpsRemoval() throws Exception {
mNotificationData.add(mRow.getEntry());
ExpandableNotificationRow row2 = new NotificationTestHelper(getContext(), mDependency)
.createRow();
mNotificationData.add(row2.getEntry());
ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA);
expectedOps.add(OP_ACCEPT_HANDOVER);
for (int op : expectedOps) {
mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
NotificationTestHelper.PKG, row2.getEntry().getKey(), true);
}
expectedOps.remove(OP_ACCEPT_HANDOVER);
mNotificationData.updateAppOp(OP_ACCEPT_HANDOVER, NotificationTestHelper.UID,
NotificationTestHelper.PKG, row2.getEntry().getKey(), false);
assertTrue(mRow.getEntry().getKey() + " doesn't have op " + OP_CAMERA,
mNotificationData.get(mRow.getEntry().getKey()).mActiveAppOps.contains(OP_CAMERA));
assertTrue(row2.getEntry().getKey() + " doesn't have op " + OP_CAMERA,
mNotificationData.get(row2.getEntry().getKey()).mActiveAppOps.contains(OP_CAMERA));
assertFalse(mRow.getEntry().getKey() + " has op " + OP_ACCEPT_HANDOVER,
mNotificationData.get(mRow.getEntry().getKey())
.mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
assertFalse(row2.getEntry().getKey() + " has op " + OP_ACCEPT_HANDOVER,
mNotificationData.get(row2.getEntry().getKey())
.mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
}
@Test
public void testGetNotificationsForCurrentUser_shouldFilterNonCurrentUserNotifications()
throws Exception {