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

Commit ef9928e0 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge changes I1169beb3,If7c7b737 into rvc-dev am: 0fd43f11 am: 2594622b

Change-Id: I208b4a7a081a398d9c194f532d8425cd90986645
parents 54dab83b 2594622b
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui.statusbar.notification.collection;
package com.android.systemui.statusbar.notification.collection;


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.OnBeforeRenderListListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
@@ -63,7 +64,7 @@ import javax.inject.Singleton;
 *  6. Top-level entries are assigned sections by NotifSections ({@link #setSections})
 *  6. Top-level entries are assigned sections by NotifSections ({@link #setSections})
 *  7. Top-level entries within the same section are sorted by NotifComparators
 *  7. Top-level entries within the same section are sorted by NotifComparators
 *     ({@link #setComparators})
 *     ({@link #setComparators})
 *  8. Pre-render filters are fired on each notification ({@link #addPreRenderFilter})
 *  8. Finalize filters are fired on each notification ({@link #addFinalizeFilter})
 *  9. OnBeforeRenderListListeners are fired ({@link #addOnBeforeRenderListListener})
 *  9. OnBeforeRenderListListeners are fired ({@link #addOnBeforeRenderListListener})
 *  9. The list is handed off to the view layer to be rendered
 *  9. The list is handed off to the view layer to be rendered
 */
 */
@@ -168,6 +169,14 @@ public class NotifPipeline implements CommonNotifCollection {
        mShadeListBuilder.setComparators(comparators);
        mShadeListBuilder.setComparators(comparators);
    }
    }


    /**
     * Called after notifs have been filtered once, grouped, and sorted but before the final
     * filtering.
     */
    public void addOnBeforeFinalizeFilterListener(OnBeforeFinalizeFilterListener listener) {
        mShadeListBuilder.addOnBeforeFinalizeFilterListener(listener);
    }

    /**
    /**
     * Registers a filter with the pipeline to filter right before rendering the list (after
     * Registers a filter with the pipeline to filter right before rendering the list (after
     * pre-group filtering, grouping, promoting and sorting occurs). Filters are
     * pre-group filtering, grouping, promoting and sorting occurs). Filters are
@@ -175,8 +184,8 @@ public class NotifPipeline implements CommonNotifCollection {
     * true, the notification is removed from the pipeline (and no other filters are called on that
     * true, the notification is removed from the pipeline (and no other filters are called on that
     * notif).
     * notif).
     */
     */
    public void addPreRenderFilter(NotifFilter filter) {
    public void addFinalizeFilter(NotifFilter filter) {
        mShadeListBuilder.addPreRenderFilter(filter);
        mShadeListBuilder.addFinalizeFilter(filter);
    }
    }


    /**
    /**
+27 −10
Original line number Original line Diff line number Diff line
@@ -18,11 +18,11 @@ package com.android.systemui.statusbar.notification.collection;


import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;
import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_BUILD_STARTED;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_BUILD_STARTED;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZE_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_GROUPING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_GROUPING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_IDLE;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_IDLE;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_PRE_GROUP_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_PRE_GROUP_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_PRE_RENDER_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_RESETTING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_RESETTING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_SORTING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_SORTING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_TRANSFORMING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_TRANSFORMING;
@@ -36,6 +36,7 @@ import androidx.annotation.NonNull;


import com.android.systemui.Dumpable;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.dump.DumpManager;
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.OnBeforeRenderListListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeSortListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeTransformGroupsListener;
@@ -82,7 +83,7 @@ public class ShadeListBuilder implements Dumpable {


    private final List<NotifFilter> mNotifPreGroupFilters = new ArrayList<>();
    private final List<NotifFilter> mNotifPreGroupFilters = new ArrayList<>();
    private final List<NotifPromoter> mNotifPromoters = new ArrayList<>();
    private final List<NotifPromoter> mNotifPromoters = new ArrayList<>();
    private final List<NotifFilter> mNotifPreRenderFilters = new ArrayList<>();
    private final List<NotifFilter> mNotifFinalizeFilters = new ArrayList<>();
    private final List<NotifComparator> mNotifComparators = new ArrayList<>();
    private final List<NotifComparator> mNotifComparators = new ArrayList<>();
    private final List<NotifSection> mNotifSections = new ArrayList<>();
    private final List<NotifSection> mNotifSections = new ArrayList<>();


@@ -90,6 +91,8 @@ public class ShadeListBuilder implements Dumpable {
            new ArrayList<>();
            new ArrayList<>();
    private final List<OnBeforeSortListener> mOnBeforeSortListeners =
    private final List<OnBeforeSortListener> mOnBeforeSortListeners =
            new ArrayList<>();
            new ArrayList<>();
    private final List<OnBeforeFinalizeFilterListener> mOnBeforeFinalizeFilterListeners =
            new ArrayList<>();
    private final List<OnBeforeRenderListListener> mOnBeforeRenderListListeners =
    private final List<OnBeforeRenderListListener> mOnBeforeRenderListListeners =
            new ArrayList<>();
            new ArrayList<>();
    @Nullable private OnRenderListListener mOnRenderListListener;
    @Nullable private OnRenderListListener mOnRenderListListener;
@@ -142,6 +145,13 @@ public class ShadeListBuilder implements Dumpable {
        mOnBeforeSortListeners.add(listener);
        mOnBeforeSortListeners.add(listener);
    }
    }


    void addOnBeforeFinalizeFilterListener(OnBeforeFinalizeFilterListener listener) {
        Assert.isMainThread();

        mPipelineState.requireState(STATE_IDLE);
        mOnBeforeFinalizeFilterListeners.add(listener);
    }

    void addOnBeforeRenderListListener(OnBeforeRenderListListener listener) {
    void addOnBeforeRenderListListener(OnBeforeRenderListListener listener) {
        Assert.isMainThread();
        Assert.isMainThread();


@@ -157,12 +167,12 @@ public class ShadeListBuilder implements Dumpable {
        filter.setInvalidationListener(this::onPreGroupFilterInvalidated);
        filter.setInvalidationListener(this::onPreGroupFilterInvalidated);
    }
    }


    void addPreRenderFilter(NotifFilter filter) {
    void addFinalizeFilter(NotifFilter filter) {
        Assert.isMainThread();
        Assert.isMainThread();
        mPipelineState.requireState(STATE_IDLE);
        mPipelineState.requireState(STATE_IDLE);


        mNotifPreRenderFilters.add(filter);
        mNotifFinalizeFilters.add(filter);
        filter.setInvalidationListener(this::onPreRenderFilterInvalidated);
        filter.setInvalidationListener(this::onFinalizeFilterInvalidated);
    }
    }


    void addPromoter(NotifPromoter promoter) {
    void addPromoter(NotifPromoter promoter) {
@@ -237,12 +247,12 @@ public class ShadeListBuilder implements Dumpable {
        rebuildListIfBefore(STATE_SORTING);
        rebuildListIfBefore(STATE_SORTING);
    }
    }


    private void onPreRenderFilterInvalidated(NotifFilter filter) {
    private void onFinalizeFilterInvalidated(NotifFilter filter) {
        Assert.isMainThread();
        Assert.isMainThread();


        mLogger.logPreRenderFilterInvalidated(filter.getName(), mPipelineState.getState());
        mLogger.logFinalizeFilterInvalidated(filter.getName(), mPipelineState.getState());


        rebuildListIfBefore(STATE_PRE_RENDER_FILTERING);
        rebuildListIfBefore(STATE_FINALIZE_FILTERING);
    }
    }


    private void onNotifComparatorInvalidated(NotifComparator comparator) {
    private void onNotifComparatorInvalidated(NotifComparator comparator) {
@@ -298,8 +308,9 @@ public class ShadeListBuilder implements Dumpable {


        // Step 6: Filter out entries after pre-group filtering, grouping, promoting and sorting
        // Step 6: Filter out entries after pre-group filtering, grouping, promoting and sorting
        // Now filters can see grouping information to determine whether to filter or not.
        // Now filters can see grouping information to determine whether to filter or not.
        mPipelineState.incrementTo(STATE_PRE_RENDER_FILTERING);
        dispatchOnBeforeFinalizeFilter(mReadOnlyNotifList);
        filterNotifs(mNotifList, mNewNotifList, mNotifPreRenderFilters);
        mPipelineState.incrementTo(STATE_FINALIZE_FILTERING);
        filterNotifs(mNotifList, mNewNotifList, mNotifFinalizeFilters);
        applyNewNotifList();
        applyNewNotifList();
        pruneIncompleteGroups(mNotifList);
        pruneIncompleteGroups(mNotifList);


@@ -772,6 +783,12 @@ public class ShadeListBuilder implements Dumpable {
        }
        }
    }
    }


    private void dispatchOnBeforeFinalizeFilter(List<ListEntry> entries) {
        for (int i = 0; i < mOnBeforeFinalizeFilterListeners.size(); i++) {
            mOnBeforeFinalizeFilterListeners.get(i).onBeforeFinalizeFilter(entries);
        }
    }

    private void dispatchOnBeforeRenderList(List<ListEntry> entries) {
    private void dispatchOnBeforeRenderList(List<ListEntry> entries) {
        for (int i = 0; i < mOnBeforeRenderListListeners.size(); i++) {
        for (int i = 0; i < mOnBeforeRenderListListeners.size(); i++) {
            mOnBeforeRenderListListeners.get(i).onBeforeRenderList(entries);
            mOnBeforeRenderListListeners.get(i).onBeforeRenderList(entries);
+1 −1
Original line number Original line Diff line number Diff line
@@ -77,7 +77,7 @@ public class BubbleCoordinator implements Coordinator {
    public void attach(NotifPipeline pipeline) {
    public void attach(NotifPipeline pipeline) {
        mNotifPipeline = pipeline;
        mNotifPipeline = pipeline;
        mNotifPipeline.addNotificationDismissInterceptor(mDismissInterceptor);
        mNotifPipeline.addNotificationDismissInterceptor(mDismissInterceptor);
        mNotifPipeline.addPreRenderFilter(mNotifFilter);
        mNotifPipeline.addFinalizeFilter(mNotifFilter);
        mBubbleController.addNotifCallback(mNotifCallback);
        mBubbleController.addNotifCallback(mNotifCallback);
    }
    }


+1 −1
Original line number Original line Diff line number Diff line
@@ -87,7 +87,7 @@ public class KeyguardCoordinator implements Coordinator {
    @Override
    @Override
    public void attach(NotifPipeline pipeline) {
    public void attach(NotifPipeline pipeline) {
        setupInvalidateNotifListCallbacks();
        setupInvalidateNotifListCallbacks();
        pipeline.addPreRenderFilter(mNotifFilter);
        pipeline.addFinalizeFilter(mNotifFilter);
    }
    }


    private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
    private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
+100 −19
Original line number Original line Diff line number Diff line
@@ -16,31 +16,39 @@


package com.android.systemui.statusbar.notification.collection.coordinator;
package com.android.systemui.statusbar.notification.collection.coordinator;


import android.annotation.IntDef;
import android.os.RemoteException;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;


import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;


import java.util.ArrayList;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Objects;


import javax.inject.Inject;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.inject.Singleton;


/**
/**
 * Kicks off notification inflation and view rebinding when a notification is added or updated.
 * Kicks off core notification inflation and view rebinding when a notification is added or updated.
 * Aborts inflation when a notification is removed.
 * Aborts inflation when a notification is removed.
 *
 *
 * If a notification is not done inflating, this coordinator will filter the notification out
 * If a notification was uninflated, this coordinator will filter the notification out from the
 * from the {@link ShadeListBuilder}.
 * {@link ShadeListBuilder} until it is inflated.
 */
 */
@Singleton
@Singleton
public class PreparationCoordinator implements Coordinator {
public class PreparationCoordinator implements Coordinator {
@@ -49,7 +57,7 @@ public class PreparationCoordinator implements Coordinator {
    private final PreparationCoordinatorLogger mLogger;
    private final PreparationCoordinatorLogger mLogger;
    private final NotifInflater mNotifInflater;
    private final NotifInflater mNotifInflater;
    private final NotifInflationErrorManager mNotifErrorManager;
    private final NotifInflationErrorManager mNotifErrorManager;
    private final List<NotificationEntry> mPendingNotifications = new ArrayList<>();
    private final Map<NotificationEntry, Integer> mInflationStates = new ArrayMap<>();
    private final IStatusBarService mStatusBarService;
    private final IStatusBarService mStatusBarService;


    @Inject
    @Inject
@@ -69,27 +77,44 @@ public class PreparationCoordinator implements Coordinator {
    @Override
    @Override
    public void attach(NotifPipeline pipeline) {
    public void attach(NotifPipeline pipeline) {
        pipeline.addCollectionListener(mNotifCollectionListener);
        pipeline.addCollectionListener(mNotifCollectionListener);
        pipeline.addPreRenderFilter(mNotifInflationErrorFilter);
        // Inflate after grouping/sorting since that affects what views to inflate.
        pipeline.addPreRenderFilter(mNotifInflatingFilter);
        pipeline.addOnBeforeFinalizeFilterListener(mOnBeforeFinalizeFilterListener);
        pipeline.addFinalizeFilter(mNotifInflationErrorFilter);
        pipeline.addFinalizeFilter(mNotifInflatingFilter);
    }
    }


    private final NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
    private final NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {

        @Override
        @Override
        public void onEntryAdded(NotificationEntry entry) {
        public void onEntryInit(NotificationEntry entry) {
            inflateEntry(entry, "entryAdded");
            mInflationStates.put(entry, STATE_UNINFLATED);
        }
        }


        @Override
        @Override
        public void onEntryUpdated(NotificationEntry entry) {
        public void onEntryUpdated(NotificationEntry entry) {
            rebind(entry, "entryUpdated");
            @InflationState int state = getInflationState(entry);
            if (state == STATE_INFLATED) {
                mInflationStates.put(entry, STATE_INFLATED_INVALID);
            } else if (state == STATE_ERROR) {
                // Updated so maybe it won't error out now.
                mInflationStates.put(entry, STATE_UNINFLATED);
            }
        }
        }


        @Override
        @Override
        public void onEntryRemoved(NotificationEntry entry, int reason) {
        public void onEntryRemoved(NotificationEntry entry, int reason) {
            abortInflation(entry, "entryRemoved reason=" + reason);
            abortInflation(entry, "entryRemoved reason=" + reason);
        }
        }

        @Override
        public void onEntryCleanUp(NotificationEntry entry) {
            mInflationStates.remove(entry);
        }
    };
    };


    private final OnBeforeFinalizeFilterListener mOnBeforeFinalizeFilterListener =
            entries -> inflateAllRequiredViews(entries);

    private final NotifFilter mNotifInflationErrorFilter = new NotifFilter(
    private final NotifFilter mNotifInflationErrorFilter = new NotifFilter(
            TAG + "InflationError") {
            TAG + "InflationError") {
        /**
        /**
@@ -97,10 +122,7 @@ public class PreparationCoordinator implements Coordinator {
         */
         */
        @Override
        @Override
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
            if (mNotifErrorManager.hasInflationError(entry)) {
            return getInflationState(entry) == STATE_ERROR;
                return true;
            }
            return false;
        }
        }
    };
    };


@@ -110,7 +132,8 @@ public class PreparationCoordinator implements Coordinator {
         */
         */
        @Override
        @Override
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
        public boolean shouldFilterOut(NotificationEntry entry, long now) {
            return mPendingNotifications.contains(entry);
            @InflationState int state = getInflationState(entry);
            return (state != STATE_INFLATED) && (state != STATE_INFLATED_INVALID);
        }
        }
    };
    };


@@ -119,7 +142,7 @@ public class PreparationCoordinator implements Coordinator {
        @Override
        @Override
        public void onInflationFinished(NotificationEntry entry) {
        public void onInflationFinished(NotificationEntry entry) {
            mLogger.logNotifInflated(entry.getKey());
            mLogger.logNotifInflated(entry.getKey());
            mPendingNotifications.remove(entry);
            mInflationStates.put(entry, STATE_INFLATED);
            mNotifInflatingFilter.invalidateList();
            mNotifInflatingFilter.invalidateList();
        }
        }
    };
    };
@@ -128,7 +151,7 @@ public class PreparationCoordinator implements Coordinator {
            new NotifInflationErrorManager.NotifInflationErrorListener() {
            new NotifInflationErrorManager.NotifInflationErrorListener() {
        @Override
        @Override
        public void onNotifInflationError(NotificationEntry entry, Exception e) {
        public void onNotifInflationError(NotificationEntry entry, Exception e) {
            mPendingNotifications.remove(entry);
            mInflationStates.put(entry, STATE_ERROR);
            try {
            try {
                final StatusBarNotification sbn = entry.getSbn();
                final StatusBarNotification sbn = entry.getSbn();
                // report notification inflation errors back up
                // report notification inflation errors back up
@@ -152,9 +175,41 @@ public class PreparationCoordinator implements Coordinator {
        }
        }
    };
    };


    private void inflateAllRequiredViews(List<ListEntry> entries) {
        for (int i = 0, size = entries.size(); i < size; i++) {
            ListEntry entry = entries.get(i);
            if (entry instanceof GroupEntry) {
                GroupEntry groupEntry = (GroupEntry) entry;
                inflateNotifRequiredViews(groupEntry.getSummary());
                List<NotificationEntry> children = groupEntry.getChildren();
                for (int j = 0, groupSize = children.size(); j < groupSize; j++) {
                    inflateNotifRequiredViews(children.get(j));
                }
            } else {
                NotificationEntry notifEntry = (NotificationEntry) entry;
                inflateNotifRequiredViews(notifEntry);
            }
        }
    }

    private void inflateNotifRequiredViews(NotificationEntry entry) {
        @InflationState int state = mInflationStates.get(entry);
        switch (state) {
            case STATE_UNINFLATED:
                inflateEntry(entry, "entryAdded");
                break;
            case STATE_INFLATED_INVALID:
                rebind(entry, "entryUpdated");
                break;
            case STATE_INFLATED:
            case STATE_ERROR:
            default:
                // Nothing to do.
        }
    }

    private void inflateEntry(NotificationEntry entry, String reason) {
    private void inflateEntry(NotificationEntry entry, String reason) {
        abortInflation(entry, reason);
        abortInflation(entry, reason);
        mPendingNotifications.add(entry);
        mNotifInflater.inflateViews(entry);
        mNotifInflater.inflateViews(entry);
    }
    }


@@ -165,6 +220,32 @@ public class PreparationCoordinator implements Coordinator {
    private void abortInflation(NotificationEntry entry, String reason) {
    private void abortInflation(NotificationEntry entry, String reason) {
        mLogger.logInflationAborted(entry.getKey(), reason);
        mLogger.logInflationAborted(entry.getKey(), reason);
        entry.abortTask();
        entry.abortTask();
        mPendingNotifications.remove(entry);
    }
    }

    private @InflationState int getInflationState(NotificationEntry entry) {
        Integer stateObj = mInflationStates.get(entry);
        Objects.requireNonNull(stateObj,
                "Asking state of a notification preparation coordinator doesn't know about");
        return stateObj;
    }

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"STATE_"},
            value = {STATE_UNINFLATED, STATE_INFLATED_INVALID, STATE_INFLATED, STATE_ERROR})
    @interface InflationState {}

    /** The notification has never been inflated before. */
    private static final int STATE_UNINFLATED = 0;

    /** The notification is inflated. */
    private static final int STATE_INFLATED = 1;

    /**
     * The notification is inflated, but its content may be out-of-date since the notification has
     * been updated.
     */
    private static final int STATE_INFLATED_INVALID = 2;

    /** The notification errored out while inflating */
    private static final int STATE_ERROR = -1;
}
}
Loading