Merge changes I2cc194ad,I1ed99b7f,I404a307a into tm-qpr-dev am: 63db155f56
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19013008 Change-Id: I72c53726df5047ce6a23d7189ae1588caa0bf3fb Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -31,6 +31,7 @@ class NotifUiAdjustment internal constructor(
|
|||||||
val smartActions: List<Notification.Action>,
|
val smartActions: List<Notification.Action>,
|
||||||
val smartReplies: List<CharSequence>,
|
val smartReplies: List<CharSequence>,
|
||||||
val isConversation: Boolean,
|
val isConversation: Boolean,
|
||||||
|
val isSnoozeEnabled: Boolean,
|
||||||
val isMinimized: Boolean,
|
val isMinimized: Boolean,
|
||||||
val needsRedaction: Boolean,
|
val needsRedaction: Boolean,
|
||||||
) {
|
) {
|
||||||
@@ -42,6 +43,7 @@ class NotifUiAdjustment internal constructor(
|
|||||||
): Boolean = when {
|
): Boolean = when {
|
||||||
oldAdjustment === newAdjustment -> false
|
oldAdjustment === newAdjustment -> false
|
||||||
oldAdjustment.isConversation != newAdjustment.isConversation -> true
|
oldAdjustment.isConversation != newAdjustment.isConversation -> true
|
||||||
|
oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true
|
||||||
oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
|
oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
|
||||||
oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
|
oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
|
||||||
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
|
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
|
||||||
@@ -57,9 +59,9 @@ class NotifUiAdjustment internal constructor(
|
|||||||
first.size != second.size -> true
|
first.size != second.size -> true
|
||||||
else -> first.asSequence().zip(second.asSequence()).any {
|
else -> first.asSequence().zip(second.asSequence()).any {
|
||||||
(!TextUtils.equals(it.first.title, it.second.title)) ||
|
(!TextUtils.equals(it.first.title, it.second.title)) ||
|
||||||
(areDifferent(it.first.getIcon(), it.second.getIcon())) ||
|
(areDifferent(it.first.getIcon(), it.second.getIcon())) ||
|
||||||
(it.first.actionIntent != it.second.actionIntent) ||
|
(it.first.actionIntent != it.second.actionIntent) ||
|
||||||
(areDifferent(it.first.remoteInputs, it.second.remoteInputs))
|
(areDifferent(it.first.remoteInputs, it.second.remoteInputs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ class NotifUiAdjustment internal constructor(
|
|||||||
first.size != second.size -> true
|
first.size != second.size -> true
|
||||||
else -> first.asSequence().zip(second.asSequence()).any {
|
else -> first.asSequence().zip(second.asSequence()).any {
|
||||||
(!TextUtils.equals(it.first.label, it.second.label)) ||
|
(!TextUtils.equals(it.first.label, it.second.label)) ||
|
||||||
(areDifferent(it.first.choices, it.second.choices))
|
(areDifferent(it.first.choices, it.second.choices))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,18 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.collection.inflation
|
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.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
|
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
|
||||||
import com.android.systemui.util.ListenerSet
|
import com.android.systemui.util.ListenerSet
|
||||||
|
import com.android.systemui.util.settings.SecureSettings
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,14 +36,23 @@ import javax.inject.Inject
|
|||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
class NotifUiAdjustmentProvider @Inject constructor(
|
class NotifUiAdjustmentProvider @Inject constructor(
|
||||||
|
@Main private val handler: Handler,
|
||||||
|
private val secureSettings: SecureSettings,
|
||||||
private val lockscreenUserManager: NotificationLockscreenUserManager,
|
private val lockscreenUserManager: NotificationLockscreenUserManager,
|
||||||
private val sectionStyleProvider: SectionStyleProvider
|
private val sectionStyleProvider: SectionStyleProvider
|
||||||
) {
|
) {
|
||||||
private val dirtyListeners = ListenerSet<Runnable>()
|
private val dirtyListeners = ListenerSet<Runnable>()
|
||||||
|
private var isSnoozeEnabled = false
|
||||||
|
|
||||||
fun addDirtyListener(listener: Runnable) {
|
fun addDirtyListener(listener: Runnable) {
|
||||||
if (dirtyListeners.isEmpty()) {
|
if (dirtyListeners.isEmpty()) {
|
||||||
lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener)
|
lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener)
|
||||||
|
updateSnoozeEnabled()
|
||||||
|
secureSettings.registerContentObserverForUser(
|
||||||
|
SHOW_NOTIFICATION_SNOOZE,
|
||||||
|
settingsObserver,
|
||||||
|
UserHandle.USER_ALL
|
||||||
|
)
|
||||||
}
|
}
|
||||||
dirtyListeners.addIfAbsent(listener)
|
dirtyListeners.addIfAbsent(listener)
|
||||||
}
|
}
|
||||||
@@ -46,6 +61,7 @@ class NotifUiAdjustmentProvider @Inject constructor(
|
|||||||
dirtyListeners.remove(listener)
|
dirtyListeners.remove(listener)
|
||||||
if (dirtyListeners.isEmpty()) {
|
if (dirtyListeners.isEmpty()) {
|
||||||
lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener)
|
lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener)
|
||||||
|
secureSettings.unregisterContentObserver(settingsObserver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +70,17 @@ class NotifUiAdjustmentProvider @Inject constructor(
|
|||||||
dirtyListeners.forEach(Runnable::run)
|
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 {
|
private fun isEntryMinimized(entry: NotificationEntry): Boolean {
|
||||||
val section = entry.section ?: error("Entry must have a section to determine if minimized")
|
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")
|
val parent = entry.parent ?: error("Entry must have a parent to determine if minimized")
|
||||||
@@ -73,6 +100,7 @@ class NotifUiAdjustmentProvider @Inject constructor(
|
|||||||
smartActions = entry.ranking.smartActions,
|
smartActions = entry.ranking.smartActions,
|
||||||
smartReplies = entry.ranking.smartReplies,
|
smartReplies = entry.ranking.smartReplies,
|
||||||
isConversation = entry.ranking.isConversation,
|
isConversation = entry.ranking.isConversation,
|
||||||
|
isSnoozeEnabled = isSnoozeEnabled,
|
||||||
isMinimized = isEntryMinimized(entry),
|
isMinimized = isEntryMinimized(entry),
|
||||||
needsRedaction = lockscreenUserManager.needsRedaction(entry),
|
needsRedaction = lockscreenUserManager.needsRedaction(entry),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
@@ -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.provider.SectionStyleProvider;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
|
import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
|
||||||
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
|
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
|
||||||
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -97,6 +99,8 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
|||||||
@Mock private IStatusBarService mService;
|
@Mock private IStatusBarService mService;
|
||||||
@Mock private BindEventManagerImpl mBindEventManagerImpl;
|
@Mock private BindEventManagerImpl mBindEventManagerImpl;
|
||||||
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
|
@Mock private Handler mHandler;
|
||||||
|
@Mock private SecureSettings mSecureSettings;
|
||||||
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
|
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
|
||||||
private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
|
private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
|
||||||
|
|
||||||
@@ -110,8 +114,11 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mAdjustmentProvider =
|
mAdjustmentProvider = new NotifUiAdjustmentProvider(
|
||||||
new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionStyleProvider);
|
mHandler,
|
||||||
|
mSecureSettings,
|
||||||
|
mLockscreenUserManager,
|
||||||
|
mSectionStyleProvider);
|
||||||
mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build();
|
mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build();
|
||||||
mInflationError = new Exception(TEST_MESSAGE);
|
mInflationError = new Exception(TEST_MESSAGE);
|
||||||
mErrorManager = new NotifInflationErrorManager();
|
mErrorManager = new NotifInflationErrorManager();
|
||||||
|
|||||||
@@ -1,16 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
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.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
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.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.mock
|
||||||
import com.android.systemui.util.mockito.withArgCaptor
|
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.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.Mockito.clearInvocations
|
||||||
|
import org.mockito.Mockito.inOrder
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -18,12 +49,39 @@ import org.mockito.Mockito.verify
|
|||||||
class NotifUiAdjustmentProviderTest : SysuiTestCase() {
|
class NotifUiAdjustmentProviderTest : SysuiTestCase() {
|
||||||
private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
|
private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
|
||||||
private val sectionStyleProvider: SectionStyleProvider = 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(
|
private val adjustmentProvider = NotifUiAdjustmentProvider(
|
||||||
|
handler,
|
||||||
|
secureSettings,
|
||||||
lockscreenUserManager,
|
lockscreenUserManager,
|
||||||
sectionStyleProvider,
|
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
|
@Test
|
||||||
fun notifLockscreenStateChangeWillNotifDirty() {
|
fun notifLockscreenStateChangeWillNotifDirty() {
|
||||||
val dirtyListener = mock<Runnable>()
|
val dirtyListener = mock<Runnable>()
|
||||||
@@ -33,6 +91,35 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() {
|
|||||||
verify(lockscreenUserManager).addNotificationStateChangedListener(capture())
|
verify(lockscreenUserManager).addNotificationStateChangedListener(capture())
|
||||||
}
|
}
|
||||||
notifLocksreenStateChangeListener.onNotificationStateChanged()
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user