add channel and group tags to the notificaiton logs
Change-Id: Icf029e42fca46262c9d9f8ff63f26de098f888bf
Fixes: 37714086
Test: runtest systemui-notification
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 31b2dcc..d1ebc6e 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -318,6 +318,17 @@
}
/**
+ * The ID passed to setGroup(), or the override, or null.
+ * @hide
+ */
+ public String getGroup() {
+ if (overrideGroupKey != null) {
+ return overrideGroupKey;
+ }
+ return getNotification().getGroup();
+ }
+
+ /**
* Sets the override group key.
*/
public void setOverrideGroupKey(String overrideGroupKey) {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index f37bfac..3dd75bb 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3962,6 +3962,16 @@
// OS: O
APP_TRANSITION_BIND_APPLICATION_DELAY_MS = 945;
+ // FIELD - The group ID of a notification.
+ // Type: string
+ // OS: O
+ FIELD_NOTIFICATION_GROUP_ID = 946;
+
+ // FIELD - If the notification is a group summary: 1.
+ // Type: int encoded boolean
+ // OS: O
+ FIELD_NOTIFICATION_GROUP_SUMMARY = 947;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1f7feb5..700a4db 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2776,7 +2776,7 @@
if (n == null) {
return;
}
- n.sbn.setOverrideGroupKey(GroupHelper.AUTOGROUP_KEY);
+ n.setOverrideGroupKey(GroupHelper.AUTOGROUP_KEY);
EventLogTags.writeNotificationAutogrouped(key);
}
@@ -2785,7 +2785,7 @@
if (n == null) {
return;
}
- n.sbn.setOverrideGroupKey(null);
+ n.setOverrideGroupKey(null);
EventLogTags.writeNotificationUnautogrouped(key);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 95e1db7..f3ae67e 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -73,6 +73,7 @@
public final class NotificationRecord {
static final String TAG = "NotificationRecord";
static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int MAX_LOGTAG_LENGTH = 35;
final StatusBarNotification sbn;
final int mOriginalFlags;
private final Context mContext;
@@ -127,6 +128,8 @@
private boolean mShowBadge;
private LogMaker mLogMaker;
private Light mLight;
+ private String mGroupLogTag;
+ private String mChannelIdLogTag;
@VisibleForTesting
public NotificationRecord(Context context, StatusBarNotification sbn,
@@ -749,6 +752,37 @@
return sbn.getGroupKey();
}
+ public void setOverrideGroupKey(String overrideGroupKey) {
+ sbn.setOverrideGroupKey(overrideGroupKey);
+ mGroupLogTag = null;
+ }
+
+ private String getGroupLogTag() {
+ if (mGroupLogTag == null) {
+ mGroupLogTag = shortenTag(sbn.getGroup());
+ }
+ return mGroupLogTag;
+ }
+
+ private String getChannelIdLogTag() {
+ if (mChannelIdLogTag == null) {
+ mChannelIdLogTag = shortenTag(mChannel.getId());
+ }
+ return mChannelIdLogTag;
+ }
+
+ private String shortenTag(String longTag) {
+ if (longTag == null) {
+ return null;
+ }
+ if (longTag.length() < MAX_LOGTAG_LENGTH) {
+ return longTag;
+ } else {
+ return longTag.substring(0, MAX_LOGTAG_LENGTH - 8) + "-" +
+ Integer.toHexString(longTag.hashCode());
+ }
+ }
+
public boolean isImportanceFromUser() {
return mImportance == mUserImportance;
}
@@ -806,16 +840,23 @@
public LogMaker getLogMaker(long now) {
if (mLogMaker == null) {
+ // initialize fields that only change on update (so a new record)
mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
.setPackageName(sbn.getPackageName())
.addTaggedData(MetricsEvent.NOTIFICATION_ID, sbn.getId())
- .addTaggedData(MetricsEvent.NOTIFICATION_TAG, sbn.getTag());
+ .addTaggedData(MetricsEvent.NOTIFICATION_TAG, sbn.getTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag());
}
+ // reset fields that can change between updates, or are used by multiple logs
return mLogMaker
.clearCategory()
.clearType()
.clearSubtype()
.clearTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX)
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE, mImportance)
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
+ sbn.getNotification().isGroupSummary() ? 1 : 0)
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS, getLifespanMs(now))
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS, getFreshnessMs(now))
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, getExposureMs(now));
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index 0812783..5a6225a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -35,6 +35,7 @@
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.media.AudioAttributes;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Build;
import android.os.UserHandle;
@@ -44,6 +45,8 @@
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,6 +74,14 @@
private final String channelId = "channel";
NotificationChannel channel =
new NotificationChannel(channelId, "test", NotificationManager.IMPORTANCE_DEFAULT);
+ private final String channelIdLong =
+ "give_a_developer_a_string_argument_and_who_knows_what_they_will_pass_in_there";
+ final String groupId = "group";
+ final String groupIdOverride = "other_group";
+ private final String groupIdLong =
+ "0|com.foo.bar|g:content://com.foo.bar.ui/account%3A-0000000/account/";
+ NotificationChannel channelLongId =
+ new NotificationChannel(channelIdLong, "long", NotificationManager.IMPORTANCE_DEFAULT);
NotificationChannel defaultChannel =
new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
NotificationManager.IMPORTANCE_UNSPECIFIED);
@@ -107,7 +118,8 @@
}
private StatusBarNotification getNotification(boolean preO, boolean noisy, boolean defaultSound,
- boolean buzzy, boolean defaultVibration, boolean lights, boolean defaultLights) {
+ boolean buzzy, boolean defaultVibration, boolean lights, boolean defaultLights,
+ String group) {
when(mMockContext.getApplicationInfo()).thenReturn(preO ? legacy : upgrade);
final Builder builder = new Builder(mMockContext)
.setContentTitle("foo")
@@ -151,6 +163,9 @@
builder.setChannelId(channelId);
}
+ if(group != null) {
+ builder.setGroup(group);
+ }
Notification n = builder.build();
if (preO) {
@@ -172,7 +187,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, record.getSound());
@@ -185,7 +200,7 @@
// pre upgrade, custom sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -199,7 +214,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -211,7 +226,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(null, record.getSound());
@@ -224,7 +239,7 @@
// post upgrade, default sound.
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -237,7 +252,7 @@
// pre upgrade, default vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, true /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNotNull(record.getVibration());
@@ -249,7 +264,7 @@
// pre upgrade, custom vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_VIBRATION, record.getVibration());
@@ -262,7 +277,7 @@
// pre upgrade, custom vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
@@ -274,7 +289,7 @@
// post upgrade, custom vibration.
StatusBarNotification sbn = getNotification(false /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_CHANNEL_VIBRATION, record.getVibration());
@@ -284,7 +299,7 @@
public void testImportance_preUpgrade() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
}
@@ -295,7 +310,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_LOW, record.getImportance());
@@ -307,7 +322,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
@@ -317,7 +332,7 @@
public void testImportance_upgrade() throws Exception {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(NotificationManager.IMPORTANCE_DEFAULT, record.getImportance());
}
@@ -326,7 +341,7 @@
public void testLights_preUpgrade_noLight() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNull(record.getLight());
}
@@ -336,7 +351,7 @@
public void testLights_preUpgrade() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_LIGHT, record.getLight());
}
@@ -347,7 +362,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertFalse(CUSTOM_LIGHT.equals(record.getLight()));
@@ -366,7 +381,7 @@
defaultLightColor, defaultLightOn, defaultLightOff);
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, true /*defaultLights */);
+ true /* lights */, true /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(expected, record.getLight());
}
@@ -382,7 +397,7 @@
Color.BLUE, defaultLightOn, defaultLightOff);
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(expected, record.getLight());
}
@@ -391,8 +406,80 @@
public void testLights_upgrade_noLight() throws Exception {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNull(record.getLight());
}
+
+ @Test
+ public void testLogmakerShortChannel() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ final LogMaker logMaker = record.getLogMaker();
+ assertEquals(channelId,
+ (String) logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID));
+ assertEquals(channel.getImportance(),
+ logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+ }
+
+ @Test
+ public void testLogmakerLongChannel() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /*defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channelLongId);
+ final String loggedId = (String)
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID);
+ assertEquals(channelIdLong.substring(0,10), loggedId.substring(0, 10));
+ }
+
+ @Test
+ public void testLogmakerNoGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /*defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertNull(record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+ @Test
+ public void testLogmakerShortGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*reO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupId /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+ @Test
+ public void testLogmakerLongGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupIdLong /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ final String loggedId = (String)
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID);
+ assertEquals(groupIdLong.substring(0,10), loggedId.substring(0, 10));
+ }
+
+ @Test
+ public void testLogmakerOverrideGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupId /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ record.setOverrideGroupKey(groupIdOverride);
+ assertEquals(groupIdOverride,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ record.setOverrideGroupKey(null);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+
}