Add more detailed tracing to the pipeline

* Use NamedListenerSet for NotifCollectionListeners
* Use NamedListenerSet for all types of ShadeListBuilder listeners
* Trace events and other callouts in ShadeListBuilder
* Trace PreparationCoordinator.inflateEntry
* Trace IconManager's createIcons and updateIcons

Bug: 289487170
Bug: 289486596
Test: perfetto
Change-Id: Id948e8dfe823cc9cd1cab827e554572c2894d1ca
This commit is contained in:
Jeff DeCew
2023-07-13 14:18:30 -04:00
parent 7828879228
commit 2e811f4cc5
5 changed files with 53 additions and 42 deletions

View File

@@ -99,6 +99,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Ra
import com.android.systemui.statusbar.notification.collection.notifcollection.RankingUpdatedEvent;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.util.Assert;
import com.android.systemui.util.NamedListenerSet;
import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
@@ -161,7 +162,8 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
private final HashMap<String, FutureDismissal> mFutureDismissals = new HashMap<>();
@Nullable private CollectionReadyForBuildListener mBuildListener;
private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
private final NamedListenerSet<NotifCollectionListener>
mNotifCollectionListeners = new NamedListenerSet<>();
private final List<NotifLifetimeExtender> mLifetimeExtenders = new ArrayList<>();
private final List<NotifDismissInterceptor> mDismissInterceptors = new ArrayList<>();
@@ -236,7 +238,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
/** @see NotifPipeline#addCollectionListener(NotifCollectionListener) */
void addCollectionListener(NotifCollectionListener listener) {
Assert.isMainThread();
mNotifCollectionListeners.add(listener);
mNotifCollectionListeners.addIfAbsent(listener);
}
/** @see NotifPipeline#removeCollectionListener(NotifCollectionListener) */

View File

@@ -69,6 +69,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener;
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
import com.android.systemui.util.Assert;
import com.android.systemui.util.NamedListenerSet;
import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
@@ -121,14 +122,14 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
private final List<NotifSection> mNotifSections = new ArrayList<>();
private NotifStabilityManager mNotifStabilityManager;
private final List<OnBeforeTransformGroupsListener> mOnBeforeTransformGroupsListeners =
new ArrayList<>();
private final List<OnBeforeSortListener> mOnBeforeSortListeners =
new ArrayList<>();
private final List<OnBeforeFinalizeFilterListener> mOnBeforeFinalizeFilterListeners =
new ArrayList<>();
private final List<OnBeforeRenderListListener> mOnBeforeRenderListListeners =
new ArrayList<>();
private final NamedListenerSet<OnBeforeTransformGroupsListener>
mOnBeforeTransformGroupsListeners = new NamedListenerSet<>();
private final NamedListenerSet<OnBeforeSortListener>
mOnBeforeSortListeners = new NamedListenerSet<>();
private final NamedListenerSet<OnBeforeFinalizeFilterListener>
mOnBeforeFinalizeFilterListeners = new NamedListenerSet<>();
private final NamedListenerSet<OnBeforeRenderListListener>
mOnBeforeRenderListListeners = new NamedListenerSet<>();
@Nullable private OnRenderListListener mOnRenderListListener;
private List<ListEntry> mReadOnlyNotifList = Collections.unmodifiableList(mNotifList);
@@ -184,28 +185,28 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
Assert.isMainThread();
mPipelineState.requireState(STATE_IDLE);
mOnBeforeTransformGroupsListeners.add(listener);
mOnBeforeTransformGroupsListeners.addIfAbsent(listener);
}
void addOnBeforeSortListener(OnBeforeSortListener listener) {
Assert.isMainThread();
mPipelineState.requireState(STATE_IDLE);
mOnBeforeSortListeners.add(listener);
mOnBeforeSortListeners.addIfAbsent(listener);
}
void addOnBeforeFinalizeFilterListener(OnBeforeFinalizeFilterListener listener) {
Assert.isMainThread();
mPipelineState.requireState(STATE_IDLE);
mOnBeforeFinalizeFilterListeners.add(listener);
mOnBeforeFinalizeFilterListeners.addIfAbsent(listener);
}
void addOnBeforeRenderListListener(OnBeforeRenderListListener listener) {
Assert.isMainThread();
mPipelineState.requireState(STATE_IDLE);
mOnBeforeRenderListListeners.add(listener);
mOnBeforeRenderListListeners.addIfAbsent(listener);
}
void addPreRenderInvalidator(Invalidator invalidator) {
@@ -496,7 +497,9 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
mTempSectionMembers.add(entry);
}
}
Trace.beginSection(section.getLabel());
section.getSectioner().onEntriesUpdated(mTempSectionMembers);
Trace.endSection();
mTempSectionMembers.clear();
}
Trace.endSection();
@@ -1430,33 +1433,33 @@ public class ShadeListBuilder implements Dumpable, PipelineDumpable {
private void dispatchOnBeforeTransformGroups(List<ListEntry> entries) {
Trace.beginSection("ShadeListBuilder.dispatchOnBeforeTransformGroups");
for (int i = 0; i < mOnBeforeTransformGroupsListeners.size(); i++) {
mOnBeforeTransformGroupsListeners.get(i).onBeforeTransformGroups(entries);
}
mOnBeforeTransformGroupsListeners.forEachTraced(listener -> {
listener.onBeforeTransformGroups(entries);
});
Trace.endSection();
}
private void dispatchOnBeforeSort(List<ListEntry> entries) {
Trace.beginSection("ShadeListBuilder.dispatchOnBeforeSort");
for (int i = 0; i < mOnBeforeSortListeners.size(); i++) {
mOnBeforeSortListeners.get(i).onBeforeSort(entries);
}
mOnBeforeSortListeners.forEachTraced(listener -> {
listener.onBeforeSort(entries);
});
Trace.endSection();
}
private void dispatchOnBeforeFinalizeFilter(List<ListEntry> entries) {
Trace.beginSection("ShadeListBuilder.dispatchOnBeforeFinalizeFilter");
for (int i = 0; i < mOnBeforeFinalizeFilterListeners.size(); i++) {
mOnBeforeFinalizeFilterListeners.get(i).onBeforeFinalizeFilter(entries);
}
mOnBeforeFinalizeFilterListeners.forEachTraced(listener -> {
listener.onBeforeFinalizeFilter(entries);
});
Trace.endSection();
}
private void dispatchOnBeforeRenderList(List<ListEntry> entries) {
Trace.beginSection("ShadeListBuilder.dispatchOnBeforeRenderList");
for (int i = 0; i < mOnBeforeRenderListListeners.size(); i++) {
mOnBeforeRenderListListeners.get(i).onBeforeRenderList(entries);
}
mOnBeforeRenderListListeners.forEachTraced(listener -> {
listener.onBeforeRenderList(entries);
});
Trace.endSection();
}

View File

@@ -23,6 +23,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.IntDef;
import android.os.RemoteException;
import android.os.Trace;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -342,11 +343,13 @@ public class PreparationCoordinator implements Coordinator {
private void inflateEntry(NotificationEntry entry,
NotifUiAdjustment newAdjustment,
String reason) {
Trace.beginSection("PrepCoord.inflateEntry");
abortInflation(entry, reason);
mInflationAdjustments.put(entry, newAdjustment);
mInflatingNotifs.add(entry);
NotifInflater.Params params = getInflaterParams(newAdjustment, reason);
mNotifInflater.inflateViews(entry, params, this::onInflationFinished);
Trace.endSection();
}
private void rebind(NotificationEntry entry,

View File

@@ -22,6 +22,8 @@ import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.util.NamedListenerSet
import com.android.systemui.util.traceSection
/**
* Set of classes that represent the various events that [NotifCollection] can dispatch to
@@ -30,10 +32,10 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry
* These events build up in a queue and are periodically emitted in chunks by the collection.
*/
sealed class NotifEvent {
fun dispatchTo(listeners: List<NotifCollectionListener>) {
for (i in listeners.indices) {
dispatchToListener(listeners[i])
sealed class NotifEvent(private val traceName: String) {
fun dispatchTo(listeners: NamedListenerSet<NotifCollectionListener>) {
traceSection(traceName) {
listeners.forEachTraced(::dispatchToListener)
}
}
@@ -43,7 +45,7 @@ sealed class NotifEvent {
data class BindEntryEvent(
val entry: NotificationEntry,
val sbn: StatusBarNotification
) : NotifEvent() {
) : NotifEvent("onEntryBind") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryBind(entry, sbn)
}
@@ -51,7 +53,7 @@ data class BindEntryEvent(
data class InitEntryEvent(
val entry: NotificationEntry
) : NotifEvent() {
) : NotifEvent("onEntryInit") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryInit(entry)
}
@@ -59,7 +61,7 @@ data class InitEntryEvent(
data class EntryAddedEvent(
val entry: NotificationEntry
) : NotifEvent() {
) : NotifEvent("onEntryAdded") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryAdded(entry)
}
@@ -68,7 +70,7 @@ data class EntryAddedEvent(
data class EntryUpdatedEvent(
val entry: NotificationEntry,
val fromSystem: Boolean
) : NotifEvent() {
) : NotifEvent(if (fromSystem) "onEntryUpdated" else "onEntryUpdated fromSystem=true") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryUpdated(entry, fromSystem)
}
@@ -77,7 +79,7 @@ data class EntryUpdatedEvent(
data class EntryRemovedEvent(
val entry: NotificationEntry,
val reason: Int
) : NotifEvent() {
) : NotifEvent("onEntryRemoved ${cancellationReasonDebugString(reason)}") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryRemoved(entry, reason)
}
@@ -85,7 +87,7 @@ data class EntryRemovedEvent(
data class CleanUpEntryEvent(
val entry: NotificationEntry
) : NotifEvent() {
) : NotifEvent("onEntryCleanUp") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onEntryCleanUp(entry)
}
@@ -93,13 +95,13 @@ data class CleanUpEntryEvent(
data class RankingUpdatedEvent(
val rankingMap: RankingMap
) : NotifEvent() {
) : NotifEvent("onRankingUpdate") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onRankingUpdate(rankingMap)
}
}
class RankingAppliedEvent() : NotifEvent() {
class RankingAppliedEvent : NotifEvent("onRankingApplied") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onRankingApplied()
}
@@ -110,7 +112,7 @@ data class ChannelChangedEvent(
val user: UserHandle,
val channel: NotificationChannel,
val modificationType: Int
) : NotifEvent() {
) : NotifEvent("onNotificationChannelModified") {
override fun dispatchToListener(listener: NotifCollectionListener) {
listener.onNotificationChannelModified(pkgName, user, channel, modificationType)
}

View File

@@ -33,6 +33,7 @@ import com.android.systemui.statusbar.notification.InflationException
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.util.traceSection
import javax.inject.Inject
/**
@@ -95,7 +96,7 @@ class IconManager @Inject constructor(
* @throws InflationException Exception if required icons are not valid or specified
*/
@Throws(InflationException::class)
fun createIcons(entry: NotificationEntry) {
fun createIcons(entry: NotificationEntry) = traceSection("IconManager.createIcons") {
// Construct the status bar icon view.
val sbIcon = iconBuilder.createIconView(entry)
sbIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
@@ -143,9 +144,9 @@ class IconManager @Inject constructor(
* @throws InflationException Exception if required icons are not valid or specified
*/
@Throws(InflationException::class)
fun updateIcons(entry: NotificationEntry) {
fun updateIcons(entry: NotificationEntry) = traceSection("IconManager.updateIcons") {
if (!entry.icons.areIconsAvailable) {
return
return@traceSection
}
entry.icons.smallIconDescriptor = null
entry.icons.peopleAvatarDescriptor = null