Merge "Do not bundle cross user." into nyc-dev

This commit is contained in:
Julia Reynolds
2016-05-11 17:20:15 +00:00
committed by Android (Google) Code Review
4 changed files with 68 additions and 33 deletions

View File

@@ -37327,7 +37327,7 @@ package android.service.media {
package android.service.notification { package android.service.notification {
public final class Adjustment implements android.os.Parcelable { public final class Adjustment implements android.os.Parcelable {
ctor public Adjustment(java.lang.String, java.lang.String, int, android.os.Bundle, java.lang.CharSequence, android.net.Uri); ctor public Adjustment(java.lang.String, java.lang.String, int, android.os.Bundle, java.lang.CharSequence, android.net.Uri, int);
ctor protected Adjustment(android.os.Parcel); ctor protected Adjustment(android.os.Parcel);
method public int describeContents(); method public int describeContents();
method public java.lang.CharSequence getExplanation(); method public java.lang.CharSequence getExplanation();
@@ -37336,6 +37336,7 @@ package android.service.notification {
method public java.lang.String getPackage(); method public java.lang.String getPackage();
method public android.net.Uri getReference(); method public android.net.Uri getReference();
method public android.os.Bundle getSignals(); method public android.os.Bundle getSignals();
method public int getUser();
method public void writeToParcel(android.os.Parcel, int); method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR; field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
field public static final java.lang.String GROUP_KEY_OVERRIDE_KEY = "group_key_override"; field public static final java.lang.String GROUP_KEY_OVERRIDE_KEY = "group_key_override";

View File

@@ -34,6 +34,7 @@ public final class Adjustment implements Parcelable {
private final CharSequence mExplanation; private final CharSequence mExplanation;
private final Uri mReference; private final Uri mReference;
private final Bundle mSignals; private final Bundle mSignals;
private final int mUser;
public static final String GROUP_KEY_OVERRIDE_KEY = "group_key_override"; public static final String GROUP_KEY_OVERRIDE_KEY = "group_key_override";
public static final String NEEDS_AUTOGROUPING_KEY = "autogroup_needed"; public static final String NEEDS_AUTOGROUPING_KEY = "autogroup_needed";
@@ -52,13 +53,14 @@ public final class Adjustment implements Parcelable {
* or null. * or null.
*/ */
public Adjustment(String pkg, String key, int importance, Bundle signals, public Adjustment(String pkg, String key, int importance, Bundle signals,
CharSequence explanation, Uri reference) { CharSequence explanation, Uri reference, int user) {
mPackage = pkg; mPackage = pkg;
mKey = key; mKey = key;
mImportance = importance; mImportance = importance;
mSignals = signals; mSignals = signals;
mExplanation = explanation; mExplanation = explanation;
mReference = reference; mReference = reference;
mUser = user;
} }
protected Adjustment(Parcel in) { protected Adjustment(Parcel in) {
@@ -80,6 +82,7 @@ public final class Adjustment implements Parcelable {
} }
mReference = in.readParcelable(Uri.class.getClassLoader()); mReference = in.readParcelable(Uri.class.getClassLoader());
mSignals = in.readBundle(); mSignals = in.readBundle();
mUser = in.readInt();
} }
public static final Creator<Adjustment> CREATOR = new Creator<Adjustment>() { public static final Creator<Adjustment> CREATOR = new Creator<Adjustment>() {
@@ -118,6 +121,10 @@ public final class Adjustment implements Parcelable {
return mSignals; return mSignals;
} }
public int getUser() {
return mUser;
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;
@@ -146,5 +153,6 @@ public final class Adjustment implements Parcelable {
} }
dest.writeParcelable(mReference, flags); dest.writeParcelable(mReference, flags);
dest.writeBundle(mSignals); dest.writeBundle(mSignals);
dest.writeInt(mUser);
} }
} }

View File

@@ -19,6 +19,7 @@ package android.ext.services.notification;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.Adjustment; import android.service.notification.Adjustment;
import android.service.notification.NotificationRankerService; import android.service.notification.NotificationRankerService;
import android.service.notification.StatusBarNotification; import android.service.notification.StatusBarNotification;
@@ -43,9 +44,9 @@ public final class Ranker extends NotificationRankerService {
private static final int AUTOBUNDLE_AT_COUNT = 4; private static final int AUTOBUNDLE_AT_COUNT = 4;
private static final String AUTOBUNDLE_KEY = "ranker_bundle"; private static final String AUTOBUNDLE_KEY = "ranker_bundle";
// Map of package : notification keys. Only contains notifications that are not bundled // Map of user : <Map of package : notification keys>. Only contains notifications that are not
// by the app (aka no group or sort key). // bundled by the app (aka no group or sort key).
Map<String, LinkedHashSet<String>> mUnbundledNotifications; Map<Integer, Map<String, LinkedHashSet<String>>> mUnbundledNotifications;
@Override @Override
public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance, public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance,
@@ -63,14 +64,20 @@ public final class Ranker extends NotificationRankerService {
// Not grouped by the app, add to the list of notifications for the app; // Not grouped by the app, add to the list of notifications for the app;
// send bundling update if app exceeds the autobundling limit. // send bundling update if app exceeds the autobundling limit.
synchronized (mUnbundledNotifications) { synchronized (mUnbundledNotifications) {
Map<String, LinkedHashSet<String>> unbundledNotificationsByUser
= mUnbundledNotifications.get(sbn.getUserId());
if (unbundledNotificationsByUser == null) {
unbundledNotificationsByUser = new HashMap<>();
}
mUnbundledNotifications.put(sbn.getUserId(), unbundledNotificationsByUser);
LinkedHashSet<String> notificationsForPackage LinkedHashSet<String> notificationsForPackage
= mUnbundledNotifications.get(sbn.getPackageName()); = unbundledNotificationsByUser.get(sbn.getPackageName());
if (notificationsForPackage == null) { if (notificationsForPackage == null) {
notificationsForPackage = new LinkedHashSet<>(); notificationsForPackage = new LinkedHashSet<>();
} }
notificationsForPackage.add(sbn.getKey()); notificationsForPackage.add(sbn.getKey());
mUnbundledNotifications.put(sbn.getPackageName(), notificationsForPackage); unbundledNotificationsByUser.put(sbn.getPackageName(), notificationsForPackage);
if (notificationsForPackage.size() >= AUTOBUNDLE_AT_COUNT) { if (notificationsForPackage.size() >= AUTOBUNDLE_AT_COUNT) {
for (String key : notificationsForPackage) { for (String key : notificationsForPackage) {
@@ -80,12 +87,13 @@ public final class Ranker extends NotificationRankerService {
} }
if (notificationsToBundle.size() > 0) { if (notificationsToBundle.size() > 0) {
adjustAutobundlingSummary(sbn.getPackageName(), notificationsToBundle.get(0), adjustAutobundlingSummary(sbn.getPackageName(), notificationsToBundle.get(0),
true); true, sbn.getUserId());
adjustNotificationBundling(sbn.getPackageName(), notificationsToBundle, true); adjustNotificationBundling(sbn.getPackageName(), notificationsToBundle, true,
sbn.getUserId());
} }
} else { } else {
// Grouped, but not by us. Send updates to unautobundle, if we bundled it. // Grouped, but not by us. Send updates to unautobundle, if we bundled it.
maybeUnbundle(sbn, false); maybeUnbundle(sbn, false, sbn.getUserId());
} }
} catch (Exception e) { } catch (Exception e) {
Slog.e(TAG, "Failure processing new notification", e); Slog.e(TAG, "Failure processing new notification", e);
@@ -95,7 +103,7 @@ public final class Ranker extends NotificationRankerService {
@Override @Override
public void onNotificationRemoved(StatusBarNotification sbn) { public void onNotificationRemoved(StatusBarNotification sbn) {
try { try {
maybeUnbundle(sbn, true); maybeUnbundle(sbn, true, sbn.getUserId());
} catch (Exception e) { } catch (Exception e) {
Slog.e(TAG, "Error processing canceled notification", e); Slog.e(TAG, "Error processing canceled notification", e);
} }
@@ -106,12 +114,17 @@ public final class Ranker extends NotificationRankerService {
* autobundling if the status change of this notification resulted in the loose notification * autobundling if the status change of this notification resulted in the loose notification
* count being under the limit. * count being under the limit.
*/ */
private void maybeUnbundle(StatusBarNotification sbn, boolean notificationGone) { private void maybeUnbundle(StatusBarNotification sbn, boolean notificationGone, int user) {
List<String> notificationsToUnAutobundle = new ArrayList<>(); List<String> notificationsToUnAutobundle = new ArrayList<>();
boolean removeSummary = false; boolean removeSummary = false;
synchronized (mUnbundledNotifications) { synchronized (mUnbundledNotifications) {
Map<String, LinkedHashSet<String>> unbundledNotificationsByUser
= mUnbundledNotifications.get(sbn.getUserId());
if (unbundledNotificationsByUser == null || unbundledNotificationsByUser.size() == 0) {
return;
}
LinkedHashSet<String> notificationsForPackage LinkedHashSet<String> notificationsForPackage
= mUnbundledNotifications.get(sbn.getPackageName()); = unbundledNotificationsByUser.get(sbn.getPackageName());
if (notificationsForPackage == null || notificationsForPackage.size() == 0) { if (notificationsForPackage == null || notificationsForPackage.size() == 0) {
return; return;
} }
@@ -132,9 +145,10 @@ public final class Ranker extends NotificationRankerService {
} }
if (notificationsToUnAutobundle.size() > 0) { if (notificationsToUnAutobundle.size() > 0) {
if (removeSummary) { if (removeSummary) {
adjustAutobundlingSummary(sbn.getPackageName(), null, false); adjustAutobundlingSummary(sbn.getPackageName(), null, false, user);
} }
adjustNotificationBundling(sbn.getPackageName(), notificationsToUnAutobundle, false); adjustNotificationBundling(sbn.getPackageName(), notificationsToUnAutobundle, false,
user);
} }
} }
@@ -147,7 +161,8 @@ public final class Ranker extends NotificationRankerService {
} }
} }
private void adjustAutobundlingSummary(String packageName, String key, boolean summaryNeeded) { private void adjustAutobundlingSummary(String packageName, String key, boolean summaryNeeded,
int user) {
Bundle signals = new Bundle(); Bundle signals = new Bundle();
if (summaryNeeded) { if (summaryNeeded) {
signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, true); signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, true);
@@ -156,7 +171,8 @@ public final class Ranker extends NotificationRankerService {
signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false); signals.putBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false);
} }
Adjustment adjustment = new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals, Adjustment adjustment = new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals,
getContext().getString(R.string.notification_ranker_autobundle_explanation), null); getContext().getString(R.string.notification_ranker_autobundle_explanation), null,
user);
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "Summary update for: " + packageName + " " Log.i(TAG, "Summary update for: " + packageName + " "
+ (summaryNeeded ? "adding" : "removing")); + (summaryNeeded ? "adding" : "removing"));
@@ -168,10 +184,11 @@ public final class Ranker extends NotificationRankerService {
} }
} }
private void adjustNotificationBundling(String packageName, List<String> keys, boolean bundle) { private void adjustNotificationBundling(String packageName, List<String> keys, boolean bundle,
int user) {
List<Adjustment> adjustments = new ArrayList<>(); List<Adjustment> adjustments = new ArrayList<>();
for (String key : keys) { for (String key : keys) {
adjustments.add(createBundlingAdjustment(packageName, key, bundle)); adjustments.add(createBundlingAdjustment(packageName, key, bundle, user));
if (DEBUG) Log.i(TAG, "Sending bundling adjustment for: " + key); if (DEBUG) Log.i(TAG, "Sending bundling adjustment for: " + key);
} }
try { try {
@@ -181,7 +198,8 @@ public final class Ranker extends NotificationRankerService {
} }
} }
private Adjustment createBundlingAdjustment(String packageName, String key, boolean bundle) { private Adjustment createBundlingAdjustment(String packageName, String key, boolean bundle,
int user) {
Bundle signals = new Bundle(); Bundle signals = new Bundle();
if (bundle) { if (bundle) {
signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, AUTOBUNDLE_KEY); signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, AUTOBUNDLE_KEY);
@@ -189,7 +207,8 @@ public final class Ranker extends NotificationRankerService {
signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, null); signals.putString(Adjustment.GROUP_KEY_OVERRIDE_KEY, null);
} }
return new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals, return new Adjustment(packageName, key, IMPORTANCE_UNSPECIFIED, signals,
getContext().getString(R.string.notification_ranker_autobundle_explanation), null); getContext().getString(R.string.notification_ranker_autobundle_explanation),
null, user);
} }
} }

View File

@@ -265,7 +265,7 @@ public class NotificationManagerService extends SystemService {
new ArrayList<NotificationRecord>(); new ArrayList<NotificationRecord>();
final ArrayMap<String, NotificationRecord> mNotificationsByKey = final ArrayMap<String, NotificationRecord> mNotificationsByKey =
new ArrayMap<String, NotificationRecord>(); new ArrayMap<String, NotificationRecord>();
final ArrayMap<String, String> mAutobundledSummaries = new ArrayMap<>(); final ArrayMap<Integer, ArrayMap<String, String>> mAutobundledSummaries = new ArrayMap<>();
final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>(); final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>();
final ArrayMap<String, NotificationRecord> mSummaryByGroupKey = new ArrayMap<>(); final ArrayMap<String, NotificationRecord> mSummaryByGroupKey = new ArrayMap<>();
final PolicyAccess mPolicyAccess = new PolicyAccess(); final PolicyAccess mPolicyAccess = new PolicyAccess();
@@ -2196,10 +2196,12 @@ public class NotificationManagerService extends SystemService {
Bundle.setDefusable(adjustment.getSignals(), true); Bundle.setDefusable(adjustment.getSignals(), true);
if (adjustment.getSignals().containsKey(Adjustment.NEEDS_AUTOGROUPING_KEY) if (adjustment.getSignals().containsKey(Adjustment.NEEDS_AUTOGROUPING_KEY)
&& !adjustment.getSignals().getBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false)) { && !adjustment.getSignals().getBoolean(Adjustment.NEEDS_AUTOGROUPING_KEY, false)) {
if (mAutobundledSummaries.containsKey(adjustment.getPackage())) { ArrayMap<String, String> summaries =
mAutobundledSummaries.get(adjustment.getUser());
if (summaries != null && summaries.containsKey(adjustment.getPackage())) {
// Clear summary. // Clear summary.
final NotificationRecord removed = mNotificationsByKey.get( final NotificationRecord removed = mNotificationsByKey.get(
mAutobundledSummaries.remove(adjustment.getPackage())); summaries.remove(adjustment.getPackage()));
if (removed != null) { if (removed != null) {
mNotificationList.remove(removed); mNotificationList.remove(removed);
cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED); cancelNotificationLocked(removed, false, REASON_UNAUTOBUNDLED);
@@ -2219,12 +2221,17 @@ public class NotificationManagerService extends SystemService {
int userId = -1; int userId = -1;
NotificationRecord summaryRecord = null; NotificationRecord summaryRecord = null;
synchronized (mNotificationList) { synchronized (mNotificationList) {
if (!mAutobundledSummaries.containsKey(adjustment.getPackage()) final StatusBarNotification adjustedSbn
= mNotificationsByKey.get(adjustment.getKey()).sbn;
userId = adjustedSbn.getUser().getIdentifier();
ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
if (summaries == null) {
summaries = new ArrayMap<>();
}
mAutobundledSummaries.put(userId, summaries);
if (!summaries.containsKey(adjustment.getPackage())
&& newAutoBundleKey != null) { && newAutoBundleKey != null) {
// Add summary // Add summary
final StatusBarNotification adjustedSbn
= mNotificationsByKey.get(adjustment.getKey()).sbn;
final ApplicationInfo appInfo = final ApplicationInfo appInfo =
adjustedSbn.getNotification().extras.getParcelable( adjustedSbn.getNotification().extras.getParcelable(
Notification.EXTRA_BUILDER_APPLICATION_INFO); Notification.EXTRA_BUILDER_APPLICATION_INFO);
@@ -2244,7 +2251,7 @@ public class NotificationManagerService extends SystemService {
if (appIntent != null) { if (appIntent != null) {
summaryNotification.contentIntent = PendingIntent.getActivityAsUser( summaryNotification.contentIntent = PendingIntent.getActivityAsUser(
getContext(), 0, appIntent, 0, null, getContext(), 0, appIntent, 0, null,
UserHandle.of(adjustedSbn.getUserId())); UserHandle.of(userId));
} }
final StatusBarNotification summarySbn = final StatusBarNotification summarySbn =
new StatusBarNotification(adjustedSbn.getPackageName(), new StatusBarNotification(adjustedSbn.getPackageName(),
@@ -2255,8 +2262,7 @@ public class NotificationManagerService extends SystemService {
newAutoBundleKey, newAutoBundleKey,
System.currentTimeMillis()); System.currentTimeMillis());
summaryRecord = new NotificationRecord(getContext(), summarySbn); summaryRecord = new NotificationRecord(getContext(), summarySbn);
mAutobundledSummaries.put(adjustment.getPackage(), summarySbn.getKey()); summaries.put(adjustment.getPackage(), summarySbn.getKey());
userId = adjustedSbn.getUser().getIdentifier();
} }
} }
if (summaryRecord != null) { if (summaryRecord != null) {
@@ -3265,8 +3271,9 @@ public class NotificationManagerService extends SystemService {
if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) { if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
mSummaryByGroupKey.remove(groupKey); mSummaryByGroupKey.remove(groupKey);
} }
if (r.sbn.getKey().equals(mAutobundledSummaries.get(r.sbn.getPackageName()))) { final ArrayMap<String, String> summaries = mAutobundledSummaries.get(r.sbn.getUserId());
mAutobundledSummaries.remove(r.sbn.getPackageName()); if (summaries != null && r.sbn.getKey().equals(summaries.get(r.sbn.getPackageName()))) {
summaries.remove(r.sbn.getPackageName());
} }
// Save it for users of getHistoricalNotifications() // Save it for users of getHistoricalNotifications()