Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt +7 −5 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ class NotifUiAdjustment internal constructor( val smartActions: List<Notification.Action>, val smartReplies: List<CharSequence>, val isConversation: Boolean, val isSnoozeEnabled: Boolean, val isMinimized: Boolean, val needsRedaction: Boolean, ) { Loading @@ -42,6 +43,7 @@ class NotifUiAdjustment internal constructor( ): Boolean = when { oldAdjustment === newAdjustment -> false oldAdjustment.isConversation != newAdjustment.isConversation -> true oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true oldAdjustment.isMinimized != newAdjustment.isMinimized -> true oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt +30 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.statusbar.notification.collection.inflation import android.database.ContentObserver import android.os.Handler import android.os.UserHandle import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.util.ListenerSet import com.android.systemui.util.settings.SecureSettings import javax.inject.Inject /** Loading @@ -30,14 +36,23 @@ import javax.inject.Inject */ @SysUISingleton class NotifUiAdjustmentProvider @Inject constructor( @Main private val handler: Handler, private val secureSettings: SecureSettings, private val lockscreenUserManager: NotificationLockscreenUserManager, private val sectionStyleProvider: SectionStyleProvider, private val sectionStyleProvider: SectionStyleProvider ) { private val dirtyListeners = ListenerSet<Runnable>() private var isSnoozeEnabled = false fun addDirtyListener(listener: Runnable) { if (dirtyListeners.isEmpty()) { lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener) updateSnoozeEnabled() secureSettings.registerContentObserverForUser( SHOW_NOTIFICATION_SNOOZE, settingsObserver, UserHandle.USER_ALL ) } dirtyListeners.addIfAbsent(listener) } Loading @@ -46,6 +61,7 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.remove(listener) if (dirtyListeners.isEmpty()) { lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener) secureSettings.unregisterContentObserver(settingsObserver) } } Loading @@ -54,6 +70,17 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.forEach(Runnable::run) } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean) { updateSnoozeEnabled() dirtyListeners.forEach(Runnable::run) } } private fun updateSnoozeEnabled() { isSnoozeEnabled = secureSettings.getInt(SHOW_NOTIFICATION_SNOOZE, 0) == 1 } private fun isEntryMinimized(entry: NotificationEntry): Boolean { val section = entry.section ?: error("Entry must have a section to determine if minimized") val parent = entry.parent ?: error("Entry must have a parent to determine if minimized") Loading @@ -73,6 +100,7 @@ class NotifUiAdjustmentProvider @Inject constructor( smartActions = entry.ranking.smartActions, smartReplies = entry.ranking.smartReplies, isConversation = entry.ranking.isConversation, isSnoozeEnabled = isSnoozeEnabled, isMinimized = isEntryMinimized(entry), needsRedaction = lockscreenUserManager.needsRedaction(entry), ) Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java +9 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.when; import static java.util.Objects.requireNonNull; import android.os.Handler; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -59,6 +60,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider; import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn; import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager; import com.android.systemui.util.settings.SecureSettings; import org.junit.Before; import org.junit.Test; Loading Loading @@ -97,6 +99,8 @@ public class PreparationCoordinatorTest extends SysuiTestCase { @Mock private IStatusBarService mService; @Mock private BindEventManagerImpl mBindEventManagerImpl; @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private Handler mHandler; @Mock private SecureSettings mSecureSettings; @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater(); private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider(); Loading @@ -110,8 +114,11 @@ public class PreparationCoordinatorTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); mAdjustmentProvider = new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionStyleProvider); mAdjustmentProvider = new NotifUiAdjustmentProvider( mHandler, mSecureSettings, mLockscreenUserManager, mSectionStyleProvider); mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build(); mInflationError = new Exception(TEST_MESSAGE); mErrorManager = new NotifInflationErrorManager(); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt +88 −1 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.inflation import android.database.ContentObserver import android.os.Handler import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` as whenever @SmallTest @RunWith(AndroidTestingRunner::class) Loading @@ -18,12 +49,39 @@ import org.mockito.Mockito.verify class NotifUiAdjustmentProviderTest : SysuiTestCase() { private val lockscreenUserManager: NotificationLockscreenUserManager = mock() private val sectionStyleProvider: SectionStyleProvider = mock() private val handler: Handler = mock() private val secureSettings: SecureSettings = mock() private val uri = FakeSettings().getUriFor(SHOW_NOTIFICATION_SNOOZE) private val dirtyListener: Runnable = mock() private val section = NotifSection(mock(), 0) private val entry = NotificationEntryBuilder() .setSection(section) .setParent(GroupEntry.ROOT_ENTRY) .build() private lateinit var contentObserver: ContentObserver private val adjustmentProvider = NotifUiAdjustmentProvider( handler, secureSettings, lockscreenUserManager, sectionStyleProvider, ) @Before fun setup() { verifyNoMoreInteractions(secureSettings) adjustmentProvider.addDirtyListener(dirtyListener) verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any()) contentObserver = withArgCaptor { verify(secureSettings).registerContentObserverForUser( eq(SHOW_NOTIFICATION_SNOOZE), capture(), any() ) } verifyNoMoreInteractions(secureSettings, dirtyListener) } @Test fun notifLockscreenStateChangeWillNotifDirty() { val dirtyListener = mock<Runnable>() Loading @@ -33,6 +91,35 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { verify(lockscreenUserManager).addNotificationStateChangedListener(capture()) } notifLocksreenStateChangeListener.onNotificationStateChanged() verify(dirtyListener).run(); verify(dirtyListener).run() } @Test fun additionalAddDoesNotRegisterAgain() { clearInvocations(secureSettings) adjustmentProvider.addDirtyListener(mock()) verifyNoMoreInteractions(secureSettings) } @Test fun onChangeWillQueryThenNotifyDirty() { contentObserver.onChange(false, listOf(uri), 0, 0) with(inOrder(secureSettings, dirtyListener)) { verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any()) verify(dirtyListener).run() } } @Test fun changingSnoozeChangesProvidedAdjustment() { whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(0) val original = adjustmentProvider.calculateAdjustment(entry) assertThat(original.isSnoozeEnabled).isFalse() whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(1) contentObserver.onChange(false, listOf(uri), 0, 0) val withSnoozing = adjustmentProvider.calculateAdjustment(entry) assertThat(withSnoozing.isSnoozeEnabled).isTrue() assertThat(withSnoozing).isNotEqualTo(original) } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt +7 −5 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ class NotifUiAdjustment internal constructor( val smartActions: List<Notification.Action>, val smartReplies: List<CharSequence>, val isConversation: Boolean, val isSnoozeEnabled: Boolean, val isMinimized: Boolean, val needsRedaction: Boolean, ) { Loading @@ -42,6 +43,7 @@ class NotifUiAdjustment internal constructor( ): Boolean = when { oldAdjustment === newAdjustment -> false oldAdjustment.isConversation != newAdjustment.isConversation -> true oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true oldAdjustment.isMinimized != newAdjustment.isMinimized -> true oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt +30 −2 Original line number Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.statusbar.notification.collection.inflation import android.database.ContentObserver import android.os.Handler import android.os.UserHandle import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.util.ListenerSet import com.android.systemui.util.settings.SecureSettings import javax.inject.Inject /** Loading @@ -30,14 +36,23 @@ import javax.inject.Inject */ @SysUISingleton class NotifUiAdjustmentProvider @Inject constructor( @Main private val handler: Handler, private val secureSettings: SecureSettings, private val lockscreenUserManager: NotificationLockscreenUserManager, private val sectionStyleProvider: SectionStyleProvider, private val sectionStyleProvider: SectionStyleProvider ) { private val dirtyListeners = ListenerSet<Runnable>() private var isSnoozeEnabled = false fun addDirtyListener(listener: Runnable) { if (dirtyListeners.isEmpty()) { lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener) updateSnoozeEnabled() secureSettings.registerContentObserverForUser( SHOW_NOTIFICATION_SNOOZE, settingsObserver, UserHandle.USER_ALL ) } dirtyListeners.addIfAbsent(listener) } Loading @@ -46,6 +61,7 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.remove(listener) if (dirtyListeners.isEmpty()) { lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener) secureSettings.unregisterContentObserver(settingsObserver) } } Loading @@ -54,6 +70,17 @@ class NotifUiAdjustmentProvider @Inject constructor( dirtyListeners.forEach(Runnable::run) } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean) { updateSnoozeEnabled() dirtyListeners.forEach(Runnable::run) } } private fun updateSnoozeEnabled() { isSnoozeEnabled = secureSettings.getInt(SHOW_NOTIFICATION_SNOOZE, 0) == 1 } private fun isEntryMinimized(entry: NotificationEntry): Boolean { val section = entry.section ?: error("Entry must have a section to determine if minimized") val parent = entry.parent ?: error("Entry must have a parent to determine if minimized") Loading @@ -73,6 +100,7 @@ class NotifUiAdjustmentProvider @Inject constructor( smartActions = entry.ranking.smartActions, smartReplies = entry.ranking.smartReplies, isConversation = entry.ranking.isConversation, isSnoozeEnabled = isSnoozeEnabled, isMinimized = isEntryMinimized(entry), needsRedaction = lockscreenUserManager.needsRedaction(entry), ) Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java +9 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.when; import static java.util.Objects.requireNonNull; import android.os.Handler; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -59,6 +60,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider; import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn; import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager; import com.android.systemui.util.settings.SecureSettings; import org.junit.Before; import org.junit.Test; Loading Loading @@ -97,6 +99,8 @@ public class PreparationCoordinatorTest extends SysuiTestCase { @Mock private IStatusBarService mService; @Mock private BindEventManagerImpl mBindEventManagerImpl; @Mock private NotificationLockscreenUserManager mLockscreenUserManager; @Mock private Handler mHandler; @Mock private SecureSettings mSecureSettings; @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater(); private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider(); Loading @@ -110,8 +114,11 @@ public class PreparationCoordinatorTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); mAdjustmentProvider = new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionStyleProvider); mAdjustmentProvider = new NotifUiAdjustmentProvider( mHandler, mSecureSettings, mLockscreenUserManager, mSectionStyleProvider); mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build(); mInflationError = new Exception(TEST_MESSAGE); mErrorManager = new NotifInflationErrorManager(); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt +88 −1 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.inflation import android.database.ContentObserver import android.os.Handler import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.SecureSettings import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` as whenever @SmallTest @RunWith(AndroidTestingRunner::class) Loading @@ -18,12 +49,39 @@ import org.mockito.Mockito.verify class NotifUiAdjustmentProviderTest : SysuiTestCase() { private val lockscreenUserManager: NotificationLockscreenUserManager = mock() private val sectionStyleProvider: SectionStyleProvider = mock() private val handler: Handler = mock() private val secureSettings: SecureSettings = mock() private val uri = FakeSettings().getUriFor(SHOW_NOTIFICATION_SNOOZE) private val dirtyListener: Runnable = mock() private val section = NotifSection(mock(), 0) private val entry = NotificationEntryBuilder() .setSection(section) .setParent(GroupEntry.ROOT_ENTRY) .build() private lateinit var contentObserver: ContentObserver private val adjustmentProvider = NotifUiAdjustmentProvider( handler, secureSettings, lockscreenUserManager, sectionStyleProvider, ) @Before fun setup() { verifyNoMoreInteractions(secureSettings) adjustmentProvider.addDirtyListener(dirtyListener) verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any()) contentObserver = withArgCaptor { verify(secureSettings).registerContentObserverForUser( eq(SHOW_NOTIFICATION_SNOOZE), capture(), any() ) } verifyNoMoreInteractions(secureSettings, dirtyListener) } @Test fun notifLockscreenStateChangeWillNotifDirty() { val dirtyListener = mock<Runnable>() Loading @@ -33,6 +91,35 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { verify(lockscreenUserManager).addNotificationStateChangedListener(capture()) } notifLocksreenStateChangeListener.onNotificationStateChanged() verify(dirtyListener).run(); verify(dirtyListener).run() } @Test fun additionalAddDoesNotRegisterAgain() { clearInvocations(secureSettings) adjustmentProvider.addDirtyListener(mock()) verifyNoMoreInteractions(secureSettings) } @Test fun onChangeWillQueryThenNotifyDirty() { contentObserver.onChange(false, listOf(uri), 0, 0) with(inOrder(secureSettings, dirtyListener)) { verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any()) verify(dirtyListener).run() } } @Test fun changingSnoozeChangesProvidedAdjustment() { whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(0) val original = adjustmentProvider.calculateAdjustment(entry) assertThat(original.isSnoozeEnabled).isFalse() whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(1) contentObserver.onChange(false, listOf(uri), 0, 0) val withSnoozing = adjustmentProvider.calculateAdjustment(entry) assertThat(withSnoozing.isSnoozeEnabled).isTrue() assertThat(withSnoozing).isNotEqualTo(original) } }