Merge "Add blocking helper logging"

This commit is contained in:
Eyal Posener
2019-01-14 11:06:12 +00:00
committed by Android (Google) Code Review
8 changed files with 287 additions and 117 deletions

View File

@@ -22,16 +22,21 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.metrics.LogMaker;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
/**
* Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
* the status bar and any {@link android.service.notification.NotificationListenerService}s.
*/
public class StatusBarNotification implements Parcelable {
static final int MAX_LOG_TAG_LENGTH = 36;
@UnsupportedAppUsage
private final String pkg;
@UnsupportedAppUsage
@@ -56,6 +61,9 @@ public class StatusBarNotification implements Parcelable {
private Context mContext; // used for inflation & icon expansion
// Contains the basic logging data of the notification.
private LogMaker mLogMaker;
/** @hide */
public StatusBarNotification(String pkg, String opPkg, int id,
String tag, int uid, int initialPid, Notification notification, UserHandle user,
@@ -381,4 +389,51 @@ public class StatusBarNotification implements Parcelable {
}
return mContext;
}
/**
* Returns a LogMaker that contains all basic information of the notification.
* @hide
*/
public LogMaker getLogMaker() {
if (mLogMaker == null) {
// Initialize fields that only change on update (so a new record).
mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
.setPackageName(getPackageName())
.addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
.addTaggedData(MetricsEvent.NOTIFICATION_TAG, 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()
.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
getNotification().isGroupSummary() ? 1 : 0);
}
private String getGroupLogTag() {
return shortenTag(getGroup());
}
private String getChannelIdLogTag() {
if (notification.getChannelId() == null) {
return null;
}
return shortenTag(notification.getChannelId());
}
// Make logTag with max size MAX_LOG_TAG_LENGTH.
// For shorter or equal tags, returns the tag.
// For longer tags, truncate the tag and append a hash of the full tag to
// fill the maximum size.
private String shortenTag(String logTag) {
if (logTag == null || logTag.length() <= MAX_LOG_TAG_LENGTH) {
return logTag;
}
String hash = Integer.toHexString(logTag.hashCode());
return logTag.substring(0, MAX_LOG_TAG_LENGTH - hash.length() - 1) + "-"
+ hash;
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.service.notification;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class StatusBarNotificationTest {
private final Context mMockContext = mock(Context.class);
@Mock
private PackageManager mPm;
private static final String PKG = "com.example.o";
private static final int UID = 9583;
private static final int ID = 1;
private static final String TAG = "tag1";
private static final String CHANNEL_ID = "channel";
private static final String CHANNEL_ID_LONG =
"give_a_developer_a_string_argument_and_who_knows_what_they_will_pass_in_there";
private static final String GROUP_ID_1 = "group1";
private static final String GROUP_ID_2 = "group2";
private static final String GROUP_ID_LONG =
"0|com.foo.bar|g:content://com.foo.bar.ui/account%3A-0000000/account/";
private static final android.os.UserHandle USER =
UserHandle.of(ActivityManager.getCurrentUser());
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockContext.getResources()).thenReturn(
InstrumentationRegistry.getContext().getResources());
when(mMockContext.getPackageManager()).thenReturn(mPm);
when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
}
@Test
public void testLogMaker() {
final LogMaker logMaker = getNotification(PKG, GROUP_ID_1, CHANNEL_ID).getLogMaker();
assertEquals(CHANNEL_ID,
(String) logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID));
assertEquals(PKG, logMaker.getPackageName());
assertEquals(ID, logMaker.getTaggedData(MetricsEvent.NOTIFICATION_ID));
assertEquals(TAG, logMaker.getTaggedData(MetricsEvent.NOTIFICATION_TAG));
assertEquals(GROUP_ID_1,
logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
}
@Test
public void testLogMakerNoChannel() {
final LogMaker logMaker = getNotification(PKG, GROUP_ID_1, null).getLogMaker();
assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID));
}
@Test
public void testLogMakerLongChannel() {
final LogMaker logMaker = getNotification(PKG, null, CHANNEL_ID_LONG).getLogMaker();
final String loggedId = (String) logMaker
.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID);
assertEquals(StatusBarNotification.MAX_LOG_TAG_LENGTH, loggedId.length());
assertEquals(CHANNEL_ID_LONG.substring(0, 10), loggedId.substring(0, 10));
}
@Test
public void testLogMakerNoGroup() {
final LogMaker logMaker = getNotification(PKG, null, CHANNEL_ID).getLogMaker();
assertNull(
logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
}
@Test
public void testLogMakerLongGroup() {
final LogMaker logMaker = getNotification(PKG, GROUP_ID_LONG, CHANNEL_ID)
.getLogMaker();
final String loggedId = (String)
logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID);
assertEquals(StatusBarNotification.MAX_LOG_TAG_LENGTH, loggedId.length());
assertEquals(GROUP_ID_LONG.substring(0, 10), loggedId.substring(0, 10));
}
@Test
public void testLogMakerOverrideGroup() {
StatusBarNotification sbn = getNotification(PKG, GROUP_ID_1, CHANNEL_ID);
assertEquals(GROUP_ID_1,
sbn.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
sbn.setOverrideGroupKey(GROUP_ID_2);
assertEquals(GROUP_ID_2,
sbn.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
sbn.setOverrideGroupKey(null);
assertEquals(GROUP_ID_1,
sbn.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
}
private StatusBarNotification getNotification(String pkg, String group, String channelId) {
final Notification.Builder builder = new Notification.Builder(mMockContext, channelId)
.setContentTitle("foo")
.setSmallIcon(android.R.drawable.sym_def_app_icon);
if (group != null) {
builder.setGroup(group);
}
Notification n = builder.build();
return new StatusBarNotification(
pkg, pkg, ID, TAG, UID, UID, n, USER, null, UID);
}
}

View File

@@ -20,11 +20,13 @@ import static android.service.notification.NotificationListenerService.Ranking
.USER_SENTIMENT_NEGATIVE;
import android.content.Context;
import android.metrics.LogMaker;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -58,6 +60,8 @@ public class NotificationBlockingHelperManager {
*/
private boolean mIsShadeExpanded;
private MetricsLogger mMetricsLogger = new MetricsLogger();
@Inject
public NotificationBlockingHelperManager(Context context) {
mContext = context;
@@ -100,6 +104,11 @@ public class NotificationBlockingHelperManager {
mBlockingHelperRow = row;
mBlockingHelperRow.setBlockingHelperShowing(true);
// Log triggering of blocking helper by the system. This log line
// should be emitted before the "display" log line.
mMetricsLogger.write(
getLogMaker().setSubtype(MetricsEvent.BLOCKING_HELPER_TRIGGERED_BY_SYSTEM));
// We don't care about the touch origin (x, y) since we're opening guts without any
// explicit user interaction.
manager.openGuts(mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext));
@@ -153,6 +162,13 @@ public class NotificationBlockingHelperManager {
|| mNonBlockablePkgs.contains(makeChannelKey(packageName, channelName));
}
private LogMaker getLogMaker() {
return mBlockingHelperRow.getStatusBarNotification()
.getLogMaker()
.setCategory(MetricsEvent.NOTIFICATION_ITEM)
.setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER);
}
// Format must stay in sync with frameworks/base/core/res/res/values/config.xml
// config_nonBlockableNotificationPackages
private String makeChannelKey(String pkg, String channel) {

View File

@@ -123,11 +123,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnClickListener mOnKeepShowing = v -> {
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
closeControls(v);
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
};
private OnClickListener mOnToggleSilent = v -> {
Runnable saveImportance = () -> {
swapContent(ACTION_TOGGLE_SILENT, true /* animate */);
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME));
};
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(saveImportance, mSbn);
@@ -139,6 +143,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnClickListener mOnStopOrMinimizeNotifications = v -> {
Runnable saveImportance = () -> {
swapContent(ACTION_BLOCK, true /* animate */);
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED));
};
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(saveImportance, mSbn);
@@ -153,6 +159,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
swapContent(ACTION_UNDO, true /* animate */);
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
};
public NotificationInfo(Context context, AttributeSet attrs) {
@@ -251,6 +259,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindHeader();
bindPrompt();
bindButtons();
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_DISPLAY));
}
private void bindHeader() throws RemoteException {
@@ -588,6 +599,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
confirmation.setAlpha(1f);
header.setVisibility(VISIBLE);
header.setAlpha(1f);
mMetricsLogger.write(getLogMaker().setType(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
.setSubtype(MetricsEvent.BLOCKING_HELPER_DISMISS));
}
@Override
@@ -733,4 +746,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
}
private LogMaker getLogMaker() {
return mSbn.getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
}
}

View File

@@ -45,7 +45,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.INotificationManager;
@@ -73,6 +72,7 @@ import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -498,12 +498,15 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
public void testLogBlockingHelperCounter_doesntLogForNormalGutsView() throws Exception {
public void testLogBlockingHelperCounter_logGutsViewDisplayed() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
IMPORTANCE_DEFAULT);
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verifyZeroInteractions(mMetricsLogger);
verify(mMetricsLogger).write(argThat(logMaker ->
logMaker.getType() == MetricsEvent.NOTIFICATION_BLOCKING_HELPER
&& logMaker.getSubtype() == MetricsEvent.BLOCKING_HELPER_DISPLAY
));
}
@Test

View File

@@ -213,6 +213,25 @@ message MetricsEvent {
IOOP_SYNC = 4;
}
// Subtypes of notifications blocking helper view
// (NOTIFICATION_BLOCKING_HELPER).
enum NotificationBlockingHelper {
BLOCKING_HELPER_UNKNOWN = 0;
BLOCKING_HELPER_DISPLAY = 1;
BLOCKING_HELPER_DISMISS = 2;
// When the view of the notification blocking helper was triggered by
// system.
BLOCKING_HELPER_TRIGGERED_BY_SYSTEM = 3;
// "block" was clicked.
BLOCKING_HELPER_CLICK_BLOCKED = 4;
// "stay silent" was clicked.
BLOCKING_HELPER_CLICK_STAY_SILENT = 5;
// "alert me" was clicked.
BLOCKING_HELPER_CLICK_ALERT_ME = 6;
// "undo" was clicked (enables the user to undo "stop notification" action).
BLOCKING_HELPER_CLICK_UNDO = 7;
}
// Known visual elements: views or controls.
enum View {
// Unknown view
@@ -6768,6 +6787,13 @@ message MetricsEvent {
// OS: Q
ACCESSIBILITY_VIBRATION_RING = 1620;
// ACTION: Notification blocking helper view, which helps the user to block
// application or channel from showing notifications.
// SUBTYPE: NotificationBlockingHelper enum.
// CATEGORY: NOTIFICATION
// OS: Q
NOTIFICATION_BLOCKING_HELPER = 1621;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.

View File

@@ -91,7 +91,6 @@ import java.util.Objects;
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;
// the period after which a notification is updated where it can make sound
private static final int MAX_SOUND_DELAY_MS = 2000;
final StatusBarNotification sbn;
@@ -162,10 +161,7 @@ public final class NotificationRecord {
private ArrayList<String> mPeopleOverride;
private ArrayList<SnoozeCriterion> mSnoozeCriteria;
private boolean mShowBadge;
private LogMaker mLogMaker;
private Light mLight;
private String mGroupLogTag;
private String mChannelIdLogTag;
/**
* This list contains system generated smart actions from NAS, app-generated smart actions are
* stored in Notification.actions with isContextual() set to true.
@@ -969,33 +965,6 @@ public final class NotificationRecord {
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 NotificationChannel getChannel() {
@@ -1272,24 +1241,9 @@ public final class NotificationRecord {
}
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.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag());
}
// reset fields that can change between updates, or are used by multiple logs
return mLogMaker
.clearCategory()
.clearType()
.clearSubtype()
return sbn.getLogMaker()
.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))

View File

@@ -56,8 +56,8 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.Adjustment;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.R;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -87,14 +87,7 @@ public class NotificationRecordTest extends UiServiceTestCase {
private final String channelId = "channel";
private 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";
private final String groupId = "group";
private final String groupIdOverride = "other_group";
private final String groupIdLong =
"0|com.foo.bar|g:content://com.foo.bar.ui/account%3A-0000000/account/";
private NotificationChannel channelLongId =
new NotificationChannel(channelIdLong, "long", NotificationManager.IMPORTANCE_DEFAULT);
private NotificationChannel defaultChannel =
new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
NotificationManager.IMPORTANCE_UNSPECIFIED);
@@ -408,73 +401,27 @@ public class NotificationRecordTest extends UiServiceTestCase {
}
@Test
public void testLogmakerShortChannel() {
public void testLogMaker() {
long timestamp = 1000L;
StatusBarNotification sbn = getNotification(PKG_O, 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();
final LogMaker logMaker = record.getLogMaker(timestamp);
assertNull(logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX));
assertEquals(channelId,
(String) logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID));
assertEquals(channel.getImportance(),
logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
}
@Test
public void testLogmakerLongChannel() {
StatusBarNotification sbn = getNotification(PKG_O, 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() {
StatusBarNotification sbn = getNotification(PKG_O, 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() {
StatusBarNotification sbn = getNotification(PKG_O, 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() {
StatusBarNotification sbn = getNotification(PKG_O, 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() {
StatusBarNotification sbn = getNotification(PKG_O, 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));
assertEquals(record.getLifespanMs(timestamp),
(int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS));
assertEquals(record.getFreshnessMs(timestamp),
(int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS));
assertEquals(record.getExposureMs(timestamp),
(int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS));
assertEquals(record.getInterruptionMs(timestamp),
(int) logMaker.getTaggedData(MetricsEvent.NOTIFICATION_SINCE_INTERRUPTION_MILLIS));
}
@Test