ValidateNotificationPeople.java revision 44d81a4b86f73ecf79861bc576c90b8f8e4ba761
1f953664dc17dca23bd724bd64f89189c16c83263Chris Wren/* 2f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* Copyright (C) 2014 The Android Open Source Project 3f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* 4f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* Licensed under the Apache License, Version 2.0 (the "License"); 5f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* you may not use this file except in compliance with the License. 6f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* You may obtain a copy of the License at 7f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* 8f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* http://www.apache.org/licenses/LICENSE-2.0 9f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* 10f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* Unless required by applicable law or agreed to in writing, software 11f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* distributed under the License is distributed on an "AS IS" BASIS, 12f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* See the License for the specific language governing permissions and 14f953664dc17dca23bd724bd64f89189c16c83263Chris Wren* limitations under the License. 15f953664dc17dca23bd724bd64f89189c16c83263Chris Wren*/ 16f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 17f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenpackage com.android.server.notification; 18f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 19f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.app.Notification; 20f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.content.Context; 21f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.database.Cursor; 22f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.net.Uri; 23f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.os.Bundle; 24f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.provider.ContactsContract; 25f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.provider.ContactsContract.Contacts; 26f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.provider.Settings; 27f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.text.TextUtils; 28f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.util.LruCache; 29f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport android.util.Slog; 30f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 31f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport com.android.server.notification.NotificationManagerService.NotificationRecord; 32f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 33f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport java.util.ArrayList; 34f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenimport java.util.LinkedList; 35f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 36f953664dc17dca23bd724bd64f89189c16c83263Chris Wren/** 37f953664dc17dca23bd724bd64f89189c16c83263Chris Wren * This {@link NotificationSignalExtractor} attempts to validate 38f953664dc17dca23bd724bd64f89189c16c83263Chris Wren * people references. Also elevates the priority of real people. 39f953664dc17dca23bd724bd64f89189c16c83263Chris Wren */ 40f953664dc17dca23bd724bd64f89189c16c83263Chris Wrenpublic class ValidateNotificationPeople implements NotificationSignalExtractor { 41f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final String TAG = "ValidateNotificationPeople"; 42f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final boolean INFO = true; 43f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final boolean DEBUG = false; 44f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 45f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final boolean ENABLE_PEOPLE_VALIDATOR = true; 46f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final String SETTING_ENABLE_PEOPLE_VALIDATOR = 47f953664dc17dca23bd724bd64f89189c16c83263Chris Wren "validate_notification_people_enabled"; 4844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private static final String[] LOOKUP_PROJECTION = { Contacts._ID, Contacts.STARRED }; 49f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final int MAX_PEOPLE = 10; 50f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final int PEOPLE_CACHE_SIZE = 200; 51f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 52f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final float NONE = 0f; 53f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final float VALID_CONTACT = 0.5f; 5444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private static final float STARRED_CONTACT = 1f; 55f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 56f953664dc17dca23bd724bd64f89189c16c83263Chris Wren protected boolean mEnabled; 57f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private Context mContext; 58f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 59f953664dc17dca23bd724bd64f89189c16c83263Chris Wren // maps raw person handle to resolved person object 60f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private LruCache<String, LookupResult> mPeopleCache; 61f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 62f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private RankingFuture validatePeople(NotificationRecord record) { 63f953664dc17dca23bd724bd64f89189c16c83263Chris Wren float affinity = NONE; 64f953664dc17dca23bd724bd64f89189c16c83263Chris Wren Bundle extras = record.getNotification().extras; 65f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (extras == null) { 66f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 67f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 68f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 69f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final String[] people = getExtraPeople(extras); 70f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (people == null || people.length == 0) { 71f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 72f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 73f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 74f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "Validating: " + record.sbn.getKey()); 75f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final LinkedList<String> pendingLookups = new LinkedList<String>(); 76f953664dc17dca23bd724bd64f89189c16c83263Chris Wren for (int personIdx = 0; personIdx < people.length && personIdx < MAX_PEOPLE; personIdx++) { 77f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final String handle = people[personIdx]; 78f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (TextUtils.isEmpty(handle)) continue; 79f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 80f953664dc17dca23bd724bd64f89189c16c83263Chris Wren synchronized (mPeopleCache) { 81f953664dc17dca23bd724bd64f89189c16c83263Chris Wren LookupResult lookupResult = mPeopleCache.get(handle); 82f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (lookupResult == null || lookupResult.isExpired()) { 83f953664dc17dca23bd724bd64f89189c16c83263Chris Wren pendingLookups.add(handle); 84f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } else { 85f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (DEBUG) Slog.d(TAG, "using cached lookupResult: " + lookupResult.mId); 86f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 87f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (lookupResult != null) { 88f953664dc17dca23bd724bd64f89189c16c83263Chris Wren affinity = Math.max(affinity, lookupResult.getAffinity()); 89f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 90f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 91f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 92f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 93f953664dc17dca23bd724bd64f89189c16c83263Chris Wren // record the best available data, so far: 94f953664dc17dca23bd724bd64f89189c16c83263Chris Wren record.setContactAffinity(affinity); 95f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 96f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (pendingLookups.isEmpty()) { 97f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "final affinity: " + affinity); 98f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 99f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 100f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 101f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (DEBUG) Slog.d(TAG, "Pending: future work scheduled for: " + record.sbn.getKey()); 102f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return new RankingFuture(record) { 103f953664dc17dca23bd724bd64f89189c16c83263Chris Wren @Override 104f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public void work() { 105f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "Executing: validation for: " + mRecord.sbn.getKey()); 106f953664dc17dca23bd724bd64f89189c16c83263Chris Wren float affinity = NONE; 107f953664dc17dca23bd724bd64f89189c16c83263Chris Wren for (final String handle: pendingLookups) { 10844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren LookupResult lookupResult = null; 109f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final Uri uri = Uri.parse(handle); 110f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if ("tel".equals(uri.getScheme())) { 111f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (DEBUG) Slog.d(TAG, "checking telephone URI: " + handle); 11244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren lookupResult = resolvePhoneContact(uri.getSchemeSpecificPart()); 11344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } else if ("mailto".equals(uri.getScheme())) { 11444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (DEBUG) Slog.d(TAG, "checking mailto URI: " + handle); 11544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren lookupResult = resolveEmailContact(uri.getSchemeSpecificPart()); 116f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) { 117f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (DEBUG) Slog.d(TAG, "checking lookup URI: " + handle); 11844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren lookupResult = searchContacts(uri); 119f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } else { 12044d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren lookupResult = new LookupResult(); // invalid person for the cache 121f953664dc17dca23bd724bd64f89189c16c83263Chris Wren Slog.w(TAG, "unsupported URI " + handle); 122f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 12344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (lookupResult != null) { 12444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren synchronized (mPeopleCache) { 12544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mPeopleCache.put(handle, lookupResult); 12644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 12744d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren affinity = Math.max(affinity, lookupResult.getAffinity()); 12844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 129f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 130f953664dc17dca23bd724bd64f89189c16c83263Chris Wren float affinityBound = mRecord.getContactAffinity(); 131f953664dc17dca23bd724bd64f89189c16c83263Chris Wren affinity = Math.max(affinity, affinityBound); 132f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mRecord.setContactAffinity(affinity); 133f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "final affinity: " + affinity); 134f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 135f953664dc17dca23bd724bd64f89189c16c83263Chris Wren }; 136f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 137f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 138f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private String[] getExtraPeople(Bundle extras) { 139f953664dc17dca23bd724bd64f89189c16c83263Chris Wren String[] people = extras.getStringArray(Notification.EXTRA_PEOPLE); 140f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (people != null) { 141f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 142f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 143f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 144f953664dc17dca23bd724bd64f89189c16c83263Chris Wren ArrayList<String> stringArray = extras.getStringArrayList(Notification.EXTRA_PEOPLE); 145f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (stringArray != null) { 146f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return (String[]) stringArray.toArray(); 147f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 148f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 149f953664dc17dca23bd724bd64f89189c16c83263Chris Wren String string = extras.getString(Notification.EXTRA_PEOPLE); 150f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (string != null) { 151f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people = new String[1]; 152f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people[0] = string; 153f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 154f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 155f953664dc17dca23bd724bd64f89189c16c83263Chris Wren char[] charArray = extras.getCharArray(Notification.EXTRA_PEOPLE); 156f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (charArray != null) { 157f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people = new String[1]; 158f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people[0] = new String(charArray); 159f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 160f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 161f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 162f953664dc17dca23bd724bd64f89189c16c83263Chris Wren CharSequence charSeq = extras.getCharSequence(Notification.EXTRA_PEOPLE); 163f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (charSeq != null) { 164f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people = new String[1]; 165f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people[0] = charSeq.toString(); 166f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 167f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 168f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 169f953664dc17dca23bd724bd64f89189c16c83263Chris Wren CharSequence[] charSeqArray = extras.getCharSequenceArray(Notification.EXTRA_PEOPLE); 170f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (charSeqArray != null) { 171f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final int N = charSeqArray.length; 172f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people = new String[N]; 173f953664dc17dca23bd724bd64f89189c16c83263Chris Wren for (int i = 0; i < N; i++) { 174f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people[i] = charSeqArray[i].toString(); 175f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 176f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 177f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 178f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 179f953664dc17dca23bd724bd64f89189c16c83263Chris Wren ArrayList<CharSequence> charSeqList = 180f953664dc17dca23bd724bd64f89189c16c83263Chris Wren extras.getCharSequenceArrayList(Notification.EXTRA_PEOPLE); 181f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (charSeqList != null) { 182f953664dc17dca23bd724bd64f89189c16c83263Chris Wren final int N = charSeqList.size(); 183f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people = new String[N]; 184f953664dc17dca23bd724bd64f89189c16c83263Chris Wren for (int i = 0; i < N; i++) { 185f953664dc17dca23bd724bd64f89189c16c83263Chris Wren people[i] = charSeqList.get(i).toString(); 186f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 187f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return people; 188f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 189f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 190f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 191f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 19244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private LookupResult resolvePhoneContact(final String number) { 19344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren Uri phoneUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, 19444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren Uri.encode(number)); 19544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren return searchContacts(phoneUri); 19644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 19744d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren 19844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private LookupResult resolveEmailContact(final String email) { 19944d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren Uri numberUri = Uri.withAppendedPath( 20044d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren ContactsContract.CommonDataKinds.Email.CONTENT_LOOKUP_URI, 20144d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren Uri.encode(email)); 20244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren return searchContacts(numberUri); 203f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 204f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 20544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private LookupResult searchContacts(Uri lookupUri) { 20644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren LookupResult lookupResult = new LookupResult(); 207f953664dc17dca23bd724bd64f89189c16c83263Chris Wren Cursor c = null; 208f953664dc17dca23bd724bd64f89189c16c83263Chris Wren try { 20944d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren c = mContext.getContentResolver().query(lookupUri, LOOKUP_PROJECTION, null, null, null); 210f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (c != null && c.getCount() > 0) { 211f953664dc17dca23bd724bd64f89189c16c83263Chris Wren c.moveToFirst(); 21244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren lookupResult.readContact(c); 213f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 214f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } catch(Throwable t) { 215f953664dc17dca23bd724bd64f89189c16c83263Chris Wren Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t); 216f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } finally { 217f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (c != null) { 218f953664dc17dca23bd724bd64f89189c16c83263Chris Wren c.close(); 219f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 220f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 221f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return lookupResult; 222f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 223f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 224f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public void initialize(Context context) { 225f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (DEBUG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + "."); 226f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mContext = context; 227f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mPeopleCache = new LruCache<String, LookupResult>(PEOPLE_CACHE_SIZE); 228f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mEnabled = ENABLE_PEOPLE_VALIDATOR && 1 == Settings.Global.getInt( 229f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mContext.getContentResolver(), SETTING_ENABLE_PEOPLE_VALIDATOR, 1); 230f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 231f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 232f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public RankingFuture process(NotificationManagerService.NotificationRecord record) { 233f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (!mEnabled) { 234f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "disabled"); 235f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 236f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 237f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (record == null || record.getNotification() == null) { 238f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (INFO) Slog.i(TAG, "skipping empty notification"); 239f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return null; 240f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 241f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return validatePeople(record); 242f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 243f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 244f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static class LookupResult { 245f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000; // 1hr 246f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public static final int INVALID_ID = -1; 247f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 248f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private final long mExpireMillis; 249f953664dc17dca23bd724bd64f89189c16c83263Chris Wren private int mId; 25044d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren private boolean mStarred; 251f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 25244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren public LookupResult() { 25344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mId = INVALID_ID; 25444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mStarred = false; 255f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mExpireMillis = System.currentTimeMillis() + CONTACT_REFRESH_MILLIS; 256f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 257f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 25844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren public void readContact(Cursor cursor) { 25944d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren final int idIdx = cursor.getColumnIndex(Contacts._ID); 26044d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (idIdx >= 0) { 26144d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mId = cursor.getInt(idIdx); 26244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (DEBUG) Slog.d(TAG, "contact _ID is: " + mId); 26344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } else { 26444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (DEBUG) Slog.d(TAG, "invalid cursor: no _ID"); 26544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 26644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren final int starIdx = cursor.getColumnIndex(Contacts.STARRED); 26744d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (starIdx >= 0) { 26844d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mStarred = cursor.getInt(starIdx) != 0; 26944d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (DEBUG) Slog.d(TAG, "contact STARRED is: " + mStarred); 27044d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } else { 27144d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren if (DEBUG) Slog.d(TAG, "invalid cursor: no STARRED"); 27244d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 27344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 27444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren 275f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public boolean isExpired() { 276f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return mExpireMillis < System.currentTimeMillis(); 277f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 278f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 279f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public boolean isInvalid() { 280f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return mId == INVALID_ID || isExpired(); 281f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 282f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 283f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public float getAffinity() { 284f953664dc17dca23bd724bd64f89189c16c83263Chris Wren if (isInvalid()) { 285f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return NONE; 28644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } else if (mStarred) { 28744d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren return STARRED_CONTACT; 288f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } else { 28944d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren return VALID_CONTACT; 290f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 291f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 292f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 29344d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren public LookupResult setStarred(boolean starred) { 29444d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren mStarred = starred; 29544d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren return this; 29644d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren } 29744d81a4b86f73ecf79861bc576c90b8f8e4ba761Chris Wren 298f953664dc17dca23bd724bd64f89189c16c83263Chris Wren public LookupResult setId(int id) { 299f953664dc17dca23bd724bd64f89189c16c83263Chris Wren mId = id; 300f953664dc17dca23bd724bd64f89189c16c83263Chris Wren return this; 301f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 302f953664dc17dca23bd724bd64f89189c16c83263Chris Wren } 303f953664dc17dca23bd724bd64f89189c16c83263Chris Wren} 304f953664dc17dca23bd724bd64f89189c16c83263Chris Wren 305