summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2014-08-29 22:17:09 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-29 22:17:10 +0000
commitbd6937841983230bd65dc08548367caa7d409238 (patch)
treec7021170d466d862701a19a29bafc132789205cc
parent0de79f16f3bfe060d25d481d52155d69233864e4 (diff)
parent2b122f4c2e691f0319e4f9ea5873989792bb56a6 (diff)
downloadframeworks_base-bd6937841983230bd65dc08548367caa7d409238.zip
frameworks_base-bd6937841983230bd65dc08548367caa7d409238.tar.gz
frameworks_base-bd6937841983230bd65dc08548367caa7d409238.tar.bz2
Merge "Add a hidden system method to check call filter." into lmp-dev
-rw-r--r--core/java/android/app/INotificationManager.aidl2
-rw-r--r--core/java/android/app/NotificationManager.java13
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java10
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java11
-rw-r--r--services/core/java/com/android/server/notification/ValidateNotificationPeople.java118
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java22
6 files changed, 130 insertions, 46 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index fb28c5d..dbd180f 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -23,6 +23,7 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.net.Uri;
+import android.os.Bundle;
import android.service.notification.Condition;
import android.service.notification.IConditionListener;
import android.service.notification.IConditionProvider;
@@ -66,6 +67,7 @@ interface INotificationManager
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
ComponentName getEffectsSuppressor();
+ boolean matchesCallFilter(in Bundle extras);
ZenModeConfig getZenModeConfig();
boolean setZenModeConfig(in ZenModeConfig config);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index fc047de..7dc1ad6 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -20,6 +20,7 @@ import android.annotation.SdkConstant;
import android.app.Notification.Builder;
import android.content.ComponentName;
import android.content.Context;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -251,5 +252,17 @@ public class NotificationManager
}
}
+ /**
+ * @hide
+ */
+ public boolean matchesCallFilter(Bundle extras) {
+ INotificationManager service = getService();
+ try {
+ return service.matchesCallFilter(extras);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
private Context mContext;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4101232..d0f4054 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -52,6 +52,7 @@ import android.media.AudioManager;
import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -1438,7 +1439,7 @@ public class NotificationManagerService extends SystemService {
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump NotificationManager from from pid="
+ pw.println("Permission Denial: can't dump NotificationManager from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
return;
@@ -1452,6 +1453,13 @@ public class NotificationManagerService extends SystemService {
enforceSystemOrSystemUI("INotificationManager.getEffectsSuppressor");
return mEffectsSuppressor;
}
+
+ @Override
+ public boolean matchesCallFilter(Bundle extras) {
+ enforceSystemOrSystemUI("INotificationManager.matchesCallFilter");
+ return mZenModeHelper.matchesCallFilter(extras,
+ mRankingHelper.findExtractor(ValidateNotificationPeople.class));
+ }
};
private String[] getActiveNotificationKeys(INotificationListener token) {
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 01188af..435177b 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -87,6 +87,17 @@ public class RankingHelper implements RankingConfig {
mProxyByGroupTmp = new ArrayMap<String, NotificationRecord>();
}
+ public <T extends NotificationSignalExtractor> T findExtractor(Class<T> extractorClass) {
+ final int N = mSignalExtractors.length;
+ for (int i = 0; i < N; i++) {
+ final NotificationSignalExtractor extractor = mSignalExtractors[i];
+ if (extractorClass.equals(extractor.getClass())) {
+ return (T) extractor;
+ }
+ }
+ return null;
+ }
+
public void extractSignals(NotificationRecord r) {
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index bdc364c..aa47858 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -71,8 +71,17 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
private LruCache<String, LookupResult> mPeopleCache;
private RankingReconsideration validatePeople(final NotificationRecord record) {
+ final String key = record.getKey();
+ final Bundle extras = record.getNotification().extras;
+ final float[] affinityOut = new float[1];
+ final RankingReconsideration rr = validatePeople(key, extras, affinityOut);
+ record.setContactAffinity(affinityOut[0]);
+ return rr;
+ }
+
+ private PeopleRankingReconsideration validatePeople(String key, Bundle extras,
+ float[] affinityOut) {
float affinity = NONE;
- Bundle extras = record.getNotification().extras;
if (extras == null) {
return null;
}
@@ -82,7 +91,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
return null;
}
- if (INFO) Slog.i(TAG, "Validating: " + record.sbn.getKey());
+ if (INFO) Slog.i(TAG, "Validating: " + key);
final LinkedList<String> pendingLookups = new LinkedList<String>();
for (int personIdx = 0; personIdx < people.length && personIdx < MAX_PEOPLE; personIdx++) {
final String handle = people[personIdx];
@@ -102,51 +111,15 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
}
// record the best available data, so far:
- record.setContactAffinity(affinity);
+ affinityOut[0] = affinity;
if (pendingLookups.isEmpty()) {
if (INFO) Slog.i(TAG, "final affinity: " + affinity);
return null;
}
- if (DEBUG) Slog.d(TAG, "Pending: future work scheduled for: " + record.sbn.getKey());
- return new RankingReconsideration(record.getKey()) {
- float mContactAffinity = NONE;
- @Override
- public void work() {
- if (INFO) Slog.i(TAG, "Executing: validation for: " + record.getKey());
- for (final String handle: pendingLookups) {
- LookupResult lookupResult = null;
- final Uri uri = Uri.parse(handle);
- if ("tel".equals(uri.getScheme())) {
- if (DEBUG) Slog.d(TAG, "checking telephone URI: " + handle);
- lookupResult = resolvePhoneContact(uri.getSchemeSpecificPart());
- } else if ("mailto".equals(uri.getScheme())) {
- if (DEBUG) Slog.d(TAG, "checking mailto URI: " + handle);
- lookupResult = resolveEmailContact(uri.getSchemeSpecificPart());
- } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) {
- if (DEBUG) Slog.d(TAG, "checking lookup URI: " + handle);
- lookupResult = searchContacts(uri);
- } else {
- lookupResult = new LookupResult(); // invalid person for the cache
- Slog.w(TAG, "unsupported URI " + handle);
- }
- if (lookupResult != null) {
- synchronized (mPeopleCache) {
- mPeopleCache.put(handle, lookupResult);
- }
- mContactAffinity = Math.max(mContactAffinity, lookupResult.getAffinity());
- }
- }
- }
-
- @Override
- public void applyChangesLocked(NotificationRecord operand) {
- float affinityBound = operand.getContactAffinity();
- operand.setContactAffinity(Math.max(mContactAffinity, affinityBound));
- if (INFO) Slog.i(TAG, "final affinity: " + operand.getContactAffinity());
- }
- };
+ if (DEBUG) Slog.d(TAG, "Pending: future work scheduled for: " + key);
+ return new PeopleRankingReconsideration(key, pendingLookups);
}
// VisibleForTesting
@@ -269,6 +242,19 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
// ignore: config has no relevant information yet.
}
+ public float getContactAffinity(Bundle extras) {
+ if (extras == null) return NONE;
+ final String key = Long.toString(System.nanoTime());
+ final float[] affinityOut = new float[1];
+ final PeopleRankingReconsideration prr = validatePeople(key, extras, affinityOut);
+ float affinity = affinityOut[0];
+ if (prr != null) {
+ prr.work();
+ affinity = Math.max(prr.getContactAffinity(), affinity);
+ }
+ return affinity;
+ }
+
private static class LookupResult {
private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000; // 1hr
public static final int INVALID_ID = -1;
@@ -328,5 +314,55 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
return this;
}
}
+
+ private class PeopleRankingReconsideration extends RankingReconsideration {
+ private final LinkedList<String> mPendingLookups;
+
+ private float mContactAffinity = NONE;
+
+ private PeopleRankingReconsideration(String key, LinkedList<String> pendingLookups) {
+ super(key);
+ mPendingLookups = pendingLookups;
+ }
+
+ @Override
+ public void work() {
+ if (INFO) Slog.i(TAG, "Executing: validation for: " + mKey);
+ for (final String handle: mPendingLookups) {
+ LookupResult lookupResult = null;
+ final Uri uri = Uri.parse(handle);
+ if ("tel".equals(uri.getScheme())) {
+ if (DEBUG) Slog.d(TAG, "checking telephone URI: " + handle);
+ lookupResult = resolvePhoneContact(uri.getSchemeSpecificPart());
+ } else if ("mailto".equals(uri.getScheme())) {
+ if (DEBUG) Slog.d(TAG, "checking mailto URI: " + handle);
+ lookupResult = resolveEmailContact(uri.getSchemeSpecificPart());
+ } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) {
+ if (DEBUG) Slog.d(TAG, "checking lookup URI: " + handle);
+ lookupResult = searchContacts(uri);
+ } else {
+ lookupResult = new LookupResult(); // invalid person for the cache
+ Slog.w(TAG, "unsupported URI " + handle);
+ }
+ if (lookupResult != null) {
+ synchronized (mPeopleCache) {
+ mPeopleCache.put(handle, lookupResult);
+ }
+ mContactAffinity = Math.max(mContactAffinity, lookupResult.getAffinity());
+ }
+ }
+ }
+
+ @Override
+ public void applyChangesLocked(NotificationRecord operand) {
+ float affinityBound = operand.getContactAffinity();
+ operand.setContactAffinity(Math.max(mContactAffinity, affinityBound));
+ if (INFO) Slog.i(TAG, "final affinity: " + operand.getContactAffinity());
+ }
+
+ public float getContactAffinity() {
+ return mContactAffinity;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 7a5336b..fd35ede 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -34,6 +34,7 @@ import android.database.ContentObserver;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings.Global;
@@ -189,7 +190,7 @@ public class ZenModeHelper {
}
private boolean shouldInterceptAudience(NotificationRecord record) {
- if (!audienceMatches(record)) {
+ if (!audienceMatches(record.getContactAffinity())) {
ZenLog.traceIntercepted(record, "!audienceMatches");
return true;
}
@@ -372,14 +373,27 @@ public class ZenModeHelper {
return record.isCategory(Notification.CATEGORY_MESSAGE) || isDefaultMessagingApp(record);
}
- private boolean audienceMatches(NotificationRecord record) {
+ public boolean matchesCallFilter(Bundle extras, ValidateNotificationPeople validator) {
+ final int zen = mZenMode;
+ if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) return false; // nothing gets through
+ if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
+ if (!mConfig.allowCalls) return false; // no calls get through
+ if (validator != null) {
+ final float contactAffinity = validator.getContactAffinity(extras);
+ return audienceMatches(contactAffinity);
+ }
+ }
+ return true;
+ }
+
+ private boolean audienceMatches(float contactAffinity) {
switch (mConfig.allowFrom) {
case ZenModeConfig.SOURCE_ANYONE:
return true;
case ZenModeConfig.SOURCE_CONTACT:
- return record.getContactAffinity() >= ValidateNotificationPeople.VALID_CONTACT;
+ return contactAffinity >= ValidateNotificationPeople.VALID_CONTACT;
case ZenModeConfig.SOURCE_STAR:
- return record.getContactAffinity() >= ValidateNotificationPeople.STARRED_CONTACT;
+ return contactAffinity >= ValidateNotificationPeople.STARRED_CONTACT;
default:
Slog.w(TAG, "Encountered unknown source: " + mConfig.allowFrom);
return true;