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

Commit a2e89906 authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Stop using NotificationContentInflater directly when the interface will work" into main

parents e89f7097 4594699b
Loading
Loading
Loading
Loading
+103 −95
Original line number Diff line number Diff line
@@ -34,8 +34,8 @@ import com.android.systemui.statusbar.notification.collection.inflation.BindEven
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationContentInflaterLogger
import com.android.systemui.statusbar.notification.row.NotificationContentView
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinderLogger
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -44,27 +44,26 @@ import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject

/** Populates additional information in conversation notifications */
class ConversationNotificationProcessor @Inject constructor(
class ConversationNotificationProcessor
@Inject
constructor(
    private val launcherApps: LauncherApps,
    private val conversationNotificationManager: ConversationNotificationManager
) {
    fun processNotification(
        entry: NotificationEntry,
        recoveredBuilder: Notification.Builder,
            logger: NotificationContentInflaterLogger
        logger: NotificationRowContentBinderLogger
    ): Notification.MessagingStyle? {
        val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return null
        messagingStyle.conversationType =
            if (entry.ranking.channel.isImportantConversation)
                Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT
                else
                    Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL
            else Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL
        entry.ranking.conversationShortcutInfo?.let { shortcutInfo ->
            logger.logAsyncTaskProgress(entry, "getting shortcut icon")
            messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo)
            shortcutInfo.label?.let { label ->
                messagingStyle.conversationTitle = label
            }
            shortcutInfo.label?.let { label -> messagingStyle.conversationTitle = label }
        }
        messagingStyle.unreadMessageCount =
            conversationNotificationManager.getUnreadCount(entry, recoveredBuilder)
@@ -77,7 +76,9 @@ class ConversationNotificationProcessor @Inject constructor(
 * animations to conserve CPU and memory.
 */
@SysUISingleton
class AnimatedImageNotificationManager @Inject constructor(
class AnimatedImageNotificationManager
@Inject
constructor(
    private val notifCollection: CommonNotifCollection,
    private val bindEventManager: BindEventManager,
    private val headsUpManager: HeadsUpManager,
@@ -88,17 +89,21 @@ class AnimatedImageNotificationManager @Inject constructor(

    /** Begins listening to state changes and updating animations accordingly. */
    fun bind() {
        headsUpManager.addListener(object : OnHeadsUpChangedListener {
        headsUpManager.addListener(
            object : OnHeadsUpChangedListener {
                override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
                    updateAnimatedImageDrawables(entry)
                }
        })
        statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
            }
        )
        statusBarStateController.addCallback(
            object : StatusBarStateController.StateListener {
                override fun onExpandedChanged(isExpanded: Boolean) {
                    isStatusBarExpanded = isExpanded
                    notifCollection.allNotifs.forEach(::updateAnimatedImageDrawables)
                }
        })
            }
        )
        bindEventManager.addListener(::updateAnimatedImageDrawables)
    }

@@ -112,36 +117,36 @@ class AnimatedImageNotificationManager @Inject constructor(
            .flatMap { layout -> layout.allViews.asSequence() }
            .flatMap { view ->
                (view as? ConversationLayout)?.messagingGroups?.asSequence()
                                ?: (view as? MessagingLayout)?.messagingGroups?.asSequence()
                                ?: emptySequence()
                    ?: (view as? MessagingLayout)?.messagingGroups?.asSequence() ?: emptySequence()
            }
            .flatMap { messagingGroup -> messagingGroup.messageContainer.children }
            .mapNotNull { view ->
                        (view as? MessagingImageMessage)
                                ?.let { imageMessage ->
                (view as? MessagingImageMessage)?.let { imageMessage ->
                    imageMessage.drawable as? AnimatedImageDrawable
                }
            }
            .forEach { animatedImageDrawable ->
                        if (animating) animatedImageDrawable.start()
                        else animatedImageDrawable.stop()
                if (animating) animatedImageDrawable.start() else animatedImageDrawable.stop()
            }
}

/**
 * Tracks state related to conversation notifications, and updates the UI of existing notifications
 * when necessary.
 *
 * TODO(b/214083332) Refactor this class to use the right coordinators and controllers
 */
@SysUISingleton
class ConversationNotificationManager @Inject constructor(
class ConversationNotificationManager
@Inject
constructor(
    bindEventManager: BindEventManager,
    private val context: Context,
    private val notifCollection: CommonNotifCollection,
    @Main private val mainHandler: Handler
) {
    // Need this state to be thread safe, since it's accessed from the ui thread
    // (NotificationEntryListener) and a bg thread (NotificationContentInflater)
    // (NotificationEntryListener) and a bg thread (NotificationRowContentBinder)
    private val states = ConcurrentHashMap<String, ConversationState>()

    private var notifPanelCollapsed = true
@@ -150,13 +155,15 @@ class ConversationNotificationManager @Inject constructor(
        fun getLayouts(view: NotificationContentView) =
            sequenceOf(view.contractedChild, view.expandedChild, view.headsUpChild)
        val ranking = Ranking()
        val activeConversationEntries = states.keys.asSequence()
                .mapNotNull { notifCollection.getEntry(it) }
        val activeConversationEntries =
            states.keys.asSequence().mapNotNull { notifCollection.getEntry(it) }
        for (entry in activeConversationEntries) {
            if (rankingMap.getRanking(entry.sbn.key, ranking) && ranking.isConversation) {
                val important = ranking.channel.isImportantConversation
                var changed = false
                entry.row?.layouts?.asSequence()
                entry.row
                    ?.layouts
                    ?.asSequence()
                    ?.flatMap(::getLayouts)
                    ?.mapNotNull { it as? ConversationLayout }
                    ?.filterNot { it.isImportantConversation == important }
@@ -166,12 +173,9 @@ class ConversationNotificationManager @Inject constructor(
                            // delay this so that it doesn't animate in until after
                            // the notif has been moved in the shade
                            mainHandler.postDelayed(
                                        {
                                            layout.setIsImportantConversation(
                                                    important,
                                                    true)
                                        },
                                        IMPORTANCE_ANIMATION_DELAY.toLong())
                                { layout.setIsImportantConversation(important, true) },
                                IMPORTANCE_ANIMATION_DELAY.toLong()
                            )
                        } else {
                            layout.setIsImportantConversation(important, false)
                        }
@@ -192,9 +196,7 @@ class ConversationNotificationManager @Inject constructor(
        }
        entry.row?.setOnExpansionChangedListener { isExpanded ->
            if (entry.row?.isShown == true && isExpanded) {
                entry.row.performOnIntrinsicHeightReached {
                    updateCount(isExpanded)
                }
                entry.row.performOnIntrinsicHeightReached { updateCount(isExpanded) }
            } else {
                updateCount(isExpanded)
            }
@@ -203,13 +205,15 @@ class ConversationNotificationManager @Inject constructor(
    }

    init {
        notifCollection.addCollectionListener(object : NotifCollectionListener {
        notifCollection.addCollectionListener(
            object : NotifCollectionListener {
                override fun onRankingUpdate(ranking: RankingMap) =
                    updateNotificationRanking(ranking)

                override fun onEntryRemoved(entry: NotificationEntry, reason: Int) =
                    removeTrackedEntry(entry)
        })
            }
        )
        bindEventManager.addListener(::onEntryViewBound)
    }

@@ -222,12 +226,17 @@ class ConversationNotificationManager @Inject constructor(
        }

    fun getUnreadCount(entry: NotificationEntry, recoveredBuilder: Notification.Builder): Int =
            states.compute(entry.key) { _, state ->
                val newCount = state?.run {
                    if (shouldIncrementUnread(recoveredBuilder)) unreadCount + 1 else unreadCount
                } ?: 1
        states
            .compute(entry.key) { _, state ->
                val newCount =
                    state?.run {
                        if (shouldIncrementUnread(recoveredBuilder)) unreadCount + 1
                        else unreadCount
                    }
                        ?: 1
                ConversationState(newCount, entry.sbn.notification)
            }!!.unreadCount
            }!!
            .unreadCount

    fun onNotificationPanelExpandStateChanged(isCollapsed: Boolean) {
        notifPanelCollapsed = isCollapsed
@@ -235,18 +244,17 @@ class ConversationNotificationManager @Inject constructor(

        // When the notification panel is expanded, reset the counters of any expanded
        // conversations
        val expanded = states
        val expanded =
            states
                .asSequence()
                .mapNotNull { (key, _) ->
                    notifCollection.getEntry(key)?.let { entry ->
                        if (entry.row?.isExpanded == true) key to entry
                        else null
                        if (entry.row?.isExpanded == true) key to entry else null
                    }
                }
                .toMap()
        states.replaceAll { key, state ->
            if (expanded.contains(key)) state.copy(unreadCount = 0)
            else state
            if (expanded.contains(key)) state.copy(unreadCount = 0) else state
        }
        // Update UI separate from the replaceAll call, since ConcurrentHashMap may re-run the
        // lambda if threads are in contention.
+2 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.systemui.statusbar.notification;

import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;

import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+3 −3
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder;

import javax.inject.Inject;

@@ -100,9 +100,9 @@ public class NotifInflaterImpl implements NotifInflater {
        requireBinder().releaseViews(entry);
    }

    private NotificationContentInflater.InflationCallback wrapInflationCallback(
    private NotificationRowContentBinder.InflationCallback wrapInflationCallback(
            InflationCallback callback) {
        return new NotificationContentInflater.InflationCallback() {
        return new NotificationRowContentBinder.InflationCallback() {
            @Override
            public void handleInflationException(
                    NotificationEntry entry,
+1 −1
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
     * and ensuring that the view is freed when it is safe to remove.
     *
     * @param inflationFlag flag corresponding to the content view to be freed
     * @deprecated By default, {@link NotificationContentInflater#unbindContent} will tell the
     * @deprecated By default, {@link NotificationRowContentBinder#unbindContent} will tell the
     * view hierarchy to only free when the view is safe to remove so this method is no longer
     * needed. Will remove when all uses are gone.
     */
+10 −10
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
    private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
    private final HeadsUpStyleProvider mHeadsUpStyleProvider;

    private final NotificationContentInflaterLogger mLogger;
    private final NotificationRowContentBinderLogger mLogger;

    @Inject
    NotificationContentInflater(
@@ -104,7 +104,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            SmartReplyStateInflater smartRepliesInflater,
            NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
            HeadsUpStyleProvider headsUpStyleProvider,
            NotificationContentInflaterLogger logger) {
            NotificationRowContentBinderLogger logger) {
        mRemoteViewCache = remoteViewCache;
        mRemoteInputManager = remoteInputManager;
        mConversationProcessor = conversationProcessor;
@@ -345,7 +345,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            Context packageContext,
            InflatedSmartReplyState previousSmartReplyState,
            SmartReplyStateInflater inflater,
            NotificationContentInflaterLogger logger) {
            NotificationRowContentBinderLogger logger) {
        boolean inflateContracted = (reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0
                && result.newContentView != null;
        boolean inflateExpanded = (reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0
@@ -377,7 +377,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            ExpandableNotificationRow row,
            NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
            HeadsUpStyleProvider headsUpStyleProvider,
            NotificationContentInflaterLogger logger) {
            NotificationRowContentBinderLogger logger) {
        return TraceUtils.trace("NotificationContentInflater.createRemoteViews", () -> {
            InflationProgress result = new InflationProgress();
            final NotificationEntry entryForLogging = row.getEntry();
@@ -465,7 +465,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            ExpandableNotificationRow row,
            RemoteViews.InteractionHandler remoteViewClickHandler,
            @Nullable InflationCallback callback,
            NotificationContentInflaterLogger logger) {
            NotificationRowContentBinderLogger logger) {
        Trace.beginAsyncSection(APPLY_TRACE_METHOD, System.identityHashCode(row));

        NotificationContentView privateLayout = row.getPrivateLayout();
@@ -676,7 +676,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            NotificationViewWrapper existingWrapper,
            final HashMap<Integer, CancellationSignal> runningInflations,
            ApplyCallback applyCallback,
            NotificationContentInflaterLogger logger) {
            NotificationRowContentBinderLogger logger) {
        RemoteViews newContentView = applyCallback.getRemoteView();
        if (inflateSynchronously) {
            try {
@@ -845,7 +845,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
    private static void handleInflationError(
            HashMap<Integer, CancellationSignal> runningInflations, Exception e,
            NotificationEntry notification, @Nullable InflationCallback callback,
            NotificationContentInflaterLogger logger, String logContext) {
            NotificationRowContentBinderLogger logger, String logContext) {
        Assert.isMainThread();
        logger.logAsyncTaskException(notification, logContext, e);
        runningInflations.values().forEach(CancellationSignal::cancel);
@@ -864,7 +864,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
            @InflationFlag int reInflateFlags, NotifRemoteViewCache remoteViewCache,
            HashMap<Integer, CancellationSignal> runningInflations,
            @Nullable InflationCallback endListener, NotificationEntry entry,
            ExpandableNotificationRow row, NotificationContentInflaterLogger logger) {
            ExpandableNotificationRow row, NotificationRowContentBinderLogger logger) {
        Assert.isMainThread();
        if (!runningInflations.isEmpty()) {
            return false;
@@ -1080,7 +1080,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
        private final SmartReplyStateInflater mSmartRepliesInflater;
        private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider;
        private final HeadsUpStyleProvider mHeadsUpStyleProvider;
        private final NotificationContentInflaterLogger mLogger;
        private final NotificationRowContentBinderLogger mLogger;

        private AsyncInflationTask(
                Executor inflationExecutor,
@@ -1099,7 +1099,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
                SmartReplyStateInflater smartRepliesInflater,
                NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
                HeadsUpStyleProvider headsUpStyleProvider,
                NotificationContentInflaterLogger logger) {
                NotificationRowContentBinderLogger logger) {
            mEntry = entry;
            mRow = row;
            mInflationExecutor = inflationExecutor;
Loading