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: Ifbc2a0592ce4f4a039fe715fff539959b9ab981b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-06-04 00:13:57 +00:00
committed by Automerger Merge Worker
7 changed files with 123 additions and 9 deletions

View File

@@ -89,6 +89,18 @@ public interface NotificationLockscreenUserManager {
*/
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. */
interface UserChangedListener {
default void onUserChanged(int userId) {}
@@ -100,4 +112,12 @@ public interface NotificationLockscreenUserManager {
interface KeyguardNotificationSuppressor {
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();
}
}

View File

@@ -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.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ListenerSet;
import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
@@ -110,6 +111,8 @@ public class NotificationLockscreenUserManagerImpl implements
protected KeyguardManager mKeyguardManager;
private int mState = StatusBarState.SHADE;
private List<KeyguardNotificationSuppressor> mKeyguardSuppressors = new ArrayList<>();
private final ListenerSet<NotificationStateChangedListener> mNotifStateChangedListeners =
new ListenerSet<>();
protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
@Override
@@ -121,6 +124,8 @@ public class NotificationLockscreenUserManagerImpl implements
mUsersAllowingPrivateNotifications.clear();
updateLockscreenNotificationSetting();
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();
getEntryManager().updateNotifications("LOCK_SCREEN_SHOW_NOTIFICATIONS,"
+ " or LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS change");
notifyNotificationStateChanged();
}
};
@@ -264,6 +270,8 @@ public class NotificationLockscreenUserManagerImpl implements
if (mDeviceProvisionedController.isDeviceProvisioned()) {
getEntryManager().updateNotifications("LOCK_SCREEN_ALLOW_REMOTE_INPUT"
+ " 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);
}
getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode");
// TODO(b/234738798): Migrate KeyguardNotificationVisibilityProvider to use this listener
// notifyNotificationStateChanged();
}
@Override
@@ -668,6 +678,22 @@ public class NotificationLockscreenUserManagerImpl implements
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() {
// //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

View File

@@ -147,6 +147,7 @@ public class PreparationCoordinator implements Coordinator {
@Override
public void attach(NotifPipeline pipeline) {
mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
mAdjustmentProvider.addDirtyListener(mNotifInflatingFilter::invalidateList);
pipeline.addCollectionListener(mNotifCollectionListener);
// Inflate after grouping/sorting since that affects what views to inflate.

View File

@@ -31,7 +31,8 @@ class NotifUiAdjustment internal constructor(
val smartActions: List<Notification.Action>,
val smartReplies: List<CharSequence>,
val isConversation: Boolean,
val isMinimized: Boolean
val isMinimized: Boolean,
val needsRedaction: Boolean,
) {
companion object {
@JvmStatic
@@ -42,6 +43,7 @@ class NotifUiAdjustment internal constructor(
oldAdjustment === newAdjustment -> false
oldAdjustment.isConversation != newAdjustment.isConversation -> true
oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
newAdjustment.smartReplies != oldAdjustment.smartReplies -> true
else -> false

View File

@@ -17,9 +17,11 @@
package com.android.systemui.statusbar.notification.collection.inflation
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.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.util.ListenerSet
import javax.inject.Inject
/**
@@ -27,9 +29,30 @@ import javax.inject.Inject
* to ensure that notifications are reinflated when ranking-derived information changes.
*/
@SysUISingleton
open class NotifUiAdjustmentProvider @Inject constructor(
private val sectionClassifier: SectionClassifier
class NotifUiAdjustmentProvider @Inject constructor(
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 {
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
* from the same notification using [NotifUiAdjustment.needReinflate] to determine if it
* should be reinflated.
* from the same notification using [NotifUiAdjustment.needReinflate] to determine if it should
* be reinflated.
*/
fun calculateAdjustment(entry: NotificationEntry) = NotifUiAdjustment(
key = entry.key,
smartActions = entry.ranking.smartActions,
smartReplies = entry.ranking.smartReplies,
isConversation = entry.ranking.isConversation,
isMinimized = isEntryMinimized(entry)
isMinimized = isEntryMinimized(entry),
needsRedaction = lockscreenUserManager.needsRedaction(entry),
)
}

View File

@@ -40,6 +40,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.notification.SectionClassifier;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
@@ -95,10 +96,11 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
@Mock private NotifPipeline mNotifPipeline;
@Mock private IStatusBarService mService;
@Mock private BindEventManagerImpl mBindEventManagerImpl;
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
private final SectionClassifier mSectionClassifier = new SectionClassifier();
private final NotifUiAdjustmentProvider mAdjustmentProvider =
new NotifUiAdjustmentProvider(mSectionClassifier);
private NotifUiAdjustmentProvider mAdjustmentProvider;
@NonNull
private NotificationEntryBuilder getNotificationEntryBuilder() {
@@ -108,7 +110,8 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mAdjustmentProvider =
new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionClassifier);
mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build();
mInflationError = new Exception(TEST_MESSAGE);
mErrorManager = new NotifInflationErrorManager();

View File

@@ -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();
}
}