diff options
| author | 2025-03-04 06:07:27 -0800 | |
|---|---|---|
| committer | 2025-03-04 06:07:27 -0800 | |
| commit | 5bd707740ae38cf9f17895257774055ed8f48338 (patch) | |
| tree | 0b27c699c9ecd361e956dd3f6f4d68b17a632393 | |
| parent | a0a2dca12d1a6c67613d22ce8430e1f25ce38512 (diff) | |
| parent | 703c86c47371ad3b4c7a8ffaaca4d6d440c7d80f (diff) | |
Merge "Invert adapter/entry relationship" into main
26 files changed, 1001 insertions, 687 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt index 83fd5dcd5f82..a13b8647e170 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt @@ -34,123 +34,122 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) @RunWithLooper -class BundleEntryTest : SysuiTestCase() { - private lateinit var underTest: BundleEntry +class BundleEntryAdapterTest : SysuiTestCase() { + private lateinit var underTest: BundleEntryAdapter - @get:Rule - val setFlagsRule = SetFlagsRule() + @get:Rule val setFlagsRule = SetFlagsRule() @Before fun setUp() { - underTest = BundleEntry("key") + underTest = BundleEntryAdapter(BundleEntry("key")) } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getParent_adapter() { - assertThat(underTest.entryAdapter.parent).isEqualTo(GroupEntry.ROOT_ENTRY) + assertThat(underTest.parent).isEqualTo(GroupEntry.ROOT_ENTRY) } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isTopLevelEntry_adapter() { - assertThat(underTest.entryAdapter.isTopLevelEntry).isTrue() + assertThat(underTest.isTopLevelEntry).isTrue() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getRow_adapter() { - assertThat(underTest.entryAdapter.row).isNull() + assertThat(underTest.row).isNull() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isGroupRoot_adapter() { - assertThat(underTest.entryAdapter.isGroupRoot).isTrue() + assertThat(underTest.isGroupRoot).isTrue() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getKey_adapter() { - assertThat(underTest.entryAdapter.key).isEqualTo("key") + assertThat(underTest.key).isEqualTo("key") } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isClearable_adapter() { - assertThat(underTest.entryAdapter.isClearable).isTrue() + assertThat(underTest.isClearable).isTrue() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getSummarization_adapter() { - assertThat(underTest.entryAdapter.summarization).isNull() + assertThat(underTest.summarization).isNull() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getContrastedColor_adapter() { - assertThat(underTest.entryAdapter.getContrastedColor(context, false, Color.WHITE)) + assertThat(underTest.getContrastedColor(context, false, Color.WHITE)) .isEqualTo(Notification.COLOR_DEFAULT) } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun canPeek_adapter() { - assertThat(underTest.entryAdapter.canPeek()).isFalse() + assertThat(underTest.canPeek()).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getWhen_adapter() { - assertThat(underTest.entryAdapter.`when`).isEqualTo(0) + assertThat(underTest.`when`).isEqualTo(0) } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isColorized() { - assertThat(underTest.entryAdapter.isColorized).isFalse() + assertThat(underTest.isColorized).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getSbn() { - assertThat(underTest.entryAdapter.sbn).isNull() + assertThat(underTest.sbn).isNull() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun canDragAndDrop() { - assertThat(underTest.entryAdapter.canDragAndDrop()).isFalse() + assertThat(underTest.canDragAndDrop()).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isBubble() { - assertThat(underTest.entryAdapter.isBubbleCapable).isFalse() + assertThat(underTest.isBubbleCapable).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getStyle() { - assertThat(underTest.entryAdapter.style).isNull() + assertThat(underTest.style).isNull() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun getSectionBucket() { - assertThat(underTest.entryAdapter.sectionBucket).isEqualTo(underTest.bucket) + assertThat(underTest.sectionBucket).isEqualTo(underTest.entry.bucket) } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isAmbient() { - assertThat(underTest.entryAdapter.isAmbient).isFalse() + assertThat(underTest.isAmbient).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun canShowFullScreen() { - assertThat(underTest.entryAdapter.isFullScreenCapable()).isFalse() + assertThat(underTest.isFullScreenCapable()).isFalse() } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt new file mode 100644 index 000000000000..b6889afa4e8a --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2025 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 + +import android.app.ActivityManager +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.os.UserHandle +import android.platform.test.annotations.EnableFlags +import android.platform.test.flag.junit.SetFlagsRule +import android.testing.TestableLooper.RunWithLooper +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.RankingBuilder +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.row.entryAdapterFactory +import com.android.systemui.statusbar.notification.shared.NotificationBundleUi +import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.Mockito.verify + +@SmallTest +@RunWith(AndroidJUnit4::class) +@RunWithLooper +class NotificationEntryAdapterTest : SysuiTestCase() { + private val kosmos = testKosmos() + + private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory + private lateinit var underTest: NotificationEntryAdapter + + @get:Rule val setFlagsRule = SetFlagsRule() + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getParent_adapter() { + val ge = GroupEntryBuilder().build() + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .setParent(ge) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.parent).isEqualTo(entry.parent) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isTopLevelEntry_adapter() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .setParent(GroupEntry.ROOT_ENTRY) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isTopLevelEntry).isTrue() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getKey_adapter() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.key).isEqualTo(entry.key) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getRow_adapter() { + val row = Mockito.mock(ExpandableNotificationRow::class.java) + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .build() + entry.row = row + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.row).isEqualTo(entry.row) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isGroupRoot_adapter_groupSummary() { + val row = Mockito.mock(ExpandableNotificationRow::class.java) + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setGroupSummary(true) + .setGroup("key") + .build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .setParent(GroupEntry.ROOT_ENTRY) + .build() + entry.row = row + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isGroupRoot).isFalse() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isGroupRoot_adapter_groupChild() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setGroupSummary(true) + .setGroup("key") + .build() + + val parent = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build() + val groupEntry = GroupEntryBuilder().setSummary(parent) + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .setParent(groupEntry.build()) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isGroupRoot).isFalse() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isClearable_adapter() { + val row = Mockito.mock(ExpandableNotificationRow::class.java) + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .build() + entry.row = row + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isClearable).isEqualTo(entry.isClearable) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getSummarization_adapter() { + val row = Mockito.mock(ExpandableNotificationRow::class.java) + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .build() + val ranking = RankingBuilder(entry.ranking).setSummarization("hello").build() + entry.setRanking(ranking) + entry.row = row + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.summarization).isEqualTo("hello") + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getIcons_adapter() { + val row = Mockito.mock(ExpandableNotificationRow::class.java) + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setUser(UserHandle(ActivityManager.getCurrentUser())) + .build() + entry.row = row + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.icons).isEqualTo(entry.icons) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isColorized() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setColorized(true) + .build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isColorized).isEqualTo(entry.sbn.notification.isColorized) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getSbn() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.sbn).isEqualTo(entry.sbn) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun canDragAndDrop() { + val pi = Mockito.mock(PendingIntent::class.java) + Mockito.`when`(pi.isActivity).thenReturn(true) + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setContentIntent(pi) + .build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.canDragAndDrop()).isTrue() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isBubble() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setFlag(Notification.FLAG_BUBBLE, true) + .build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isBubbleCapable).isEqualTo(entry.isBubble) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getStyle() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setStyle(Notification.BigTextStyle()) + .build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.style).isEqualTo(entry.notificationStyle) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun getSectionBucket() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setStyle(Notification.BigTextStyle()) + .build() + + val entry = NotificationEntryBuilder().setNotification(notification).build() + entry.bucket = BUCKET_ALERTING + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.sectionBucket).isEqualTo(BUCKET_ALERTING) + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun isAmbient() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setImportance(NotificationManager.IMPORTANCE_MIN) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isAmbient).isTrue() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun canShowFullScreen() { + val notification: Notification = + Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setFullScreenIntent(Mockito.mock(PendingIntent::class.java), true) + .build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setImportance(NotificationManager.IMPORTANCE_MIN) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + assertThat(underTest.isFullScreenCapable).isTrue() + } + + @Test + @EnableFlags(NotificationBundleUi.FLAG_NAME) + fun onNotificationBubbleIconClicked() { + val notification: Notification = + Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + + val entry = + NotificationEntryBuilder() + .setNotification(notification) + .setImportance(NotificationManager.IMPORTANCE_MIN) + .build() + + underTest = factory.create(entry) as NotificationEntryAdapter + + underTest.onNotificationBubbleIconClicked() + verify((factory as? EntryAdapterFactoryImpl)?.getNotificationActivityStarter()) + ?.onNotificationBubbleIconClicked(entry) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 481081344dbb..790b2c343a11 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -21,24 +21,17 @@ import static android.app.Notification.CATEGORY_CALL; import static android.app.Notification.CATEGORY_EVENT; import static android.app.Notification.CATEGORY_MESSAGE; import static android.app.Notification.CATEGORY_REMINDER; -import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED; import static android.app.Notification.FLAG_PROMOTED_ONGOING; -import static android.app.NotificationManager.IMPORTANCE_MIN; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking; import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn; -import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_ALERTING; - -import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.Notification; @@ -66,8 +59,6 @@ import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips; import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; @@ -458,336 +449,6 @@ public class NotificationEntryTest extends SysuiTestCase { // no crash, good } - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getParent_adapter() { - GroupEntry ge = new GroupEntryBuilder() - .build(); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .setParent(ge) - .build(); - - assertThat(entry.getEntryAdapter().getParent()).isEqualTo(entry.getParent()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isTopLevelEntry_adapter() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .setParent(GroupEntry.ROOT_ENTRY) - .build(); - - assertThat(entry.getEntryAdapter().isTopLevelEntry()).isTrue(); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getKey_adapter() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .build(); - - assertThat(entry.getEntryAdapter().getKey()).isEqualTo(entry.getKey()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getRow_adapter() { - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .build(); - entry.setRow(row); - - assertThat(entry.getEntryAdapter().getRow()).isEqualTo(entry.getRow()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isGroupRoot_adapter_groupSummary() { - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setGroupSummary(true) - .setGroup("key") - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .setParent(GroupEntry.ROOT_ENTRY) - .build(); - entry.setRow(row); - - assertThat(entry.getEntryAdapter().isGroupRoot()).isFalse(); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isGroupRoot_adapter_groupChild() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setGroupSummary(true) - .setGroup("key") - .build(); - - NotificationEntry parent = new NotificationEntryBuilder() - .setParent(GroupEntry.ROOT_ENTRY) - .build(); - GroupEntryBuilder groupEntry = new GroupEntryBuilder() - .setSummary(parent); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .setParent(groupEntry.build()) - .build(); - - assertThat(entry.getEntryAdapter().isGroupRoot()).isFalse(); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isClearable_adapter() { - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .build(); - entry.setRow(row); - - assertThat(entry.getEntryAdapter().isClearable()).isEqualTo(entry.isClearable()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getSummarization_adapter() { - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .build(); - Ranking ranking = new RankingBuilder(entry.getRanking()) - .setSummarization("hello") - .build(); - entry.setRanking(ranking); - entry.setRow(row); - - assertThat(entry.getEntryAdapter().getSummarization()).isEqualTo("hello"); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getIcons_adapter() { - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg(TEST_PACKAGE_NAME) - .setOpPkg(TEST_PACKAGE_NAME) - .setUid(TEST_UID) - .setChannel(mChannel) - .setId(mId++) - .setNotification(notification) - .setUser(new UserHandle(ActivityManager.getCurrentUser())) - .build(); - entry.setRow(row); - - assertThat(entry.getEntryAdapter().getIcons()).isEqualTo(entry.getIcons()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isColorized() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setColorized(true) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - assertThat(entry.getEntryAdapter().isColorized()).isEqualTo( - entry.getSbn().getNotification().isColorized()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getSbn() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - assertThat(entry.getEntryAdapter().getSbn()).isEqualTo( - entry.getSbn()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void canDragAndDrop() { - PendingIntent pi = mock(PendingIntent.class); - when(pi.isActivity()).thenReturn(true); - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setContentIntent(pi) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - assertThat(entry.getEntryAdapter().canDragAndDrop()).isTrue(); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isBubble() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setFlag(FLAG_BUBBLE, true) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - assertThat(entry.getEntryAdapter().isBubbleCapable()).isEqualTo(entry.isBubble()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getStyle() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setStyle(new Notification.BigTextStyle()) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - assertThat(entry.getEntryAdapter().getStyle()).isEqualTo(entry.getNotificationStyle()); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void getSectionBucket() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setStyle(new Notification.BigTextStyle()) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .build(); - entry.setBucket(BUCKET_ALERTING); - - assertThat(entry.getEntryAdapter().getSectionBucket()).isEqualTo(BUCKET_ALERTING); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void isAmbient() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .setImportance(IMPORTANCE_MIN) - .build(); - - assertThat(entry.getEntryAdapter().isAmbient()).isTrue(); - } - - @Test - @EnableFlags(NotificationBundleUi.FLAG_NAME) - public void canShowFullScreen() { - Notification notification = new Notification.Builder(mContext, "") - .setSmallIcon(R.drawable.ic_person) - .setFullScreenIntent(mock(PendingIntent.class), true) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setNotification(notification) - .setImportance(IMPORTANCE_MIN) - .build(); - - assertThat(entry.getEntryAdapter().isFullScreenCapable()).isTrue(); - } - private Notification.Action createContextualAction(String title) { return new Notification.Action.Builder( Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon), diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt index 8e6aedcae506..9e27c79d54b8 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt @@ -16,8 +16,6 @@ package com.android.systemui.statusbar.notification.collection.render -import android.os.Build -import android.os.UserHandle import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.SetFlagsRule @@ -26,6 +24,7 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import com.android.systemui.log.assertLogsWtf +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.ListEntry @@ -36,12 +35,13 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper +import com.android.systemui.statusbar.notification.row.entryAdapterFactory import com.android.systemui.statusbar.notification.shared.NotificationBundleUi +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat -import org.junit.Assume import org.junit.Before import org.junit.Rule import org.junit.Test @@ -54,11 +54,11 @@ import org.mockito.Mockito.`when` as whenever @SmallTest @RunWith(AndroidJUnit4::class) class GroupExpansionManagerTest : SysuiTestCase() { - @get:Rule - val setFlagsRule = SetFlagsRule() + @get:Rule val setFlagsRule = SetFlagsRule() private lateinit var underTest: GroupExpansionManagerImpl + private val kosmos = testKosmos() private lateinit var testHelper: NotificationTestHelper private val dumpManager: DumpManager = mock() private val groupMembershipManager: GroupMembershipManager = mock() @@ -66,15 +66,14 @@ class GroupExpansionManagerTest : SysuiTestCase() { private val pipeline: NotifPipeline = mock() private lateinit var beforeRenderListListener: OnBeforeRenderListListener + private val factory: EntryAdapterFactoryImpl = kosmos.entryAdapterFactory private lateinit var summary1: NotificationEntry private lateinit var summary2: NotificationEntry private lateinit var entries: List<ListEntry> private fun notificationEntry(pkg: String, id: Int, parent: ExpandableNotificationRow?) = NotificationEntryBuilder().setPkg(pkg).setId(id).build().apply { - row = testHelper.createRow().apply { - setIsChildInGroup(true, parent) - } + row = testHelper.createRow().apply { setIsChildInGroup(true, parent) } } @Before @@ -91,7 +90,7 @@ class GroupExpansionManagerTest : SysuiTestCase() { listOf( notificationEntry("foo", 2, summary1.row), notificationEntry("foo", 3, summary1.row), - notificationEntry("foo", 4, summary1.row) + notificationEntry("foo", 4, summary1.row), ) ) .build(), @@ -101,11 +100,11 @@ class GroupExpansionManagerTest : SysuiTestCase() { listOf( notificationEntry("bar", 2, summary2.row), notificationEntry("bar", 3, summary2.row), - notificationEntry("bar", 4, summary2.row) + notificationEntry("bar", 4, summary2.row), ) ) .build(), - notificationEntry("baz", 1, null) + notificationEntry("baz", 1, null), ) whenever(groupMembershipManager.getGroupSummary(summary1)).thenReturn(summary1) @@ -135,18 +134,20 @@ class GroupExpansionManagerTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun notifyOnlyOnChange_withEntryAdapter() { + val entryAdapter1 = factory.create(summary1) + val entryAdapter2 = factory.create(summary2) var listenerCalledCount = 0 underTest.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ } - underTest.setGroupExpanded(summary1.entryAdapter, false) + underTest.setGroupExpanded(entryAdapter1, false) assertThat(listenerCalledCount).isEqualTo(0) - underTest.setGroupExpanded(summary1.entryAdapter, true) + underTest.setGroupExpanded(entryAdapter1, true) assertThat(listenerCalledCount).isEqualTo(1) - underTest.setGroupExpanded(summary2.entryAdapter, true) + underTest.setGroupExpanded(entryAdapter2, true) assertThat(listenerCalledCount).isEqualTo(2) - underTest.setGroupExpanded(summary1.entryAdapter, true) + underTest.setGroupExpanded(entryAdapter1, true) assertThat(listenerCalledCount).isEqualTo(2) - underTest.setGroupExpanded(summary2.entryAdapter, false) + underTest.setGroupExpanded(entryAdapter2, false) assertThat(listenerCalledCount).isEqualTo(3) } @@ -168,16 +169,17 @@ class GroupExpansionManagerTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun expandUnattachedEntryAdapter() { + val entryAdapter = factory.create(summary1) // First, expand the entry when it is attached. - underTest.setGroupExpanded(summary1.entryAdapter, true) - assertThat(underTest.isGroupExpanded(summary1.entryAdapter)).isTrue() + underTest.setGroupExpanded(entryAdapter, true) + assertThat(underTest.isGroupExpanded(entryAdapter)).isTrue() // Un-attach it, and un-expand it. NotificationEntryBuilder.setNewParent(summary1, null) - underTest.setGroupExpanded(summary1.entryAdapter, false) + underTest.setGroupExpanded(entryAdapter, false) // Expanding again should throw. - assertLogsWtf { underTest.setGroupExpanded(summary1.entryAdapter, true) } + assertLogsWtf { underTest.setGroupExpanded(entryAdapter, true) } } @Test @@ -207,6 +209,7 @@ class GroupExpansionManagerTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun syncWithPipeline_withEntryAdapter() { + val entryAdapter = factory.create(summary1) underTest.attach(pipeline) beforeRenderListListener = withArgCaptor { verify(pipeline).addOnBeforeRenderListListener(capture()) @@ -219,7 +222,7 @@ class GroupExpansionManagerTest : SysuiTestCase() { verify(listener, never()).onGroupExpansionChange(any(), any()) // Expand one of the groups. - underTest.setGroupExpanded(summary1.entryAdapter, true) + underTest.setGroupExpanded(entryAdapter, true) verify(listener).onGroupExpansionChange(summary1.row, true) // Empty the pipeline list and verify that the group is no longer expanded. @@ -231,11 +234,15 @@ class GroupExpansionManagerTest : SysuiTestCase() { @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isGroupExpanded() { - underTest.setGroupExpanded(summary1.entryAdapter, true) - - assertThat(underTest.isGroupExpanded(summary1.entryAdapter)).isTrue(); - assertThat(underTest.isGroupExpanded( - (entries[0] as? GroupEntry)?.getChildren()?.get(0)?.entryAdapter)) - .isTrue(); + val entryAdapter = summary1.row.entryAdapter + underTest.setGroupExpanded(entryAdapter, true) + + assertThat(underTest.isGroupExpanded(entryAdapter)).isTrue() + assertThat( + underTest.isGroupExpanded( + (entries[0] as? GroupEntry)?.getChildren()?.get(0)?.row?.entryAdapter + ) + ) + .isTrue() } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt index 2bbf094021cf..0ccf58507696 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt @@ -22,10 +22,13 @@ import android.platform.test.flag.junit.SetFlagsRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.row.entryAdapterFactory import com.android.systemui.statusbar.notification.shared.NotificationBundleUi +import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import org.junit.Rule import org.junit.Test @@ -35,8 +38,10 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class GroupMembershipManagerTest : SysuiTestCase() { - @get:Rule - val setFlagsRule = SetFlagsRule() + @get:Rule val setFlagsRule = SetFlagsRule() + + private val kosmos = testKosmos() + private val factory: EntryAdapterFactoryImpl = kosmos.entryAdapterFactory private var underTest = GroupMembershipManagerImpl() @@ -144,14 +149,14 @@ class GroupMembershipManagerTest : SysuiTestCase() { @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isChildEntryAdapterInGroup_topLevel() { val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build() - assertThat(underTest.isChildInGroup(topLevelEntry.entryAdapter)).isFalse() + assertThat(underTest.isChildInGroup(factory.create(topLevelEntry))).isFalse() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isChildEntryAdapterInGroup_noParent() { val noParentEntry = NotificationEntryBuilder().setParent(null).build() - assertThat(underTest.isChildInGroup(noParentEntry.entryAdapter)).isFalse() + assertThat(underTest.isChildInGroup(factory.create(noParentEntry))).isFalse() } @Test @@ -165,7 +170,7 @@ class GroupMembershipManagerTest : SysuiTestCase() { .build() GroupEntryBuilder().setKey(groupKey).setSummary(summary).build() - assertThat(underTest.isChildInGroup(summary.entryAdapter)).isFalse() + assertThat(underTest.isChildInGroup(factory.create(summary))).isFalse() } @Test @@ -180,14 +185,14 @@ class GroupMembershipManagerTest : SysuiTestCase() { val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build() GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build() - assertThat(underTest.isChildInGroup(entry.entryAdapter)).isTrue() + assertThat(underTest.isChildInGroup(factory.create(entry))).isTrue() } @Test @EnableFlags(NotificationBundleUi.FLAG_NAME) fun isGroupRoot_topLevelEntry() { val entry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build() - assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse() + assertThat(underTest.isGroupRoot(factory.create(entry))).isFalse() } @Test @@ -201,7 +206,7 @@ class GroupMembershipManagerTest : SysuiTestCase() { .build() GroupEntryBuilder().setKey(groupKey).setSummary(summary).build() - assertThat(underTest.isGroupRoot(summary.entryAdapter)).isTrue() + assertThat(underTest.isGroupRoot(factory.create(summary))).isTrue() } @Test @@ -216,6 +221,6 @@ class GroupMembershipManagerTest : SysuiTestCase() { val entry = NotificationEntryBuilder().setGroup(mContext, groupKey).build() GroupEntryBuilder().setKey(groupKey).setSummary(summary).addChild(entry).build() - assertThat(underTest.isGroupRoot(entry.entryAdapter)).isFalse() + assertThat(underTest.isGroupRoot(factory.create(entry))).isFalse() } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt index f060caea4f24..bb12eff51288 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt @@ -37,9 +37,12 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.SbnBuilder import com.android.systemui.statusbar.SmartReplyController import com.android.systemui.statusbar.notification.ColorUpdateLogger +import com.android.systemui.statusbar.notification.NotificationActivityStarter import com.android.systemui.statusbar.notification.collection.EntryAdapter +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider import com.android.systemui.statusbar.notification.collection.render.FakeNodeController import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager @@ -47,6 +50,7 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember import com.android.systemui.statusbar.notification.headsup.HeadsUpManager import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController.BUBBLES_SETTING_URI +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger import com.android.systemui.statusbar.notification.stack.NotificationListContainer @@ -112,6 +116,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() { private val uiEventLogger: UiEventLogger = mock() private val msdlPlayer: MSDLPlayer = mock() private val rebindingTracker: NotificationRebindingTracker = mock() + private val entryAdapterFactory: EntryAdapterFactory = mock() private lateinit var controller: ExpandableNotificationRowController @Before @@ -154,6 +159,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() { uiEventLogger, msdlPlayer, rebindingTracker, + entryAdapterFactory, ) whenever(view.childrenContainer).thenReturn(childrenContainer) @@ -277,8 +283,10 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() { whenever(view.privateLayout).thenReturn(childView) val entryAdapter = mock(EntryAdapter::class.java) val sbn = - SbnBuilder().setNotification(Notification.Builder(mContext).build()) - .setUser(UserHandle.of(view.entry.sbn.userId)).build() + SbnBuilder() + .setNotification(Notification.Builder(mContext).build()) + .setUser(UserHandle.of(view.entry.sbn.userId)) + .build() whenever(entryAdapter.sbn).thenReturn(sbn) whenever(view.entryAdapter).thenReturn(entryAdapter) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index c376fad1503f..8e7733bb23ca 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -70,10 +70,14 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.ConversationNotificationProcessor; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.collection.EntryAdapter; +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; @@ -87,6 +91,7 @@ import com.android.systemui.statusbar.notification.promoted.FakePromotedNotifica import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider; import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -101,11 +106,6 @@ import com.android.systemui.util.time.SystemClock; import com.android.systemui.util.time.SystemClockImpl; import com.android.systemui.wmshell.BubblesTestActivity; -import kotlin.coroutines.CoroutineContext; - -import kotlinx.coroutines.flow.StateFlowKt; -import kotlinx.coroutines.test.TestScope; - import org.mockito.ArgumentCaptor; import java.util.List; @@ -114,6 +114,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import kotlin.coroutines.CoroutineContext; +import kotlinx.coroutines.flow.StateFlowKt; +import kotlinx.coroutines.test.TestScope; + /** * A helper class to create {@link ExpandableNotificationRow} (for both individual and group * notifications). @@ -734,7 +738,16 @@ public class NotificationTestHelper { mBindPipelineEntryListener.onEntryInit(entry); mBindPipeline.manageRow(entry, row); + EntryAdapter entryAdapter = new EntryAdapterFactoryImpl( + mock(NotificationActivityStarter.class), + mock(MetricsLogger.class), + mock(PeopleNotificationIdentifier.class), + mock(NotificationIconStyleProvider.class), + mock(VisualStabilityCoordinator.class) + ).create(entry); + row.initialize( + entryAdapter, entry, mock(RemoteInputViewSubcomponent.Factory.class), APP_NAME, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt index 47967b3f0828..670c195ee5a1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.kt @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.commandQueue import com.android.systemui.statusbar.lockscreenShadeTransitionController +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.domain.interactor.notificationAlertsInteractor @@ -54,6 +55,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.row.entryAdapterFactory import com.android.systemui.statusbar.notification.shared.NotificationBundleUi import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController import com.android.systemui.statusbar.notification.visualInterruptionDecisionProvider @@ -105,10 +107,14 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() { private val notificationAlertsInteractor = kosmos.notificationAlertsInteractor private val visualInterruptionDecisionProvider = kosmos.visualInterruptionDecisionProvider + private lateinit var factory: EntryAdapterFactoryImpl + private lateinit var underTest: StatusBarNotificationPresenter @Before fun setup() { + factory = kosmos.entryAdapterFactory + underTest = createPresenter() if (VisualInterruptionRefactor.isEnabled) { verifyAndCaptureSuppressors() @@ -451,7 +457,7 @@ class StatusBarNotificationPresenterTest : SysuiTestCase() { private fun createRow(entry: NotificationEntry): ExpandableNotificationRow { val row: ExpandableNotificationRow = mock() if (NotificationBundleUi.isEnabled) { - whenever(row.entryAdapter).thenReturn(entry.entryAdapter) + whenever(row.entryAdapter).thenReturn(factory.create(entry)) } else { whenever(row.entry).thenReturn(entry) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java index 345ddae42798..c23e0e733b41 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java @@ -46,7 +46,7 @@ import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.NotificationEntry.NotifEntryAdapter; +import com.android.systemui.statusbar.notification.collection.NotificationEntryAdapter; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationContentView; @@ -135,7 +135,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class); final NotificationContentView privateLayout = mock(NotificationContentView.class); final NotificationEntry enrEntry = mock(NotificationEntry.class); - final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class); + final NotificationEntryAdapter enrEntryAdapter = mock(NotificationEntryAdapter.class); when(enr.getPrivateLayout()).thenReturn(privateLayout); when(enr.getEntry()).thenReturn(enrEntry); @@ -178,7 +178,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { // THEN verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); verify(enr).setUserExpanded(true); verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner); } @@ -203,7 +203,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { // THEN verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); verify(enr).setUserExpanded(true); verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner); } @@ -217,7 +217,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class); final NotificationContentView privateLayout = mock(NotificationContentView.class); final NotificationEntry enrEntry = mock(NotificationEntry.class); - final NotifEntryAdapter enrEntryAdapter = mock(NotifEntryAdapter.class); + final NotificationEntryAdapter enrEntryAdapter = mock(NotificationEntryAdapter.class); when(enr.getPrivateLayout()).thenReturn(privateLayout); when(enr.getEntry()).thenReturn(enrEntry); @@ -260,7 +260,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { // THEN verify(mGroupExpansionManager, never()).toggleGroupExpansion(enrEntry); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); verify(enr, never()).setUserExpanded(anyBoolean()); verify(privateLayout, never()).setOnExpandedVisibleListener(any()); } @@ -290,7 +290,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner); verify(enr, never()).setUserExpanded(anyBoolean()); verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); } @Test @@ -318,7 +318,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner); verify(enr, never()).setUserExpanded(anyBoolean()); verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); } @Test @@ -346,7 +346,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner); verify(enr, never()).setUserExpanded(anyBoolean()); verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); } @Test @@ -374,6 +374,6 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner); verify(enr, never()).setUserExpanded(anyBoolean()); verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntry.class)); - verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotifEntryAdapter.class)); + verify(mGroupExpansionManager, never()).toggleGroupExpansion(any(NotificationEntryAdapter.class)); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java index 4053d065cb16..8be9e410f8f6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java @@ -124,8 +124,14 @@ public final class NotificationClicker implements View.OnClickListener { Notification notification = sbn.getNotification(); if (notification.contentIntent != null || notification.fullScreenIntent != null || row.getEntry().isBubble()) { - row.setBubbleClickListener(v -> - mNotificationActivityStarter.onNotificationBubbleIconClicked(row.getEntry())); + if (NotificationBundleUi.isEnabled()) { + row.setBubbleClickListener( + v -> row.getEntryAdapter().onNotificationBubbleIconClicked()); + } else { + row.setBubbleClickListener(v -> + mNotificationActivityStarter.onNotificationBubbleIconClicked( + row.getEntry())); + } row.setOnClickListener(this); row.setOnDragSuccessListener(mOnDragSuccessListener); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java index 6dd44a123538..41353b9921bd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java @@ -45,8 +45,6 @@ import kotlinx.coroutines.flow.StateFlowKt; */ public class BundleEntry extends PipelineEntry { - private final BundleEntryAdapter mEntryAdapter; - // TODO(b/394483200): move NotificationEntry's implementation to PipelineEntry? private final MutableStateFlow<Boolean> mSensitive = StateFlowKt.MutableStateFlow(false); @@ -55,7 +53,6 @@ public class BundleEntry extends PipelineEntry { public BundleEntry(String key) { super(key); - mEntryAdapter = new BundleEntryAdapter(); } @Nullable @@ -86,126 +83,9 @@ public class BundleEntry extends PipelineEntry { return false; } - @VisibleForTesting - public BundleEntryAdapter getEntryAdapter() { - return mEntryAdapter; - } - - public class BundleEntryAdapter implements EntryAdapter { - - /** - * TODO (b/394483200): convert to PipelineEntry.ROOT_ENTRY when pipeline is migrated? - */ - @Override - public GroupEntry getParent() { - return GroupEntry.ROOT_ENTRY; - } - - @Override - public boolean isTopLevelEntry() { - return true; - } - - @NonNull - @Override - public String getKey() { - return mKey; - } - - @Override - @Nullable - public ExpandableNotificationRow getRow() { - return mRow; - } - - @Override - public boolean isGroupRoot() { - return true; - } - - @Override - public StateFlow<Boolean> isSensitive() { - return BundleEntry.this.mSensitive; - } - - @Override - public boolean isClearable() { - // TODO(b/394483200): check whether all of the children are clearable, when implemented - return true; - } - - @Override - public int getTargetSdk() { - return Build.VERSION_CODES.CUR_DEVELOPMENT; - } - - @Override - public String getSummarization() { - return null; - } - - @Override - public int getContrastedColor(Context context, boolean isLowPriority, int backgroundColor) { - return Notification.COLOR_DEFAULT; - } - - @Override - public boolean canPeek() { - return false; - } - - @Override - public long getWhen() { - return 0; - } - - @Override - public IconPack getIcons() { - // TODO(b/396446620): implement bundle icons - return null; - } - - @Override - public boolean isColorized() { - return false; - } - - @Override - @Nullable - public StatusBarNotification getSbn() { - return null; - } - - @Override - public boolean canDragAndDrop() { - return false; - } - - @Override - public boolean isBubbleCapable() { - return false; - } - - @Override - @Nullable - public String getStyle() { - return null; - } - - @Override - public int getSectionBucket() { - return mBucket; - } - - @Override - public boolean isAmbient() { - return false; - } - - @Override - public boolean isFullScreenCapable() { - return false; - } + @Nullable + public ExpandableNotificationRow getRow() { + return mRow; } public static final List<BundleEntry> ROOT_BUNDLES = List.of( @@ -213,4 +93,8 @@ public class BundleEntry extends PipelineEntry { new BundleEntry(SOCIAL_MEDIA_ID), new BundleEntry(NEWS_ID), new BundleEntry(RECS_ID)); + + public MutableStateFlow<Boolean> isSensitive() { + return mSensitive; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt new file mode 100644 index 000000000000..64db9df8270c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2025 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 + +import android.app.Notification +import android.content.Context +import android.os.Build +import android.service.notification.StatusBarNotification +import com.android.systemui.statusbar.notification.icon.IconPack +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import kotlinx.coroutines.flow.StateFlow + +class BundleEntryAdapter(val entry: BundleEntry) : EntryAdapter { + /** TODO (b/394483200): convert to PipelineEntry.ROOT_ENTRY when pipeline is migrated? */ + override fun getParent(): GroupEntry { + return GroupEntry.ROOT_ENTRY + } + + override fun isTopLevelEntry(): Boolean { + return true + } + + override fun getKey(): String { + return entry.key + } + + override fun getRow(): ExpandableNotificationRow? { + return entry.row + } + + override fun isGroupRoot(): Boolean { + return true + } + + override fun isSensitive(): StateFlow<Boolean> { + return entry.isSensitive + } + + override fun isClearable(): Boolean { + // TODO(b/394483200): check whether all of the children are clearable, when implemented + return true + } + + override fun getTargetSdk(): Int { + return Build.VERSION_CODES.CUR_DEVELOPMENT + } + + override fun getSummarization(): String? { + return null + } + + override fun getContrastedColor( + context: Context?, + isLowPriority: Boolean, + backgroundColor: Int, + ): Int { + return Notification.COLOR_DEFAULT + } + + override fun canPeek(): Boolean { + return false + } + + override fun getWhen(): Long { + return 0 + } + + override fun getIcons(): IconPack? { + // TODO(b/396446620): implement bundle icons + return null + } + + override fun isColorized(): Boolean { + return false + } + + override fun getSbn(): StatusBarNotification? { + return null + } + + override fun canDragAndDrop(): Boolean { + return false + } + + override fun isBubbleCapable(): Boolean { + return false + } + + override fun getStyle(): String? { + return null + } + + override fun getSectionBucket(): Int { + return entry.bucket + } + + override fun isAmbient(): Boolean { + return false + } + + override fun isFullScreenCapable(): Boolean { + return false + } + + override fun onNotificationBubbleIconClicked() { + // do nothing. these cannot be a bubble + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java index 307a9573d5d8..0e75b6050678 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java @@ -50,7 +50,7 @@ public interface EntryAdapter { /** * Gets the view that this entry is backing. */ - @NonNull + @Nullable ExpandableNotificationRow getRow(); /** @@ -135,5 +135,10 @@ public interface EntryAdapter { default boolean isFullScreenCapable() { return false; } + + /** + * Process a click on a notification bubble icon + */ + void onNotificationBubbleIconClicked(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt new file mode 100644 index 000000000000..b7a84ddef103 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactory.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2025 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 + +/** Creates an appropriate EntryAdapter for the entry type given */ +interface EntryAdapterFactory { + fun create(entry: PipelineEntry): EntryAdapter +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt new file mode 100644 index 000000000000..779c25a3b402 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapterFactoryImpl.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2025 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 + +import androidx.annotation.VisibleForTesting +import com.android.internal.logging.MetricsLogger +import com.android.systemui.statusbar.notification.NotificationActivityStarter +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider +import javax.inject.Inject + +/** Creates an appropriate EntryAdapter for the entry type given */ +class EntryAdapterFactoryImpl +@Inject +constructor( + private val notificationActivityStarter: NotificationActivityStarter, + private val metricsLogger: MetricsLogger, + private val peopleNotificationIdentifier: PeopleNotificationIdentifier, + private val iconStyleProvider: NotificationIconStyleProvider, + private val visualStabilityCoordinator: VisualStabilityCoordinator, +) : EntryAdapterFactory { + override fun create(entry: PipelineEntry): EntryAdapter { + return if (entry is NotificationEntry) { + NotificationEntryAdapter( + notificationActivityStarter, + metricsLogger, + peopleNotificationIdentifier, + iconStyleProvider, + visualStabilityCoordinator, + entry, + ) + } else { + BundleEntryAdapter((entry as BundleEntry)) + } + } + + @VisibleForTesting + fun getNotificationActivityStarter() : NotificationActivityStarter { + return notificationActivityStarter + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index b19ba3a18826..3d8ba7f335bd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -109,7 +109,6 @@ public final class NotificationEntry extends ListEntry { private final String mKey; private StatusBarNotification mSbn; private Ranking mRanking; - private final NotifEntryAdapter mEntryAdapter; /* * Bookkeeping members @@ -270,141 +269,6 @@ public final class NotificationEntry extends ListEntry { mKey = sbn.getKey(); setSbn(sbn); setRanking(ranking); - mEntryAdapter = new NotifEntryAdapter(); - } - - public class NotifEntryAdapter implements EntryAdapter { - @Override - public PipelineEntry getParent() { - return NotificationEntry.this.getParent(); - } - - @Override - public boolean isTopLevelEntry() { - return getParent() != null - && (getParent() == ROOT_ENTRY || ROOT_BUNDLES.contains(getParent())); - } - - @Override - public String getKey() { - return NotificationEntry.this.getKey(); - } - - @Override - public ExpandableNotificationRow getRow() { - return NotificationEntry.this.getRow(); - } - - @Override - public boolean isGroupRoot() { - if (isTopLevelEntry() || getParent() == null) { - return false; - } - if (NotificationEntry.this.getParent() instanceof GroupEntry parentGroupEntry) { - return parentGroupEntry.getSummary() == NotificationEntry.this; - } - return false; - } - - @Override - public StateFlow<Boolean> isSensitive() { - return NotificationEntry.this.isSensitive(); - } - - @Override - public boolean isClearable() { - return NotificationEntry.this.isClearable(); - } - - @Override - public int getTargetSdk() { - return NotificationEntry.this.targetSdk; - } - - @Override - public String getSummarization() { - return getRanking().getSummarization(); - } - - @Override - public void prepareForInflation() { - getSbn().clearPackageContext(); - } - - @Override - public int getContrastedColor(Context context, boolean isLowPriority, int backgroundColor) { - return NotificationEntry.this.getContrastedColor( - context, isLowPriority, backgroundColor); - } - - @Override - public boolean canPeek() { - return isStickyAndNotDemoted(); - } - - @Override - public long getWhen() { - return getSbn().getNotification().getWhen(); - } - - @Override - public IconPack getIcons() { - return NotificationEntry.this.getIcons(); - } - - @Override - public boolean isColorized() { - return getSbn().getNotification().isColorized(); - } - - @Override - @Nullable - public StatusBarNotification getSbn() { - return NotificationEntry.this.getSbn(); - } - - @Override - public boolean canDragAndDrop() { - boolean canBubble = canBubble(); - Notification notif = getSbn().getNotification(); - PendingIntent dragIntent = notif.contentIntent != null ? notif.contentIntent - : notif.fullScreenIntent; - if (dragIntent != null && dragIntent.isActivity() && !canBubble) { - return true; - } - return false; - } - - @Override - public boolean isBubbleCapable() { - return NotificationEntry.this.isBubble(); - } - - @Override - @Nullable - public String getStyle() { - return getNotificationStyle(); - } - - @Override - public int getSectionBucket() { - return mBucket; - } - - @Override - public boolean isAmbient() { - return mRanking.isAmbient(); - } - - @Override - public boolean isFullScreenCapable() { - return getSbn().getNotification().fullScreenIntent != null; - } - - } - - public EntryAdapter getEntryAdapter() { - return mEntryAdapter; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt new file mode 100644 index 000000000000..0ff2dd7c7f43 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2025 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 + +import android.content.Context +import android.service.notification.StatusBarNotification +import com.android.internal.logging.MetricsLogger +import com.android.systemui.statusbar.notification.NotificationActivityStarter +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator +import com.android.systemui.statusbar.notification.icon.IconPack +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider +import kotlinx.coroutines.flow.StateFlow + +class NotificationEntryAdapter( + private val notificationActivityStarter: NotificationActivityStarter, + private val metricsLogger: MetricsLogger, + private val peopleNotificationIdentifier: PeopleNotificationIdentifier, + private val iconStyleProvider: NotificationIconStyleProvider, + private val visualStabilityCoordinator: VisualStabilityCoordinator, + private val entry: NotificationEntry, +) : EntryAdapter { + + override fun getParent(): PipelineEntry? { + return entry.parent + } + + override fun isTopLevelEntry(): Boolean { + return parent != null && + (parent === GroupEntry.ROOT_ENTRY || BundleEntry.ROOT_BUNDLES.contains(parent)) + } + + override fun getKey(): String { + return entry.key + } + + override fun getRow(): ExpandableNotificationRow { + return entry.row + } + + override fun isGroupRoot(): Boolean { + if (isTopLevelEntry || parent == null) { + return false + } + return (entry.parent as? GroupEntry)?.summary == entry + } + + override fun isSensitive(): StateFlow<Boolean> { + return entry.isSensitive + } + + override fun isClearable(): Boolean { + return entry.isClearable + } + + override fun getTargetSdk(): Int { + return entry.targetSdk + } + + override fun getSummarization(): String? { + return entry.ranking?.summarization + } + + override fun prepareForInflation() { + entry.sbn.clearPackageContext() + } + + override fun getContrastedColor( + context: Context?, + isLowPriority: Boolean, + backgroundColor: Int, + ): Int { + return entry.getContrastedColor(context, isLowPriority, backgroundColor) + } + + override fun canPeek(): Boolean { + return entry.isStickyAndNotDemoted + } + + override fun getWhen(): Long { + return entry.sbn.notification.getWhen() + } + + override fun getIcons(): IconPack { + return entry.icons + } + + override fun isColorized(): Boolean { + return entry.sbn.notification.isColorized + } + + override fun getSbn(): StatusBarNotification { + return entry.sbn + } + + override fun canDragAndDrop(): Boolean { + val canBubble: Boolean = entry.canBubble() + val notif = entry.sbn.notification + val dragIntent = + if (notif.contentIntent != null) notif.contentIntent else notif.fullScreenIntent + if (dragIntent != null && dragIntent.isActivity && !canBubble) { + return true + } + return false + } + + override fun isBubbleCapable(): Boolean { + return entry.isBubble + } + + override fun getStyle(): String? { + return entry.notificationStyle + } + + override fun getSectionBucket(): Int { + return entry.bucket + } + + override fun isAmbient(): Boolean { + return entry.ranking.isAmbient + } + + override fun isFullScreenCapable(): Boolean { + return entry.sbn.notification.fullScreenIntent != null + } + + override fun onNotificationBubbleIconClicked() { + notificationActivityStarter.onNotificationBubbleIconClicked(entry) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 53d5dbc58677..ef3da9498f70 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -37,6 +37,8 @@ import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory; +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl; import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStoreImpl; @@ -340,4 +342,8 @@ public interface NotificationsModule { return MagneticNotificationRowManager.getEmpty(); } } + + /** Provides an instance of {@link EntryAdapterFactory} */ + @Binds + EntryAdapterFactory provideEntryAdapterFactory(EntryAdapterFactoryImpl impl); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 987068df3ee9..ad20f023f5ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -111,6 +111,8 @@ import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.SourceType; import com.android.systemui.statusbar.notification.collection.EntryAdapter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.NotificationEntryAdapter; +import com.android.systemui.statusbar.notification.collection.PipelineEntry; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; @@ -2124,7 +2126,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * Initialize row. */ public void initialize( - NotificationEntry entry, + EntryAdapter entryAdapter, + PipelineEntry entry, RemoteInputViewSubcomponent.Factory rivSubcomponentFactory, String appName, @NonNull String notificationKey, @@ -2152,11 +2155,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView NotificationRebindingTracker notificationRebindingTracker) { if (NotificationBundleUi.isEnabled()) { + mEntryAdapter = entryAdapter; // TODO (b/395857098): remove when all usages are migrated - mEntryAdapter = entry.getEntryAdapter(); - mEntry = entry; + mEntry = (NotificationEntry) entry; } else { - mEntry = entry; + mEntry = (NotificationEntry) entry; } mAppName = appName; mRebindingTracker = notificationRebindingTracker; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index 02e8f4917da4..ac55930f5c11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -45,7 +45,11 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.FeedbackIcon; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory; +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl; +import com.android.systemui.statusbar.notification.collection.PipelineEntry; +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; @@ -56,6 +60,7 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden import com.android.systemui.statusbar.notification.row.dagger.AppName; import com.android.systemui.statusbar.notification.row.dagger.NotificationKey; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider; import com.android.systemui.statusbar.notification.shared.NotificationBundleUi; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -118,8 +123,8 @@ public class ExpandableNotificationRowController implements NotifViewController private final IStatusBarService mStatusBarService; private final UiEventLogger mUiEventLogger; private final MSDLPlayer mMSDLPlayer; - private final NotificationSettingsController mSettingsController; + private final EntryAdapterFactory mEntryAdapterFactory; @VisibleForTesting final NotificationSettingsController.Listener mSettingsListener = @@ -285,7 +290,8 @@ public class ExpandableNotificationRowController implements NotifViewController IStatusBarService statusBarService, UiEventLogger uiEventLogger, MSDLPlayer msdlPlayer, - NotificationRebindingTracker notificationRebindingTracker) { + NotificationRebindingTracker notificationRebindingTracker, + EntryAdapterFactory entryAdapterFactory) { mView = view; mListContainer = listContainer; mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory; @@ -322,14 +328,16 @@ public class ExpandableNotificationRowController implements NotifViewController mStatusBarService = statusBarService; mUiEventLogger = uiEventLogger; mMSDLPlayer = msdlPlayer; + mEntryAdapterFactory = entryAdapterFactory; } /** * Initialize the controller. */ - public void init(NotificationEntry entry) { + public void init(PipelineEntry entry) { mActivatableNotificationViewController.init(); mView.initialize( + mEntryAdapterFactory.create(entry), entry, mRemoteInputViewSubcomponentFactory, mAppName, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt index c337ac201b3d..8e98fe31a56a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationActivityStarterKosmos.kt @@ -18,6 +18,10 @@ package com.android.systemui.statusbar.notification import com.android.systemui.kosmos.Kosmos import com.android.systemui.statusbar.phone.statusBarNotificationActivityStarter +import org.mockito.kotlin.mock var Kosmos.notificationActivityStarter: NotificationActivityStarter by Kosmos.Fixture { statusBarNotificationActivityStarter } + +var Kosmos.mockNotificationActivityStarter: NotificationActivityStarter by +Kosmos.Fixture { mock<NotificationActivityStarter>() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt new file mode 100644 index 000000000000..f3cdabb5813e --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerKosmos.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2025 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.render + +import com.android.systemui.kosmos.Kosmos +import org.mockito.kotlin.mock + +var Kosmos.groupMembershipManager by Kosmos.Fixture { mock<GroupMembershipManager>() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt new file mode 100644 index 000000000000..c263c5d96610 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractorKosmos.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2025 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.people + +import com.android.systemui.kosmos.Kosmos +import org.mockito.kotlin.mock + +val Kosmos.notificationPersonExtractor by Kosmos.Fixture { mock<NotificationPersonExtractor>() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt new file mode 100644 index 000000000000..20982eb43797 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifierKosmos.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2025 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.people + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.statusbar.notification.collection.render.groupMembershipManager + +val Kosmos.peopleNotificationIdentifier by + Kosmos.Fixture { + PeopleNotificationIdentifierImpl(notificationPersonExtractor, groupMembershipManager) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt new file mode 100644 index 000000000000..e99f61e7cd13 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/EntryAdapterFactoryKosmos.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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.row + +import com.android.internal.logging.metricsLogger +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl +import com.android.systemui.statusbar.notification.collection.coordinator.visualStabilityCoordinator +import com.android.systemui.statusbar.notification.mockNotificationActivityStarter +import com.android.systemui.statusbar.notification.people.peopleNotificationIdentifier +import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider + +val Kosmos.entryAdapterFactory by +Kosmos.Fixture { + EntryAdapterFactoryImpl( + mockNotificationActivityStarter, + metricsLogger, + peopleNotificationIdentifier, + notificationIconStyleProvider, + visualStabilityCoordinator, + ) +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt index 771e1a5dccc3..ff4fbf9f0e94 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt @@ -53,8 +53,11 @@ import com.android.systemui.statusbar.SmartReplyController import com.android.systemui.statusbar.notification.ColorUpdateLogger import com.android.systemui.statusbar.notification.ConversationNotificationManager import com.android.systemui.statusbar.notification.ConversationNotificationProcessor +import com.android.systemui.statusbar.notification.NotificationActivityStarter +import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider @@ -76,6 +79,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag import com.android.systemui.statusbar.notification.row.icon.AppIconProviderImpl +import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderImpl import com.android.systemui.statusbar.notification.row.icon.NotificationRowIconViewInflaterFactory import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor @@ -364,11 +368,22 @@ class ExpandableNotificationRowBuilder( ) val row = rowInflaterTask.inflateSynchronously(context, null, entry) + val entryAdapter = + EntryAdapterFactoryImpl( + Mockito.mock(NotificationActivityStarter::class.java), + Mockito.mock(MetricsLogger::class.java), + Mockito.mock(PeopleNotificationIdentifier::class.java), + Mockito.mock(NotificationIconStyleProvider::class.java), + Mockito.mock(VisualStabilityCoordinator::class.java), + ) + .create(entry) + entry.row = row mIconManager.createIcons(entry) mBindPipelineEntryListener.onEntryInit(entry) mBindPipeline.manageRow(entry, row) row.initialize( + entryAdapter, entry, Mockito.mock(RemoteInputViewSubcomponent.Factory::class.java, STUB_ONLY), APP_NAME, |