summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSantos Cordon <santoscordon@google.com>2015-02-20 07:26:48 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-02-20 07:26:49 +0000
commit27b9706496f9474bc5af4420cb0effedcdcdb341 (patch)
tree8b725b706478af0188587da3fe1d6bd84f4bee04
parentcced281d8268e94c2ebcb66f0819fb6c4dc28dc1 (diff)
parenta9a82f52cbcadd0b9a4aafa0c785c0d6af629f1c (diff)
Merge "Add cache for isVoicemail check."
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java2
-rw-r--r--src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java51
2 files changed, 46 insertions, 7 deletions
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 9c50a3b73..b6f91e75b 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -631,6 +631,8 @@ public class CallLogAdapter extends GroupingListAdapter
/**
* Binds the views in the entry to the data in the call log.
+ * TODO: This gets called 20-30 times when Dialer starts up for a single call log entry and
+ * should not. It invokes cross-process methods and the repeat execution can get costly.
*
* @param callLogItemView the view corresponding to this entry
* @param c the cursor pointing to the entry in the call log
diff --git a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
index 11f4a67f6..6fa81435f 100644
--- a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
+++ b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
@@ -20,13 +20,15 @@ import android.content.Context;
import android.provider.CallLog;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
-import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
import com.android.contacts.common.util.PhoneNumberHelper;
-
import com.google.common.collect.Sets;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
/**
@@ -34,8 +36,20 @@ import java.util.Set;
*/
public class PhoneNumberUtilsWrapper {
private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3");
+ private static final long MAX_VOICEMAIL_CACHE_AGE_IN_MS = 60 * 1000; // 60 seconds
private final Context mContext;
+ // Keeps a cache of recently-made voicemail queries. The entire point of this cache is to
+ // reduce the number of cross-process requests to TelecomManager.
+ // Maps from a phone-account/number pair to a boolean because multiple numbers could return true
+ // for the voicemail number if those numbers are not pre-normalized.
+ //
+ // TODO: Dialer should be fixed so as not to check isVoicemail() so often but at the time of
+ // this writing, that was a much larger undertaking than creating this cache.
+ private final Map<Pair<PhoneAccountHandle, CharSequence>, Boolean> mVoicemailQueryCache =
+ new HashMap<>();
+ private long mVoicemailCacheTimestamp = 0;
+
public PhoneNumberUtilsWrapper(Context context) {
mContext = context;
}
@@ -50,11 +64,34 @@ public class PhoneNumberUtilsWrapper {
* Returns true if the given number is the number of the configured voicemail. To be able to
* mock-out this, it is not a static method.
*/
- public boolean isVoicemailNumber(PhoneAccountHandle accountHandle,
- CharSequence number) {
- final TelecomManager telecomManager =
- (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- return number!= null && telecomManager.isVoiceMailNumber(accountHandle, number.toString());
+ public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) {
+ if (TextUtils.isEmpty(number)) {
+ return false;
+ }
+
+ long currentTime = System.currentTimeMillis();
+ // check the age of the voicemail cache first.
+ if (currentTime - mVoicemailCacheTimestamp > MAX_VOICEMAIL_CACHE_AGE_IN_MS) {
+ mVoicemailQueryCache.clear();
+
+ // We set the timestamp of the voicemail cache to the point where the cache is recreated
+ // instead of when an item is added.
+ // 1) This is easier to write
+ // 2) Ensures that the oldest entry is never older than MAX_VOICEMAIL_CACHE_AGE
+ mVoicemailCacheTimestamp = currentTime;
+ }
+
+ Pair<PhoneAccountHandle, CharSequence> key = new Pair<>(accountHandle, number);
+ if (mVoicemailQueryCache.containsKey(key)) {
+ return mVoicemailQueryCache.get(key);
+ } else {
+ final TelecomManager telecomManager =
+ (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+ Boolean isVoicemail =
+ telecomManager.isVoiceMailNumber(accountHandle, number.toString());
+ mVoicemailQueryCache.put(key, isVoicemail);
+ return isVoicemail;
+ }
}
/**