summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/notification/NotificationStats.java50
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl2
-rw-r--r--packages/ExtServices/src/android/ext/services/notification/Assistant.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java1
-rw-r--r--services/core/java/com/android/server/notification/NotificationDelegate.java1
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java10
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java4
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java6
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java18
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationStatsTest.java12
11 files changed, 112 insertions, 18 deletions
diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java
index 76d5328d2fc5..9e23de1158de 100644
--- a/core/java/android/service/notification/NotificationStats.java
+++ b/core/java/android/service/notification/NotificationStats.java
@@ -52,7 +52,7 @@ public final class NotificationStats implements Parcelable {
/**
* Notification has not been dismissed yet.
*/
- public static final int DISMISSAL_NOT_DISMISSED = -1;
+ public static final int DISMISSAL_NOT_DISMISSED = -1000;
/**
* Notification has been dismissed from a {@link NotificationListenerService} or the app
* itself.
@@ -71,6 +71,37 @@ public final class NotificationStats implements Parcelable {
*/
public static final int DISMISSAL_SHADE = 3;
+ /** @hide */
+ @IntDef(prefix = { "DISMISS_SENTIMENT_" }, value = {
+ DISMISS_SENTIMENT_UNKNOWN, DISMISS_SENTIMENT_NEGATIVE, DISMISS_SENTIMENT_NEUTRAL,
+ DISMISS_SENTIMENT_POSITIVE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DismissalSentiment {}
+
+ /**
+ * No information is available about why this notification was dismissed, or the notification
+ * isn't dismissed yet.
+ */
+ public static final int DISMISS_SENTIMENT_UNKNOWN = -1000;
+ /**
+ * The user indicated while dismissing that they did not like the notification.
+ */
+ public static final int DISMISS_SENTIMENT_NEGATIVE = 0;
+ /**
+ * The user didn't indicate one way or another how they felt about the notification while
+ * dismissing it.
+ */
+ public static final int DISMISS_SENTIMENT_NEUTRAL = 1;
+ /**
+ * The user indicated while dismissing that they did like the notification.
+ */
+ public static final int DISMISS_SENTIMENT_POSITIVE = 2;
+
+
+ private @DismissalSentiment
+ int mDismissalSentiment = DISMISS_SENTIMENT_UNKNOWN;
+
public NotificationStats() {
}
@@ -82,6 +113,7 @@ public final class NotificationStats implements Parcelable {
mViewedSettings = in.readByte() != 0;
mInteracted = in.readByte() != 0;
mDismissalSurface = in.readInt();
+ mDismissalSentiment = in.readInt();
}
@Override
@@ -93,6 +125,7 @@ public final class NotificationStats implements Parcelable {
dest.writeByte((byte) (mViewedSettings ? 1 : 0));
dest.writeByte((byte) (mInteracted ? 1 : 0));
dest.writeInt(mDismissalSurface);
+ dest.writeInt(mDismissalSentiment);
}
@Override
@@ -212,6 +245,21 @@ public final class NotificationStats implements Parcelable {
mDismissalSurface = dismissalSurface;
}
+ /**
+ * Records whether the user indicated how they felt about a notification before or
+ * during dismissal.
+ */
+ public void setDismissalSentiment(@DismissalSentiment int dismissalSentiment) {
+ mDismissalSentiment = dismissalSentiment;
+ }
+
+ /**
+ * Returns how the user indicated they felt about a notification before or during dismissal.
+ */
+ public @DismissalSentiment int getDismissalSentiment() {
+ return mDismissalSentiment;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index a79e15a0b7e7..b3af147063d0 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -60,7 +60,7 @@ interface IStatusBarService
int uid, int initialPid, String message, int userId);
void onClearAllNotifications(int userId);
void onNotificationClear(String pkg, String tag, int id, int userId, String key,
- int dismissalSurface, in NotificationVisibility nv);
+ int dismissalSurface, int dismissalSentiment, in NotificationVisibility nv);
void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys,
in NotificationVisibility[] noLongerVisibleKeys);
void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded);
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index f0f31fbded6f..3333e1592bfa 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -316,7 +316,7 @@ public class Assistant extends NotificationAssistantService {
saveFile();
}
} catch (Throwable e) {
- Slog.e(TAG, "Error occurred processing removal", e);
+ Slog.e(TAG, "Error occurred processing removal of " + sbn, e);
}
}
@@ -327,17 +327,21 @@ public class Assistant extends NotificationAssistantService {
@Override
public void onNotificationsSeen(List<String> keys) {
- if (keys == null) {
- return;
- }
+ try {
+ if (keys == null) {
+ return;
+ }
- for (String key : keys) {
- NotificationEntry entry = mLiveNotifications.get(key);
+ for (String key : keys) {
+ NotificationEntry entry = mLiveNotifications.get(key);
- if (entry != null) {
- entry.setSeen();
- mAgingHelper.onNotificationSeen(entry);
+ if (entry != null) {
+ entry.setSeen();
+ mAgingHelper.onNotificationSeen(entry);
+ }
}
+ } catch (Throwable e) {
+ Slog.e(TAG, "Error occurred processing seen", e);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 1393f8fed2ff..b655a6bab5b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -414,7 +414,9 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
} else if (mListContainer.hasPulsingNotifications()) {
dismissalSurface = NotificationStats.DISMISSAL_AOD;
}
- mBarService.onNotificationClear(pkg, tag, id, userId, n.getKey(), dismissalSurface, nv);
+ int dismissalSentiment = NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
+ mBarService.onNotificationClear(pkg, tag, id, userId, n.getKey(), dismissalSurface,
+ dismissalSentiment, nv);
removeNotification(n.getKey(), null);
} catch (RemoteException ex) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 094912b2cdc5..67db68deb928 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1307,6 +1307,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
setDismissed(fromAccessibility);
if (isClearable()) {
+ // TODO: track dismiss sentiment
if (mOnDismissRunnable != null) {
mOnDismissRunnable.run();
}
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 8be8450b3413..decdac6cbfce 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -30,6 +30,7 @@ public interface NotificationDelegate {
void onNotificationClear(int callingUid, int callingPid,
String pkg, String tag, int id, int userId, String key,
@NotificationStats.DismissalSurface int dismissalSurface,
+ @NotificationStats.DismissalSentiment int dismissalSentiment,
NotificationVisibility nv);
void onNotificationError(int callingUid, int callingPid,
String pkg, String tag, int id,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 62b35788c2b8..ce71dd2ec9ad 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -700,7 +700,8 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onNotificationClick(int callingUid, int callingPid, String key, NotificationVisibility nv) {
+ public void onNotificationClick(int callingUid, int callingPid, String key,
+ NotificationVisibility nv) {
exitIdle();
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
@@ -757,11 +758,13 @@ public class NotificationManagerService extends SystemService {
public void onNotificationClear(int callingUid, int callingPid,
String pkg, String tag, int id, int userId, String key,
@NotificationStats.DismissalSurface int dismissalSurface,
+ @NotificationStats.DismissalSentiment int dismissalSentiment,
NotificationVisibility nv) {
synchronized (mNotificationLock) {
NotificationRecord r = mNotificationsByKey.get(key);
if (r != null) {
r.recordDismissalSurface(dismissalSurface);
+ r.recordDismissalSentiment(dismissalSentiment);
}
}
cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
@@ -797,8 +800,8 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
- int uid, int initialPid, String message, int userId) {
+ public void onNotificationError(int callingUid, int callingPid, String pkg, String tag,
+ int id, int uid, int initialPid, String message, int userId) {
cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
REASON_ERROR, null);
}
@@ -5966,6 +5969,7 @@ public class NotificationManagerService extends SystemService {
}
notificationList.remove(i);
mNotificationsByKey.remove(r.getKey());
+ r.recordDismissalSentiment(NotificationStats.DISMISS_SENTIMENT_NEUTRAL);
canceledNotifications.add(r);
cancelNotificationLocked(r, sendDelete, reason, wasPosted, listenerName);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index a6d861565080..fbb42ea160da 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -1065,6 +1065,10 @@ public final class NotificationRecord {
mStats.setDismissalSurface(surface);
}
+ public void recordDismissalSentiment(@NotificationStats.DismissalSentiment int sentiment) {
+ mStats.setDismissalSentiment(sentiment);
+ }
+
public void recordSnoozed() {
mStats.setSnoozed();
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index f418ad4bf173..b8c9be777fef 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1053,14 +1053,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
@Override
public void onNotificationClear(String pkg, String tag, int id, int userId, String key,
- @NotificationStats.DismissalSurface int dismissalSurface, NotificationVisibility nv) {
+ @NotificationStats.DismissalSurface int dismissalSurface,
+ @NotificationStats.DismissalSentiment int dismissalSentiment,
+ NotificationVisibility nv) {
enforceStatusBarService();
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
long identity = Binder.clearCallingIdentity();
try {
mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId,
- key, dismissalSurface, nv);
+ key, dismissalSurface, dismissalSentiment, nv);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 4dcb8cf8b327..0ff124e4ce7a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2483,13 +2483,29 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
- r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD, nv);
+ r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
+ NotificationStats.DISMISS_SENTIMENT_POSITIVE, nv);
waitForIdle();
assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface());
}
@Test
+ public void testStats_dismissalSentiment() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addNotification(r);
+
+ final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
+ mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.sbn.getTag(),
+ r.sbn.getId(), r.getUserId(), r.getKey(), NotificationStats.DISMISSAL_AOD,
+ NotificationStats.DISMISS_SENTIMENT_NEGATIVE, nv);
+ waitForIdle();
+
+ assertEquals(NotificationStats.DISMISS_SENTIMENT_NEGATIVE,
+ r.getStats().getDismissalSentiment());
+ }
+
+ @Test
public void testApplyAdjustmentMultiUser() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationStatsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationStatsTest.java
index 0a630f462949..bae8564a0694 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationStatsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationStatsTest.java
@@ -16,6 +16,8 @@
package com.android.server.notification;
import static android.service.notification.NotificationStats.DISMISSAL_PEEK;
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_POSITIVE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -46,6 +48,7 @@ public class NotificationStatsTest extends UiServiceTestCase {
assertFalse(stats.hasViewedSettings());
assertFalse(stats.hasSnoozed());
assertEquals(NotificationStats.DISMISSAL_NOT_DISMISSED, stats.getDismissalSurface());
+ assertEquals(NotificationStats.DISMISS_SENTIMENT_UNKNOWN, stats.getDismissalSentiment());
}
@Test
@@ -97,10 +100,19 @@ public class NotificationStatsTest extends UiServiceTestCase {
}
@Test
+ public void testDismissalSentiment() {
+ NotificationStats stats = new NotificationStats();
+ stats.setDismissalSentiment(DISMISS_SENTIMENT_NEGATIVE);
+ assertEquals(DISMISS_SENTIMENT_NEGATIVE, stats.getDismissalSentiment());
+ assertFalse(stats.hasInteracted());
+ }
+
+ @Test
public void testWriteToParcel() {
NotificationStats stats = new NotificationStats();
stats.setViewedSettings();
stats.setDismissalSurface(NotificationStats.DISMISSAL_AOD);
+ stats.setDismissalSentiment(NotificationStats.DISMISS_SENTIMENT_POSITIVE);
Parcel parcel = Parcel.obtain();
stats.writeToParcel(parcel, 0);
parcel.setDataPosition(0);