Fetch contact details as soon as possible.
If we currently do not have contact details available, do not wait one
second since the first redraw to start the thread that fetches the
contact details. Instead, start the thread right away, do reduce the
latency of displaying the contact details.
If, however, we simply want to refresh the content of the existing
cache, keep the delay as before: in that case, there is no particular
hurry.
Change-Id: Iecef7a47f972641bed53d47b7b22dd115410583a
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 9dc50f2..84e6a8a 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -176,8 +176,25 @@
/** Adapter class to fill in data for the Call Log */
public final class CallLogAdapter extends GroupingListAdapter
implements Runnable, ViewTreeObserver.OnPreDrawListener, View.OnClickListener {
+ /** The time in millis to delay starting the thread processing requests. */
+ private static final int START_PROCESSING_REQUESTS_DELAY_MILLIS = 1000;
+
+ /**
+ * A cache of the contact details for the phone numbers in the call log.
+ * <p>
+ * The content of the cache is expired (but not purged) whenever the application comes to
+ * the foreground.
+ */
private ExpirableCache<String, ContactInfo> mContactInfoCache;
+
+ /**
+ * List of requests to update contact details.
+ * <p>
+ * The requests are added when displaying the contacts and are processed by a background
+ * thread.
+ */
private final LinkedList<CallerInfoQuery> mRequests;
+
private volatile boolean mDone;
private boolean mLoading = true;
private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
@@ -220,7 +237,8 @@
@Override
public boolean onPreDraw() {
if (mFirst) {
- mHandler.sendEmptyMessageDelayed(START_THREAD, 1000);
+ mHandler.sendEmptyMessageDelayed(START_THREAD,
+ START_PROCESSING_REQUESTS_DELAY_MILLIS);
mFirst = false;
}
return true;
@@ -234,9 +252,7 @@
notifyDataSetChanged();
break;
case START_THREAD:
- if (!mRequestProcessingDisabled) {
- startRequestProcessing();
- }
+ startRequestProcessing();
break;
}
}
@@ -296,6 +312,10 @@
}
public void startRequestProcessing() {
+ if (mRequestProcessingDisabled) {
+ return;
+ }
+
mDone = false;
mCallerIdThread = new Thread(this);
mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
@@ -346,7 +366,7 @@
}
}
- private void enqueueRequest(String number, int position,
+ private void enqueueRequest(String number, boolean immediate, int position,
String name, int numberType, String numberLabel, long photoId, String lookupKey) {
CallerInfoQuery ciq = new CallerInfoQuery();
ciq.number = number;
@@ -360,6 +380,10 @@
mRequests.add(ciq);
mRequests.notifyAll();
}
+ if (mFirst && immediate) {
+ startRequestProcessing();
+ mFirst = false;
+ }
}
private boolean queryContactInfo(CallerInfoQuery ciq) {
@@ -675,7 +699,8 @@
info = ContactInfo.EMPTY;
mContactInfoCache.put(number, info);
Log.d(TAG, "Contact info missing: " + number);
- enqueueRequest(number, c.getPosition(),
+ // Request the contact details immediately since they are currently missing.
+ enqueueRequest(number, true, c.getPosition(),
callerName, callerNumberType, callerNumberLabel, 0L, "");
} else if (info != ContactInfo.EMPTY) { // Has been queried
// Check if any data is different from the data cached in the
@@ -686,7 +711,8 @@
|| !TextUtils.equals(info.label, callerNumberLabel)) {
// Something is amiss, so sync up.
Log.w(TAG, "Contact info inconsistent: " + number);
- enqueueRequest(number, c.getPosition(),
+ // Request the contact details immediately since they are probably wrong.
+ enqueueRequest(number, true, c.getPosition(),
callerName, callerNumberType, callerNumberLabel, info.photoId,
info.lookupKey);
} else if (cachedInfo.isExpired()) {
@@ -694,8 +720,9 @@
// Put it back in the cache, therefore marking it as not expired, so that other
// entries with the same number will not re-request it.
mContactInfoCache.put(number, info);
- // The contact info is no longer up to date, we should request it.
- enqueueRequest(number, c.getPosition(), info.name, info.type, info.label,
+ // The contact info is no longer up to date, we should request it. However, we
+ // do not need to request them immediately.
+ enqueueRequest(number, false, c.getPosition(), info.name, info.type, info.label,
info.photoId, info.lookupKey);
}
diff --git a/tests/src/com/android/contacts/activities/CallLogActivityTests.java b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
index adc1838..6421a9e 100644
--- a/tests/src/com/android/contacts/activities/CallLogActivityTests.java
+++ b/tests/src/com/android/contacts/activities/CallLogActivityTests.java
@@ -113,6 +113,7 @@
// Do not process requests for details during tests. This would start a background thread,
// which makes the tests flaky.
mAdapter.disableRequestProcessingForTest();
+ mAdapter.stopRequestProcessing();
mParentView = new FrameLayout(mActivity);
mCursor = new MatrixCursor(CALL_LOG_PROJECTION);
buildIconMap();