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

Commit c02423f6 authored by Matías Hernández's avatar Matías Hernández Committed by Automerger Merge Worker
Browse files

Merge "Rework how notification posts are logged to statsd" into udc-dev am: 485c0dd3

parents 07764de4 485c0dd3
Loading
Loading
Loading
Loading
+239 −60

File changed.

Preview size limit exceeded, changes collapsed.

+90 −9
Original line number Diff line number Diff line
@@ -42,26 +42,45 @@ import java.util.Objects;
 * in production.  Use NotificationRecordLoggerFake for testing.
 * @hide
 */
public interface NotificationRecordLogger {
interface NotificationRecordLogger {

    // The high-level interface used by clients.

    /**
     * May log a NotificationReported atom reflecting the posting or update of a notification.
     * @param r The new NotificationRecord. If null, no action is taken.
     * @param old The previous NotificationRecord.  Null if there was no previous record.
     * Prepare to log an atom reflecting the posting or update of a notification.
     *
     * The returned {@link NotificationReported} object, if any, should be supplied to
     * {@link #logNotificationPosted}. Because only some updates are considered "interesting
     * enough" to log, this method may return {@code null}. In that case, the follow-up call
     * should not be performed.
     *
     * @param r The new {@link NotificationRecord}.
     * @param old The previous {@link NotificationRecord}. Null if there was no previous record.
     * @param position The position at which this notification is ranked.
     * @param buzzBeepBlink Logging code reflecting whether this notification alerted the user.
     * @param groupId The instance Id of the group summary notification, or null.
     * @param groupId The {@link InstanceId} of the group summary notification, or null.
     */
    void maybeLogNotificationPosted(@Nullable NotificationRecord r,
    @Nullable
    default NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
            @Nullable NotificationRecord old,
            int position, int buzzBeepBlink,
            InstanceId groupId);
            InstanceId groupId) {
        NotificationRecordPair p = new NotificationRecordPair(r, old);
        if (!p.shouldLogReported(buzzBeepBlink)) {
            return null;
        }
        return new NotificationReported(p, NotificationReportedEvent.fromRecordPair(p), position,
                buzzBeepBlink, groupId);
    }

    /**
     * Log a NotificationReported atom reflecting the posting or update of a notification.
     */
    void logNotificationPosted(NotificationReported nr);

    /**
     * Logs a NotificationReported atom reflecting an adjustment to a notification.
     * Unlike maybeLogNotificationPosted, this method is guaranteed to log a notification update,
     * Unlike for posted notifications, this method is guaranteed to log a notification update,
     * so the caller must take responsibility for checking that that logging update is necessary,
     * and that the notification is meaningfully changed.
     * @param r The NotificationRecord. If null, no action is taken.
@@ -450,6 +469,68 @@ public interface NotificationRecordLogger {

    }

    /** Data object corresponding to a NotificationReported atom.
     *
     * Fields must be kept in sync with frameworks/proto_logging/stats/atoms.proto.
     */
    class NotificationReported {
        final int event_id;
        final int uid;
        final String package_name;
        final int instance_id;
        final int notification_id_hash;
        final int channel_id_hash;
        final int group_id_hash;
        final int group_instance_id;
        final boolean is_group_summary;
        final String category;
        final int style;
        final int num_people;
        final int position;
        final int importance;
        final int alerting;
        final int importance_source;
        final int importance_initial;
        final int importance_initial_source;
        final int importance_asst;
        final int assistant_hash;
        final float assistant_ranking_score;
        final boolean is_ongoing;
        final boolean is_foreground_service;
        final long timeout_millis;
        final boolean is_non_dismissible;

        NotificationReported(NotificationRecordPair p,
                NotificationReportedEvent eventType, int position, int buzzBeepBlink,
                InstanceId groupId) {
            this.event_id = eventType.getId();
            this.uid = p.r.getUid();
            this.package_name = p.r.getSbn().getPackageName();
            this.instance_id = p.getInstanceId();
            this.notification_id_hash = p.getNotificationIdHash();
            this.channel_id_hash = p.getChannelIdHash();
            this.group_id_hash = p.getGroupIdHash();
            this.group_instance_id = (groupId == null) ? 0 : groupId.getId();
            this.is_group_summary = p.r.getSbn().getNotification().isGroupSummary();
            this.category = p.r.getSbn().getNotification().category;
            this.style = p.getStyle();
            this.num_people = p.getNumPeople();
            this.position = position;
            this.importance = NotificationRecordLogger.getLoggingImportance(p.r);
            this.alerting = buzzBeepBlink;
            this.importance_source = p.r.getImportanceExplanationCode();
            this.importance_initial = p.r.getInitialImportance();
            this.importance_initial_source = p.r.getInitialImportanceExplanationCode();
            this.importance_asst = p.r.getAssistantImportance();
            this.assistant_hash = p.getAssistantHash();
            this.assistant_ranking_score = p.r.getRankingScore();
            this.is_ongoing = p.r.getSbn().isOngoing();
            this.is_foreground_service = NotificationRecordLogger.isForegroundService(p.r);
            this.timeout_millis = p.r.getSbn().getNotification().getTimeoutAfter();
            this.is_non_dismissible = NotificationRecordLogger.isNonDismissible(p.r);
        }
    }

    /**
     * @param r NotificationRecord
     * @return Logging importance of record, taking important conversation channels into account.
+35 −50
Original line number Diff line number Diff line
@@ -27,20 +27,13 @@ import com.android.internal.util.FrameworkStatsLog;
 * Standard implementation of NotificationRecordLogger interface.
 * @hide
 */
public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
class NotificationRecordLoggerImpl implements NotificationRecordLogger {

    private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();

    @Override
    public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
            int position, int buzzBeepBlink,
            InstanceId groupId) {
        NotificationRecordPair p = new NotificationRecordPair(r, old);
        if (!p.shouldLogReported(buzzBeepBlink)) {
            return;
        }
        writeNotificationReportedAtom(p, NotificationReportedEvent.fromRecordPair(p),
                position, buzzBeepBlink, groupId);
    public void logNotificationPosted(NotificationReported nr) {
        writeNotificationReportedAtom(nr);
    }

    @Override
@@ -48,48 +41,40 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
            int position, int buzzBeepBlink,
            InstanceId groupId) {
        NotificationRecordPair p = new NotificationRecordPair(r, null);
        writeNotificationReportedAtom(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
                position, buzzBeepBlink, groupId);
        writeNotificationReportedAtom(
                new NotificationReported(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
                        position, buzzBeepBlink, groupId));
    }

    private void writeNotificationReportedAtom(NotificationRecordPair p,
            NotificationReportedEvent eventType, int position, int buzzBeepBlink,
            InstanceId groupId) {
        FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_REPORTED,
                /* int32 event_id = 1 */ eventType.getId(),
                /* int32 uid = 2 */ p.r.getUid(),
                /* string package_name = 3 */ p.r.getSbn().getPackageName(),
                /* int32 instance_id = 4 */ p.getInstanceId(),
                /* int32 notification_id_hash = 5 */ p.getNotificationIdHash(),
                /* int32 channel_id_hash = 6 */ p.getChannelIdHash(),
                /* string group_id_hash = 7 */ p.getGroupIdHash(),
                /* int32 group_instance_id = 8 */ (groupId == null) ? 0 : groupId.getId(),
                /* bool is_group_summary = 9 */ p.r.getSbn().getNotification().isGroupSummary(),
                /* string category = 10 */ p.r.getSbn().getNotification().category,
                /* int32 style = 11 */ p.getStyle(),
                /* int32 num_people = 12 */ p.getNumPeople(),
                /* int32 position = 13 */ position,
                /* android.stats.sysui.NotificationImportance importance = 14 */
                NotificationRecordLogger.getLoggingImportance(p.r),
                /* int32 alerting = 15 */ buzzBeepBlink,
                /* NotificationImportanceExplanation importance_source = 16 */
                p.r.getImportanceExplanationCode(),
                /* android.stats.sysui.NotificationImportance importance_initial = 17 */
                p.r.getInitialImportance(),
                /* NotificationImportanceExplanation importance_initial_source = 18 */
                p.r.getInitialImportanceExplanationCode(),
                /* android.stats.sysui.NotificationImportance importance_asst = 19 */
                p.r.getAssistantImportance(),
                /* int32 assistant_hash = 20 */ p.getAssistantHash(),
                /* float assistant_ranking_score = 21 */ p.r.getRankingScore(),
                /* bool is_ongoing = 22 */ p.r.getSbn().isOngoing(),
                /* bool is_foreground_service = 23 */
                NotificationRecordLogger.isForegroundService(p.r),
                /* optional int64 timeout_millis = 24 */
                p.r.getSbn().getNotification().getTimeoutAfter(),
                /* bool is_nondismissible = 25 */
                NotificationRecordLogger.isNonDismissible(p.r)
        );
    private void writeNotificationReportedAtom(
            NotificationReported notificationReported) {
        FrameworkStatsLog.write(
                FrameworkStatsLog.NOTIFICATION_REPORTED,
                notificationReported.event_id,
                notificationReported.uid,
                notificationReported.package_name,
                notificationReported.instance_id,
                notificationReported.notification_id_hash,
                notificationReported.channel_id_hash,
                notificationReported.group_id_hash,
                notificationReported.group_instance_id,
                notificationReported.is_group_summary,
                notificationReported.category,
                notificationReported.style,
                notificationReported.num_people,
                notificationReported.position,
                notificationReported.importance,
                notificationReported.alerting,
                notificationReported.importance_source,
                notificationReported.importance_initial,
                notificationReported.importance_initial_source,
                notificationReported.importance_asst,
                notificationReported.assistant_hash,
                notificationReported.assistant_ranking_score,
                notificationReported.is_ongoing,
                notificationReported.is_foreground_service,
                notificationReported.timeout_millis,
                notificationReported.is_non_dismissible);
    }

    @Override
+126 −37

File changed.

Preview size limit exceeded, changes collapsed.

+34 −4
Original line number Diff line number Diff line
@@ -16,11 +16,15 @@

package com.android.server.notification;

import androidx.annotation.Nullable;

import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Fake implementation of NotificationRecordLogger, for testing.
@@ -60,7 +64,8 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
            this.event = event;
        }
    }
    private List<CallRecord> mCalls = new ArrayList<>();
    private final List<CallRecord> mCalls = new ArrayList<>();
    private final Map<NotificationReported, CallRecord> mPendingLogs = new HashMap<>();

    public int numCalls() {
        return mCalls.size();
@@ -70,6 +75,10 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
        return mCalls;
    }

    List<NotificationReported> getPendingLogs() {
        return new ArrayList<>(mPendingLogs.keySet());
    }

    CallRecord get(int index) {
        return mCalls.get(index);
    }
@@ -77,10 +86,31 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
        return mCalls.get(index).event;
    }

    @Nullable
    @Override
    public NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
            @Nullable NotificationRecord old, int position, int buzzBeepBlink, InstanceId groupId) {
        NotificationReported nr = NotificationRecordLogger.super.prepareToLogNotificationPosted(r,
                old, position, buzzBeepBlink, groupId);
        CallRecord callRecord = new CallRecord(r, old, position, buzzBeepBlink, groupId);
        callRecord.wasLogged = false;
        mCalls.add(callRecord);
        if (nr != null) {
            mPendingLogs.put(nr, callRecord);
        }
        return nr;
    }

    @Override
    public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
            int position, int buzzBeepBlink, InstanceId groupId) {
        mCalls.add(new CallRecord(r, old, position, buzzBeepBlink, groupId));
    public void logNotificationPosted(NotificationReported nr) {
        CallRecord callRecord = mPendingLogs.get(nr);
        if (callRecord == null) {
            throw new IllegalStateException(
                    "Didn't find corresponding CallRecord in mPreparedCalls. Did you call "
                            + "logNotificationPosted() twice!?");
        }
        mPendingLogs.remove(nr);
        callRecord.wasLogged = true;
    }

    @Override
Loading