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

Commit 4594699b authored by Jeff DeCew's avatar Jeff DeCew
Browse files

Stop using NotificationContentInflater directly when the interface will work

Flag: EXEMPT rename
Test: presubmit
Change-Id: Ie48d489a22da2a78e33fe8dc18a24e1f3f31915c
parent 45aaef93
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