Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd693784 authored by John Spurlock's avatar John Spurlock Committed by Android (Google) Code Review
Browse files

Merge "Add a hidden system method to check call filter." into lmp-dev

parents 0de79f16 2b122f4c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+13 −0
Original line number Diff line number Diff line
@@ -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;
}
+9 −1
Original line number Diff line number Diff line
@@ -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) {
+11 −0
Original line number Diff line number Diff line
@@ -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++) {
+77 −41
Original line number Diff line number Diff line
@@ -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;
        }
    }
}
Loading