diff options
| author | 2025-03-04 09:11:28 -0800 | |
|---|---|---|
| committer | 2025-03-04 09:11:28 -0800 | |
| commit | c86d8f05ee722b28f311b7c604d6f2cdd0b12e49 (patch) | |
| tree | edd1c2466317a3f99b6b2ac44cddb89d5875d160 | |
| parent | 08328b6c5984a39c4e6987f70a3d7098cf56e174 (diff) | |
| parent | a0e53b545266e293f6e2c135fa9133aad72cda2b (diff) | |
Merge "[RONs] Do not use cached images when reinflating a notification." into main
7 files changed, 83 insertions, 38 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt index 216fd2d54a1e..3116143504eb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt @@ -57,7 +57,8 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() { private val underTest = kosmos.promotedNotificationContentExtractor private val systemClock = kosmos.fakeSystemClock - private val rowImageInflater = RowImageInflater.newInstance(previousIndex = null) + private val rowImageInflater = + RowImageInflater.newInstance(previousIndex = null, reinflating = false) private val imageModelProvider by lazy { rowImageInflater.useForContentModel() } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt index ce3aee1d88d2..31413b06e5fd 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt @@ -41,7 +41,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTIO import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.notification.ConversationNotificationProcessor -import com.android.systemui.statusbar.notification.collection.EntryAdapter import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.promoted.FakePromotedNotificationContentExtractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi @@ -204,7 +203,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() { val result = NotificationRowContentBinderImpl.InflationProgress( packageContext = mContext, - rowImageInflater = RowImageInflater.newInstance(null), + rowImageInflater = RowImageInflater.newInstance(null, reinflating = false), remoteViews = NewRemoteViews(), contentModel = NotificationContentModel(headsUpStatusBarModel), promotedContent = null, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index daa598b5f297..51569c1596ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -57,7 +57,6 @@ import com.android.systemui.statusbar.notification.ConversationNotificationProce import com.android.systemui.statusbar.notification.InflationException; import com.android.systemui.statusbar.notification.NmSummarizationUiFlag; import com.android.systemui.statusbar.notification.NotificationUtils; -import com.android.systemui.statusbar.notification.collection.EntryAdapter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded; @@ -441,8 +440,12 @@ public class NotificationContentInflater implements NotificationRowContentBinder NotificationRowContentBinderLogger logger) { return TraceUtils.trace("NotificationContentInflater.createRemoteViews", () -> { InflationProgress result = new InflationProgress(); + + // inflating the contracted view is the legacy invalidation trigger + boolean reinflating = (reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0; // create an image inflater - result.mRowImageInflater = RowImageInflater.newInstance(row.mImageModelIndex); + result.mRowImageInflater = RowImageInflater.newInstance(row.mImageModelIndex, + reinflating); if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { logger.logAsyncTaskProgress(row.getLoggingKey(), "creating contracted remote view"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt index 3586078c9e82..482b315aa14d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt @@ -499,7 +499,10 @@ constructor( logger.logAsyncTaskProgress(entry.logKey, "loading RON images") inflationProgress.rowImageInflater.loadImagesSynchronously(packageContext) - logger.logAsyncTaskProgress(entry.logKey, "getting row image resolver (on wrong thread!)") + logger.logAsyncTaskProgress( + entry.logKey, + "getting row image resolver (on wrong thread!)", + ) val imageResolver = row.imageResolver // wait for image resolver to finish preloading logger.logAsyncTaskProgress(entry.logKey, "waiting for preloaded images") @@ -685,13 +688,17 @@ constructor( logger: NotificationRowContentBinderLogger, ): InflationProgress { val rowImageInflater = - RowImageInflater.newInstance(previousIndex = row.mImageModelIndex) + RowImageInflater.newInstance( + previousIndex = row.mImageModelIndex, + // inflating the contracted view is the legacy invalidation trigger + reinflating = reInflateFlags and FLAG_CONTENT_VIEW_CONTRACTED != 0, + ) val promotedContent = if (PromotedNotificationContentModel.featureFlagEnabled()) { logger.logAsyncTaskProgress( entry.logKey, - "extracting promoted notification content" + "extracting promoted notification content", ) val imageModelProvider = rowImageInflater.useForContentModel() promotedNotificationContentExtractor @@ -750,7 +757,7 @@ constructor( ) { logger.logAsyncTaskProgress( entry.logKey, - "inflating public single line view model" + "inflating public single line view model", ) if (bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT) { SingleLineViewInflater.inflateSingleLineViewModel( @@ -852,18 +859,12 @@ constructor( } else null val expanded = if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) { - logger.logAsyncTaskProgress( - row.loggingKey, - "creating expanded remote view", - ) + logger.logAsyncTaskProgress(row.loggingKey, "creating expanded remote view") createExpandedView(builder, bindParams.isMinimized) } else null val headsUp = if (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0) { - logger.logAsyncTaskProgress( - row.loggingKey, - "creating heads up remote view", - ) + logger.logAsyncTaskProgress(row.loggingKey, "creating heads up remote view") val isHeadsUpCompact = headsUpStyleProvider.shouldApplyCompactStyle() if (isHeadsUpCompact) { builder.createCompactHeadsUpContentView() @@ -873,10 +874,7 @@ constructor( } else null val public = if (reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC != 0) { - logger.logAsyncTaskProgress( - row.loggingKey, - "creating public remote view" - ) + logger.logAsyncTaskProgress(row.loggingKey, "creating public remote view") if ( LockscreenOtpRedaction.isEnabled && bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT @@ -1142,7 +1140,7 @@ constructor( override fun setResultView(v: View) { logger.logAsyncTaskProgress( entry.logKey, - "group header view applied" + "group header view applied", ) result.inflatedGroupHeaderView = v as NotificationHeaderView? } @@ -1198,7 +1196,7 @@ constructor( } logger.logAsyncTaskProgress( entry.logKey, - "applying low priority group header view" + "applying low priority group header view", ) applyRemoteView( inflationExecutor = inflationExecutor, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt index 95ef60fdcefe..7bac17f4c227 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowImageInflater.kt @@ -83,9 +83,9 @@ interface RowImageInflater { inline fun featureFlagEnabled() = PromotedNotificationUiAod.isEnabled @JvmStatic - fun newInstance(previousIndex: ImageModelIndex?): RowImageInflater = + fun newInstance(previousIndex: ImageModelIndex?, reinflating: Boolean): RowImageInflater = if (featureFlagEnabled()) { - RowImageInflaterImpl(previousIndex) + RowImageInflaterImpl(previousIndex, reinflating) } else { RowImageInflaterStub } @@ -110,7 +110,8 @@ private object RowImageInflaterStub : RowImageInflater { override fun getNewImageIndex(): ImageModelIndex? = null } -class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?) : RowImageInflater { +class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?, val reinflating: Boolean) : + RowImageInflater { private val providedImages = mutableListOf<LazyImage>() /** @@ -139,10 +140,15 @@ class RowImageInflaterImpl(private val previousIndex: ImageModelIndex?) : RowIma // ensure all entries are stored providedImages.add(newImage) // load the image result from the index into our new object - previousIndex?.findImage(iconData, sizeClass, transform)?.let { - // copy the result into our new object - newImage.result = it - } + previousIndex + // skip the cached image when we are "reinflating" to avoid stale content + // being displayed from the same URI after the app updated the notif + ?.takeUnless { reinflating } + ?.findImage(iconData, sizeClass, transform) + ?.let { + // copy the result into our new object + newImage.result = it + } } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt index 86689cb88569..d0357603665d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/RowImageInflaterTest.kt @@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod +import com.android.systemui.statusbar.notification.row.shared.IconData import com.android.systemui.statusbar.notification.row.shared.ImageModel import com.android.systemui.statusbar.notification.row.shared.ImageModelProvider.ImageSizeClass.SmallSquare import com.google.common.truth.Truth.assertThat @@ -38,20 +39,22 @@ class RowImageInflaterTest : SysuiTestCase() { private val resIcon2 = Icon.createWithResource(context, android.R.drawable.ic_delete) private val badUriIcon = Icon.createWithContentUri("content://com.test/does_not_exist") + private var latestImageModelIndex: ImageModelIndex? = null + @Before fun setUp() { - rowImageInflater = RowImageInflater.newInstance(null) + rowImageInflater = RowImageInflater.newInstance(null, reinflating = false) } @Test fun getNewImageIndex_returnsNullWhenUnused() { - assertThat(rowImageInflater.getNewImageIndex()).isNull() + assertThat(getNewImageIndex()).isNull() } @Test fun getNewImageIndex_returnsEmptyIndexWhenZeroImagesLoaded() { assertThat(getImageModelsForIcons()).isEmpty() - val result = rowImageInflater.getNewImageIndex() + val result = getNewImageIndex() assertThat(result).isNotNull() assertThat(result?.contentsForTesting).isEmpty() } @@ -59,7 +62,7 @@ class RowImageInflaterTest : SysuiTestCase() { @Test fun getNewImageIndex_returnsSingleImageWhenOneImageLoaded() { assertThat(getImageModelsForIcons(resIcon1)).hasSize(1) - val result = rowImageInflater.getNewImageIndex() + val result = getNewImageIndex() assertThat(result).isNotNull() assertThat(result?.contentsForTesting).hasSize(1) } @@ -85,7 +88,7 @@ class RowImageInflaterTest : SysuiTestCase() { assertThat(providedModels[3].drawable).isNotNull() // VERIFY the returned index has all 3 entries, 2 of which have drawables - val indexGen1 = rowImageInflater.getNewImageIndex() + val indexGen1 = getNewImageIndex() assertThat(indexGen1).isNotNull() assertThat(indexGen1?.contentsForTesting).hasSize(3) assertThat(indexGen1?.contentsForTesting?.mapNotNull { it.drawable }).hasSize(2) @@ -96,7 +99,7 @@ class RowImageInflaterTest : SysuiTestCase() { exampleFirstGeneration() // THEN start a new generation of the inflation - rowImageInflater = RowImageInflater.newInstance(rowImageInflater.getNewImageIndex()) + rowImageInflater = RowImageInflater.newInstance(getNewImageIndex(), reinflating = false) getNewImageIndex_returnsEmptyIndexWhenZeroImagesLoaded() } @@ -104,13 +107,47 @@ class RowImageInflaterTest : SysuiTestCase() { @Test fun exampleSecondGeneration_whichLoadsOneImage() { exampleFirstGeneration() + val gen1Index = latestImageModelIndex!! // THEN start a new generation of the inflation - rowImageInflater = RowImageInflater.newInstance(rowImageInflater.getNewImageIndex()) + rowImageInflater = RowImageInflater.newInstance(gen1Index, reinflating = false) getNewImageIndex_returnsSingleImageWhenOneImageLoaded() + val gen2Index = latestImageModelIndex!! + + // VERIFY that the drawable was copied from the previous index + val gen1model = gen1Index.findModel(resIcon1) + val gen2model = gen2Index.findModel(resIcon1) + assertThat(gen2model).isNotSameInstanceAs(gen1model) + assertThat(gen2model.drawable).isSameInstanceAs(gen1model.drawable) } + @Test + fun exampleSecondGeneration_reinflating_whichLoadsOneImage() { + exampleFirstGeneration() + val gen1Index = latestImageModelIndex!! + + // THEN start a new generation of the inflation + rowImageInflater = RowImageInflater.newInstance(gen1Index, reinflating = true) + + getNewImageIndex_returnsSingleImageWhenOneImageLoaded() + val gen2Index = latestImageModelIndex!! + + // VERIFY that the drawable was reloaded rather than copied from the previous index + val gen1model = gen1Index.findModel(resIcon1) + val gen2model = gen2Index.findModel(resIcon1) + assertThat(gen2model).isNotSameInstanceAs(gen1model) + assertThat(gen2model.drawable).isNotSameInstanceAs(gen1model.drawable) + } + + private fun ImageModelIndex.findModel(icon: Icon): LazyImage = + IconData.fromIcon(icon) + .let { iconData -> contentsForTesting.find { it.icon == iconData } } + .also { assertThat(it).isNotNull() }!! + + private fun getNewImageIndex(): ImageModelIndex? = + rowImageInflater.getNewImageIndex().also { latestImageModelIndex = it } + private fun getImageModelsForIcons(vararg icons: Icon): List<ImageModel> { val provider = rowImageInflater.useForContentModel() return icons.map { icon -> diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt index da879d9e314d..2b3158da38f9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt @@ -39,7 +39,8 @@ fun Kosmos.setPromotedContent(entry: NotificationEntry) { promotedNotificationContentExtractor.extractContent( entry, Notification.Builder.recoverBuilder(applicationContext, entry.sbn.notification), - RowImageInflater.newInstance(null).useForContentModel(), + RowImageInflater.newInstance(previousIndex = null, reinflating = false) + .useForContentModel(), ) entry.promotedNotificationContentModel = requireNotNull(extractedContent) { "extractContent returned null" } |