Merge "Add blocking helper logging"
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user