summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig7
-rw-r--r--packages/SystemUI/res/values/dimens.xml10
-rw-r--r--packages/SystemUI/res/values/ids.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt166
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt119
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt27
30 files changed, 609 insertions, 118 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 9df739c8f3c2..37581e5c5dcf 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -403,6 +403,13 @@ flag {
}
flag {
+ name: "status_bar_call_chip_notification_icon"
+ namespace: "systemui"
+ description: "Use the small icon set on the notification for the status bar call chip"
+ bug: "354930838"
+}
+
+flag {
name: "compose_bouncer"
namespace: "systemui"
description: "Use the new compose bouncer in SystemUI"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index eda7bb0e7f6d..e5750d278bfe 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1729,10 +1729,18 @@
<dimen name="wallet_button_vertical_padding">8dp</dimen>
<!-- Ongoing activity chip -->
+ <!-- The activity chip side padding, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_side_padding">12dp</dimen>
+ <!-- The activity chip side padding, used with an icon that has embedded padding (e.g. if the icon comes from the notification's smallIcon field). If the icon has padding, the chip itself can have less padding. -->
+ <dimen name="ongoing_activity_chip_side_padding_for_embedded_padding_icon">6dp</dimen>
+ <!-- The icon size, used with the default phone icon. -->
<dimen name="ongoing_activity_chip_icon_size">16dp</dimen>
- <!-- The padding between the icon and the text. -->
+ <!-- The icon size, used with an icon that has embedded padding. (If the icon has embedded padding, we need to make the whole icon larger so the icon itself doesn't look small.) -->
+ <dimen name="ongoing_activity_chip_embedded_padding_icon_size">22dp</dimen>
+ <!-- The padding between the icon and the text. Only used if the default phone icon is used. -->
<dimen name="ongoing_activity_chip_icon_text_padding">4dp</dimen>
+ <!-- The end padding for the timer text view. Only used if an embedded padding icon is used. -->
+ <dimen name="ongoing_activity_chip_text_end_padding_for_embedded_padding_icon">6dp</dimen>
<dimen name="ongoing_activity_chip_corner_radius">28dp</dimen>
<!-- Status bar user chip -->
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 212dae279387..e4f900d3a31a 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -132,6 +132,7 @@
<!-- Status bar -->
<item type="id" name="status_bar_dot" />
+ <item type="id" name="ongoing_activity_chip_custom_icon" />
<!-- Default display cutout on the physical top of screen -->
<item type="id" name="display_cutout" />
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
index 64dedea3e6d4..108e22bc392b 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
@@ -16,7 +16,6 @@
package com.android.systemui.common.ui.binder
-import android.view.View
import android.widget.ImageView
import com.android.systemui.common.shared.model.Icon
@@ -31,13 +30,4 @@ object IconViewBinder {
is Icon.Resource -> view.setImageResource(icon.res)
}
}
-
- fun bindNullable(icon: Icon?, view: ImageView) {
- if (icon != null) {
- view.visibility = View.VISIBLE
- bind(icon, view)
- } else {
- view.visibility = View.GONE
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
index 6e4038d85e03..59de2032c4f1 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
@@ -23,7 +23,13 @@ import com.android.server.notification.Flags.crossAppPoliteNotifications
import com.android.server.notification.Flags.politeNotifications
import com.android.server.notification.Flags.vibrateWhileUnlocked
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
+import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
+import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
import com.android.systemui.Flags.communalHub
+import com.android.systemui.Flags.statusBarCallChipNotificationIcon
+import com.android.systemui.Flags.statusBarScreenSharingChips
+import com.android.systemui.Flags.statusBarUseReposForCallChip
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
import com.android.systemui.keyguard.MigrateClocksToBlueprint
@@ -38,9 +44,9 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.shared.NotificationAvalancheSuppression
import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor
import com.android.systemui.statusbar.notification.shared.NotificationMinimalismPrototype
+import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
-import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
import javax.inject.Inject
@@ -77,6 +83,10 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha
// QS Fragment using Compose dependencies
QSComposeFragment.token dependsOn NewQsUI.token
+
+ // Status bar chip dependencies
+ statusBarCallChipNotificationIconToken dependsOn statusBarUseReposForCallChipToken
+ statusBarCallChipNotificationIconToken dependsOn statusBarScreenSharingChipsToken
}
private inline val politeNotifications
@@ -96,4 +106,17 @@ class FlagDependencies @Inject constructor(featureFlags: FeatureFlagsClassic, ha
private inline val communalHub
get() = FlagToken(FLAG_COMMUNAL_HUB, communalHub())
+
+ private inline val statusBarCallChipNotificationIconToken
+ get() =
+ FlagToken(
+ FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON,
+ statusBarCallChipNotificationIcon()
+ )
+
+ private inline val statusBarScreenSharingChipsToken
+ get() = FlagToken(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, statusBarScreenSharingChips())
+
+ private inline val statusBarUseReposForCallChipToken
+ get() = FlagToken(FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP, statusBarUseReposForCallChip())
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 59fd0ca4513e..18ea0b445481 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.chips.call.ui.viewmodel
import android.view.View
import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.Flags
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -59,12 +60,24 @@ constructor(
when (state) {
is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden()
is OngoingCallModel.InCall -> {
+ val icon =
+ if (
+ Flags.statusBarCallChipNotificationIcon() &&
+ state.notificationIconView != null
+ ) {
+ OngoingActivityChipModel.ChipIcon.StatusBarView(
+ state.notificationIconView
+ )
+ } else {
+ OngoingActivityChipModel.ChipIcon.Basic(phoneIcon)
+ }
+
// This block mimics OngoingCallController#updateChip.
if (state.startTimeMs <= 0L) {
// If the start time is invalid, don't show a timer and show just an
// icon. See b/192379214.
OngoingActivityChipModel.Shown.IconOnly(
- icon = phoneIcon,
+ icon = icon,
colors = ColorsModel.Themed,
getOnClickListener(state),
)
@@ -73,7 +86,7 @@ constructor(
state.startTimeMs - systemClock.currentTimeMillis() +
systemClock.elapsedRealtime()
OngoingActivityChipModel.Shown.Timer(
- icon = phoneIcon,
+ icon = icon,
colors = ColorsModel.Themed,
startTimeMs = startTimeInElapsedRealtime,
getOnClickListener(state),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index d9b0504308f8..cf4e7072a7d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -190,12 +190,14 @@ constructor(
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- CAST_TO_OTHER_DEVICE_ICON,
- // This string is "Casting screen"
- ContentDescription.Resource(
- R.string.cast_screen_to_other_device_chip_accessibility_label,
- ),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ // This string is "Casting screen"
+ ContentDescription.Resource(
+ R.string.cast_screen_to_other_device_chip_accessibility_label,
+ ),
+ )
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
@@ -213,10 +215,12 @@ constructor(
private fun createIconOnlyCastChip(deviceName: String?): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.IconOnly(
icon =
- Icon.Resource(
- CAST_TO_OTHER_DEVICE_ICON,
- // This string is just "Casting"
- ContentDescription.Resource(R.string.accessibility_casting),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ // This string is just "Casting"
+ ContentDescription.Resource(R.string.accessibility_casting),
+ )
),
colors = ColorsModel.Red,
createDialogLaunchOnClickListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index fcf3de42eb32..6ba4fefd6f3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -78,11 +78,13 @@ constructor(
is ScreenRecordChipModel.Recording -> {
OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- ICON,
- ContentDescription.Resource(
- R.string.screenrecord_ongoing_screen_only,
- ),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ ICON,
+ ContentDescription.Resource(
+ R.string.screenrecord_ongoing_screen_only,
+ ),
+ )
),
colors = ColorsModel.Red,
startTimeMs = systemClock.elapsedRealtime(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index 85973fca4326..7897f93b6496 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -110,9 +110,11 @@ constructor(
): OngoingActivityChipModel.Shown {
return OngoingActivityChipModel.Shown.Timer(
icon =
- Icon.Resource(
- SHARE_TO_APP_ICON,
- ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+ OngoingActivityChipModel.ChipIcon.Basic(
+ Icon.Resource(
+ SHARE_TO_APP_ICON,
+ ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+ )
),
colors = ColorsModel.Red,
// TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index 17cf60bf2dc5..26a2f9139608 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -17,7 +17,9 @@
package com.android.systemui.statusbar.chips.ui.model
import android.view.View
+import com.android.systemui.Flags
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.statusbar.StatusBarIconView
/** Model representing the display of an ongoing activity as a chip in the status bar. */
sealed class OngoingActivityChipModel {
@@ -38,7 +40,7 @@ sealed class OngoingActivityChipModel {
/** This chip should be shown with the given information. */
abstract class Shown(
/** The icon to show on the chip. If null, no icon will be shown. */
- open val icon: Icon?,
+ open val icon: ChipIcon?,
/** What colors to use for the chip. */
open val colors: ColorsModel,
/**
@@ -50,7 +52,7 @@ sealed class OngoingActivityChipModel {
/** This chip shows only an icon and nothing else. */
data class IconOnly(
- override val icon: Icon,
+ override val icon: ChipIcon,
override val colors: ColorsModel,
override val onClickListener: View.OnClickListener?,
) : Shown(icon, colors, onClickListener) {
@@ -59,7 +61,7 @@ sealed class OngoingActivityChipModel {
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
- override val icon: Icon,
+ override val icon: ChipIcon,
override val colors: ColorsModel,
/**
* The time this event started, used to show the timer.
@@ -88,4 +90,23 @@ sealed class OngoingActivityChipModel {
override val logName = "Shown.Countdown"
}
}
+
+ /** Represents an icon to show on the chip. */
+ sealed interface ChipIcon {
+ /**
+ * The icon is a custom icon, which is set on [impl]. The icon was likely created by an
+ * external app.
+ */
+ data class StatusBarView(val impl: StatusBarIconView) : ChipIcon {
+ init {
+ check(Flags.statusBarCallChipNotificationIcon()) {
+ "OngoingActivityChipModel.ChipIcon.StatusBarView created even though " +
+ "Flags.statusBarCallChipNotificationIcon is not enabled"
+ }
+ }
+ }
+
+ /** The icon is a basic resource or drawable icon that System UI created internally. */
+ data class Basic(val impl: Icon) : ChipIcon
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index 5d2d56acd0e4..10084517ec19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -25,6 +25,8 @@ import android.graphics.drawable.Icon
import android.service.notification.StatusBarNotification
import android.util.ArrayMap
import com.android.app.tracing.traceSection
+import com.android.systemui.Flags
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -128,8 +130,14 @@ private class ActiveNotificationsStoreBuilder(
return result
}
- private fun NotificationEntry.toModel(): ActiveNotificationModel =
- existingModels.createOrReuse(
+ private fun NotificationEntry.toModel(): ActiveNotificationModel {
+ val statusBarChipIcon =
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ icons.statusBarChipIcon
+ } else {
+ null
+ }
+ return existingModels.createOrReuse(
key = key,
groupKey = sbn.groupKey,
whenTime = sbn.notification.`when`,
@@ -142,6 +150,7 @@ private class ActiveNotificationsStoreBuilder(
aodIcon = icons.aodIcon?.sourceIcon,
shelfIcon = icons.shelfIcon?.sourceIcon,
statusBarIcon = icons.statusBarIcon?.sourceIcon,
+ statusBarChipIconView = statusBarChipIcon,
uid = sbn.uid,
packageName = sbn.packageName,
contentIntent = sbn.notification.contentIntent,
@@ -150,6 +159,7 @@ private class ActiveNotificationsStoreBuilder(
bucket = bucket,
callType = sbn.toCallType(),
)
+ }
}
private fun ActiveNotificationsStore.createOrReuse(
@@ -165,6 +175,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon: Icon?,
shelfIcon: Icon?,
statusBarIcon: Icon?,
+ statusBarChipIconView: StatusBarIconView?,
uid: Int,
packageName: String,
contentIntent: PendingIntent?,
@@ -187,6 +198,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIconView,
uid = uid,
instanceId = instanceId,
isGroupSummary = isGroupSummary,
@@ -209,6 +221,7 @@ private fun ActiveNotificationsStore.createOrReuse(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIconView,
uid = uid,
instanceId = instanceId,
isGroupSummary = isGroupSummary,
@@ -232,6 +245,7 @@ private fun ActiveNotificationModel.isCurrent(
aodIcon: Icon?,
shelfIcon: Icon?,
statusBarIcon: Icon?,
+ statusBarChipIconView: StatusBarIconView?,
uid: Int,
packageName: String,
contentIntent: PendingIntent?,
@@ -253,6 +267,7 @@ private fun ActiveNotificationModel.isCurrent(
aodIcon != this.aodIcon -> false
shelfIcon != this.shelfIcon -> false
statusBarIcon != this.statusBarIcon -> false
+ statusBarChipIconView != this.statusBarChipIconView -> false
uid != this.uid -> false
instanceId != this.instanceId -> false
isGroupSummary != this.isGroupSummary -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 331d3cc4c21b..dc6ab4126337 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -123,6 +123,13 @@ constructor(
// Construct the status bar icon view.
val sbIcon = iconBuilder.createIconView(entry)
sbIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ val sbChipIcon: StatusBarIconView?
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ sbChipIcon = iconBuilder.createIconView(entry)
+ sbChipIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ } else {
+ sbChipIcon = null
+ }
// Construct the shelf icon view.
val shelfIcon = iconBuilder.createIconView(entry)
@@ -139,9 +146,19 @@ constructor(
try {
setIcon(entry, normalIconDescriptor, sbIcon)
+ if (Flags.statusBarCallChipNotificationIcon() && sbChipIcon != null) {
+ setIcon(entry, normalIconDescriptor, sbChipIcon)
+ }
setIcon(entry, sensitiveIconDescriptor, shelfIcon)
setIcon(entry, sensitiveIconDescriptor, aodIcon)
- entry.icons = IconPack.buildPack(sbIcon, shelfIcon, aodIcon, entry.icons)
+ entry.icons =
+ IconPack.buildPack(
+ sbIcon,
+ sbChipIcon,
+ shelfIcon,
+ aodIcon,
+ entry.icons,
+ )
} catch (e: InflationException) {
entry.icons = IconPack.buildEmptyPack(entry.icons)
throw e
@@ -182,6 +199,11 @@ constructor(
setIcon(entry, normalIconDescriptor, it)
}
+ entry.icons.statusBarChipIcon?.let {
+ it.setNotification(entry.sbn, notificationContentDescription)
+ setIcon(entry, normalIconDescriptor, it)
+ }
+
entry.icons.shelfIcon?.let {
it.setNotification(entry.sbn, notificationContentDescription)
setIcon(entry, sensitiveIconDescriptor, it)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
index d029ce722af9..611cebcf6427 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconPack.java
@@ -29,6 +29,7 @@ public final class IconPack {
private final boolean mAreIconsAvailable;
@Nullable private final StatusBarIconView mStatusBarIcon;
+ @Nullable private final StatusBarIconView mStatusBarChipIcon;
@Nullable private final StatusBarIconView mShelfIcon;
@Nullable private final StatusBarIconView mAodIcon;
@@ -43,7 +44,7 @@ public final class IconPack {
* haven't been inflated yet or there was an error while inflating them).
*/
public static IconPack buildEmptyPack(@Nullable IconPack fromSource) {
- return new IconPack(false, null, null, null, fromSource);
+ return new IconPack(false, null, null, null, null, fromSource);
}
/**
@@ -51,20 +52,23 @@ public final class IconPack {
*/
public static IconPack buildPack(
@NonNull StatusBarIconView statusBarIcon,
+ @Nullable StatusBarIconView statusBarChipIcon,
@NonNull StatusBarIconView shelfIcon,
@NonNull StatusBarIconView aodIcon,
@Nullable IconPack source) {
- return new IconPack(true, statusBarIcon, shelfIcon, aodIcon, source);
+ return new IconPack(true, statusBarIcon, statusBarChipIcon, shelfIcon, aodIcon, source);
}
private IconPack(
boolean areIconsAvailable,
@Nullable StatusBarIconView statusBarIcon,
+ @Nullable StatusBarIconView statusBarChipIcon,
@Nullable StatusBarIconView shelfIcon,
@Nullable StatusBarIconView aodIcon,
@Nullable IconPack source) {
mAreIconsAvailable = areIconsAvailable;
mStatusBarIcon = statusBarIcon;
+ mStatusBarChipIcon = statusBarChipIcon;
mShelfIcon = shelfIcon;
mAodIcon = aodIcon;
if (source != null) {
@@ -79,6 +83,17 @@ public final class IconPack {
}
/**
+ * The version of the notification icon that appears inside a chip within the status bar.
+ *
+ * Separate from {@link #getStatusBarIcon()} so that we don't have to worry about detaching and
+ * re-attaching the same view when the chip appears and hides.
+ */
+ @Nullable
+ public StatusBarIconView getStatusBarChipIcon() {
+ return mStatusBarChipIcon;
+ }
+
+ /**
* The version of the icon that appears in the "shelf" at the bottom of the notification shade.
* In general, this icon also appears somewhere on the notification and is "sucked" into the
* shelf as the scrolls beyond it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index 6960791f7bcb..cf19938aa533 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.shared
import android.app.PendingIntent
import android.graphics.drawable.Icon
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.stack.PriorityBucket
/**
@@ -59,6 +60,8 @@ data class ActiveNotificationModel(
val shelfIcon: Icon?,
/** Icon to display in the status bar. */
val statusBarIcon: Icon?,
+ /** Icon to display in the status bar chip. */
+ val statusBarChipIconView: StatusBarIconView?,
/** The notifying app's [packageName]'s uid. */
val uid: Int,
/** The notifying app's packageName. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 7af066646629..4368239c31f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -38,6 +38,7 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
@@ -114,6 +115,9 @@ constructor(
CallNotificationInfo(
entry.sbn.key,
entry.sbn.notification.getWhen(),
+ // In this old listener pattern, we don't have access to the
+ // notification icon.
+ notificationIconView = null,
entry.sbn.notification.contentIntent,
entry.sbn.uid,
entry.sbn.notification.extras.getInt(
@@ -223,8 +227,15 @@ constructor(
callNotificationInfo
// This shouldn't happen, but protect against it in case
?: return OngoingCallModel.NoCall
+ val icon =
+ if (Flags.statusBarCallChipNotificationIcon()) {
+ currentInfo.notificationIconView
+ } else {
+ null
+ }
return OngoingCallModel.InCall(
startTimeMs = currentInfo.callStartTime,
+ notificationIconView = icon,
intent = currentInfo.intent,
)
} else {
@@ -260,6 +271,7 @@ constructor(
CallNotificationInfo(
notifModel.key,
notifModel.whenTime,
+ notifModel.statusBarChipIconView,
notifModel.contentIntent,
notifModel.uid,
isOngoing = true,
@@ -407,6 +419,8 @@ constructor(
private data class CallNotificationInfo(
val key: String,
val callStartTime: Long,
+ /** The icon set as the [android.app.Notification.getSmallIcon] field. */
+ val notificationIconView: StatusBarIconView?,
val intent: PendingIntent?,
val uid: Int,
/** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 2c4848776b66..34bff80ea919 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone.ongoingcall.shared.model
import android.app.PendingIntent
+import com.android.systemui.statusbar.StatusBarIconView
/** Represents the state of any ongoing calls. */
sealed interface OngoingCallModel {
@@ -31,7 +32,13 @@ sealed interface OngoingCallModel {
* [com.android.systemui.util.time.SystemClock.currentTimeMillis], **not**
* [com.android.systemui.util.time.SystemClock.elapsedRealtime]. This value can be 0 if the
* user has started an outgoing call that hasn't been answered yet - see b/192379214.
+ * @property notificationIconView the [android.app.Notification.getSmallIcon] that's set on the
+ * call notification. We may use this icon in the chip instead of the default phone icon.
* @property intent the intent associated with the call notification.
*/
- data class InCall(val startTimeMs: Long, val intent: PendingIntent?) : OngoingCallModel
+ data class InCall(
+ val startTimeMs: Long,
+ val notificationIconView: StatusBarIconView?,
+ val intent: PendingIntent?,
+ ) : OngoingCallModel
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 16bd7f830c66..d46aaf45b1a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -18,9 +18,12 @@ package com.android.systemui.statusbar.pipeline.shared.ui.binder
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
+import android.annotation.IdRes
import android.content.res.ColorStateList
import android.graphics.drawable.GradientDrawable
import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.Lifecycle
@@ -31,6 +34,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
@@ -90,7 +94,7 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
if (Flags.statusBarScreenSharingChips()) {
val chipView: View = view.requireViewById(R.id.ongoing_activity_chip)
val chipContext = chipView.context
- val chipIconView: ImageView =
+ val chipDefaultIconView: ImageView =
chipView.requireViewById(R.id.ongoing_activity_chip_icon)
val chipTimeView: ChipChronometer =
chipView.requireViewById(R.id.ongoing_activity_chip_time)
@@ -105,16 +109,25 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
when (chipModel) {
is OngoingActivityChipModel.Shown -> {
// Data
- IconViewBinder.bindNullable(chipModel.icon, chipIconView)
+ setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView)
setChipMainContent(chipModel, chipTextView, chipTimeView)
chipView.setOnClickListener(chipModel.onClickListener)
+ updateChipPadding(
+ chipModel,
+ chipBackgroundView,
+ chipTextView,
+ chipTimeView,
+ )
// Accessibility
setChipAccessibility(chipModel, chipView, chipBackgroundView)
// Colors
val textColor = chipModel.colors.text(chipContext)
- chipIconView.imageTintList = ColorStateList.valueOf(textColor)
+ chipDefaultIconView.imageTintList =
+ ColorStateList.valueOf(textColor)
+ chipBackgroundView.getCustomIconView()?.imageTintList =
+ ColorStateList.valueOf(textColor)
chipTimeView.setTextColor(textColor)
chipTextView.setTextColor(textColor)
(chipBackgroundView.background as GradientDrawable).color =
@@ -151,6 +164,69 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
}
}
+ private fun setChipIcon(
+ chipModel: OngoingActivityChipModel.Shown,
+ backgroundView: ChipBackgroundContainer,
+ defaultIconView: ImageView,
+ ) {
+ // Always remove any previously set custom icon. If we have a new custom icon, we'll re-add
+ // it.
+ backgroundView.removeView(backgroundView.getCustomIconView())
+
+ when (val icon = chipModel.icon) {
+ null -> {
+ defaultIconView.visibility = View.GONE
+ }
+ is OngoingActivityChipModel.ChipIcon.Basic -> {
+ IconViewBinder.bind(icon.impl, defaultIconView)
+ defaultIconView.visibility = View.VISIBLE
+ }
+ is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
+ // Hide the default icon since we'll show this custom icon instead.
+ defaultIconView.visibility = View.GONE
+
+ // Add the new custom icon:
+ // 1. Set up the right visual params.
+ val iconView = icon.impl
+ with(iconView) {
+ id = CUSTOM_ICON_VIEW_ID
+ // TODO(b/354930838): Update the content description to not include "phone" and
+ // maybe include the app name.
+ contentDescription =
+ context.resources.getString(R.string.ongoing_phone_call_content_description)
+ }
+
+ // 2. If we just reinflated the view, we may need to detach the icon view from the
+ // old chip before we reattach it to the new one.
+ // See also: NotificationIconContainerViewBinder#bindIcons.
+ val currentParent = iconView.parent as? ViewGroup
+ if (currentParent != null && currentParent != backgroundView) {
+ currentParent.removeView(iconView)
+ currentParent.removeTransientView(iconView)
+ }
+
+ // 3: Add the icon as the starting view.
+ backgroundView.addView(
+ iconView,
+ /* index= */ 0,
+ generateCustomIconLayoutParams(iconView),
+ )
+ }
+ }
+ }
+
+ private fun View.getCustomIconView(): StatusBarIconView? {
+ return this.findViewById(CUSTOM_ICON_VIEW_ID)
+ }
+
+ private fun generateCustomIconLayoutParams(iconView: ImageView): FrameLayout.LayoutParams {
+ val customIconSize =
+ iconView.context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_embedded_padding_icon_size
+ )
+ return FrameLayout.LayoutParams(customIconSize, customIconSize)
+ }
+
private fun setChipMainContent(
chipModel: OngoingActivityChipModel.Shown,
chipTextView: TextView,
@@ -180,37 +256,93 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
chipTimeView.visibility = View.GONE
}
}
- updateChipTextPadding(chipModel, chipTextView, chipTimeView)
}
- private fun updateChipTextPadding(
+ private fun updateChipPadding(
chipModel: OngoingActivityChipModel.Shown,
+ backgroundView: View,
chipTextView: TextView,
chipTimeView: ChipChronometer,
) {
- val requiresPadding = chipModel.icon != null
- if (requiresPadding) {
- chipTextView.addChipTextPaddingStart()
- chipTimeView.addChipTextPaddingStart()
+ if (chipModel.icon != null) {
+ if (chipModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView) {
+ // If the icon is a custom [StatusBarIconView], then it should've come from
+ // `Notification.smallIcon`, which is required to embed its own paddings. We need to
+ // adjust the other paddings to make everything look good :)
+ backgroundView.setBackgroundPaddingForEmbeddedPaddingIcon()
+ chipTextView.setTextPaddingForEmbeddedPaddingIcon()
+ chipTimeView.setTextPaddingForEmbeddedPaddingIcon()
+ } else {
+ backgroundView.setBackgroundPaddingForNormalIcon()
+ chipTextView.setTextPaddingForNormalIcon()
+ chipTimeView.setTextPaddingForNormalIcon()
+ }
} else {
- chipTextView.removeChipTextPaddingStart()
- chipTimeView.removeChipTextPaddingStart()
+ backgroundView.setBackgroundPaddingForNoIcon()
+ chipTextView.setTextPaddingForNoIcon()
+ chipTimeView.setTextPaddingForNoIcon()
}
}
- private fun View.addChipTextPaddingStart() {
+ private fun View.setTextPaddingForEmbeddedPaddingIcon() {
+ val newPaddingEnd =
+ context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_text_end_padding_for_embedded_padding_icon
+ )
+ setPaddingRelative(
+ // The icon should embed enough padding between the icon and time view.
+ /* start= */ 0,
+ this.paddingTop,
+ newPaddingEnd,
+ this.paddingBottom,
+ )
+ }
+
+ private fun View.setTextPaddingForNormalIcon() {
this.setPaddingRelative(
this.context.resources.getDimensionPixelSize(
R.dimen.ongoing_activity_chip_icon_text_padding
),
paddingTop,
- paddingEnd,
+ // The background view will contain the right end padding.
+ /* end= */ 0,
+ paddingBottom,
+ )
+ }
+
+ private fun View.setTextPaddingForNoIcon() {
+ // The background view will have even start & end paddings, so we don't want the text view
+ // to add any additional padding.
+ this.setPaddingRelative(/* start= */ 0, paddingTop, /* end= */ 0, paddingBottom)
+ }
+
+ private fun View.setBackgroundPaddingForEmbeddedPaddingIcon() {
+ val sidePadding =
+ context.resources.getDimensionPixelSize(
+ R.dimen.ongoing_activity_chip_side_padding_for_embedded_padding_icon
+ )
+ setPaddingRelative(
+ sidePadding,
+ paddingTop,
+ sidePadding,
+ paddingBottom,
+ )
+ }
+
+ private fun View.setBackgroundPaddingForNormalIcon() {
+ val sidePadding =
+ context.resources.getDimensionPixelSize(R.dimen.ongoing_activity_chip_side_padding)
+ setPaddingRelative(
+ sidePadding,
+ paddingTop,
+ sidePadding,
paddingBottom,
)
}
- private fun View.removeChipTextPaddingStart() {
- this.setPaddingRelative(/* start= */ 0, paddingTop, paddingEnd, paddingBottom)
+ private fun View.setBackgroundPaddingForNoIcon() {
+ // The padding for the normal icon is also appropriate for no icon.
+ setBackgroundPaddingForNormalIcon()
}
private fun setChipAccessibility(
@@ -269,6 +401,10 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
)
.start()
}
+
+ companion object {
+ @IdRes private val CUSTOM_ICON_VIEW_ID = R.id.ongoing_activity_chip_custom_icon
+ }
}
/** Listener for various events that may affect the status bar's visibility. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
index cd8a7407970f..8f41caf54ec8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
@@ -23,6 +23,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
@@ -39,7 +40,7 @@ class CallChipInteractorTest : SysuiTestCase() {
kosmos.testScope.runTest {
val latest by collectLastValue(underTest.ongoingCallState)
- val inCall = OngoingCallModel.InCall(startTimeMs = 1000, intent = null)
+ val inCall = inCallModel(startTimeMs = 1000)
repo.setOngoingCallState(inCall)
assertThat(latest).isEqualTo(inCall)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 1a6b420dace5..ce79fbde77a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -17,8 +17,11 @@
package com.android.systemui.statusbar.chips.call.ui.viewmodel
import android.app.PendingIntent
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
@@ -26,11 +29,13 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -73,7 +78,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
}
@@ -83,7 +88,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = -2, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = -2))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
}
@@ -93,7 +98,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 345, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 345))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
}
@@ -106,7 +111,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setCurrentTimeMillis(3000)
kosmos.fakeSystemClock.setElapsedRealtime(400_000)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
// The OngoingCallModel start time is relative to currentTimeMillis, so this call
// started 2000ms ago (1000 - 3000). The OngoingActivityChipModel start time needs to be
@@ -117,29 +122,97 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_positiveStartTime_iconIsPhone() =
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_positiveStartTime_notifIconFlagOff_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(
+ inCallModel(startTimeMs = 1000, notificationIcon = mock<StatusBarIconView>())
+ )
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_positiveStartTime_notifIconFlagOn_iconIsNotifIcon() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val notifIcon = mock<StatusBarIconView>()
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, notificationIcon = notifIcon))
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
+ val actualIcon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.StatusBarView)
+ .impl
+ assertThat(actualIcon).isEqualTo(notifIcon)
+ }
+
+ @Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_zeroStartTime_notifIconFlagOff_iconIsPhone() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(
+ inCallModel(startTimeMs = 0, notificationIcon = mock<StatusBarIconView>())
+ )
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_zeroStartTime_notifIconFlagOn_iconIsNotifIcon() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val notifIcon = mock<StatusBarIconView>()
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0, notificationIcon = notifIcon))
- assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
- assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
- .isNotNull()
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
+ val actualIcon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.StatusBarView)
+ .impl
+ assertThat(actualIcon).isEqualTo(notifIcon)
}
@Test
- fun chip_zeroStartTime_iconIsPhone() =
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun chip_notifIconFlagOn_butNullNotifIcon_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, notificationIcon = null))
- assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
- assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
- .isNotNull()
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(OngoingActivityChipModel.ChipIcon.Basic::class.java)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat(icon.contentDescription).isNotNull()
}
@Test
@@ -147,7 +220,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
assertThat((latest as OngoingActivityChipModel.Shown).colors)
.isEqualTo(ColorsModel.Themed)
@@ -158,7 +231,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0))
assertThat((latest as OngoingActivityChipModel.Shown).colors)
.isEqualTo(ColorsModel.Themed)
@@ -172,7 +245,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setElapsedRealtime(400_000)
// Start a call
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
.isEqualTo(398_000)
@@ -186,7 +259,7 @@ class CallChipViewModelTest : SysuiTestCase() {
kosmos.fakeSystemClock.setElapsedRealtime(500_000)
// Start a new call, which started 1000ms ago
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 102_000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 102_000))
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
.isEqualTo(499_000)
@@ -197,7 +270,7 @@ class CallChipViewModelTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.chip)
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = null))
assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
}
@@ -208,7 +281,7 @@ class CallChipViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.chip)
val intent = mock<PendingIntent>()
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = intent))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = intent))
val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
assertThat(clickListener).isNotNull()
@@ -223,7 +296,7 @@ class CallChipViewModelTest : SysuiTestCase() {
val latest by collectLastValue(underTest.chip)
val intent = mock<PendingIntent>()
- repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = intent))
+ repo.setOngoingCallState(inCallModel(startTimeMs = 0, intent = intent))
val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
assertThat(clickListener).isNotNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index 02764f8a15fd..a8d2c5b4cdd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -125,8 +125,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
}
@@ -141,8 +144,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
}
@@ -176,8 +182,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
// This content description is just generic "Casting", not "Casting screen"
assertThat((icon.contentDescription as ContentDescription.Resource).res)
.isEqualTo(R.string.accessibility_casting)
@@ -203,8 +212,11 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
// Only the projection info will show a timer
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_cast_connected)
// MediaProjection == screen casting, so this content description reflects that we're
// using the MediaProjection information.
assertThat((icon.contentDescription as ContentDescription.Resource).res)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index b4a37ee1a55e..e68fa0bc6eb3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -148,8 +148,11 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_screenrecord)
assertThat(icon.contentDescription).isNotNull()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 2658679dee08..a2ef59916ff6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -133,8 +133,11 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
assertThat(icon.contentDescription).isNotNull()
}
@@ -147,8 +150,11 @@ class ShareToAppChipViewModelTest : SysuiTestCase() {
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
assertThat(icon.contentDescription).isNotNull()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
index b9049e8f76b6..a724cfaa4798 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.chips.ui.viewmodel
+import androidx.annotation.DrawableRes
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
@@ -50,7 +51,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val newChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -62,7 +63,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val newerChip =
OngoingActivityChipModel.Shown.IconOnly(
- icon = Icon.Resource(R.drawable.ic_hotspot, contentDescription = null),
+ icon = createIcon(R.drawable.ic_hotspot),
colors = ColorsModel.Themed,
onClickListener = null,
)
@@ -82,7 +83,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val shownChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -122,7 +123,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
val shownChip =
OngoingActivityChipModel.Shown.Timer(
- icon = Icon.Resource(R.drawable.ic_cake, contentDescription = null),
+ icon = createIcon(R.drawable.ic_cake),
colors = ColorsModel.Themed,
startTimeMs = 100L,
onClickListener = null,
@@ -151,4 +152,7 @@ class ChipTransitionHelperTest : SysuiTestCase() {
advanceTimeBy(2)
assertThat(latest).isEqualTo(shownChip)
}
+
+ private fun createIcon(@DrawableRes drawable: Int) =
+ OngoingActivityChipModel.ChipIcon.Basic(Icon.Resource(drawable, contentDescription = null))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index ee249f0f8a2c..556ec6a307ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -120,7 +121,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
testScope.runTest {
screenRecordState.value = ScreenRecordModel.Recording
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -146,7 +147,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
screenRecordState.value = ScreenRecordModel.DoingNothing
mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -160,7 +161,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
// MediaProjection covers both share-to-app and cast-to-other-device
mediaProjectionState.value = MediaProjectionState.NotProjecting
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -171,7 +172,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
fun chip_higherPriorityChipAdded_lowerPriorityChipReplaced() =
testScope.runTest {
// Start with just the lower priority call chip
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
mediaProjectionState.value = MediaProjectionState.NotProjecting
screenRecordState.value = ScreenRecordModel.DoingNothing
@@ -205,7 +206,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
mediaProjectionState.value =
MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
- callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
+ callRepo.setOngoingCallState(inCallModel(startTimeMs = 34))
val latest by collectLastValue(underTest.chip)
@@ -335,21 +336,29 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
fun assertIsScreenRecordChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_screenrecord)
}
fun assertIsShareToAppChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(R.drawable.ic_present_to_all)
}
fun assertIsCallChip(latest: OngoingActivityChipModel?) {
assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res)
- .isEqualTo(com.android.internal.R.drawable.ic_phone)
+ val icon =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.Basic)
+ .impl as Icon.Resource
+ assertThat(icon.res).isEqualTo(com.android.internal.R.drawable.ic_phone)
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
index 6a5976eccd3a..48ae7a2aa260 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.phone.StatusBarBoundsProvider
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
@@ -396,9 +397,7 @@ class StatusBarModeRepositoryImplTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.statusBarAppearance)
- ongoingCallRepository.setOngoingCallState(
- OngoingCallModel.InCall(startTimeMs = 34, intent = null)
- )
+ ongoingCallRepository.setOngoingCallState(inCallModel(startTimeMs = 34))
onSystemBarAttributesChanged(
requestedVisibleTypes = WindowInsets.Type.navigationBars(),
)
@@ -411,9 +410,8 @@ class StatusBarModeRepositoryImplTest : SysuiTestCase() {
testScope.runTest {
val latest by collectLastValue(underTest.statusBarAppearance)
- ongoingCallRepository.setOngoingCallState(
- OngoingCallModel.InCall(startTimeMs = 789, intent = null)
- )
+ ongoingCallRepository.setOngoingCallState(inCallModel(startTimeMs = 789))
+
onSystemBarAttributesChanged(
requestedVisibleTypes = WindowInsets.Type.statusBars(),
appearance = APPEARANCE_OPAQUE_STATUS_BARS,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
index bfa816e65eb2..25138fd0ff83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
@@ -30,9 +30,12 @@ import android.graphics.drawable.Icon
import android.os.Bundle
import android.os.SystemClock
import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapperTest.Companion.any
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -108,6 +111,28 @@ class IconManagerTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun testCreateIcons_chipNotifIconFlagDisabled_statusBarChipIconIsNull() {
+ val entry =
+ notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
+ entry?.let { iconManager.createIcons(it) }
+ testScope.runCurrent()
+
+ assertThat(entry?.icons?.statusBarChipIcon).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun testCreateIcons_chipNotifIconFlagEnabled_statusBarChipIconIsNull() {
+ val entry =
+ notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
+ entry?.let { iconManager.createIcons(it) }
+ testScope.runCurrent()
+
+ assertThat(entry?.icons?.statusBarChipIcon).isNotNull()
+ }
+
+ @Test
fun testCreateIcons_importantConversation_shortcutIcon() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = true)
@@ -179,6 +204,7 @@ class IconManagerTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
fun testCreateIcons_sensitiveImportantConversation() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = false)
@@ -187,11 +213,13 @@ class IconManagerTest : SysuiTestCase() {
entry?.let { iconManager.createIcons(it) }
testScope.runCurrent()
assertThat(entry?.icons?.statusBarIcon?.sourceIcon).isEqualTo(shortcutIc)
+ assertThat(entry?.icons?.statusBarChipIcon?.sourceIcon).isEqualTo(shortcutIc)
assertThat(entry?.icons?.shelfIcon?.sourceIcon).isEqualTo(smallIc)
assertThat(entry?.icons?.aodIcon?.sourceIcon).isEqualTo(smallIc)
}
@Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
fun testUpdateIcons_sensitiveImportantConversation() {
val entry =
notificationEntry(hasShortcut = true, hasMessageSenderIcon = true, hasLargeIcon = false)
@@ -202,6 +230,7 @@ class IconManagerTest : SysuiTestCase() {
entry?.let { iconManager.updateIcons(it) }
testScope.runCurrent()
assertThat(entry?.icons?.statusBarIcon?.sourceIcon).isEqualTo(shortcutIc)
+ assertThat(entry?.icons?.statusBarChipIcon?.sourceIcon).isEqualTo(shortcutIc)
assertThat(entry?.icons?.shelfIcon?.sourceIcon).isEqualTo(smallIc)
assertThat(entry?.icons?.aodIcon?.sourceIcon).isEqualTo(smallIc)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
index 6c2e2c6ef47d..dfe01bf45f38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
@@ -28,7 +28,7 @@ import android.view.View
import android.widget.LinearLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.Flags
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
import com.android.systemui.SysuiTestCase
@@ -39,6 +39,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -160,6 +161,47 @@ class OngoingCallControllerViaRepoTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun interactorHasOngoingCallNotif_notifIconFlagOff_repoHasNoNotifIcon() =
+ testScope.runTest {
+ val icon = mock<StatusBarIconView>()
+ setNotifOnRepo(
+ activeNotificationModel(
+ key = "ongoingNotif",
+ callType = CallType.Ongoing,
+ uid = CALL_UID,
+ statusBarChipIcon = icon,
+ whenTime = 567,
+ )
+ )
+
+ val repoState = ongoingCallRepository.ongoingCallState.value
+ assertThat(repoState).isInstanceOf(OngoingCallModel.InCall::class.java)
+ assertThat((repoState as OngoingCallModel.InCall).notificationIconView).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
+ fun interactorHasOngoingCallNotif_notifIconFlagOn_repoHasNotifIcon() =
+ testScope.runTest {
+ val icon = mock<StatusBarIconView>()
+
+ setNotifOnRepo(
+ activeNotificationModel(
+ key = "ongoingNotif",
+ callType = CallType.Ongoing,
+ uid = CALL_UID,
+ statusBarChipIcon = icon,
+ whenTime = 567,
+ )
+ )
+
+ val repoState = ongoingCallRepository.ongoingCallState.value
+ assertThat(repoState).isInstanceOf(OngoingCallModel.InCall::class.java)
+ assertThat((repoState as OngoingCallModel.InCall).notificationIconView).isEqualTo(icon)
+ }
+
+ @Test
fun notifRepoHasOngoingCallNotif_isOngoingCallNotif_windowControllerUpdated() {
setCallNotifOnRepo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index cbb8fe82eff1..4c6eaa589e6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
@@ -21,6 +21,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -33,7 +34,7 @@ class OngoingCallRepositoryTest : SysuiTestCase() {
@Test
fun hasOngoingCall_matchesSet() {
- val inCallModel = OngoingCallModel.InCall(startTimeMs = 654, intent = null)
+ val inCallModel = inCallModel(startTimeMs = 654)
underTest.setOngoingCallState(inCallModel)
assertThat(underTest.ongoingCallState.value).isEqualTo(inCallModel)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
index 37f1f137094e..76bdc0de3d7b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.data.model
import android.app.PendingIntent
import android.graphics.drawable.Icon
+import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.CallType
import com.android.systemui.statusbar.notification.stack.BUCKET_UNKNOWN
@@ -36,6 +37,7 @@ fun activeNotificationModel(
aodIcon: Icon? = null,
shelfIcon: Icon? = null,
statusBarIcon: Icon? = null,
+ statusBarChipIcon: StatusBarIconView? = null,
uid: Int = 0,
instanceId: Int? = null,
isGroupSummary: Boolean = false,
@@ -57,6 +59,7 @@ fun activeNotificationModel(
aodIcon = aodIcon,
shelfIcon = shelfIcon,
statusBarIcon = statusBarIcon,
+ statusBarChipIconView = statusBarChipIcon,
uid = uid,
packageName = packageName,
contentIntent = contentIntent,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
new file mode 100644
index 000000000000..3963d7c5be63
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.ongoingcall.shared.model
+
+import android.app.PendingIntent
+import com.android.systemui.statusbar.StatusBarIconView
+
+/** Helper for building [OngoingCallModel.InCall] instances in tests. */
+fun inCallModel(
+ startTimeMs: Long,
+ notificationIcon: StatusBarIconView? = null,
+ intent: PendingIntent? = null
+) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent)