Merge "Revert "Revert "Notification statsd logs: Notification panel.""" into rvc-dev am: 98f21c2474 am: 829fa681d0
Change-Id: I04cff078f7ab444899bb29463518b4568f379417
This commit is contained in:
@@ -237,16 +237,24 @@ public class StatusBarNotification implements Parcelable {
|
|||||||
public StatusBarNotification cloneLight() {
|
public StatusBarNotification cloneLight() {
|
||||||
final Notification no = new Notification();
|
final Notification no = new Notification();
|
||||||
this.notification.cloneInto(no, false); // light copy
|
this.notification.cloneInto(no, false); // light copy
|
||||||
return new StatusBarNotification(this.pkg, this.opPkg,
|
return cloneShallow(no);
|
||||||
this.id, this.tag, this.uid, this.initialPid,
|
|
||||||
no, this.user, this.overrideGroupKey, this.postTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusBarNotification clone() {
|
public StatusBarNotification clone() {
|
||||||
return new StatusBarNotification(this.pkg, this.opPkg,
|
return cloneShallow(this.notification.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param notification Some kind of clone of this.notification.
|
||||||
|
* @return A shallow copy of self, with notification in place of this.notification.
|
||||||
|
*/
|
||||||
|
StatusBarNotification cloneShallow(Notification notification) {
|
||||||
|
StatusBarNotification result = new StatusBarNotification(this.pkg, this.opPkg,
|
||||||
this.id, this.tag, this.uid, this.initialPid,
|
this.id, this.tag, this.uid, this.initialPid,
|
||||||
this.notification.clone(), this.user, this.overrideGroupKey, this.postTime);
|
notification, this.user, this.overrideGroupKey, this.postTime);
|
||||||
|
result.setInstanceId(this.mInstanceId);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,6 +48,17 @@ public final class InstanceId implements Parcelable {
|
|||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a fake instance ID for testing purposes. Not for production use. See also
|
||||||
|
* InstanceIdSequenceFake, which is a testing replacement for InstanceIdSequence.
|
||||||
|
* @param id The ID you want to assign.
|
||||||
|
* @return new InstanceId.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static InstanceId fakeInstanceId(int id) {
|
||||||
|
return new InstanceId(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return mId;
|
return mId;
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ import com.android.systemui.statusbar.notification.init.NotificationsController;
|
|||||||
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
|
import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
|
||||||
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
|
import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
|
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||||
@@ -146,13 +148,22 @@ public interface NotificationsModule {
|
|||||||
@UiBackground Executor uiBgExecutor,
|
@UiBackground Executor uiBgExecutor,
|
||||||
NotificationEntryManager entryManager,
|
NotificationEntryManager entryManager,
|
||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
NotificationLogger.ExpansionStateLogger expansionStateLogger) {
|
NotificationLogger.ExpansionStateLogger expansionStateLogger,
|
||||||
|
NotificationPanelLogger notificationPanelLogger) {
|
||||||
return new NotificationLogger(
|
return new NotificationLogger(
|
||||||
notificationListener,
|
notificationListener,
|
||||||
uiBgExecutor,
|
uiBgExecutor,
|
||||||
entryManager,
|
entryManager,
|
||||||
statusBarStateController,
|
statusBarStateController,
|
||||||
expansionStateLogger);
|
expansionStateLogger,
|
||||||
|
notificationPanelLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides an instance of {@link NotificationPanelLogger} */
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
static NotificationPanelLogger provideNotificationPanelLogger() {
|
||||||
|
return new NotificationPanelLoggerImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
|
/** Provides an instance of {@link com.android.internal.logging.UiEventLogger} */
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public class NotificationLogger implements StateListener {
|
|||||||
private final NotificationListenerService mNotificationListener;
|
private final NotificationListenerService mNotificationListener;
|
||||||
private final Executor mUiBgExecutor;
|
private final Executor mUiBgExecutor;
|
||||||
private final NotificationEntryManager mEntryManager;
|
private final NotificationEntryManager mEntryManager;
|
||||||
|
private final NotificationPanelLogger mNotificationPanelLogger;
|
||||||
private HeadsUpManager mHeadsUpManager;
|
private HeadsUpManager mHeadsUpManager;
|
||||||
private final ExpansionStateLogger mExpansionStateLogger;
|
private final ExpansionStateLogger mExpansionStateLogger;
|
||||||
|
|
||||||
@@ -198,13 +199,15 @@ public class NotificationLogger implements StateListener {
|
|||||||
@UiBackground Executor uiBgExecutor,
|
@UiBackground Executor uiBgExecutor,
|
||||||
NotificationEntryManager entryManager,
|
NotificationEntryManager entryManager,
|
||||||
StatusBarStateController statusBarStateController,
|
StatusBarStateController statusBarStateController,
|
||||||
ExpansionStateLogger expansionStateLogger) {
|
ExpansionStateLogger expansionStateLogger,
|
||||||
|
NotificationPanelLogger notificationPanelLogger) {
|
||||||
mNotificationListener = notificationListener;
|
mNotificationListener = notificationListener;
|
||||||
mUiBgExecutor = uiBgExecutor;
|
mUiBgExecutor = uiBgExecutor;
|
||||||
mEntryManager = entryManager;
|
mEntryManager = entryManager;
|
||||||
mBarService = IStatusBarService.Stub.asInterface(
|
mBarService = IStatusBarService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||||
mExpansionStateLogger = expansionStateLogger;
|
mExpansionStateLogger = expansionStateLogger;
|
||||||
|
mNotificationPanelLogger = notificationPanelLogger;
|
||||||
// Not expected to be destroyed, don't need to unsubscribe
|
// Not expected to be destroyed, don't need to unsubscribe
|
||||||
statusBarStateController.addCallback(this);
|
statusBarStateController.addCallback(this);
|
||||||
|
|
||||||
@@ -264,6 +267,8 @@ public class NotificationLogger implements StateListener {
|
|||||||
// (Note that in cases where the scroller does emit events, this
|
// (Note that in cases where the scroller does emit events, this
|
||||||
// additional event doesn't break anything.)
|
// additional event doesn't break anything.)
|
||||||
mNotificationLocationsChangedListener.onChildLocationsChanged();
|
mNotificationLocationsChangedListener.onChildLocationsChanged();
|
||||||
|
mNotificationPanelLogger.logPanelShown(mListContainer.hasPulsingNotifications(),
|
||||||
|
mEntryManager.getVisibleNotifications());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDozing(boolean dozing) {
|
private void setDozing(boolean dozing) {
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 com.android.systemui.statusbar.notification.logging;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
|
import com.android.internal.logging.UiEvent;
|
||||||
|
import com.android.internal.logging.UiEventLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
/**
|
||||||
|
* Statsd logging for notification panel.
|
||||||
|
*/
|
||||||
|
public interface NotificationPanelLogger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a NOTIFICATION_PANEL_REPORTED statsd event.
|
||||||
|
* @param visibleNotifications as provided by NotificationEntryManager.getVisibleNotifications()
|
||||||
|
*/
|
||||||
|
void logPanelShown(boolean isLockscreen,
|
||||||
|
@Nullable List<NotificationEntry> visibleNotifications);
|
||||||
|
|
||||||
|
enum NotificationPanelEvent implements UiEventLogger.UiEventEnum {
|
||||||
|
@UiEvent(doc = "Notification panel shown from status bar.")
|
||||||
|
NOTIFICATION_PANEL_OPEN_STATUS_BAR(200),
|
||||||
|
@UiEvent(doc = "Notification panel shown from lockscreen.")
|
||||||
|
NOTIFICATION_PANEL_OPEN_LOCKSCREEN(201);
|
||||||
|
|
||||||
|
private final int mId;
|
||||||
|
NotificationPanelEvent(int id) {
|
||||||
|
mId = id;
|
||||||
|
}
|
||||||
|
@Override public int getId() {
|
||||||
|
return mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NotificationPanelEvent fromLockscreen(boolean isLockscreen) {
|
||||||
|
return isLockscreen ? NOTIFICATION_PANEL_OPEN_LOCKSCREEN :
|
||||||
|
NOTIFICATION_PANEL_OPEN_STATUS_BAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes a NotificationsList proto from the list of visible notifications.
|
||||||
|
* @param visibleNotifications as provided by NotificationEntryManager.getVisibleNotifications()
|
||||||
|
* @return NotificationList proto suitable for SysUiStatsLog.write(NOTIFICATION_PANEL_REPORTED)
|
||||||
|
*/
|
||||||
|
static Notifications.NotificationList toNotificationProto(
|
||||||
|
@Nullable List<NotificationEntry> visibleNotifications) {
|
||||||
|
Notifications.NotificationList notificationList = new Notifications.NotificationList();
|
||||||
|
if (visibleNotifications == null) {
|
||||||
|
return notificationList;
|
||||||
|
}
|
||||||
|
final Notifications.Notification[] proto_array =
|
||||||
|
new Notifications.Notification[visibleNotifications.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (NotificationEntry ne : visibleNotifications) {
|
||||||
|
final StatusBarNotification n = ne.getSbn();
|
||||||
|
if (n != null) {
|
||||||
|
final Notifications.Notification proto = new Notifications.Notification();
|
||||||
|
proto.uid = n.getUid();
|
||||||
|
proto.packageName = n.getPackageName();
|
||||||
|
if (n.getInstanceId() != null) {
|
||||||
|
proto.instanceId = n.getInstanceId().getId();
|
||||||
|
}
|
||||||
|
// TODO set np.groupInstanceId
|
||||||
|
if (n.getNotification() != null) {
|
||||||
|
proto.isGroupSummary = n.getNotification().isGroupSummary();
|
||||||
|
}
|
||||||
|
proto.section = 1 + ne.getBucket(); // We want 0 to mean not set / unknown
|
||||||
|
proto_array[i] = proto;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
notificationList.notifications = proto_array;
|
||||||
|
return notificationList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 com.android.systemui.statusbar.notification.logging;
|
||||||
|
|
||||||
|
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||||
|
|
||||||
|
import com.google.protobuf.nano.MessageNano;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normal implementation of NotificationPanelLogger.
|
||||||
|
*/
|
||||||
|
public class NotificationPanelLoggerImpl implements NotificationPanelLogger {
|
||||||
|
@Override
|
||||||
|
public void logPanelShown(boolean isLockscreen,
|
||||||
|
List<NotificationEntry> visibleNotifications) {
|
||||||
|
final Notifications.NotificationList proto = NotificationPanelLogger.toNotificationProto(
|
||||||
|
visibleNotifications);
|
||||||
|
SysUiStatsLog.write(SysUiStatsLog.NOTIFICATION_PANEL_REPORTED,
|
||||||
|
/* int event_id */ NotificationPanelEvent.fromLockscreen(isLockscreen).getId(),
|
||||||
|
/* int num_notifications*/ proto.notifications.length,
|
||||||
|
/* byte[] notifications*/ MessageNano.toByteArray(proto));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 com.android.systemui.statusbar.notification.logging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NotificationList proto from atoms.proto, duplicated here so that it's accessible in the build.
|
||||||
|
* Must be kept in sync with the version in atoms.proto.
|
||||||
|
*/
|
||||||
|
|
||||||
|
message Notification {
|
||||||
|
// The notifying app's uid and package.
|
||||||
|
optional int32 uid = 1;
|
||||||
|
optional string package_name = 2;
|
||||||
|
// A small system-assigned identifier for the notification.
|
||||||
|
optional int32 instance_id = 3;
|
||||||
|
|
||||||
|
// Grouping information.
|
||||||
|
optional int32 group_instance_id = 4;
|
||||||
|
optional bool is_group_summary = 5;
|
||||||
|
|
||||||
|
// The section of the shade that the notification is in.
|
||||||
|
// See NotificationSectionsManager.PriorityBucket.
|
||||||
|
enum NotificationSection {
|
||||||
|
SECTION_UNKNOWN = 0;
|
||||||
|
SECTION_HEADS_UP = 1;
|
||||||
|
SECTION_PEOPLE = 2;
|
||||||
|
SECTION_ALERTING = 3;
|
||||||
|
SECTION_SILENT = 4;
|
||||||
|
}
|
||||||
|
optional NotificationSection section = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NotificationList {
|
||||||
|
repeated Notification notifications = 1; // An ordered sequence of notifications.
|
||||||
|
}
|
||||||
@@ -22,6 +22,8 @@ import android.content.Context;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience builder for {@link StatusBarNotification} since its constructor is terrifying.
|
* Convenience builder for {@link StatusBarNotification} since its constructor is terrifying.
|
||||||
*
|
*
|
||||||
@@ -40,6 +42,7 @@ public class SbnBuilder {
|
|||||||
private UserHandle mUser = UserHandle.of(0);
|
private UserHandle mUser = UserHandle.of(0);
|
||||||
private String mOverrideGroupKey;
|
private String mOverrideGroupKey;
|
||||||
private long mPostTime;
|
private long mPostTime;
|
||||||
|
private InstanceId mInstanceId;
|
||||||
|
|
||||||
public SbnBuilder() {
|
public SbnBuilder() {
|
||||||
}
|
}
|
||||||
@@ -55,6 +58,7 @@ public class SbnBuilder {
|
|||||||
mUser = source.getUser();
|
mUser = source.getUser();
|
||||||
mOverrideGroupKey = source.getOverrideGroupKey();
|
mOverrideGroupKey = source.getOverrideGroupKey();
|
||||||
mPostTime = source.getPostTime();
|
mPostTime = source.getPostTime();
|
||||||
|
mInstanceId = source.getInstanceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusBarNotification build() {
|
public StatusBarNotification build() {
|
||||||
@@ -71,7 +75,7 @@ public class SbnBuilder {
|
|||||||
notification.setBubbleMetadata(mBubbleMetadata);
|
notification.setBubbleMetadata(mBubbleMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StatusBarNotification(
|
StatusBarNotification result = new StatusBarNotification(
|
||||||
mPkg,
|
mPkg,
|
||||||
mOpPkg,
|
mOpPkg,
|
||||||
mId,
|
mId,
|
||||||
@@ -82,6 +86,10 @@ public class SbnBuilder {
|
|||||||
mUser,
|
mUser,
|
||||||
mOverrideGroupKey,
|
mOverrideGroupKey,
|
||||||
mPostTime);
|
mPostTime);
|
||||||
|
if (mInstanceId != null) {
|
||||||
|
result.setInstanceId(mInstanceId);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SbnBuilder setPkg(String pkg) {
|
public SbnBuilder setPkg(String pkg) {
|
||||||
@@ -175,4 +183,9 @@ public class SbnBuilder {
|
|||||||
mBubbleMetadata = data;
|
mBubbleMetadata = data;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SbnBuilder setInstanceId(InstanceId instanceId) {
|
||||||
|
mInstanceId = instanceId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.os.UserHandle;
|
|||||||
import android.service.notification.SnoozeCriterion;
|
import android.service.notification.SnoozeCriterion;
|
||||||
import android.service.notification.StatusBarNotification;
|
import android.service.notification.StatusBarNotification;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.systemui.statusbar.RankingBuilder;
|
import com.android.systemui.statusbar.RankingBuilder;
|
||||||
import com.android.systemui.statusbar.SbnBuilder;
|
import com.android.systemui.statusbar.SbnBuilder;
|
||||||
|
|
||||||
@@ -141,6 +142,11 @@ public class NotificationEntryBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NotificationEntryBuilder setInstanceId(InstanceId instanceId) {
|
||||||
|
mSbnBuilder.setInstanceId(instanceId);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delegated to Notification.Builder (via SbnBuilder) */
|
/* Delegated to Notification.Builder (via SbnBuilder) */
|
||||||
|
|
||||||
public NotificationEntryBuilder setContentTitle(Context context, String contentTitle) {
|
public NotificationEntryBuilder setContentTitle(Context context, String contentTitle) {
|
||||||
|
|||||||
@@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.notification.logging;
|
package com.android.systemui.statusbar.notification.logging;
|
||||||
|
|
||||||
|
import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -34,6 +37,7 @@ import android.testing.TestableLooper;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.internal.statusbar.NotificationVisibility;
|
import com.android.internal.statusbar.NotificationVisibility;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
@@ -43,6 +47,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
|
|||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
@@ -81,9 +86,10 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private NotificationEntry mEntry;
|
private NotificationEntry mEntry;
|
||||||
private TestableNotificationLogger mLogger;
|
private TestableNotificationLogger mLogger;
|
||||||
private NotificationEntryListener mNotificationEntryListener;
|
|
||||||
private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
|
||||||
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
|
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
|
||||||
|
private NotificationPanelLoggerFake mNotificationPanelLoggerFake =
|
||||||
|
new NotificationPanelLoggerFake();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -97,6 +103,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
|||||||
.setUid(TEST_UID)
|
.setUid(TEST_UID)
|
||||||
.setNotification(new Notification())
|
.setNotification(new Notification())
|
||||||
.setUser(UserHandle.CURRENT)
|
.setUser(UserHandle.CURRENT)
|
||||||
|
.setInstanceId(InstanceId.fakeInstanceId(1))
|
||||||
.build();
|
.build();
|
||||||
mEntry.setRow(mRow);
|
mEntry.setRow(mRow);
|
||||||
|
|
||||||
@@ -105,7 +112,6 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
|||||||
mExpansionStateLogger);
|
mExpansionStateLogger);
|
||||||
mLogger.setUpWithContainer(mListContainer);
|
mLogger.setUpWithContainer(mListContainer);
|
||||||
verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture());
|
verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture());
|
||||||
mNotificationEntryListener = mEntryListenerCaptor.getValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -164,6 +170,41 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
|||||||
verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any());
|
verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogPanelShownOnLoggingStart() {
|
||||||
|
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(mEntry));
|
||||||
|
mLogger.startNotificationLogging();
|
||||||
|
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||||
|
assertEquals(false, mNotificationPanelLoggerFake.get(0).isLockscreen);
|
||||||
|
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
|
||||||
|
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
|
||||||
|
assertEquals(TEST_PACKAGE_NAME, n.packageName);
|
||||||
|
assertEquals(TEST_UID, n.uid);
|
||||||
|
assertEquals(1, n.instanceId);
|
||||||
|
assertEquals(false, n.isGroupSummary);
|
||||||
|
assertEquals(1 + BUCKET_ALERTING, n.section);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogPanelShownHandlesNullInstanceIds() {
|
||||||
|
// Construct a NotificationEntry like mEntry, but with a null instance id.
|
||||||
|
NotificationEntry entry = new NotificationEntryBuilder()
|
||||||
|
.setPkg(TEST_PACKAGE_NAME)
|
||||||
|
.setOpPkg(TEST_PACKAGE_NAME)
|
||||||
|
.setUid(TEST_UID)
|
||||||
|
.setNotification(new Notification())
|
||||||
|
.setUser(UserHandle.CURRENT)
|
||||||
|
.build();
|
||||||
|
entry.setRow(mRow);
|
||||||
|
|
||||||
|
when(mEntryManager.getVisibleNotifications()).thenReturn(Lists.newArrayList(entry));
|
||||||
|
mLogger.startNotificationLogging();
|
||||||
|
assertEquals(1, mNotificationPanelLoggerFake.getCalls().size());
|
||||||
|
assertEquals(1, mNotificationPanelLoggerFake.get(0).list.notifications.length);
|
||||||
|
Notifications.Notification n = mNotificationPanelLoggerFake.get(0).list.notifications[0];
|
||||||
|
assertEquals(0, n.instanceId);
|
||||||
|
}
|
||||||
|
|
||||||
private class TestableNotificationLogger extends NotificationLogger {
|
private class TestableNotificationLogger extends NotificationLogger {
|
||||||
|
|
||||||
TestableNotificationLogger(NotificationListener notificationListener,
|
TestableNotificationLogger(NotificationListener notificationListener,
|
||||||
@@ -173,7 +214,7 @@ public class NotificationLoggerTest extends SysuiTestCase {
|
|||||||
IStatusBarService barService,
|
IStatusBarService barService,
|
||||||
ExpansionStateLogger expansionStateLogger) {
|
ExpansionStateLogger expansionStateLogger) {
|
||||||
super(notificationListener, uiBgExecutor, entryManager, statusBarStateController,
|
super(notificationListener, uiBgExecutor, entryManager, statusBarStateController,
|
||||||
expansionStateLogger);
|
expansionStateLogger, mNotificationPanelLoggerFake);
|
||||||
mBarService = barService;
|
mBarService = barService;
|
||||||
// Make this on the current thread so we can wait for it during tests.
|
// Make this on the current thread so we can wait for it during tests.
|
||||||
mHandler = Handler.createAsync(Looper.myLooper());
|
mHandler = Handler.createAsync(Looper.myLooper());
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 com.android.systemui.statusbar.notification.logging;
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.nano.Notifications;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NotificationPanelLoggerFake implements NotificationPanelLogger {
|
||||||
|
private List<CallRecord> mCalls = new ArrayList<>();
|
||||||
|
|
||||||
|
List<CallRecord> getCalls() {
|
||||||
|
return mCalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallRecord get(int index) {
|
||||||
|
return mCalls.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logPanelShown(boolean isLockscreen,
|
||||||
|
List<NotificationEntry> visibleNotifications) {
|
||||||
|
mCalls.add(new CallRecord(isLockscreen,
|
||||||
|
NotificationPanelLogger.toNotificationProto(visibleNotifications)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CallRecord {
|
||||||
|
public boolean isLockscreen;
|
||||||
|
public Notifications.NotificationList list;
|
||||||
|
CallRecord(boolean isLockscreen, Notifications.NotificationList list) {
|
||||||
|
this.isLockscreen = isLockscreen;
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -122,6 +122,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
|||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||||
import com.android.systemui.statusbar.notification.init.NotificationsController;
|
import com.android.systemui.statusbar.notification.init.NotificationsController;
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
|
||||||
|
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerFake;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||||
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
|
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
|
||||||
@@ -273,7 +274,7 @@ public class StatusBarTest extends SysuiTestCase {
|
|||||||
mMetricsLogger = new FakeMetricsLogger();
|
mMetricsLogger = new FakeMetricsLogger();
|
||||||
NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener,
|
NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener,
|
||||||
mUiBgExecutor, mock(NotificationEntryManager.class), mStatusBarStateController,
|
mUiBgExecutor, mock(NotificationEntryManager.class), mStatusBarStateController,
|
||||||
mExpansionStateLogger);
|
mExpansionStateLogger, new NotificationPanelLoggerFake());
|
||||||
notificationLogger.setVisibilityReporter(mock(Runnable.class));
|
notificationLogger.setVisibilityReporter(mock(Runnable.class));
|
||||||
|
|
||||||
when(mCommandQueue.asBinder()).thenReturn(new Binder());
|
when(mCommandQueue.asBinder()).thenReturn(new Binder());
|
||||||
|
|||||||
Reference in New Issue
Block a user