Loading packages/SystemUI/aconfig/systemui.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,17 @@ flag { bug: "332662551" } flag { name: "status_bar_use_repos_for_call_chip" namespace: "systemui" description: "Use repositories as the source of truth for call notifications shown as a chip in" "the status bar" bug: "328584859" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "compose_bouncer" namespace: "systemui" Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt +114 −0 Original line number Diff line number Diff line Loading @@ -24,8 +24,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading Loading @@ -55,6 +58,117 @@ class ActiveNotificationsInteractorTest : SysuiTestCase() { assertThat(underTest.allNotificationsCountValue).isEqualTo(5) } @Test fun ongoingCallNotification_noCallNotifs_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val normalNotifs = listOf( activeNotificationModel( key = "notif1", callType = CallType.None, ), activeNotificationModel( key = "notif2", callType = CallType.None, ) ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { normalNotifs.forEach(::addIndividualNotif) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_incomingCallNotif_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "incomingNotif", callType = CallType.Incoming, ) ) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_screeningCallNotif_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "screeningNotif", callType = CallType.Screening, ) ) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_ongoingCallNotif_hasNotif() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val ongoingNotif = activeNotificationModel( key = "ongoingNotif", callType = CallType.Ongoing, ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif(ongoingNotif) } .build() assertThat(latest).isEqualTo(ongoingNotif) } @Test fun ongoingCallNotification_multipleCallNotifs_usesEarlierNotif() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val earlierOngoingNotif = activeNotificationModel( key = "earlierOngoingNotif", callType = CallType.Ongoing, whenTime = 45L, ) val laterOngoingNotif = activeNotificationModel( key = "laterOngoingNotif", callType = CallType.Ongoing, whenTime = 55L, ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif(earlierOngoingNotif) } .apply { addIndividualNotif(laterOngoingNotif) } .build() assertThat(latest).isEqualTo(earlierOngoingNotif) } @Test fun areAnyNotificationsPresent_isTrue() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt +16 −0 Original line number Diff line number Diff line Loading @@ -15,11 +15,13 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow Loading @@ -27,6 +29,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @SysUISingleton class ActiveNotificationsInteractor @Inject constructor( Loading Loading @@ -71,6 +74,19 @@ constructor( val allNotificationsCountValue: Int get() = repository.activeNotifications.value.individuals.size /** * The priority ongoing call notification, or null if there is no ongoing call. * * The output model is guaranteed to have [ActiveNotificationModel.callType] to be equal to * [CallType.Ongoing]. */ val ongoingCallNotification: Flow<ActiveNotificationModel?> = allRepresentativeNotifications.map { notifMap -> // Once a call has started, its `whenTime` should stay the same, so we can use it as a // stable sort value. notifMap.values.filter { it.callType == CallType.Ongoing }.minByOrNull { it.whenTime } } /** Are any notifications being actively presented in the notification stack? */ val areAnyNotificationsPresent: Flow<Boolean> = repository.activeNotifications Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt +36 −0 Original line number Diff line number Diff line Loading @@ -15,7 +15,14 @@ */ package com.android.systemui.statusbar.notification.domain.interactor import android.app.Notification.CallStyle.CALL_TYPE_INCOMING import android.app.Notification.CallStyle.CALL_TYPE_ONGOING import android.app.Notification.CallStyle.CALL_TYPE_SCREENING import android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN import android.app.Notification.EXTRA_CALL_TYPE import android.app.PendingIntent import android.graphics.drawable.Icon import android.service.notification.StatusBarNotification import android.util.ArrayMap import com.android.app.tracing.traceSection import com.android.systemui.statusbar.notification.collection.GroupEntry Loading @@ -27,6 +34,7 @@ import com.android.systemui.statusbar.notification.data.repository.ActiveNotific import com.android.systemui.statusbar.notification.shared.ActiveNotificationEntryModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import javax.inject.Inject import kotlinx.coroutines.flow.update Loading Loading @@ -124,6 +132,7 @@ private class ActiveNotificationsStoreBuilder( existingModels.createOrReuse( key = key, groupKey = sbn.groupKey, whenTime = sbn.notification.`when`, isAmbient = sectionStyleProvider.isMinimized(this), isRowDismissed = isRowDismissed, isSilent = sectionStyleProvider.isSilent(this), Loading @@ -135,15 +144,18 @@ private class ActiveNotificationsStoreBuilder( statusBarIcon = icons.statusBarIcon?.sourceIcon, uid = sbn.uid, packageName = sbn.packageName, contentIntent = sbn.notification.contentIntent, instanceId = sbn.instanceId?.id, isGroupSummary = sbn.notification.isGroupSummary, bucket = bucket, callType = sbn.toCallType(), ) } private fun ActiveNotificationsStore.createOrReuse( key: String, groupKey: String?, whenTime: Long, isAmbient: Boolean, isRowDismissed: Boolean, isSilent: Boolean, Loading @@ -155,14 +167,17 @@ private fun ActiveNotificationsStore.createOrReuse( statusBarIcon: Icon?, uid: Int, packageName: String, contentIntent: PendingIntent?, instanceId: Int?, isGroupSummary: Boolean, bucket: Int, callType: CallType, ): ActiveNotificationModel { return individuals[key]?.takeIf { it.isCurrent( key = key, groupKey = groupKey, whenTime = whenTime, isAmbient = isAmbient, isRowDismissed = isRowDismissed, isSilent = isSilent, Loading @@ -176,12 +191,15 @@ private fun ActiveNotificationsStore.createOrReuse( instanceId = instanceId, isGroupSummary = isGroupSummary, packageName = packageName, contentIntent = contentIntent, bucket = bucket, callType = callType, ) } ?: ActiveNotificationModel( key = key, groupKey = groupKey, whenTime = whenTime, isAmbient = isAmbient, isRowDismissed = isRowDismissed, isSilent = isSilent, Loading @@ -195,13 +213,16 @@ private fun ActiveNotificationsStore.createOrReuse( instanceId = instanceId, isGroupSummary = isGroupSummary, packageName = packageName, contentIntent = contentIntent, bucket = bucket, callType = callType, ) } private fun ActiveNotificationModel.isCurrent( key: String, groupKey: String?, whenTime: Long, isAmbient: Boolean, isRowDismissed: Boolean, isSilent: Boolean, Loading @@ -213,13 +234,16 @@ private fun ActiveNotificationModel.isCurrent( statusBarIcon: Icon?, uid: Int, packageName: String, contentIntent: PendingIntent?, instanceId: Int?, isGroupSummary: Boolean, bucket: Int, callType: CallType, ): Boolean { return when { key != this.key -> false groupKey != this.groupKey -> false whenTime != this.whenTime -> false isAmbient != this.isAmbient -> false isRowDismissed != this.isRowDismissed -> false isSilent != this.isSilent -> false Loading @@ -233,7 +257,9 @@ private fun ActiveNotificationModel.isCurrent( instanceId != this.instanceId -> false isGroupSummary != this.isGroupSummary -> false packageName != this.packageName -> false contentIntent != this.contentIntent -> false bucket != this.bucket -> false callType != this.callType -> false else -> true } } Loading @@ -259,3 +285,13 @@ private fun ActiveNotificationGroupModel.isCurrent( else -> true } } private fun StatusBarNotification.toCallType(): CallType = when (this.notification.extras.getInt(EXTRA_CALL_TYPE, -1)) { -1 -> CallType.None CALL_TYPE_INCOMING -> CallType.Incoming CALL_TYPE_ONGOING -> CallType.Ongoing CALL_TYPE_SCREENING -> CallType.Screening CALL_TYPE_UNKNOWN -> CallType.Unknown else -> CallType.Unknown } packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt +21 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package com.android.systemui.statusbar.notification.shared import android.app.PendingIntent import android.graphics.drawable.Icon import com.android.systemui.statusbar.notification.stack.PriorityBucket Loading @@ -32,6 +33,8 @@ data class ActiveNotificationModel( val key: String, /** Notification group key associated with this entry. */ val groupKey: String?, /** When this notification was posted. */ val whenTime: Long, /** Is this entry in the ambient / minimized section (lowest priority)? */ val isAmbient: Boolean, /** Loading Loading @@ -60,12 +63,16 @@ data class ActiveNotificationModel( val uid: Int, /** The notifying app's packageName. */ val packageName: String, /** The intent to execute if UI related to this notification is clicked. */ val contentIntent: PendingIntent?, /** A small per-notification ID, used for statsd logging. */ val instanceId: Int?, /** If this notification is the group summary for a group of notifications. */ val isGroupSummary: Boolean, /** Indicates in which section the notification is displayed in. @see [PriorityBucket]. */ @PriorityBucket val bucket: Int, /** The call type set on the notification. */ val callType: CallType, ) : ActiveNotificationEntryModel() /** Model for a group of notifications. */ Loading @@ -74,3 +81,17 @@ data class ActiveNotificationGroupModel( val summary: ActiveNotificationModel, val children: List<ActiveNotificationModel>, ) : ActiveNotificationEntryModel() /** Specifies the call type set on the notification. For most notifications, will be [None]. */ enum class CallType { /** This notification isn't a call-type notification. */ None, /** See [android.app.Notification.CallStyle.CALL_TYPE_INCOMING]. */ Incoming, /** See [android.app.Notification.CallStyle.CALL_TYPE_ONGOING]. */ Ongoing, /** See [android.app.Notification.CallStyle.CALL_TYPE_SCREENING]. */ Screening, /** See [android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN]. */ Unknown, } Loading
packages/SystemUI/aconfig/systemui.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,17 @@ flag { bug: "332662551" } flag { name: "status_bar_use_repos_for_call_chip" namespace: "systemui" description: "Use repositories as the source of truth for call notifications shown as a chip in" "the status bar" bug: "328584859" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "compose_bouncer" namespace: "systemui" Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt +114 −0 Original line number Diff line number Diff line Loading @@ -24,8 +24,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi Loading Loading @@ -55,6 +58,117 @@ class ActiveNotificationsInteractorTest : SysuiTestCase() { assertThat(underTest.allNotificationsCountValue).isEqualTo(5) } @Test fun ongoingCallNotification_noCallNotifs_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val normalNotifs = listOf( activeNotificationModel( key = "notif1", callType = CallType.None, ), activeNotificationModel( key = "notif2", callType = CallType.None, ) ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { normalNotifs.forEach(::addIndividualNotif) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_incomingCallNotif_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "incomingNotif", callType = CallType.Incoming, ) ) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_screeningCallNotif_null() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( key = "screeningNotif", callType = CallType.Screening, ) ) } .build() assertThat(latest).isNull() } @Test fun ongoingCallNotification_ongoingCallNotif_hasNotif() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val ongoingNotif = activeNotificationModel( key = "ongoingNotif", callType = CallType.Ongoing, ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif(ongoingNotif) } .build() assertThat(latest).isEqualTo(ongoingNotif) } @Test fun ongoingCallNotification_multipleCallNotifs_usesEarlierNotif() = testScope.runTest { val latest by collectLastValue(underTest.ongoingCallNotification) val earlierOngoingNotif = activeNotificationModel( key = "earlierOngoingNotif", callType = CallType.Ongoing, whenTime = 45L, ) val laterOngoingNotif = activeNotificationModel( key = "laterOngoingNotif", callType = CallType.Ongoing, whenTime = 55L, ) activeNotificationListRepository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif(earlierOngoingNotif) } .apply { addIndividualNotif(laterOngoingNotif) } .build() assertThat(latest).isEqualTo(earlierOngoingNotif) } @Test fun areAnyNotificationsPresent_isTrue() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt +16 −0 Original line number Diff line number Diff line Loading @@ -15,11 +15,13 @@ package com.android.systemui.statusbar.notification.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.notification.collection.render.NotifStats import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow Loading @@ -27,6 +29,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @SysUISingleton class ActiveNotificationsInteractor @Inject constructor( Loading Loading @@ -71,6 +74,19 @@ constructor( val allNotificationsCountValue: Int get() = repository.activeNotifications.value.individuals.size /** * The priority ongoing call notification, or null if there is no ongoing call. * * The output model is guaranteed to have [ActiveNotificationModel.callType] to be equal to * [CallType.Ongoing]. */ val ongoingCallNotification: Flow<ActiveNotificationModel?> = allRepresentativeNotifications.map { notifMap -> // Once a call has started, its `whenTime` should stay the same, so we can use it as a // stable sort value. notifMap.values.filter { it.callType == CallType.Ongoing }.minByOrNull { it.whenTime } } /** Are any notifications being actively presented in the notification stack? */ val areAnyNotificationsPresent: Flow<Boolean> = repository.activeNotifications Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt +36 −0 Original line number Diff line number Diff line Loading @@ -15,7 +15,14 @@ */ package com.android.systemui.statusbar.notification.domain.interactor import android.app.Notification.CallStyle.CALL_TYPE_INCOMING import android.app.Notification.CallStyle.CALL_TYPE_ONGOING import android.app.Notification.CallStyle.CALL_TYPE_SCREENING import android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN import android.app.Notification.EXTRA_CALL_TYPE import android.app.PendingIntent import android.graphics.drawable.Icon import android.service.notification.StatusBarNotification import android.util.ArrayMap import com.android.app.tracing.traceSection import com.android.systemui.statusbar.notification.collection.GroupEntry Loading @@ -27,6 +34,7 @@ import com.android.systemui.statusbar.notification.data.repository.ActiveNotific import com.android.systemui.statusbar.notification.shared.ActiveNotificationEntryModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import javax.inject.Inject import kotlinx.coroutines.flow.update Loading Loading @@ -124,6 +132,7 @@ private class ActiveNotificationsStoreBuilder( existingModels.createOrReuse( key = key, groupKey = sbn.groupKey, whenTime = sbn.notification.`when`, isAmbient = sectionStyleProvider.isMinimized(this), isRowDismissed = isRowDismissed, isSilent = sectionStyleProvider.isSilent(this), Loading @@ -135,15 +144,18 @@ private class ActiveNotificationsStoreBuilder( statusBarIcon = icons.statusBarIcon?.sourceIcon, uid = sbn.uid, packageName = sbn.packageName, contentIntent = sbn.notification.contentIntent, instanceId = sbn.instanceId?.id, isGroupSummary = sbn.notification.isGroupSummary, bucket = bucket, callType = sbn.toCallType(), ) } private fun ActiveNotificationsStore.createOrReuse( key: String, groupKey: String?, whenTime: Long, isAmbient: Boolean, isRowDismissed: Boolean, isSilent: Boolean, Loading @@ -155,14 +167,17 @@ private fun ActiveNotificationsStore.createOrReuse( statusBarIcon: Icon?, uid: Int, packageName: String, contentIntent: PendingIntent?, instanceId: Int?, isGroupSummary: Boolean, bucket: Int, callType: CallType, ): ActiveNotificationModel { return individuals[key]?.takeIf { it.isCurrent( key = key, groupKey = groupKey, whenTime = whenTime, isAmbient = isAmbient, isRowDismissed = isRowDismissed, isSilent = isSilent, Loading @@ -176,12 +191,15 @@ private fun ActiveNotificationsStore.createOrReuse( instanceId = instanceId, isGroupSummary = isGroupSummary, packageName = packageName, contentIntent = contentIntent, bucket = bucket, callType = callType, ) } ?: ActiveNotificationModel( key = key, groupKey = groupKey, whenTime = whenTime, isAmbient = isAmbient, isRowDismissed = isRowDismissed, isSilent = isSilent, Loading @@ -195,13 +213,16 @@ private fun ActiveNotificationsStore.createOrReuse( instanceId = instanceId, isGroupSummary = isGroupSummary, packageName = packageName, contentIntent = contentIntent, bucket = bucket, callType = callType, ) } private fun ActiveNotificationModel.isCurrent( key: String, groupKey: String?, whenTime: Long, isAmbient: Boolean, isRowDismissed: Boolean, isSilent: Boolean, Loading @@ -213,13 +234,16 @@ private fun ActiveNotificationModel.isCurrent( statusBarIcon: Icon?, uid: Int, packageName: String, contentIntent: PendingIntent?, instanceId: Int?, isGroupSummary: Boolean, bucket: Int, callType: CallType, ): Boolean { return when { key != this.key -> false groupKey != this.groupKey -> false whenTime != this.whenTime -> false isAmbient != this.isAmbient -> false isRowDismissed != this.isRowDismissed -> false isSilent != this.isSilent -> false Loading @@ -233,7 +257,9 @@ private fun ActiveNotificationModel.isCurrent( instanceId != this.instanceId -> false isGroupSummary != this.isGroupSummary -> false packageName != this.packageName -> false contentIntent != this.contentIntent -> false bucket != this.bucket -> false callType != this.callType -> false else -> true } } Loading @@ -259,3 +285,13 @@ private fun ActiveNotificationGroupModel.isCurrent( else -> true } } private fun StatusBarNotification.toCallType(): CallType = when (this.notification.extras.getInt(EXTRA_CALL_TYPE, -1)) { -1 -> CallType.None CALL_TYPE_INCOMING -> CallType.Incoming CALL_TYPE_ONGOING -> CallType.Ongoing CALL_TYPE_SCREENING -> CallType.Screening CALL_TYPE_UNKNOWN -> CallType.Unknown else -> CallType.Unknown }
packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt +21 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package com.android.systemui.statusbar.notification.shared import android.app.PendingIntent import android.graphics.drawable.Icon import com.android.systemui.statusbar.notification.stack.PriorityBucket Loading @@ -32,6 +33,8 @@ data class ActiveNotificationModel( val key: String, /** Notification group key associated with this entry. */ val groupKey: String?, /** When this notification was posted. */ val whenTime: Long, /** Is this entry in the ambient / minimized section (lowest priority)? */ val isAmbient: Boolean, /** Loading Loading @@ -60,12 +63,16 @@ data class ActiveNotificationModel( val uid: Int, /** The notifying app's packageName. */ val packageName: String, /** The intent to execute if UI related to this notification is clicked. */ val contentIntent: PendingIntent?, /** A small per-notification ID, used for statsd logging. */ val instanceId: Int?, /** If this notification is the group summary for a group of notifications. */ val isGroupSummary: Boolean, /** Indicates in which section the notification is displayed in. @see [PriorityBucket]. */ @PriorityBucket val bucket: Int, /** The call type set on the notification. */ val callType: CallType, ) : ActiveNotificationEntryModel() /** Model for a group of notifications. */ Loading @@ -74,3 +81,17 @@ data class ActiveNotificationGroupModel( val summary: ActiveNotificationModel, val children: List<ActiveNotificationModel>, ) : ActiveNotificationEntryModel() /** Specifies the call type set on the notification. For most notifications, will be [None]. */ enum class CallType { /** This notification isn't a call-type notification. */ None, /** See [android.app.Notification.CallStyle.CALL_TYPE_INCOMING]. */ Incoming, /** See [android.app.Notification.CallStyle.CALL_TYPE_ONGOING]. */ Ongoing, /** See [android.app.Notification.CallStyle.CALL_TYPE_SCREENING]. */ Screening, /** See [android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN]. */ Unknown, }