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

Commit 974aea57 authored by Julia Tuttle's avatar Julia Tuttle Committed by Android (Google) Code Review
Browse files

Merge changes I86ad6c32,Ic9507d80,Ia55a9386 into main

* changes:
  Use small icon as conversation icon for call AOD RONs
  Fix content margin top on AOD RONs with redesign enabled
  Move clock to left when AOD RON is present on split shade
parents 1e8281ec eeb8fc37
Loading
Loading
Loading
Loading
+38 −5
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod
import com.android.systemui.statusbar.notification.promoted.domain.interactor.AODPromotedNotificationInteractor
import com.android.systemui.util.kotlin.combine
import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractor
import javax.inject.Inject
@@ -45,6 +47,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn

@@ -57,6 +60,7 @@ class KeyguardClockInteractor
constructor(
    mediaCarouselInteractor: MediaCarouselInteractor,
    activeNotificationsInteractor: ActiveNotificationsInteractor,
    aodPromotedNotificationInteractor: AODPromotedNotificationInteractor,
    shadeInteractor: ShadeInteractor,
    keyguardInteractor: KeyguardInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -80,11 +84,30 @@ constructor(

    var clock: ClockController? by keyguardClockRepository.clockEventController::clock

    private val isAodPromotedNotificationPresent: Flow<Boolean> =
        if (PromotedNotificationUiAod.isEnabled) {
            aodPromotedNotificationInteractor.isPresent
        } else {
            flowOf(false)
        }

    private val areAnyNotificationsPresent: Flow<Boolean> =
        if (PromotedNotificationUiAod.isEnabled) {
            combine(
                activeNotificationsInteractor.areAnyNotificationsPresent,
                isAodPromotedNotificationPresent,
            ) { areAnyNotificationsPresent, isAodPromotedNotificationPresent ->
                areAnyNotificationsPresent || isAodPromotedNotificationPresent
            }
        } else {
            activeNotificationsInteractor.areAnyNotificationsPresent
        }

    val clockSize: StateFlow<ClockSize> =
        if (SceneContainerFlag.isEnabled) {
            combine(
                    shadeInteractor.isShadeLayoutWide,
                    activeNotificationsInteractor.areAnyNotificationsPresent,
                    areAnyNotificationsPresent,
                    mediaCarouselInteractor.hasActiveMediaOrRecommendation,
                    keyguardInteractor.isDozing,
                    isOnAod,
@@ -110,23 +133,32 @@ constructor(
        if (SceneContainerFlag.isEnabled) {
            combine(
                shadeInteractor.isShadeLayoutWide,
                activeNotificationsInteractor.areAnyNotificationsPresent,
                areAnyNotificationsPresent,
                isAodPromotedNotificationPresent,
                isOnAod,
                headsUpNotificationInteractor.isHeadsUpOrAnimatingAway,
                keyguardInteractor.isDozing,
            ) { isShadeLayoutWide, areAnyNotificationsPresent, isOnAod, isHeadsUp, isDozing ->
            ) {
                isShadeLayoutWide,
                areAnyNotificationsPresent,
                isAodPromotedNotificationPresent,
                isOnAod,
                isHeadsUp,
                isDozing ->
                when {
                    !isShadeLayoutWide -> true
                    !areAnyNotificationsPresent -> true
                    // Pulsing notification appears on the right. Move clock left to avoid overlap.
                    isHeadsUp && isDozing -> false
                    isAodPromotedNotificationPresent -> false
                    else -> isOnAod
                }
            }
        } else {
            combine(
                    shadeInteractor.isShadeLayoutWide,
                    activeNotificationsInteractor.areAnyNotificationsPresent,
                    areAnyNotificationsPresent,
                    isAodPromotedNotificationPresent,
                    keyguardInteractor.dozeTransitionModel,
                    keyguardTransitionInteractor.startedKeyguardTransitionStep.map { it.to == AOD },
                    keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
@@ -140,6 +172,7 @@ constructor(
                ) {
                    isShadeLayoutWide,
                    areAnyNotificationsPresent,
                    isAodPromotedNotificationPresent,
                    dozeTransitionModel,
                    startedToAod,
                    startedToLockScreen,
@@ -156,7 +189,7 @@ constructor(
                        // use null to skip emitting wrong value
                        startedToGone || startedToDoze -> null
                        startedToLockScreen -> !areAnyNotificationsPresent
                        startedToAod -> !isPulsing
                        startedToAod -> !(isPulsing || isAodPromotedNotificationPresent)
                        else -> true
                    }
                }
+32 −10
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup.MarginLayoutParams
import android.view.ViewStub
import android.widget.Chronometer
import android.widget.DateTimeView
@@ -164,8 +165,8 @@ private class AODPromotedNotificationViewUpdater(root: View) {
    private var chronometerStub: ViewStub? = root.findViewById(R.id.chronometer)
    private var chronometer: Chronometer? = null
    private val closeButton: View? = root.findViewById(R.id.close_button)
    private val conversationIconContainer: View? =
        root.findViewById(R.id.conversation_icon_container)
    private val conversationIconBadge: View? = root.findViewById(R.id.conversation_icon_badge)
    private val conversationIcon: CachingIconView? = root.findViewById(R.id.conversation_icon)
    private val conversationText: TextView? = root.findViewById(R.id.conversation_text)
    private val expandButton: NotificationExpandButton? = root.findViewById(R.id.expand_button)
    private val headerText: TextView? = root.findViewById(R.id.header_text)
@@ -175,12 +176,13 @@ private class AODPromotedNotificationViewUpdater(root: View) {
        root.findViewById(R.id.header_text_secondary_divider)
    private val icon: NotificationRowIconView? = root.findViewById(R.id.icon)
    private val leftIcon: ImageView? = root.findViewById(R.id.left_icon)
    private val rightIcon: ImageView? = root.findViewById(R.id.right_icon)
    private val mainColumn: View? = root.findViewById(R.id.notification_main_column)
    private val notificationProgressEndIcon: CachingIconView? =
        root.findViewById(R.id.notification_progress_end_icon)
    private val notificationProgressStartIcon: CachingIconView? =
        root.findViewById(R.id.notification_progress_start_icon)
    private val profileBadge: ImageView? = root.findViewById(R.id.profile_badge)
    private val rightIcon: ImageView? = root.findViewById(R.id.right_icon)
    private val text: ImageFloatingTextView? = root.findViewById(R.id.text)
    private val time: DateTimeView? = root.findViewById(R.id.time)
    private val timeDivider: View? = root.findViewById(R.id.time_divider)
@@ -198,7 +200,7 @@ private class AODPromotedNotificationViewUpdater(root: View) {
        alternateExpandTarget?.visibility = GONE
        bigPicture?.visibility = GONE
        closeButton?.visibility = GONE
        conversationIconContainer?.visibility = GONE
        conversationIconBadge?.visibility = GONE
        expandButton?.visibility = GONE
        leftIcon?.visibility = GONE
        notificationProgressEndIcon?.visibility = GONE
@@ -209,6 +211,16 @@ private class AODPromotedNotificationViewUpdater(root: View) {
            ?.drawable
            ?.mutate()
            ?.setColorFilter(SecondaryText.colorInt, PorterDuff.Mode.SRC_IN)

        if (Flags.notificationsRedesignTemplates()) {
            (mainColumn?.layoutParams as? MarginLayoutParams)?.let { mainColumnMargins ->
                mainColumnMargins.topMargin =
                    Notification.Builder.getContentMarginTop(
                        root.context,
                        R.dimen.notification_2025_content_margin_top,
                    )
            }
        }
    }

    fun update(content: PromotedNotificationContentModel, audiblyAlertedIconVisible: Boolean) {
@@ -229,16 +241,11 @@ private class AODPromotedNotificationViewUpdater(root: View) {
        textView: ImageFloatingTextView? = null,
        showOldProgress: Boolean = true,
    ) {
        // Icon binding must be called in this order
        updateImageView(icon, content.smallIcon)
        icon?.setImageLevel(content.iconLevel)
        icon?.setBackgroundColor(Background.colorInt)
        icon?.originalIconColor = PrimaryText.colorInt

        updateHeader(content, hideTitle = true)

        updateTitle(title, content)
        updateText(textView ?: text, content)
        updateSmallIcon(icon, content)
        updateImageView(rightIcon, content.skeletonLargeIcon)

        if (showOldProgress) {
@@ -341,6 +348,8 @@ private class AODPromotedNotificationViewUpdater(root: View) {

        updateImageView(verificationIcon, content.verificationIcon)
        updateTextView(verificationText, content.verificationText)

        updateSmallIcon(conversationIcon, content)
    }

    private fun updateConversationHeaderDividers(
@@ -398,6 +407,19 @@ private class AODPromotedNotificationViewUpdater(root: View) {
        }
    }

    private fun updateSmallIcon(
        smallIconView: CachingIconView?,
        content: PromotedNotificationContentModel,
    ) {
        smallIconView ?: return

        // Icon binding must be called in this order
        updateImageView(smallIconView, content.smallIcon)
        smallIconView.setImageLevel(content.iconLevel)
        smallIconView.setBackgroundColor(Background.colorInt)
        smallIconView.originalIconColor = PrimaryText.colorInt
    }

    private fun inflateChronometer() {
        if (chronometer != null) {
            return
+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.promoted.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@@ -31,4 +32,6 @@ constructor(activeNotificationsInteractor: ActiveNotificationsInteractor) {
        activeNotificationsInteractor.topLevelRepresentativeNotifications.map { notifs ->
            notifs.firstNotNullOfOrNull { it.promotedContent }
        }

    val isPresent: Flow<Boolean> = content.map { (it != null) && (it.style != Style.Ineligible) }
}
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.promoted.domain.interactor.aodPromotedNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.wallpapers.domain.interactor.wallpaperFocalAreaInteractor

@@ -30,6 +31,7 @@ val Kosmos.keyguardClockInteractor by
        KeyguardClockInteractor(
            mediaCarouselInteractor = mediaCarouselInteractor,
            activeNotificationsInteractor = activeNotificationsInteractor,
            aodPromotedNotificationInteractor = aodPromotedNotificationInteractor,
            shadeInteractor = shadeInteractor,
            keyguardInteractor = keyguardInteractor,
            keyguardTransitionInteractor = keyguardTransitionInteractor,
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.notification.promoted.domain.interactor

import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor

val Kosmos.aodPromotedNotificationInteractor by
    Kosmos.Fixture {
        AODPromotedNotificationInteractor(
            activeNotificationsInteractor = activeNotificationsInteractor
        )
    }