Merge "Eliminate delay before contacts lookup for a Notification" into udc-dev am: e180d3cf1d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21931041 Change-Id: I951d4bb335af27b2785ca4fdc76e88023230b6cf Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -62,7 +62,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
||||||
// Using a shorter log tag since setprop has a limit of 32chars on variable name.
|
// Using a shorter log tag since setprop has a limit of 32chars on variable name.
|
||||||
private static final String TAG = "ValidateNoPeople";
|
private static final String TAG = "ValidateNoPeople";
|
||||||
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);;
|
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
|
||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
private static final boolean ENABLE_PEOPLE_VALIDATOR = true;
|
private static final boolean ENABLE_PEOPLE_VALIDATOR = true;
|
||||||
@@ -105,12 +105,13 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
private int mEvictionCount;
|
private int mEvictionCount;
|
||||||
private NotificationUsageStats mUsageStats;
|
private NotificationUsageStats mUsageStats;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void initialize(Context context, NotificationUsageStats usageStats) {
|
public void initialize(Context context, NotificationUsageStats usageStats) {
|
||||||
if (DEBUG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
|
if (DEBUG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
|
||||||
mUserToContextMap = new ArrayMap<>();
|
mUserToContextMap = new ArrayMap<>();
|
||||||
mBaseContext = context;
|
mBaseContext = context;
|
||||||
mUsageStats = usageStats;
|
mUsageStats = usageStats;
|
||||||
mPeopleCache = new LruCache<String, LookupResult>(PEOPLE_CACHE_SIZE);
|
mPeopleCache = new LruCache<>(PEOPLE_CACHE_SIZE);
|
||||||
mEnabled = ENABLE_PEOPLE_VALIDATOR && 1 == Settings.Global.getInt(
|
mEnabled = ENABLE_PEOPLE_VALIDATOR && 1 == Settings.Global.getInt(
|
||||||
mBaseContext.getContentResolver(), SETTING_ENABLE_PEOPLE_VALIDATOR, 1);
|
mBaseContext.getContentResolver(), SETTING_ENABLE_PEOPLE_VALIDATOR, 1);
|
||||||
if (mEnabled) {
|
if (mEnabled) {
|
||||||
@@ -134,7 +135,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
// For tests: just do the setting of various local variables without actually doing work
|
// For tests: just do the setting of various local variables without actually doing work
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected void initForTests(Context context, NotificationUsageStats usageStats,
|
protected void initForTests(Context context, NotificationUsageStats usageStats,
|
||||||
LruCache peopleCache) {
|
LruCache<String, LookupResult> peopleCache) {
|
||||||
mUserToContextMap = new ArrayMap<>();
|
mUserToContextMap = new ArrayMap<>();
|
||||||
mBaseContext = context;
|
mBaseContext = context;
|
||||||
mUsageStats = usageStats;
|
mUsageStats = usageStats;
|
||||||
@@ -142,6 +143,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public RankingReconsideration process(NotificationRecord record) {
|
public RankingReconsideration process(NotificationRecord record) {
|
||||||
if (!mEnabled) {
|
if (!mEnabled) {
|
||||||
if (VERBOSE) Slog.i(TAG, "disabled");
|
if (VERBOSE) Slog.i(TAG, "disabled");
|
||||||
@@ -272,7 +274,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (VERBOSE) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
|
if (VERBOSE) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
|
||||||
final LinkedList<String> pendingLookups = new LinkedList<String>();
|
final LinkedList<String> pendingLookups = new LinkedList<>();
|
||||||
int personIdx = 0;
|
int personIdx = 0;
|
||||||
for (String handle : people) {
|
for (String handle : people) {
|
||||||
if (TextUtils.isEmpty(handle)) continue;
|
if (TextUtils.isEmpty(handle)) continue;
|
||||||
@@ -320,7 +322,6 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
return Integer.toString(userId) + ":" + handle;
|
return Integer.toString(userId) + ":" + handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VisibleForTesting
|
|
||||||
public static String[] getExtraPeople(Bundle extras) {
|
public static String[] getExtraPeople(Bundle extras) {
|
||||||
String[] peopleList = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE_LIST);
|
String[] peopleList = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE_LIST);
|
||||||
String[] legacyPeople = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE);
|
String[] legacyPeople = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE);
|
||||||
@@ -417,101 +418,6 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LookupResult resolvePhoneContact(Context context, final String number) {
|
|
||||||
Uri phoneUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
|
|
||||||
Uri.encode(number));
|
|
||||||
return searchContacts(context, phoneUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LookupResult resolveEmailContact(Context context, final String email) {
|
|
||||||
Uri numberUri = Uri.withAppendedPath(
|
|
||||||
ContactsContract.CommonDataKinds.Email.CONTENT_LOOKUP_URI,
|
|
||||||
Uri.encode(email));
|
|
||||||
return searchContacts(context, numberUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
LookupResult searchContacts(Context context, Uri lookupUri) {
|
|
||||||
LookupResult lookupResult = new LookupResult();
|
|
||||||
final Uri corpLookupUri =
|
|
||||||
ContactsContract.Contacts.createCorpLookupUriFromEnterpriseLookupUri(lookupUri);
|
|
||||||
if (corpLookupUri == null) {
|
|
||||||
addContacts(lookupResult, context, lookupUri);
|
|
||||||
} else {
|
|
||||||
addWorkContacts(lookupResult, context, corpLookupUri);
|
|
||||||
}
|
|
||||||
return lookupResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
// Performs a contacts search using searchContacts, and then follows up by looking up
|
|
||||||
// any phone numbers associated with the resulting contact information and merge those
|
|
||||||
// into the lookup result as well. Will have no additional effect if the contact does
|
|
||||||
// not have any phone numbers.
|
|
||||||
LookupResult searchContactsAndLookupNumbers(Context context, Uri lookupUri) {
|
|
||||||
LookupResult lookupResult = searchContacts(context, lookupUri);
|
|
||||||
String phoneLookupKey = lookupResult.getPhoneLookupKey();
|
|
||||||
if (phoneLookupKey != null) {
|
|
||||||
String selection = Contacts.LOOKUP_KEY + " = ?";
|
|
||||||
String[] selectionArgs = new String[] { phoneLookupKey };
|
|
||||||
try (Cursor cursor = context.getContentResolver().query(
|
|
||||||
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PHONE_LOOKUP_PROJECTION,
|
|
||||||
selection, selectionArgs, /* sortOrder= */ null)) {
|
|
||||||
if (cursor == null) {
|
|
||||||
Slog.w(TAG, "Cursor is null when querying contact phone number.");
|
|
||||||
return lookupResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
lookupResult.mergePhoneNumber(cursor);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Problem getting content resolver or querying phone numbers.", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lookupResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addWorkContacts(LookupResult lookupResult, Context context, Uri corpLookupUri) {
|
|
||||||
final int workUserId = findWorkUserId(context);
|
|
||||||
if (workUserId == -1) {
|
|
||||||
Slog.w(TAG, "Work profile user ID not found for work contact: " + corpLookupUri);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Uri corpLookupUriWithUserId =
|
|
||||||
ContentProvider.maybeAddUserId(corpLookupUri, workUserId);
|
|
||||||
addContacts(lookupResult, context, corpLookupUriWithUserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the user ID of the managed profile or -1 if none is found. */
|
|
||||||
private int findWorkUserId(Context context) {
|
|
||||||
final UserManager userManager = context.getSystemService(UserManager.class);
|
|
||||||
final int[] profileIds =
|
|
||||||
userManager.getProfileIds(context.getUserId(), /* enabledOnly= */ true);
|
|
||||||
for (int profileId : profileIds) {
|
|
||||||
if (userManager.isManagedProfile(profileId)) {
|
|
||||||
return profileId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Modifies the given lookup result to add contacts found at the given URI. */
|
|
||||||
private void addContacts(LookupResult lookupResult, Context context, Uri uri) {
|
|
||||||
try (Cursor c = context.getContentResolver().query(
|
|
||||||
uri, LOOKUP_PROJECTION, null, null, null)) {
|
|
||||||
if (c == null) {
|
|
||||||
Slog.w(TAG, "Null cursor from contacts query.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
lookupResult.mergeContact(c);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected static class LookupResult {
|
protected static class LookupResult {
|
||||||
private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000; // 1hr
|
private static final long CONTACT_REFRESH_MILLIS = 60 * 60 * 1000; // 1hr
|
||||||
@@ -619,19 +525,18 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PeopleRankingReconsideration extends RankingReconsideration {
|
@VisibleForTesting
|
||||||
|
class PeopleRankingReconsideration extends RankingReconsideration {
|
||||||
private final LinkedList<String> mPendingLookups;
|
private final LinkedList<String> mPendingLookups;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
// Amount of time to wait for a result from the contacts db before rechecking affinity.
|
|
||||||
private static final long LOOKUP_TIME = 1000;
|
|
||||||
private float mContactAffinity = NONE;
|
private float mContactAffinity = NONE;
|
||||||
private ArraySet<String> mPhoneNumbers = null;
|
private ArraySet<String> mPhoneNumbers = null;
|
||||||
private NotificationRecord mRecord;
|
private NotificationRecord mRecord;
|
||||||
|
|
||||||
private PeopleRankingReconsideration(Context context, String key,
|
private PeopleRankingReconsideration(Context context, String key,
|
||||||
LinkedList<String> pendingLookups) {
|
LinkedList<String> pendingLookups) {
|
||||||
super(key, LOOKUP_TIME);
|
super(key);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPendingLookups = pendingLookups;
|
mPendingLookups = pendingLookups;
|
||||||
}
|
}
|
||||||
@@ -642,7 +547,7 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
long timeStartMs = System.currentTimeMillis();
|
long timeStartMs = System.currentTimeMillis();
|
||||||
for (final String handle: mPendingLookups) {
|
for (final String handle: mPendingLookups) {
|
||||||
final String cacheKey = getCacheKey(mContext.getUserId(), handle);
|
final String cacheKey = getCacheKey(mContext.getUserId(), handle);
|
||||||
LookupResult lookupResult = null;
|
LookupResult lookupResult;
|
||||||
boolean cacheHit = false;
|
boolean cacheHit = false;
|
||||||
synchronized (mPeopleCache) {
|
synchronized (mPeopleCache) {
|
||||||
lookupResult = mPeopleCache.get(cacheKey);
|
lookupResult = mPeopleCache.get(cacheKey);
|
||||||
@@ -703,6 +608,102 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static LookupResult resolvePhoneContact(Context context, final String number) {
|
||||||
|
Uri phoneUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
|
||||||
|
Uri.encode(number));
|
||||||
|
return searchContacts(context, phoneUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LookupResult resolveEmailContact(Context context, final String email) {
|
||||||
|
Uri numberUri = Uri.withAppendedPath(
|
||||||
|
ContactsContract.CommonDataKinds.Email.CONTENT_LOOKUP_URI,
|
||||||
|
Uri.encode(email));
|
||||||
|
return searchContacts(context, numberUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static LookupResult searchContacts(Context context, Uri lookupUri) {
|
||||||
|
LookupResult lookupResult = new LookupResult();
|
||||||
|
final Uri corpLookupUri =
|
||||||
|
ContactsContract.Contacts.createCorpLookupUriFromEnterpriseLookupUri(lookupUri);
|
||||||
|
if (corpLookupUri == null) {
|
||||||
|
addContacts(lookupResult, context, lookupUri);
|
||||||
|
} else {
|
||||||
|
addWorkContacts(lookupResult, context, corpLookupUri);
|
||||||
|
}
|
||||||
|
return lookupResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
// Performs a contacts search using searchContacts, and then follows up by looking up
|
||||||
|
// any phone numbers associated with the resulting contact information and merge those
|
||||||
|
// into the lookup result as well. Will have no additional effect if the contact does
|
||||||
|
// not have any phone numbers.
|
||||||
|
static LookupResult searchContactsAndLookupNumbers(Context context, Uri lookupUri) {
|
||||||
|
LookupResult lookupResult = searchContacts(context, lookupUri);
|
||||||
|
String phoneLookupKey = lookupResult.getPhoneLookupKey();
|
||||||
|
if (phoneLookupKey != null) {
|
||||||
|
String selection = Contacts.LOOKUP_KEY + " = ?";
|
||||||
|
String[] selectionArgs = new String[] { phoneLookupKey };
|
||||||
|
try (Cursor cursor = context.getContentResolver().query(
|
||||||
|
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PHONE_LOOKUP_PROJECTION,
|
||||||
|
selection, selectionArgs, /* sortOrder= */ null)) {
|
||||||
|
if (cursor == null) {
|
||||||
|
Slog.w(TAG, "Cursor is null when querying contact phone number.");
|
||||||
|
return lookupResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
lookupResult.mergePhoneNumber(cursor);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Slog.w(TAG, "Problem getting content resolver or querying phone numbers.", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lookupResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addWorkContacts(LookupResult lookupResult, Context context,
|
||||||
|
Uri corpLookupUri) {
|
||||||
|
final int workUserId = findWorkUserId(context);
|
||||||
|
if (workUserId == -1) {
|
||||||
|
Slog.w(TAG, "Work profile user ID not found for work contact: " + corpLookupUri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Uri corpLookupUriWithUserId =
|
||||||
|
ContentProvider.maybeAddUserId(corpLookupUri, workUserId);
|
||||||
|
addContacts(lookupResult, context, corpLookupUriWithUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the user ID of the managed profile or -1 if none is found. */
|
||||||
|
private static int findWorkUserId(Context context) {
|
||||||
|
final UserManager userManager = context.getSystemService(UserManager.class);
|
||||||
|
final int[] profileIds =
|
||||||
|
userManager.getProfileIds(context.getUserId(), /* enabledOnly= */ true);
|
||||||
|
for (int profileId : profileIds) {
|
||||||
|
if (userManager.isManagedProfile(profileId)) {
|
||||||
|
return profileId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Modifies the given lookup result to add contacts found at the given URI. */
|
||||||
|
private static void addContacts(LookupResult lookupResult, Context context, Uri uri) {
|
||||||
|
try (Cursor c = context.getContentResolver().query(
|
||||||
|
uri, LOOKUP_PROJECTION, null, null, null)) {
|
||||||
|
if (c == null) {
|
||||||
|
Slog.w(TAG, "Null cursor from contacts query.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
lookupResult.mergeContact(c);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyChangesLocked(NotificationRecord operand) {
|
public void applyChangesLocked(NotificationRecord operand) {
|
||||||
float affinityBound = operand.getContactAffinity();
|
float affinityBound = operand.getContactAffinity();
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.notification;
|
package com.android.server.notification;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -51,6 +53,8 @@ import android.util.LruCache;
|
|||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.server.UiServiceTestCase;
|
import com.android.server.UiServiceTestCase;
|
||||||
|
import com.android.server.notification.ValidateNotificationPeople.LookupResult;
|
||||||
|
import com.android.server.notification.ValidateNotificationPeople.PeopleRankingReconsideration;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -60,6 +64,7 @@ import org.mockito.stubbing.Answer;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@@ -215,7 +220,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
ContactsContract.Contacts.CONTENT_LOOKUP_URI,
|
ContactsContract.Contacts.CONTENT_LOOKUP_URI,
|
||||||
ContactsContract.Contacts.ENTERPRISE_CONTACT_LOOKUP_PREFIX + contactId);
|
ContactsContract.Contacts.ENTERPRISE_CONTACT_LOOKUP_PREFIX + contactId);
|
||||||
|
|
||||||
new ValidateNotificationPeople().searchContacts(mockContext, lookupUri);
|
PeopleRankingReconsideration.searchContacts(mockContext, lookupUri);
|
||||||
|
|
||||||
ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
|
ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
|
||||||
verify(mockContentResolver).query(
|
verify(mockContentResolver).query(
|
||||||
@@ -242,7 +247,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
final Uri lookupUri = Uri.withAppendedPath(
|
final Uri lookupUri = Uri.withAppendedPath(
|
||||||
ContactsContract.Contacts.CONTENT_LOOKUP_URI, String.valueOf(contactId));
|
ContactsContract.Contacts.CONTENT_LOOKUP_URI, String.valueOf(contactId));
|
||||||
|
|
||||||
new ValidateNotificationPeople().searchContacts(mockContext, lookupUri);
|
PeopleRankingReconsideration.searchContacts(mockContext, lookupUri);
|
||||||
|
|
||||||
ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
|
ArgumentCaptor<Uri> queryUri = ArgumentCaptor.forClass(Uri.class);
|
||||||
verify(mockContentResolver).query(
|
verify(mockContentResolver).query(
|
||||||
@@ -277,7 +282,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
// call searchContacts and then mergePhoneNumbers, make sure we never actually
|
// call searchContacts and then mergePhoneNumbers, make sure we never actually
|
||||||
// query the content resolver for a phone number
|
// query the content resolver for a phone number
|
||||||
new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri);
|
PeopleRankingReconsideration.searchContactsAndLookupNumbers(mockContext, lookupUri);
|
||||||
verify(mockContentResolver, never()).query(
|
verify(mockContentResolver, never()).query(
|
||||||
eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
|
eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
|
||||||
eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
|
eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
|
||||||
@@ -320,7 +325,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
// call searchContacts and then mergePhoneNumbers, and check that we query
|
// call searchContacts and then mergePhoneNumbers, and check that we query
|
||||||
// once for the
|
// once for the
|
||||||
new ValidateNotificationPeople().searchContactsAndLookupNumbers(mockContext, lookupUri);
|
PeopleRankingReconsideration.searchContactsAndLookupNumbers(mockContext, lookupUri);
|
||||||
verify(mockContentResolver, times(1)).query(
|
verify(mockContentResolver, times(1)).query(
|
||||||
eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
|
eq(ContactsContract.CommonDataKinds.Phone.CONTENT_URI),
|
||||||
eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
|
eq(ValidateNotificationPeople.PHONE_LOOKUP_PROJECTION),
|
||||||
@@ -339,7 +344,7 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
// Create validator with empty cache
|
// Create validator with empty cache
|
||||||
ValidateNotificationPeople vnp = new ValidateNotificationPeople();
|
ValidateNotificationPeople vnp = new ValidateNotificationPeople();
|
||||||
LruCache cache = new LruCache<String, ValidateNotificationPeople.LookupResult>(5);
|
LruCache<String, LookupResult> cache = new LruCache<>(5);
|
||||||
vnp.initForTests(mockContext, mockNotificationUsageStats, cache);
|
vnp.initForTests(mockContext, mockNotificationUsageStats, cache);
|
||||||
|
|
||||||
NotificationRecord record = getNotificationRecord();
|
NotificationRecord record = getNotificationRecord();
|
||||||
@@ -366,9 +371,8 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
float affinity = 0.7f;
|
float affinity = 0.7f;
|
||||||
|
|
||||||
// Create a fake LookupResult for the data we'll pass in
|
// Create a fake LookupResult for the data we'll pass in
|
||||||
LruCache cache = new LruCache<String, ValidateNotificationPeople.LookupResult>(5);
|
LruCache<String, LookupResult> cache = new LruCache<>(5);
|
||||||
ValidateNotificationPeople.LookupResult lr =
|
LookupResult lr = mock(LookupResult.class);
|
||||||
mock(ValidateNotificationPeople.LookupResult.class);
|
|
||||||
when(lr.getAffinity()).thenReturn(affinity);
|
when(lr.getAffinity()).thenReturn(affinity);
|
||||||
when(lr.getPhoneNumbers()).thenReturn(new ArraySet<>(new String[]{lookupTel}));
|
when(lr.getPhoneNumbers()).thenReturn(new ArraySet<>(new String[]{lookupTel}));
|
||||||
when(lr.isExpired()).thenReturn(false);
|
when(lr.isExpired()).thenReturn(false);
|
||||||
@@ -392,6 +396,23 @@ public class ValidateNotificationPeopleTest extends UiServiceTestCase {
|
|||||||
assertTrue(record.getPhoneNumbers().contains(lookupTel));
|
assertTrue(record.getPhoneNumbers().contains(lookupTel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validatePeople_reconsiderationWillNotBeDelayed() {
|
||||||
|
final Context mockContext = mock(Context.class);
|
||||||
|
final ContentResolver mockContentResolver = mock(ContentResolver.class);
|
||||||
|
when(mockContext.getContentResolver()).thenReturn(mockContentResolver);
|
||||||
|
ValidateNotificationPeople vnp = new ValidateNotificationPeople();
|
||||||
|
vnp.initForTests(mockContext, mock(NotificationUsageStats.class), new LruCache<>(5));
|
||||||
|
NotificationRecord record = getNotificationRecord();
|
||||||
|
String[] callNumber = new String[]{"tel:12345678910"};
|
||||||
|
setNotificationPeople(record, callNumber);
|
||||||
|
|
||||||
|
RankingReconsideration rr = vnp.validatePeople(mockContext, record);
|
||||||
|
|
||||||
|
assertThat(rr).isNotNull();
|
||||||
|
assertThat(rr.getDelay(TimeUnit.MILLISECONDS)).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a cursor that points to one item of Contacts data with the specified
|
// Creates a cursor that points to one item of Contacts data with the specified
|
||||||
// columns.
|
// columns.
|
||||||
private Cursor makeMockCursor(int id, String lookupKey, int starred, int hasPhone) {
|
private Cursor makeMockCursor(int id, String lookupKey, int starred, int hasPhone) {
|
||||||
|
|||||||
Reference in New Issue
Block a user