Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26b6a899 authored by Julia Tuttle's avatar Julia Tuttle
Browse files

Add and plumb PromotedNotificationContentExtractor

Bug: 369151941
Test: TODO
Flag: android.app.ui_rich_ongoing
Flag: com.android.systemui.status_bar_notification_chips
Change-Id: I180bc9998330a35e414aeee6c74c1cd3b45ad0bd
parent a8926f09
Loading
Loading
Loading
Loading
+210 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.promoted

import android.app.Notification
import android.app.Notification.BigPictureStyle
import android.app.Notification.BigTextStyle
import android.app.Notification.CallStyle
import android.app.Notification.MessagingStyle
import android.app.Notification.ProgressStyle
import android.app.Notification.ProgressStyle.Segment
import android.app.PendingIntent
import android.app.Person
import android.content.Intent
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class PromotedNotificationContentExtractorTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private val provider =
        FakePromotedNotificationsProvider().also { kosmos.promotedNotificationsProvider = it }

    private val underTest = kosmos.promotedNotificationContentExtractor

    @Test
    @DisableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun shouldNotExtract_bothFlagsDisabled() {
        val notif = createEntry().also { provider.promotedEntries.add(it) }
        val content = extractContent(notif)
        assertThat(content).isNull()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
    fun shouldExtract_promotedNotificationUiFlagEnabled() {
        val entry = createEntry().also { provider.promotedEntries.add(it) }
        val content = extractContent(entry)
        assertThat(content).isNotNull()
    }

    @Test
    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    fun shouldExtract_statusBarNotifChipsFlagEnabled() {
        val entry = createEntry().also { provider.promotedEntries.add(it) }
        val content = extractContent(entry)
        assertThat(content).isNotNull()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun shouldExtract_bothFlagsEnabled() {
        val entry = createEntry().also { provider.promotedEntries.add(it) }
        val content = extractContent(entry)
        assertThat(content).isNotNull()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun shouldNotExtract_providerDidNotPromote() {
        val entry = createEntry().also { provider.promotedEntries.remove(it) }
        val content = extractContent(entry)
        assertThat(content).isNull()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_commonFields() {
        val entry =
            createEntry {
                    setSubText(TEST_SUB_TEXT)
                    setContentTitle(TEST_CONTENT_TITLE)
                    setContentText(TEST_CONTENT_TEXT)
                }
                .also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.subText).isEqualTo(TEST_SUB_TEXT)
        assertThat(content?.title).isEqualTo(TEST_CONTENT_TITLE)
        assertThat(content?.text).isEqualTo(TEST_CONTENT_TEXT)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_fromBigPictureStyle() {
        val entry =
            createEntry { setStyle(BigPictureStyle()) }.also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.style).isEqualTo(Style.BigPicture)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_fromBigTextStyle() {
        val entry =
            createEntry { setStyle(BigTextStyle()) }.also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.style).isEqualTo(Style.BigText)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_fromCallStyle() {
        val hangUpIntent =
            PendingIntent.getBroadcast(context, 0, Intent("hangup"), PendingIntent.FLAG_IMMUTABLE)

        val entry =
            createEntry { setStyle(CallStyle.forOngoingCall(TEST_PERSON, hangUpIntent)) }
                .also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.style).isEqualTo(Style.Call)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_fromProgressStyle() {
        val entry =
            createEntry {
                    setStyle(ProgressStyle().addProgressSegment(Segment(100)).setProgress(75))
                }
                .also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.style).isEqualTo(Style.Progress)
        assertThat(content?.progress).isNotNull()
        assertThat(content?.progress?.progress).isEqualTo(75)
        assertThat(content?.progress?.progressMax).isEqualTo(100)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun extractContent_fromIneligibleStyle() {
        val entry =
            createEntry {
                    setStyle(
                        MessagingStyle(TEST_PERSON).addMessage("message text", 0L, TEST_PERSON)
                    )
                }
                .also { provider.promotedEntries.add(it) }

        val content = extractContent(entry)

        assertThat(content).isNotNull()
        assertThat(content?.style).isEqualTo(Style.Ineligible)
    }

    private fun extractContent(entry: NotificationEntry): PromotedNotificationContentModel? {
        val recoveredBuilder = Notification.Builder(context, entry.sbn.notification)
        return underTest.extractContent(entry, recoveredBuilder)
    }

    private fun createEntry(builderBlock: Notification.Builder.() -> Unit = {}): NotificationEntry {
        val notif = Notification.Builder(context, "a").also(builderBlock).build()
        return NotificationEntryBuilder().setNotification(notif).build()
    }

    companion object {
        private const val TEST_SUB_TEXT = "sub text"
        private const val TEST_CONTENT_TITLE = "content title"
        private const val TEST_CONTENT_TEXT = "content text"

        private const val TEST_PERSON_NAME = "person name"
        private const val TEST_PERSON_KEY = "person key"
        private val TEST_PERSON =
            Person.Builder().setKey(TEST_PERSON_KEY).setName(TEST_PERSON_NAME).build()
    }
}
+77 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -42,6 +43,7 @@ import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.TypedValue;
@@ -56,8 +58,12 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.controls.util.MediaFeatureFlag;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor;
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -99,6 +105,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
    @Mock private NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
    @Mock private HeadsUpStyleProvider mHeadsUpStyleProvider;
    @Mock private NotifLayoutInflaterFactory mNotifLayoutInflaterFactory;
    @Mock private PromotedNotificationContentExtractor mPromotedNotificationContentExtractor;

    private final SmartReplyStateInflater mSmartReplyStateInflater =
            new SmartReplyStateInflater() {
@@ -142,6 +149,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
                mSmartReplyStateInflater,
                mNotifLayoutInflaterFactoryProvider,
                mHeadsUpStyleProvider,
                mPromotedNotificationContentExtractor,
                mock(NotificationRowContentBinderLogger.class));
    }

@@ -382,6 +390,75 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
        verify(mRow, times(0)).onNotificationUpdated();
    }

    @Test
    @DisableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
    public void testExtractsPromotedContent_notWhenBothFlagsDisabled() throws Exception {
        final PromotedNotificationContentModel content =
                new PromotedNotificationContentModel.Builder("key").build();
        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
                .thenReturn(content);

        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);

        verify(mPromotedNotificationContentExtractor, never()).extractContent(any(), any());
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
    public void testExtractsPromotedContent_whenPromotedNotificationUiFlagEnabled()
            throws Exception {
        final PromotedNotificationContentModel content =
                new PromotedNotificationContentModel.Builder("key").build();
        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
                .thenReturn(content);

        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);

        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
    }

    @Test
    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    public void testExtractsPromotedContent_whenStatusBarNotifChipsFlagEnabled() throws Exception {
        final PromotedNotificationContentModel content =
                new PromotedNotificationContentModel.Builder("key").build();
        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
                .thenReturn(content);

        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);

        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
    }

    @Test
    @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
    public void testExtractsPromotedContent_whenBothFlagsEnabled() throws Exception {
        final PromotedNotificationContentModel content =
                new PromotedNotificationContentModel.Builder("key").build();
        when(mPromotedNotificationContentExtractor.extractContent(any(), any()))
                .thenReturn(content);

        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);

        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
        assertEquals(content, mRow.getEntry().getPromotedNotificationContentModel());
    }

    @Test
    @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
    public void testExtractsPromotedContent_null() throws Exception {
        when(mPromotedNotificationContentExtractor.extractContent(any(), any())).thenReturn(null);

        inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);

        verify(mPromotedNotificationContentExtractor, times(1)).extractContent(any(), any());
        assertNull(mRow.getEntry().getPromotedNotificationContentModel());
    }

    private static void inflateAndWait(NotificationContentInflater inflater,
            @InflationFlag int contentToInflate,
            ExpandableNotificationRow row)
+84 −20
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context
import android.os.AsyncTask
import android.os.Build
import android.os.CancellationSignal
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import android.util.TypedValue
@@ -33,8 +34,12 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
@@ -62,6 +67,7 @@ import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.spy
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@@ -82,7 +88,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        object : NotifLayoutInflaterFactory.Provider {
            override fun provide(
                row: ExpandableNotificationRow,
                layoutType: Int
                layoutType: Int,
            ): NotifLayoutInflaterFactory = mock()
        }
    private val smartReplyStateInflater: SmartReplyStateInflater =
@@ -95,7 +101,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                notifPackageContext: Context,
                entry: NotificationEntry,
                existingSmartReplyState: InflatedSmartReplyState?,
                newSmartReplyState: InflatedSmartReplyState
                newSmartReplyState: InflatedSmartReplyState,
            ): InflatedSmartReplyViewHolder {
                return inflatedSmartReplies
            }
@@ -104,6 +110,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                return inflatedSmartReplyState
            }
        }
    private val promotedNotificationContentExtractor: PromotedNotificationContentExtractor = mock()

    @Before
    fun setUp() {
@@ -125,7 +132,8 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                smartReplyStateInflater,
                layoutInflaterFactoryProvider,
                mock<HeadsUpStyleProvider>(),
                mock()
                promotedNotificationContentExtractor,
                mock(),
            )
    }

@@ -142,7 +150,8 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            FLAG_CONTENT_VIEW_ALL,
            builder,
            mContext,
            smartReplyStateInflater
            smartReplyStateInflater,
            mock(),
        )
        verify(builder).createHeadsUpContentView(true)
    }
@@ -160,7 +169,8 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            FLAG_CONTENT_VIEW_ALL,
            builder,
            mContext,
            smartReplyStateInflater
            smartReplyStateInflater,
            mock(),
        )
        verify(builder).createContentView(true)
    }
@@ -187,7 +197,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            true /* expectingException */,
            notificationInflater,
            FLAG_CONTENT_VIEW_ALL,
            row
            row,
        )
        Assert.assertTrue(row.privateLayout.childCount == 0)
        verify(row, times(0)).onNotificationUpdated()
@@ -210,7 +220,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            FLAG_CONTENT_VIEW_ALL,
            BindParams(),
            false /* forceInflate */,
            null /* callback */
            null, /* callback */
        )
        Assert.assertNull(row.entry.runningTask)
    }
@@ -223,7 +233,8 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            NotificationRowContentBinderImpl.InflationProgress(
                packageContext = mContext,
                remoteViews = NewRemoteViews(),
                contentModel = NotificationContentModel(headsUpStatusBarModel)
                contentModel = NotificationContentModel(headsUpStatusBarModel),
                extractedPromotedNotificationContentModel = null,
            )
        val countDownLatch = CountDownLatch(1)
        NotificationRowContentBinderImpl.applyRemoteView(
@@ -261,7 +272,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                        get() =
                            AsyncFailRemoteView(
                                mContext.packageName,
                                com.android.systemui.tests.R.layout.custom_view_dark
                                com.android.systemui.tests.R.layout.custom_view_dark,
                            )
                },
            logger = mock(),
@@ -280,7 +291,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        val decoratedMediaView = builder.createContentView()
        Assert.assertFalse(
            "The decorated media style doesn't allow a view to be reapplied!",
            NotificationRowContentBinderImpl.canReapplyRemoteView(mediaView, decoratedMediaView)
            NotificationRowContentBinderImpl.canReapplyRemoteView(mediaView, decoratedMediaView),
        )
    }

@@ -304,7 +315,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        Assert.assertEquals(
            "Binder inflated a new view even though the old one was cached and usable.",
            view,
            row.privateLayout.contractedChild
            row.privateLayout.contractedChild,
        )
    }

@@ -327,7 +338,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        Assert.assertNotEquals(
            "Binder (somehow) used the same view when inflating.",
            view,
            row.privateLayout.contractedChild
            row.privateLayout.contractedChild,
        )
    }

@@ -396,7 +407,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
    private fun getValidationError(
        measuredHeightDp: Float,
        targetSdk: Int,
        contentView: RemoteViews?
        contentView: RemoteViews?,
    ): String? {
        val view: View = mock()
        whenever(view.measuredHeight)
@@ -404,7 +415,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                TypedValue.applyDimension(
                        COMPLEX_UNIT_SP,
                        measuredHeightDp,
                        mContext.resources.displayMetrics
                        mContext.resources.displayMetrics,
                    )
                    .toInt()
            )
@@ -419,7 +430,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        row.entry.sbn.notification.contentView =
            RemoteViews(
                mContext.packageName,
                com.android.systemui.tests.R.layout.invalid_notification_height
                com.android.systemui.tests.R.layout.invalid_notification_height,
            )
        inflateAndWait(true, notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
        Assert.assertEquals(0, row.privateLayout.childCount.toLong())
@@ -451,7 +462,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            false,
            notificationInflater,
            FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
            messagingRow
            messagingRow,
        )
        Assert.assertNotNull(messagingRow.publicLayout.mSingleLineView)
        // assert this is the conversation layout
@@ -460,6 +471,59 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        )
    }

    @Test
    @DisableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun testExtractsPromotedContent_notWhenBothFlagsDisabled() {
        val content = PromotedNotificationContentModel.Builder("key").build()
        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
            .thenReturn(content)

        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)

        verify(promotedNotificationContentExtractor, never()).extractContent(any(), any())
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    @DisableFlags(StatusBarNotifChips.FLAG_NAME)
    fun testExtractsPromotedContent_whenPromotedNotificationUiFlagEnabled() {
        val content = PromotedNotificationContentModel.Builder("key").build()
        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
            .thenReturn(content)

        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)

        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
    }

    @Test
    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    fun testExtractsPromotedContent_whenStatusBarNotifChipsFlagEnabled() {
        val content = PromotedNotificationContentModel.Builder("key").build()
        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
            .thenReturn(content)

        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)

        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun testExtractsPromotedContent_whenBothFlagsEnabled() {
        val content = PromotedNotificationContentModel.Builder("key").build()
        whenever(promotedNotificationContentExtractor.extractContent(any(), any()))
            .thenReturn(content)

        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)

        verify(promotedNotificationContentExtractor, times(1)).extractContent(any(), any())
        Assert.assertEquals(content, row.entry.promotedNotificationContentModel)
    }

    private class ExceptionHolder {
        var exception: Exception? = null
    }
@@ -476,7 +540,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            parent: ViewGroup,
            executor: Executor,
            listener: OnViewAppliedListener,
            handler: InteractionHandler?
            handler: InteractionHandler?,
        ): CancellationSignal {
            executor.execute { listener.onError(RuntimeException("Failed to inflate async")) }
            return CancellationSignal()
@@ -486,7 +550,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
            context: Context,
            parent: ViewGroup,
            executor: Executor,
            listener: OnViewAppliedListener
            listener: OnViewAppliedListener,
        ): CancellationSignal {
            return applyAsync(context, parent, executor, listener, null)
        }
@@ -496,7 +560,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
        private fun inflateAndWait(
            inflater: NotificationRowContentBinderImpl,
            @InflationFlag contentToInflate: Int,
            row: ExpandableNotificationRow
            row: ExpandableNotificationRow,
        ) {
            inflateAndWait(false /* expectingException */, inflater, contentToInflate, row)
        }
@@ -535,7 +599,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() {
                contentToInflate,
                BindParams(),
                false /* forceInflate */,
                callback /* callback */
                callback, /* callback */
            )
            Assert.assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS))
            exceptionHolder.exception?.let { throw it }
+3 −0

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -1075,7 +1075,7 @@ public final class NotificationEntry extends ListEntry {
        if (PromotedNotificationContentModel.featureFlagEnabled()) {
            return mPromotedNotificationContentModel;
        } else {
            Log.wtf(TAG, "getting promoted content without feature flag enabled");
            Log.wtf(TAG, "getting promoted content without feature flag enabled", new Throwable());
            return null;
        }
    }
@@ -1089,7 +1089,7 @@ public final class NotificationEntry extends ListEntry {
        if (PromotedNotificationContentModel.featureFlagEnabled()) {
            this.mPromotedNotificationContentModel = promotedNotificationContentModel;
        } else {
            Log.wtf(TAG, "setting promoted content without feature flag enabled");
            Log.wtf(TAG, "setting promoted content without feature flag enabled", new Throwable());
        }
    }

Loading