diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 2a5bdc75361d4..404e791291d8f 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -127,7 +127,7 @@ android_library { "SystemUI-proto", "metrics-helper-lib", "androidx.test.rules", "hamcrest-library", - "mockito-target-inline-minus-junit4", + "mockito-target-extended-minus-junit4", "testables", "truth-prebuilt", "dagger2-2.19", diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 606605ad02920..6ea3f4ef958c9 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; import android.app.INotificationManager; import android.content.Context; +import android.content.pm.IPackageManager; import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.NightDisplayListener; import android.os.Handler; @@ -147,6 +148,13 @@ public class DependencyProvider { ServiceManager.getService(Context.NOTIFICATION_SERVICE)); } + /** */ + @Singleton + @Provides + public IPackageManager provideIPackageManager() { + return IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + } + /** */ @Singleton @Provides diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java index defa3722deef7..b68cb0dd3320a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.collection.coordinator; import android.Manifest; -import android.app.AppGlobals; import android.app.Notification; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; @@ -43,10 +42,13 @@ public class DeviceProvisionedCoordinator implements Coordinator { private static final String TAG = "DeviceProvisionedCoordinator"; private final DeviceProvisionedController mDeviceProvisionedController; + private final IPackageManager mIPackageManager; @Inject - public DeviceProvisionedCoordinator(DeviceProvisionedController deviceProvisionedController) { + public DeviceProvisionedCoordinator(DeviceProvisionedController deviceProvisionedController, + IPackageManager packageManager) { mDeviceProvisionedController = deviceProvisionedController; + mIPackageManager = packageManager; } @Override @@ -70,17 +72,16 @@ public class DeviceProvisionedCoordinator implements Coordinator { * marking them as relevant for setup are allowed to show when device is unprovisioned */ private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) { - final boolean hasPermission = checkUidPermission(AppGlobals.getPackageManager(), + final boolean hasPermission = checkUidPermission( Manifest.permission.NOTIFICATION_DURING_SETUP, sbn.getUid()) == PackageManager.PERMISSION_GRANTED; return hasPermission && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP); } - private static int checkUidPermission(IPackageManager packageManager, String permission, - int uid) { + private int checkUidPermission(String permission, int uid) { try { - return packageManager.checkUidPermission(permission, uid); + return mIPackageManager.checkUidPermission(permission, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index 81e2c22d5c4fa..e5f56d43f4d70 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -32,7 +32,8 @@ LOCAL_MULTILIB := both LOCAL_JNI_SHARED_LIBRARIES := \ libdexmakerjvmtiagent \ - libmultiplejvmtiagentsinterferenceagent + libmultiplejvmtiagentsinterferenceagent \ + libstaticjvmtiagent LOCAL_JAVA_LIBRARIES := \ android.test.runner \ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java new file mode 100644 index 0000000000000..a9413c78d770e --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.coordinator; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.Manifest; +import android.app.ActivityManagerInternal; +import android.app.Notification; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.RemoteException; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.NotificationEntryBuilder; +import com.android.systemui.statusbar.RankingBuilder; +import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class DeviceProvisionedCoordinatorTest extends SysuiTestCase { + private static final int NOTIF_UID = 0; + + private static final String SHOW_WHEN_UNPROVISIONED_FLAG = + Notification.EXTRA_ALLOW_DURING_SETUP; + private static final String SETUP_NOTIF_PERMISSION = + Manifest.permission.NOTIFICATION_DURING_SETUP; + + private MockitoSession mMockitoSession; + + @Mock private ActivityManagerInternal mActivityMangerInternal; + @Mock private IPackageManager mIPackageManager; + @Mock private DeviceProvisionedController mDeviceProvisionedController; + @Mock private NotifListBuilderImpl mNotifListBuilder; + private Notification mNotification; + private NotificationEntry mEntry; + private DeviceProvisionedCoordinator mDeviceProvisionedCoordinator; + private NotifFilter mDeviceProvisionedFilter; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mDeviceProvisionedCoordinator = new DeviceProvisionedCoordinator( + mDeviceProvisionedController, mIPackageManager); + + mNotification = new Notification(); + mEntry = new NotificationEntryBuilder() + .setNotification(mNotification) + .setUid(NOTIF_UID) + .build(); + + ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(NotifFilter.class); + mDeviceProvisionedCoordinator.attach(null, mNotifListBuilder); + verify(mNotifListBuilder, times(1)).addFilter(filterCaptor.capture()); + mDeviceProvisionedFilter = filterCaptor.getValue(); + } + + @Test + public void deviceProvisioned() { + // GIVEN device is provisioned + when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true); + + // THEN don't filter out the notification + assertFalse(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void deviceUnprovisioned() { + // GIVEN device is unprovisioned + when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(false); + + // THEN filter out the notification + assertTrue(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void deviceUnprovisionedCanBypass() throws RemoteException { + // GIVEN device is unprovisioned + when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(false); + + // GIVEN notification has a flag to allow the notification during setup + Bundle extras = new Bundle(); + extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true); + mNotification.extras = extras; + + // GIVEN notification has the permission to display during setup + when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + // THEN don't filter out the notification + assertFalse(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void deviceUnprovisionedTryBypassWithoutPermission() throws RemoteException { + // GIVEN device is unprovisioned + when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(false); + + // GIVEN notification has a flag to allow the notification during setup + Bundle extras = new Bundle(); + extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true); + mNotification.extras = extras; + + // GIVEN notification does NOT have permission to display during setup + when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID)) + .thenReturn(PackageManager.PERMISSION_DENIED); + + // THEN filter out the notification + assertTrue(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0)); + } + + private RankingBuilder getRankingForUnfilteredNotif() { + return new RankingBuilder() + .setKey(mEntry.getKey()) + .setSuppressedVisualEffects(0) + .setSuspended(false); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java new file mode 100644 index 0000000000000..ffaa335f91bc8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.coordinator; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Notification; +import android.os.Bundle; +import android.os.Handler; +import android.os.UserHandle; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.ForegroundServiceController; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.appops.AppOpsController; +import com.android.systemui.statusbar.NotificationEntryBuilder; +import com.android.systemui.statusbar.notification.collection.NotifCollection; +import com.android.systemui.statusbar.notification.collection.NotifLifetimeExtender; +import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class ForegroundCoordinatorTest extends SysuiTestCase { + private static final String TEST_PKG = "test_pkg"; + private static final int NOTIF_USER_ID = 0; + + @Mock private Handler mMainHandler; + @Mock private ForegroundServiceController mForegroundServiceController; + @Mock private AppOpsController mAppOpsController; + @Mock private NotifListBuilderImpl mNotifListBuilder; + @Mock private NotifCollection mNotifCollection; + + private NotificationEntry mEntry; + private Notification mNotification; + private ForegroundCoordinator mForegroundCoordinator; + private NotifFilter mForegroundFilter; + private NotifLifetimeExtender mForegroundNotifLifetimeExtender; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mForegroundCoordinator = new ForegroundCoordinator( + mForegroundServiceController, mAppOpsController, mMainHandler); + + mNotification = new Notification(); + mEntry = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setNotification(mNotification) + .build(); + + ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(NotifFilter.class); + ArgumentCaptor lifetimeExtenderCaptor = + ArgumentCaptor.forClass(NotifLifetimeExtender.class); + + mForegroundCoordinator.attach(mNotifCollection, mNotifListBuilder); + verify(mNotifListBuilder, times(1)).addFilter(filterCaptor.capture()); + verify(mNotifCollection, times(1)).addNotificationLifetimeExtender( + lifetimeExtenderCaptor.capture()); + + mForegroundFilter = filterCaptor.getValue(); + mForegroundNotifLifetimeExtender = lifetimeExtenderCaptor.getValue(); + } + + @Test + public void filterTest_disclosureUnnecessary() { + StatusBarNotification sbn = mEntry.getSbn(); + + // GIVEN the notification is a disclosure notification + when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(true); + + // GIVEN the disclosure isn't needed for this user + when(mForegroundServiceController.isDisclosureNeededForUser(sbn.getUserId())) + .thenReturn(false); + + // THEN filter out the notification + assertTrue(mForegroundFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void filterTest_systemAlertNotificationUnnecessary() { + StatusBarNotification sbn = mEntry.getSbn(); + + // GIVEN the notification is a system alert notification + not a disclosure notification + when(mForegroundServiceController.isSystemAlertNotification(sbn)).thenReturn(true); + when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(false); + + // GIVEN the alert notification isn't needed for this user + final Bundle extras = new Bundle(); + extras.putStringArray(Notification.EXTRA_FOREGROUND_APPS, + new String[]{TEST_PKG}); + mNotification.extras = extras; + when(mForegroundServiceController.isSystemAlertWarningNeeded(sbn.getUserId(), TEST_PKG)) + .thenReturn(false); + + // THEN filter out the notification + assertTrue(mForegroundFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void filterTest_doNotFilter() { + StatusBarNotification sbn = mEntry.getSbn(); + + // GIVEN the notification isn't a system alert notification nor a disclosure notification + when(mForegroundServiceController.isSystemAlertNotification(sbn)).thenReturn(false); + when(mForegroundServiceController.isDisclosureNotification(sbn)).thenReturn(false); + + // THEN don't filter out the notification + assertFalse(mForegroundFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void extendLifetimeText_notForeground() { + // GIVEN the notification doesn't represent a foreground service + mNotification.flags = 0; + + // THEN don't extend the lifetime + assertFalse(mForegroundNotifLifetimeExtender + .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + } + + @Test + public void extendLifetimeText_foregroundNotifRecentlyPosted() { + // GIVEN the notification represents a foreground service that was just posted + mNotification.flags |= Notification.FLAG_FOREGROUND_SERVICE; + mEntry = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setSbn(new StatusBarNotification(TEST_PKG, TEST_PKG, NOTIF_USER_ID, "", + NOTIF_USER_ID, NOTIF_USER_ID, mNotification, + new UserHandle(NOTIF_USER_ID), "", System.currentTimeMillis())) + .setNotification(mNotification) + .build(); + + // THEN extend the lifetime + assertTrue(mForegroundNotifLifetimeExtender + .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + } + + @Test + public void extendLifetimeText_foregroundNotifOld() { + // GIVEN the notification represents a foreground service that was posted 10 seconds ago + mNotification.flags |= Notification.FLAG_FOREGROUND_SERVICE; + mEntry = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setSbn(new StatusBarNotification(TEST_PKG, TEST_PKG, NOTIF_USER_ID, "", + NOTIF_USER_ID, NOTIF_USER_ID, mNotification, + new UserHandle(NOTIF_USER_ID), "", + System.currentTimeMillis() - 10000)) + .setNotification(mNotification) + .build(); + + // THEN don't extend the lifetime because the extended time exceeds + // ForegroundCoordinator.MIN_FGS_TIME_MS + assertFalse(mForegroundNotifLifetimeExtender + .shouldExtendLifetime(mEntry, NotificationListenerService.REASON_CLICK)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java index 87b3783d19845..527370e46b6ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java @@ -24,6 +24,8 @@ import static android.app.NotificationManager.IMPORTANCE_MIN; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.Handler; @@ -40,12 +42,15 @@ import com.android.systemui.statusbar.NotificationEntryBuilder; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.notification.collection.GroupEntry; +import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -61,14 +66,16 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock private StatusBarStateController mStatusBarStateController; @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + @Mock private NotifListBuilderImpl mNotifListBuilder; private NotificationEntry mEntry; - private KeyguardCoordinator mKeyguardNotificationCoordinator; + private KeyguardCoordinator mKeyguardCoordinator; + private NotifFilter mKeyguardFilter; @Before public void setup() { MockitoAnnotations.initMocks(this); - mKeyguardNotificationCoordinator = new KeyguardCoordinator( + mKeyguardCoordinator = new KeyguardCoordinator( mContext, mMainHandler, mKeyguardStateController, mLockscreenUserManager, mBroadcastDispatcher, mStatusBarStateController, mKeyguardUpdateMonitor); @@ -76,6 +83,11 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { mEntry = new NotificationEntryBuilder() .setUser(new UserHandle(NOTIF_USER_ID)) .build(); + + ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(NotifFilter.class); + mKeyguardCoordinator.attach(null, mNotifListBuilder); + verify(mNotifListBuilder, times(1)).addFilter(filterCaptor.capture()); + mKeyguardFilter = filterCaptor.getValue(); } @Test @@ -84,7 +96,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { setupUnfilteredState(); // THEN don't filter out the entry - assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertFalse(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -94,7 +106,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { when(mLockscreenUserManager.isCurrentProfile(NOTIF_USER_ID)).thenReturn(false); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -104,7 +116,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { when(mKeyguardStateController.isShowing()).thenReturn(false); // THEN don't filter out the entry - assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertFalse(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -116,7 +128,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { when(mLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -128,7 +140,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { when(mKeyguardUpdateMonitor.isUserInLockdown(NOTIF_USER_ID)).thenReturn(true); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -143,7 +155,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .thenReturn(false); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -159,7 +171,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .setVisibilityOverride(VISIBILITY_SECRET).build()); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -174,7 +186,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { .build()); // THEN filter out the entry - assertTrue(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertTrue(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } @Test @@ -199,7 +211,7 @@ public class KeyguardCoordinatorTest extends SysuiTestCase { mEntry.setParent(group); // THEN don't filter out the entry - assertFalse(mKeyguardNotificationCoordinator.mNotifFilter.shouldFilterOut(mEntry, 0)); + assertFalse(mKeyguardFilter.shouldFilterOut(mEntry, 0)); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java new file mode 100644 index 0000000000000..182e86667c636 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.coordinator; + +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.NotificationEntryBuilder; +import com.android.systemui.statusbar.RankingBuilder; +import com.android.systemui.statusbar.notification.collection.NotifListBuilderImpl; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class RankingCoordinatorTest extends SysuiTestCase { + + @Mock private StatusBarStateController mStatusBarStateController; + @Mock private NotifListBuilderImpl mNotifListBuilder; + private NotificationEntry mEntry; + private RankingCoordinator mRankingCoordinator; + private NotifFilter mRankingFilter; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mRankingCoordinator = new RankingCoordinator(mStatusBarStateController); + mEntry = new NotificationEntryBuilder().build(); + + ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(NotifFilter.class); + mRankingCoordinator.attach(null, mNotifListBuilder); + verify(mNotifListBuilder, times(1)).addFilter(filterCaptor.capture()); + mRankingFilter = filterCaptor.getValue(); + } + + @Test + public void testUnfilteredState() { + // GIVEN no suppressed visual effects + app not suspended + mEntry.setRanking(getRankingForUnfilteredNotif().build()); + + // THEN don't filter out the notification + assertFalse(mRankingFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void filterSuspended() { + // GIVEN the notification's app is suspended + mEntry.setRanking(getRankingForUnfilteredNotif() + .setSuspended(true) + .build()); + + // THEN filter out the notification + assertTrue(mRankingFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void filterDozingSuppressAmbient() { + // GIVEN should suppress ambient + mEntry.setRanking(getRankingForUnfilteredNotif() + .setSuppressedVisualEffects(SUPPRESSED_EFFECT_AMBIENT) + .build()); + + // WHEN it's dozing (on ambient display) + when(mStatusBarStateController.isDozing()).thenReturn(true); + + // THEN filter out the notification + assertTrue(mRankingFilter.shouldFilterOut(mEntry, 0)); + + // WHEN it's not dozing (showing the notification list) + when(mStatusBarStateController.isDozing()).thenReturn(false); + + // THEN don't filter out the notification + assertFalse(mRankingFilter.shouldFilterOut(mEntry, 0)); + } + + @Test + public void filterDozingSuppressNotificationList() { + // GIVEN should suppress from the notification list + mEntry.setRanking(getRankingForUnfilteredNotif() + .setSuppressedVisualEffects(SUPPRESSED_EFFECT_NOTIFICATION_LIST) + .build()); + + // WHEN it's dozing (on ambient display) + when(mStatusBarStateController.isDozing()).thenReturn(true); + + // THEN don't filter out the notification + assertFalse(mRankingFilter.shouldFilterOut(mEntry, 0)); + + // WHEN it's not dozing (showing the notification list) + when(mStatusBarStateController.isDozing()).thenReturn(false); + + // THEN filter out the notification + assertTrue(mRankingFilter.shouldFilterOut(mEntry, 0)); + } + + private RankingBuilder getRankingForUnfilteredNotif() { + return new RankingBuilder() + .setKey(mEntry.getKey()) + .setSuppressedVisualEffects(0) + .setSuspended(false); + } +}