Merge "Wait 100 ms for assistant response before posting."
This commit is contained in:
committed by
Android (Google) Code Review
commit
d791bbcf81
@@ -92,6 +92,7 @@ interface INotificationManager
|
||||
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
|
||||
void setInterruptionFilter(String pkg, int interruptionFilter);
|
||||
|
||||
void applyEnqueuedAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
|
||||
void applyAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
|
||||
void applyAdjustmentsFromAssistant(in INotificationListener token, in List<Adjustment> adjustments);
|
||||
void createNotificationChannelFromAssistant(in INotificationListener token, String pkg, in NotificationChannel channel);
|
||||
|
||||
@@ -210,7 +210,14 @@ public abstract class NotificationAssistantService extends NotificationListenerS
|
||||
args.recycle();
|
||||
Adjustment adjustment = onNotificationEnqueued(sbn, importance, user);
|
||||
if (adjustment != null) {
|
||||
adjustNotification(adjustment);
|
||||
if (!isBound()) return;
|
||||
try {
|
||||
getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(
|
||||
mWrapper, adjustment);
|
||||
} catch (android.os.RemoteException ex) {
|
||||
Log.v(TAG, "Unable to contact notification manager", ex);
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/** {@hide} */
|
||||
@@ -225,6 +226,8 @@ public class NotificationManagerService extends SystemService {
|
||||
private static final int EVENTLOG_ENQUEUE_STATUS_IGNORED = 2;
|
||||
private static final long MIN_PACKAGE_OVERRATE_LOG_INTERVAL = 5000; // milliseconds
|
||||
|
||||
private static final long DELAY_FOR_ASSISTANT_TIME = 100;
|
||||
|
||||
private IActivityManager mAm;
|
||||
private IPackageManager mPackageManager;
|
||||
AudioManager mAudioManager;
|
||||
@@ -2363,6 +2366,28 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEnqueuedAdjustmentFromAssistant(INotificationListener token,
|
||||
Adjustment adjustment) throws RemoteException {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mEnqueuedNotifications) {
|
||||
mNotificationAssistants.checkServiceTokenLocked(token);
|
||||
int N = mEnqueuedNotifications.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationRecord n = mEnqueuedNotifications.get(i);
|
||||
if (Objects.equals(adjustment.getKey(), n.getKey())
|
||||
&& Objects.equals(adjustment.getUser(), n.getUserId())) {
|
||||
applyAdjustment(n, adjustment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAdjustmentFromAssistant(INotificationListener token,
|
||||
Adjustment adjustment) throws RemoteException {
|
||||
@@ -2370,7 +2395,8 @@ public class NotificationManagerService extends SystemService {
|
||||
try {
|
||||
synchronized (mNotificationList) {
|
||||
mNotificationAssistants.checkServiceTokenLocked(token);
|
||||
applyAdjustmentLocked(adjustment);
|
||||
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
|
||||
applyAdjustment(n, adjustment);
|
||||
}
|
||||
mRankingHandler.requestSort(true);
|
||||
} finally {
|
||||
@@ -2387,7 +2413,8 @@ public class NotificationManagerService extends SystemService {
|
||||
synchronized (mNotificationList) {
|
||||
mNotificationAssistants.checkServiceTokenLocked(token);
|
||||
for (Adjustment adjustment : adjustments) {
|
||||
applyAdjustmentLocked(adjustment);
|
||||
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
|
||||
applyAdjustment(n, adjustment);
|
||||
}
|
||||
}
|
||||
mRankingHandler.requestSort(true);
|
||||
@@ -2444,8 +2471,7 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
private void applyAdjustmentLocked(Adjustment adjustment) {
|
||||
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
|
||||
private void applyAdjustment(NotificationRecord n, Adjustment adjustment) {
|
||||
if (n == null) {
|
||||
return;
|
||||
}
|
||||
@@ -2653,6 +2679,21 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mEnqueuedNotifications) {
|
||||
if (!zenOnly) {
|
||||
N = mEnqueuedNotifications.size();
|
||||
if (N > 0) {
|
||||
pw.println(" Enqueued Notification List:");
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationRecord nr = mEnqueuedNotifications.get(i);
|
||||
if (filter.filtered && !filter.matches(nr.sbn)) continue;
|
||||
nr.dump(pw, " ", getContext(), filter.redact);
|
||||
}
|
||||
pw.println(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!zenOnly) {
|
||||
pw.println("\n Usage Stats:");
|
||||
mUsageStats.dump(pw, " ", filter);
|
||||
@@ -2880,66 +2921,121 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (mNotificationList) {
|
||||
if (mSnoozeHelper.isSnoozed(userId, r.sbn.getPackageName(), r.getKey())) {
|
||||
// TODO: log to event log
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
|
||||
}
|
||||
mSnoozeHelper.update(userId, r);
|
||||
savePolicyFile();
|
||||
return;
|
||||
synchronized (mNotificationList) {
|
||||
if (mSnoozeHelper.isSnoozed(userId, r.sbn.getPackageName(), r.getKey())) {
|
||||
// TODO: log to event log
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
|
||||
}
|
||||
mSnoozeHelper.update(userId, r);
|
||||
savePolicyFile();
|
||||
return;
|
||||
}
|
||||
|
||||
final StatusBarNotification n = r.sbn;
|
||||
if (DBG) Slog.d(TAG, "EnqueueNotificationRunnable.run for: " + n.getKey());
|
||||
NotificationRecord old = mNotificationsByKey.get(n.getKey());
|
||||
final StatusBarNotification n = r.sbn;
|
||||
if (DBG) Slog.d(TAG, "EnqueueNotificationRunnable.run for: " + n.getKey());
|
||||
NotificationRecord old = mNotificationsByKey.get(n.getKey());
|
||||
if (old != null) {
|
||||
// Retain ranking information from previous record
|
||||
r.copyRankingInformation(old);
|
||||
}
|
||||
|
||||
final int callingUid = n.getUid();
|
||||
final int callingPid = n.getInitialPid();
|
||||
final Notification notification = n.getNotification();
|
||||
final String pkg = n.getPackageName();
|
||||
final int id = n.getId();
|
||||
final String tag = n.getTag();
|
||||
|
||||
// Handle grouped notifications and bail out early if we
|
||||
// can to avoid extracting signals.
|
||||
handleGroupedNotificationLocked(r, old, callingUid, callingPid);
|
||||
|
||||
// This conditional is a dirty hack to limit the logging done on
|
||||
// behalf of the download manager without affecting other apps.
|
||||
if (!pkg.equals("com.android.providers.downloads")
|
||||
|| Log.isLoggable("DownloadManager", Log.VERBOSE)) {
|
||||
int enqueueStatus = EVENTLOG_ENQUEUE_STATUS_NEW;
|
||||
if (old != null) {
|
||||
// Retain ranking information from previous record
|
||||
r.copyRankingInformation(old);
|
||||
enqueueStatus = EVENTLOG_ENQUEUE_STATUS_UPDATE;
|
||||
}
|
||||
EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
|
||||
pkg, id, tag, userId, notification.toString(),
|
||||
enqueueStatus);
|
||||
}
|
||||
|
||||
final int callingUid = n.getUid();
|
||||
final int callingPid = n.getInitialPid();
|
||||
final Notification notification = n.getNotification();
|
||||
final String pkg = n.getPackageName();
|
||||
final int id = n.getId();
|
||||
final String tag = n.getTag();
|
||||
final boolean isSystemNotification = isUidSystem(callingUid) ||
|
||||
("android".equals(pkg));
|
||||
mRankingHelper.extractSignals(r);
|
||||
|
||||
// Handle grouped notifications and bail out early if we
|
||||
// can to avoid extracting signals.
|
||||
handleGroupedNotificationLocked(r, old, callingUid, callingPid);
|
||||
// blocked apps
|
||||
if (isBlocked(r, mUsageStats)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This conditional is a dirty hack to limit the logging done on
|
||||
// behalf of the download manager without affecting other apps.
|
||||
if (!pkg.equals("com.android.providers.downloads")
|
||||
|| Log.isLoggable("DownloadManager", Log.VERBOSE)) {
|
||||
int enqueueStatus = EVENTLOG_ENQUEUE_STATUS_NEW;
|
||||
if (old != null) {
|
||||
enqueueStatus = EVENTLOG_ENQUEUE_STATUS_UPDATE;
|
||||
// tell the assistant service about the notification
|
||||
if (mNotificationAssistants.isEnabled()) {
|
||||
mNotificationAssistants.onNotificationEnqueued(r);
|
||||
mHandler.postDelayed(new PostNotificationRunnable(userId, r.getKey()),
|
||||
DELAY_FOR_ASSISTANT_TIME);
|
||||
} else {
|
||||
mHandler.post(new PostNotificationRunnable(userId, r.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
|
||||
final String pkg = r.sbn.getPackageName();
|
||||
final int callingUid = r.sbn.getUid();
|
||||
|
||||
final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
|
||||
if (isPackageSuspended) {
|
||||
Slog.e(TAG, "Suppressing notification from package due to package "
|
||||
+ "suspended by administrator.");
|
||||
usageStats.registerSuspendedByAdmin(r);
|
||||
return isPackageSuspended;
|
||||
}
|
||||
|
||||
final boolean isBlocked = r.getImportance() == NotificationManager.IMPORTANCE_NONE
|
||||
|| !r.getChannel().isAllowed()
|
||||
|| !noteNotificationOp(pkg, callingUid);
|
||||
if (isBlocked) {
|
||||
Slog.e(TAG, "Suppressing notification from package by user request.");
|
||||
usageStats.registerBlocked(r);
|
||||
}
|
||||
return isBlocked;
|
||||
}
|
||||
}
|
||||
|
||||
protected class PostNotificationRunnable implements Runnable {
|
||||
private final String key;
|
||||
private final int userId;
|
||||
|
||||
PostNotificationRunnable(int userId, String key) {
|
||||
this.userId = userId;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
NotificationRecord r = null;
|
||||
synchronized (mEnqueuedNotifications) {
|
||||
int N = mEnqueuedNotifications.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationRecord enqueued = mEnqueuedNotifications.get(i);
|
||||
if (Objects.equals(key, enqueued.getKey())) {
|
||||
r = enqueued;
|
||||
break;
|
||||
}
|
||||
EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
|
||||
pkg, id, tag, userId, notification.toString(),
|
||||
enqueueStatus);
|
||||
}
|
||||
|
||||
mRankingHelper.extractSignals(r);
|
||||
|
||||
// blocked apps
|
||||
if (isBlocked(r, mUsageStats)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// tell the assistant service about the notification
|
||||
if (mNotificationAssistants.isEnabled()) {
|
||||
mNotificationAssistants.onNotificationEnqueued(r);
|
||||
// TODO delay the code below here for 100ms or until there is an answer
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (r == null) {
|
||||
Slog.e(TAG, "Cannot find enqueued record for key: " + key);
|
||||
return;
|
||||
}
|
||||
synchronized (mNotificationList) {
|
||||
NotificationRecord old = mNotificationsByKey.get(key);
|
||||
final StatusBarNotification n = r.sbn;
|
||||
final Notification notification = n.getNotification();
|
||||
int index = indexOfNotificationLocked(n.getKey());
|
||||
if (index < 0) {
|
||||
mNotificationList.add(r);
|
||||
@@ -2998,32 +3094,17 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
} finally {
|
||||
synchronized (mEnqueuedNotifications) {
|
||||
mEnqueuedNotifications.remove(r);
|
||||
int N = mEnqueuedNotifications.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final NotificationRecord enqueued = mEnqueuedNotifications.get(i);
|
||||
if (Objects.equals(key, enqueued.getKey())) {
|
||||
mEnqueuedNotifications.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
|
||||
final String pkg = r.sbn.getPackageName();
|
||||
final int callingUid = r.sbn.getUid();
|
||||
|
||||
final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
|
||||
if (isPackageSuspended) {
|
||||
Slog.e(TAG, "Suppressing notification from package due to package "
|
||||
+ "suspended by administrator.");
|
||||
usageStats.registerSuspendedByAdmin(r);
|
||||
return isPackageSuspended;
|
||||
}
|
||||
|
||||
final boolean isBlocked = r.getImportance() == NotificationManager.IMPORTANCE_NONE
|
||||
|| !r.getChannel().isAllowed()
|
||||
|| !noteNotificationOp(pkg, callingUid);
|
||||
if (isBlocked) {
|
||||
Slog.e(TAG, "Suppressing notification from package by user request.");
|
||||
usageStats.registerBlocked(r);
|
||||
}
|
||||
return isBlocked;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.provider.Settings;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.SnoozeCriterion;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -318,7 +319,7 @@ public final class NotificationRecord {
|
||||
if (notification.actions != null && notification.actions.length > 0) {
|
||||
pw.println(prefix + " actions={");
|
||||
final int N = notification.actions.length;
|
||||
for (int i=0; i<N; i++) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
final Notification.Action action = notification.actions[i];
|
||||
if (action != null) {
|
||||
pw.println(String.format("%s [%d] \"%s\" -> %s",
|
||||
@@ -350,7 +351,7 @@ public final class NotificationRecord {
|
||||
final int N = Array.getLength(val);
|
||||
pw.print(" (" + N + ")");
|
||||
if (!redact) {
|
||||
for (int j=0; j<N; j++) {
|
||||
for (int j = 0; j < N; j++) {
|
||||
pw.println();
|
||||
pw.print(String.format("%s [%d] %s",
|
||||
prefix, j, String.valueOf(Array.get(val, j))));
|
||||
@@ -385,6 +386,13 @@ public final class NotificationRecord {
|
||||
pw.println(prefix + " mSound= " + mSound);
|
||||
pw.println(prefix + " mVibration= " + mVibration);
|
||||
pw.println(prefix + " mAttributes= " + mAttributes);
|
||||
pw.println(prefix + " overrideChannel=" + getChannel());
|
||||
if (getPeopleOverride() != null) {
|
||||
pw.println(prefix + " overridePeople= " + TextUtils.join(",", getPeopleOverride()));
|
||||
}
|
||||
if (getSnoozeCriteria() != null) {
|
||||
pw.println(prefix + " snoozeCriteria=" + TextUtils.join(",", getSnoozeCriteria()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user