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

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

Merge "New Pipeline: Extend the NotifPipeline to include a render stage with callbacks"

parents 060bf121 43018ba2
Loading
Loading
Loading
Loading
+58 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar;

import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;

import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
@@ -39,6 +41,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.legacy.LowPriorityInflationHelper;
import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
import com.android.systemui.statusbar.notification.collection.render.NotifStats;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -97,6 +101,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
    private final Context mContext;

    private NotificationPresenter mPresenter;
    private NotifStackController mStackController;
    private NotificationListContainer mListContainer;

    // Used to help track down re-entrant calls to our update methods, which will cause bugs.
@@ -147,8 +152,10 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
    }

    public void setUpWithPresenter(NotificationPresenter presenter,
            NotifStackController stackController,
            NotificationListContainer listContainer) {
        mPresenter = presenter;
        mStackController = stackController;
        mListContainer = listContainer;
        if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
            mDynamicPrivacyController.addListener(this);
@@ -328,12 +335,62 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
        mTmpChildOrderMap.clear();

        updateRowStatesInternal();
        updateNotifStats();

        mListContainer.onNotificationViewUpdateFinished();

        endUpdate();
    }

    /**
     * In the spirit of unidirectional data flow, calculate this information when the notification
     * views are updated, and set it once, speeding up lookups later.
     * This is analogous to logic in the
     * {@link com.android.systemui.statusbar.notification.collection.coordinator.StackCoordinator}
     */
    private void updateNotifStats() {
        boolean hasNonClearableAlertingNotifs = false;
        boolean hasClearableAlertingNotifs = false;
        boolean hasNonClearableSilentNotifs = false;
        boolean hasClearableSilentNotifs = false;
        final int childCount = mListContainer.getContainerChildCount();
        int visibleTopLevelEntries = 0;
        for (int i = 0; i < childCount; i++) {
            View child = mListContainer.getContainerChildAt(i);
            if (child == null || child.getVisibility() == View.GONE) {
                continue;
            }
            if (!(child instanceof ExpandableNotificationRow)) {
                continue;
            }
            final ExpandableNotificationRow row = (ExpandableNotificationRow) child;
            boolean isSilent = row.getEntry().getBucket() == BUCKET_SILENT;
            // NOTE: NotificationEntry.isClearable() will internally check group children to ensure
            //  the group itself definitively clearable.
            boolean isClearable = row.getEntry().isClearable();
            if (isSilent) {
                if (isClearable) {
                    hasClearableSilentNotifs = true;
                } else {  // !isClearable
                    hasNonClearableSilentNotifs = true;
                }
            } else {  // !isSilent
                if (isClearable) {
                    hasClearableAlertingNotifs = true;
                } else {  // !isClearable
                    hasNonClearableAlertingNotifs = true;
                }
            }
        }
        mStackController.setNotifStats(new NotifStats(
                visibleTopLevelEntries /* numActiveNotifs */,
                hasNonClearableAlertingNotifs /* hasNonClearableAlertingNotifs */,
                hasClearableAlertingNotifs /* hasClearableAlertingNotifs */,
                hasNonClearableSilentNotifs /* hasNonClearableSilentNotifs */,
                hasClearableSilentNotifs /* hasClearableSilentNotifs */
        ));
    }

    /**
     * Should a notification entry from the active list be suppressed and not show?
     */
@@ -528,9 +585,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle

    @Override
    public void onDynamicPrivacyChanged() {
        if (mNotifPipelineFlags.isNewPipelineEnabled()) {
            throw new IllegalStateException("Old pipeline code running w/ new pipeline enabled");
        }
        mNotifPipelineFlags.assertLegacyPipelineEnabled();
        if (mPerformingUpdate) {
            Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call");
        }
+10 −7
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ class NotifPipelineFlags @Inject constructor(
    val featureFlags: FeatureFlags
) {
    fun checkLegacyPipelineEnabled(): Boolean {
        if (!featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)) {
        if (!isNewPipelineEnabled()) {
            return true
        }
        Log.d("NotifPipeline", "Old pipeline code running w/ new pipeline enabled", Exception())
@@ -36,10 +36,13 @@ class NotifPipelineFlags @Inject constructor(
        return false
    }

    fun isNewPipelineEnabled(): Boolean = featureFlags.isEnabled(
            Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)
    fun assertLegacyPipelineEnabled(): Nothing =
        error("Old pipeline code running w/ new pipeline enabled")

    fun isNewPipelineEnabled(): Boolean =
        featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)

    fun isSmartspaceDedupingEnabled(): Boolean =
            featureFlags.isEnabled(Flags.SMARTSPACE)
                    && featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING)
            featureFlags.isEnabled(Flags.SMARTSPACE) &&
                    featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING)
}
 No newline at end of file
+0 −20
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.systemui.statusbar.notification.collection;
import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -61,24 +59,6 @@ public class GroupEntry extends ListEntry {
        mSummary = summary;
    }

    /**
     * @see #getUntruncatedChildCount()
     */
    public void setUntruncatedChildCount(int childCount) {
        mUntruncatedChildCount = childCount;
    }

    /**
     * Get the untruncated number of children from the data model, including those that will not
     * have views bound. This includes children that {@link PreparationCoordinator} will filter out
     * entirely when they are beyond the last visible child.
     *
     * TODO: This should move to some shared class between the model and view hierarchy
     */
    public int getUntruncatedChildCount() {
        return mUntruncatedChildCount;
    }

    void clearChildren() {
        mChildren.clear();
    }
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ public class NotifInflaterImpl implements NotifInflater {
            public void onAsyncInflationFinished(NotificationEntry entry) {
                mNotifErrorManager.clearInflationError(entry);
                if (callback != null) {
                    callback.onInflationFinished(entry);
                    callback.onInflationFinished(entry, entry.getRowController());
                }
            }
        };
+31 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.notification.collection

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener
@@ -31,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.In
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender
import com.android.systemui.statusbar.notification.collection.render.RenderStageManager
import javax.inject.Inject

/**
@@ -65,11 +69,15 @@ import javax.inject.Inject
 *  9. Finalize filters are fired on each notification ([.addFinalizeFilter])
 *  10. OnBeforeRenderListListeners are fired ([.addOnBeforeRenderListListener])
 *  11. The list is handed off to the view layer to be rendered
 *  12. OnAfterRenderListListeners are fired ([.addOnAfterRenderListListener])
 *  13. OnAfterRenderGroupListeners are fired ([.addOnAfterRenderGroupListener])
 *  13. OnAfterRenderEntryListeners are fired ([.addOnAfterRenderEntryListener])
 */
@SysUISingleton
class NotifPipeline @Inject constructor(
    private val mNotifCollection: NotifCollection,
    private val mShadeListBuilder: ShadeListBuilder
    private val mShadeListBuilder: ShadeListBuilder,
    private val mRenderStageManager: RenderStageManager
) : CommonNotifCollection {
    /**
     * Returns the list of all known notifications, i.e. the notifications that are currently posted
@@ -205,6 +213,28 @@ class NotifPipeline @Inject constructor(
        mShadeListBuilder.addPreRenderInvalidator(invalidator)
    }

    /**
     * Called at the end of the pipeline after the notif list has been handed off to the view layer.
     */
    fun addOnAfterRenderListListener(listener: OnAfterRenderListListener) {
        mRenderStageManager.addOnAfterRenderListListener(listener)
    }

    /**
     * Called at the end of the pipeline after a group has been handed off to the view layer.
     */
    fun addOnAfterRenderGroupListener(listener: OnAfterRenderGroupListener) {
        mRenderStageManager.addOnAfterRenderGroupListener(listener)
    }

    /**
     * Called at the end of the pipeline after an entry has been handed off to the view layer.
     * This will be called for every top level entry, every group summary, and every group child.
     */
    fun addOnAfterRenderEntryListener(listener: OnAfterRenderEntryListener) {
        mRenderStageManager.addOnAfterRenderEntryListener(listener)
    }

    /**
     * Get an object which can be used to update a notification (internally to the pipeline)
     * in response to a user action.
Loading