Merge "Trigger re-inflate when sensitive setting changes" into tm-dev am: 8df521fb73
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18715234 Change-Id: I86b3e0e0ee070f2fedc668ab8ca0c66f6a41705c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -89,6 +89,18 @@ public interface NotificationLockscreenUserManager {
|
|||||||
*/
|
*/
|
||||||
boolean userAllowsNotificationsInPublic(int userId);
|
boolean userAllowsNotificationsInPublic(int userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link NotificationStateChangedListener} to be notified of any state changes that
|
||||||
|
* would affect presentation of notifications.
|
||||||
|
*/
|
||||||
|
void addNotificationStateChangedListener(NotificationStateChangedListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@link NotificationStateChangedListener} that was previously registered with
|
||||||
|
* {@link #addNotificationStateChangedListener(NotificationStateChangedListener)}.
|
||||||
|
*/
|
||||||
|
void removeNotificationStateChangedListener(NotificationStateChangedListener listener);
|
||||||
|
|
||||||
/** Notified when the current user changes. */
|
/** Notified when the current user changes. */
|
||||||
interface UserChangedListener {
|
interface UserChangedListener {
|
||||||
default void onUserChanged(int userId) {}
|
default void onUserChanged(int userId) {}
|
||||||
@@ -100,4 +112,12 @@ public interface NotificationLockscreenUserManager {
|
|||||||
interface KeyguardNotificationSuppressor {
|
interface KeyguardNotificationSuppressor {
|
||||||
boolean shouldSuppressOnKeyguard(NotificationEntry entry);
|
boolean shouldSuppressOnKeyguard(NotificationEntry entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notified when any state pertaining to Notifications has changed; any methods pertaining to
|
||||||
|
* notifications should be re-queried.
|
||||||
|
*/
|
||||||
|
interface NotificationStateChangedListener {
|
||||||
|
void onNotificationStateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co
|
|||||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
|
import com.android.systemui.util.ListenerSet;
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -110,6 +111,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
protected KeyguardManager mKeyguardManager;
|
protected KeyguardManager mKeyguardManager;
|
||||||
private int mState = StatusBarState.SHADE;
|
private int mState = StatusBarState.SHADE;
|
||||||
private List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>();
|
private List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>();
|
||||||
|
private final ListenerSet<NotificationStateChangedListener> mNotifStateChangedListeners =
|
||||||
|
new ListenerSet<>();
|
||||||
|
|
||||||
protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
|
protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
@@ -121,6 +124,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mUsersAllowingPrivateNotifications.clear();
|
mUsersAllowingPrivateNotifications.clear();
|
||||||
updateLockscreenNotificationSetting();
|
updateLockscreenNotificationSetting();
|
||||||
getEntryManager().updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED");
|
getEntryManager().updateNotifications("ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED");
|
||||||
|
// TODO(b/231976036): Consolidate pipeline invalidations related to this event
|
||||||
|
// notifyNotificationStateChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -254,6 +259,7 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
updateLockscreenNotificationSetting();
|
updateLockscreenNotificationSetting();
|
||||||
getEntryManager().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS,"
|
getEntryManager().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS,"
|
||||||
+ " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change");
|
+ " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change");
|
||||||
|
notifyNotificationStateChanged();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -264,6 +270,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
if (mDeviceProvisionedController.isDeviceProvisioned()) {
|
if (mDeviceProvisionedController.isDeviceProvisioned()) {
|
||||||
getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
|
getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
|
||||||
+ " or ZEN_MODE change");
|
+ " or ZEN_MODE change");
|
||||||
|
// TODO(b/231976036): Consolidate pipeline invalidations related to this event
|
||||||
|
// notifyNotificationStateChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -651,6 +659,8 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mUsersWithSeparateWorkChallenge.put(userId, needsSeparateChallenge);
|
mUsersWithSeparateWorkChallenge.put(userId, needsSeparateChallenge);
|
||||||
}
|
}
|
||||||
getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
|
getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
|
||||||
|
// TODO(b/234738798): Migrate KeyguardNotificationVisibilityProvider to use this listener
|
||||||
|
// notifyNotificationStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -668,6 +678,22 @@ public class NotificationLockscreenUserManagerImpl implements
|
|||||||
mListeners.remove(listener);
|
mListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotificationStateChangedListener(NotificationStateChangedListener listener) {
|
||||||
|
mNotifStateChangedListeners.addIfAbsent(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeNotificationStateChangedListener(NotificationStateChangedListener listener) {
|
||||||
|
mNotifStateChangedListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyNotificationStateChanged() {
|
||||||
|
for (NotificationStateChangedListener listener : mNotifStateChangedListeners) {
|
||||||
|
listener.onNotificationStateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// public void updatePublicMode() {
|
// public void updatePublicMode() {
|
||||||
// //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns
|
// //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns
|
||||||
// // false when it should be true. Therefore, if we are not on the SHADE, don't even bother
|
// // false when it should be true. Therefore, if we are not on the SHADE, don't even bother
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ public class PreparationCoordinator implements Coordinator {
|
|||||||
@Override
|
@Override
|
||||||
public void attach(NotifPipeline pipeline) {
|
public void attach(NotifPipeline pipeline) {
|
||||||
mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
|
mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
|
||||||
|
mAdjustmentProvider.addDirtyListener(mNotifInflatingFilter::invalidateList);
|
||||||
|
|
||||||
pipeline.addCollectionListener(mNotifCollectionListener);
|
pipeline.addCollectionListener(mNotifCollectionListener);
|
||||||
// Inflate after grouping/sorting since that affects what views to inflate.
|
// Inflate after grouping/sorting since that affects what views to inflate.
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ 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 isMinimized: Boolean
|
val isMinimized: Boolean,
|
||||||
|
val needsRedaction: Boolean,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -42,6 +43,7 @@ class NotifUiAdjustment internal constructor(
|
|||||||
oldAdjustment === newAdjustment -> false
|
oldAdjustment === newAdjustment -> false
|
||||||
oldAdjustment.isConversation != newAdjustment.isConversation -> true
|
oldAdjustment.isConversation != newAdjustment.isConversation -> true
|
||||||
oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
|
oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
|
||||||
|
oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
|
||||||
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
|
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
|
||||||
newAdjustment.smartReplies != oldAdjustment.smartReplies -> true
|
newAdjustment.smartReplies != oldAdjustment.smartReplies -> true
|
||||||
else -> false
|
else -> false
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
package com.android.systemui.statusbar.notification.collection.inflation
|
package com.android.systemui.statusbar.notification.collection.inflation
|
||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
import com.android.systemui.statusbar.notification.SectionClassifier
|
import com.android.systemui.statusbar.notification.SectionClassifier
|
||||||
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.util.ListenerSet
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,9 +29,30 @@ import javax.inject.Inject
|
|||||||
* to ensure that notifications are reinflated when ranking-derived information changes.
|
* to ensure that notifications are reinflated when ranking-derived information changes.
|
||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
open class NotifUiAdjustmentProvider @Inject constructor(
|
class NotifUiAdjustmentProvider @Inject constructor(
|
||||||
private val sectionClassifier: SectionClassifier
|
private val lockscreenUserManager: NotificationLockscreenUserManager,
|
||||||
|
private val sectionClassifier: SectionClassifier,
|
||||||
) {
|
) {
|
||||||
|
private val dirtyListeners = ListenerSet<Runnable>()
|
||||||
|
|
||||||
|
fun addDirtyListener(listener: Runnable) {
|
||||||
|
if (dirtyListeners.isEmpty()) {
|
||||||
|
lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener)
|
||||||
|
}
|
||||||
|
dirtyListeners.addIfAbsent(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeDirtyListener(listener: Runnable) {
|
||||||
|
dirtyListeners.remove(listener)
|
||||||
|
if (dirtyListeners.isEmpty()) {
|
||||||
|
lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val notifStateChangedListener =
|
||||||
|
NotificationLockscreenUserManager.NotificationStateChangedListener {
|
||||||
|
dirtyListeners.forEach(Runnable::run)
|
||||||
|
}
|
||||||
|
|
||||||
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")
|
||||||
@@ -42,14 +65,15 @@ open class NotifUiAdjustmentProvider @Inject constructor(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a adjustment object for the given entry. This can be compared to a previous instance
|
* Returns a adjustment object for the given entry. This can be compared to a previous instance
|
||||||
* from the same notification using [NotifUiAdjustment.needReinflate] to determine if it
|
* from the same notification using [NotifUiAdjustment.needReinflate] to determine if it should
|
||||||
* should be reinflated.
|
* be reinflated.
|
||||||
*/
|
*/
|
||||||
fun calculateAdjustment(entry: NotificationEntry) = NotifUiAdjustment(
|
fun calculateAdjustment(entry: NotificationEntry) = NotifUiAdjustment(
|
||||||
key = entry.key,
|
key = entry.key,
|
||||||
smartActions = entry.ranking.smartActions,
|
smartActions = entry.ranking.smartActions,
|
||||||
smartReplies = entry.ranking.smartReplies,
|
smartReplies = entry.ranking.smartReplies,
|
||||||
isConversation = entry.ranking.isConversation,
|
isConversation = entry.ranking.isConversation,
|
||||||
isMinimized = isEntryMinimized(entry)
|
isMinimized = isEntryMinimized(entry),
|
||||||
|
needsRedaction = lockscreenUserManager.needsRedaction(entry),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -40,6 +40,7 @@ import androidx.test.filters.SmallTest;
|
|||||||
|
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
|
||||||
import com.android.systemui.statusbar.RankingBuilder;
|
import com.android.systemui.statusbar.RankingBuilder;
|
||||||
import com.android.systemui.statusbar.notification.SectionClassifier;
|
import com.android.systemui.statusbar.notification.SectionClassifier;
|
||||||
import com.android.systemui.statusbar.notification.collection.GroupEntry;
|
import com.android.systemui.statusbar.notification.collection.GroupEntry;
|
||||||
@@ -95,10 +96,11 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
|||||||
@Mock private NotifPipeline mNotifPipeline;
|
@Mock private NotifPipeline mNotifPipeline;
|
||||||
@Mock private IStatusBarService mService;
|
@Mock private IStatusBarService mService;
|
||||||
@Mock private BindEventManagerImpl mBindEventManagerImpl;
|
@Mock private BindEventManagerImpl mBindEventManagerImpl;
|
||||||
|
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
|
||||||
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
|
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
|
||||||
private final SectionClassifier mSectionClassifier = new SectionClassifier();
|
private final SectionClassifier mSectionClassifier = new SectionClassifier();
|
||||||
private final NotifUiAdjustmentProvider mAdjustmentProvider =
|
|
||||||
new NotifUiAdjustmentProvider(mSectionClassifier);
|
private NotifUiAdjustmentProvider mAdjustmentProvider;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private NotificationEntryBuilder getNotificationEntryBuilder() {
|
private NotificationEntryBuilder getNotificationEntryBuilder() {
|
||||||
@@ -108,7 +110,8 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mAdjustmentProvider =
|
||||||
|
new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionClassifier);
|
||||||
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();
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.android.systemui.statusbar.notification.collection.inflation
|
||||||
|
|
||||||
|
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.SectionClassifier
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import com.android.systemui.util.mockito.withArgCaptor
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidTestingRunner::class)
|
||||||
|
@RunWithLooper
|
||||||
|
class NotifUiAdjustmentProviderTest : SysuiTestCase() {
|
||||||
|
private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
|
||||||
|
private val sectionClassifier: SectionClassifier = mock()
|
||||||
|
|
||||||
|
private val adjustmentProvider = NotifUiAdjustmentProvider(
|
||||||
|
lockscreenUserManager,
|
||||||
|
sectionClassifier,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun notifLockscreenStateChangeWillNotifDirty() {
|
||||||
|
val dirtyListener = mock<Runnable>()
|
||||||
|
adjustmentProvider.addDirtyListener(dirtyListener)
|
||||||
|
val notifLocksreenStateChangeListener =
|
||||||
|
withArgCaptor<NotificationLockscreenUserManager.NotificationStateChangedListener> {
|
||||||
|
verify(lockscreenUserManager).addNotificationStateChangedListener(capture())
|
||||||
|
}
|
||||||
|
notifLocksreenStateChangeListener.onNotificationStateChanged()
|
||||||
|
verify(dirtyListener).run();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user