am bab70c36: Merge "Cache repeated Telecom requests from call log." into mnc-dev

* commit 'bab70c36308ca61950b9b64afe754d9ec2d98b30':
  Cache repeated Telecom requests from call log.
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index b851372..734e78f 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -57,9 +57,9 @@
 import com.android.dialer.calllog.ContactInfoHelper;
 import com.android.dialer.calllog.PhoneAccountUtils;
 import com.android.dialer.calllog.PhoneNumberDisplayUtil;
-import com.android.dialer.calllog.PhoneNumberUtilsWrapper;
-import com.android.dialer.util.IntentUtil;
 import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.IntentUtil;
+import com.android.dialer.util.PhoneNumberUtil;
 import com.android.dialer.util.TelecomUtil;
 
 import java.util.List;
@@ -116,11 +116,10 @@
 
             // Cache the details about the phone number.
             final boolean canPlaceCallsTo =
-                    PhoneNumberUtilsWrapper.canPlaceCallsTo(mNumber, numberPresentation);
-            final PhoneNumberUtilsWrapper phoneUtils = new PhoneNumberUtilsWrapper(mContext);
+                    PhoneNumberUtil.canPlaceCallsTo(mNumber, numberPresentation);
             mIsVoicemailNumber =
-                    phoneUtils.isVoicemailNumber(accountHandle, mNumber);
-            final boolean isSipNumber = PhoneNumberUtilsWrapper.isSipNumber(mNumber);
+                    PhoneNumberUtil.isVoicemailNumber(mContext, accountHandle, mNumber);
+            final boolean isSipNumber = PhoneNumberUtil.isSipNumber(mNumber);
 
             final CharSequence callLocationOrType = getNumberTypeOrLocation(firstDetails);
 
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 2ba257a..bb776d2 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -42,10 +42,10 @@
 
 import com.android.contacts.common.util.PermissionsUtil;
 import com.android.dialer.PhoneCallDetails;
-import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
 import com.android.dialer.contactinfo.ContactInfoCache;
 import com.android.dialer.contactinfo.ContactInfoCache.OnContactInfoChangedListener;
+import com.android.dialer.util.PhoneNumberUtil;
 import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -123,10 +123,11 @@
     private boolean mShowPromoCard = false;
 
     /** Instance of helper class for managing views. */
-    private final CallLogListItemHelper mCallLogViewsHelper;
+    private final CallLogListItemHelper mCallLogListItemHelper;
 
-    /** Helper to access Telephony phone number utils class */
-    protected final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper;
+    /** Cache for repeated requests to TelecomManager. */
+    protected final TelecomCallLogCache mTelecomCallLogCache;
+
     /** Helper to group call log entries. */
     private final CallLogGroupBuilder mCallLogGroupBuilder;
 
@@ -256,10 +257,11 @@
         Resources resources = mContext.getResources();
         CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
 
-        mPhoneNumberUtilsWrapper = new PhoneNumberUtilsWrapper(mContext);
+        mTelecomCallLogCache = new TelecomCallLogCache(mContext);
         PhoneCallDetailsHelper phoneCallDetailsHelper =
-                new PhoneCallDetailsHelper(mContext, resources, mPhoneNumberUtilsWrapper);
-        mCallLogViewsHelper = new CallLogListItemHelper(phoneCallDetailsHelper, resources);
+                new PhoneCallDetailsHelper(mContext, resources, mTelecomCallLogCache);
+        mCallLogListItemHelper =
+                new CallLogListItemHelper(phoneCallDetailsHelper, resources, mTelecomCallLogCache);
         mCallLogGroupBuilder = new CallLogGroupBuilder(this);
         mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
         maybeShowVoicemailPromoCard();
@@ -329,6 +331,7 @@
 
     public void pauseCache() {
         mContactInfoCache.stop();
+        mTelecomCallLogCache.reset();
     }
 
     @Override
@@ -359,8 +362,8 @@
                 view,
                 mContext,
                 mExpandCollapseListener,
-                mPhoneNumberUtilsWrapper,
-                mCallLogViewsHelper,
+                mTelecomCallLogCache,
+                mCallLogListItemHelper,
                 mVoicemailPlaybackPresenter);
 
         viewHolder.callLogEntryView.setTag(viewHolder);
@@ -432,14 +435,13 @@
         final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
         final ContactInfo cachedContactInfo = mContactInfoHelper.getContactInfo(c);
         final boolean isVoicemailNumber =
-                mPhoneNumberUtilsWrapper.isVoicemailNumber(accountHandle, number);
+                mTelecomCallLogCache.isVoicemailNumber(accountHandle, number);
 
         // Note: Binding of the action buttons is done as required in configureActionViews when the
         // user expands the actions ViewStub.
 
         ContactInfo info = ContactInfo.EMPTY;
-        if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)
-                && !isVoicemailNumber) {
+        if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemailNumber) {
             // Lookup contacts with this number
             info = mContactInfoCache.getValue(number, countryIso, cachedContactInfo);
         }
@@ -499,7 +501,7 @@
             views.dayGroupHeader.setVisibility(View.GONE);
         }
 
-        mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details);
+        mCallLogListItemHelper.setPhoneCallDetails(views, details);
 
         if (mCurrentlyExpandedRowId == views.rowId) {
             // In case ViewHolders were added/removed, update the expanded position if the rowIds
@@ -522,7 +524,7 @@
         views.setPhoto(info.photoId, info.photoUri, info.lookupUri, nameForDefaultImage,
                 isVoicemailNumber, mContactInfoHelper.isBusiness(info.sourceType));
 
-        mCallLogViewsHelper.setPhoneCallDetails(mContext, views, details);
+        mCallLogListItemHelper.setPhoneCallDetails(views, details);
 
         // Listen for the first draw
         if (mViewTreeObserver == null) {
diff --git a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
index 812e1a7..1becc89 100644
--- a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
+++ b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java
@@ -32,6 +32,7 @@
 import com.android.dialer.PhoneCallDetails;
 import com.android.dialer.util.AsyncTaskExecutor;
 import com.android.dialer.util.AsyncTaskExecutors;
+import com.android.dialer.util.PhoneNumberUtil;
 import com.android.dialer.util.TelecomUtil;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -151,12 +152,9 @@
             // If this is not a regular number, there is no point in looking it up in the contacts.
             ContactInfoHelper contactInfoHelper =
                     new ContactInfoHelper(context, GeoUtil.getCurrentCountryIso(context));
-            PhoneNumberUtilsWrapper phoneNumberUtilsWrapper =
-                    new PhoneNumberUtilsWrapper(context);
-            boolean isVoicemail = phoneNumberUtilsWrapper.isVoicemailNumber(accountHandle, number);
+            boolean isVoicemail = PhoneNumberUtil.isVoicemailNumber(context, accountHandle, number);
             boolean shouldLookupNumber =
-                    PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)
-                            && !isVoicemail;
+                    PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemail;
             ContactInfo info = shouldLookupNumber
                             ? contactInfoHelper.lookupNumber(number, countryIso)
                             : ContactInfo.EMPTY;
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index d088107..1c8e397 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -24,7 +24,6 @@
 import android.util.Log;
 
 import com.android.dialer.PhoneCallDetails;
-import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
 
 /**
@@ -37,6 +36,7 @@
     private final PhoneCallDetailsHelper mPhoneCallDetailsHelper;
     /** Resources to look up strings. */
     private final Resources mResources;
+    private final TelecomCallLogCache mTelecomCallLogCache;
 
     /**
      * Creates a new helper instance.
@@ -45,9 +45,12 @@
      * @param phoneNumberHelper used to process phone number
      */
     public CallLogListItemHelper(
-            PhoneCallDetailsHelper phoneCallDetailsHelper, Resources resources) {
+            PhoneCallDetailsHelper phoneCallDetailsHelper,
+            Resources resources,
+            TelecomCallLogCache telecomCallLogCache) {
         mPhoneCallDetailsHelper = phoneCallDetailsHelper;
         mResources = resources;
+        mTelecomCallLogCache = telecomCallLogCache;
     }
 
     /**
@@ -58,14 +61,15 @@
      * @param details the details of a phone call needed to fill in the data
      */
     public void setPhoneCallDetails(
-            Context context, CallLogListItemViewHolder views, PhoneCallDetails details) {
+            CallLogListItemViewHolder views,
+            PhoneCallDetails details) {
         mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details);
 
         // Set the accessibility text for the contact badge
         views.quickContactView.setContentDescription(getContactBadgeDescription(details));
 
         // Set the primary action accessibility description
-        views.primaryActionView.setContentDescription(getCallDescription(context, details));
+        views.primaryActionView.setContentDescription(getCallDescription(details));
 
         // Cache name or number of caller.  Used when setting the content descriptions of buttons
         // when the actions ViewStub is inflated.
@@ -151,7 +155,7 @@
      * @param details Details of call.
      * @return Return call action description.
      */
-    public CharSequence getCallDescription(Context context, PhoneCallDetails details) {
+    public CharSequence getCallDescription(PhoneCallDetails details) {
         int lastCallType = getLastCallType(details.callTypes);
         boolean isVoiceMail = lastCallType == Calls.VOICEMAIL_TYPE;
 
@@ -183,7 +187,7 @@
         }
 
         int stringID = getCallDescriptionStringID(details.callTypes);
-        String accountLabel = PhoneAccountUtils.getAccountLabel(context, details.accountHandle);
+        String accountLabel = mTelecomCallLogCache.getAccountLabel(details.accountHandle);
 
         // Use chosen string resource to build up the message.
         CharSequence onAccountLabel = accountLabel == null
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index f54720b..361e1c7 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -39,11 +39,10 @@
 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.contacts.common.util.UriUtils;
-import com.android.dialer.PhoneCallDetailsHelper;
-import com.android.dialer.PhoneCallDetailsViews;
 import com.android.dialer.R;
 import com.android.dialer.calllog.CallLogAsyncTaskUtil;
 import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.PhoneNumberUtil;
 import com.android.dialer.voicemail.VoicemailPlaybackPresenter;
 import com.android.dialer.voicemail.VoicemailPlaybackLayout;
 
@@ -139,7 +138,7 @@
     private static final int VOICEMAIL_TRANSCRIPTION_MAX_LINES = 10;
 
     private final Context mContext;
-    private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper;
+    private final TelecomCallLogCache mTelecomCallLogCache;
     private final CallLogListItemHelper mCallLogListItemHelper;
     private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter;
 
@@ -151,7 +150,7 @@
     private CallLogListItemViewHolder(
             Context context,
             View.OnClickListener expandCollapseListener,
-            PhoneNumberUtilsWrapper phoneNumberUtilsWrapper,
+            TelecomCallLogCache telecomCallLogCache,
             CallLogListItemHelper callLogListItemHelper,
             VoicemailPlaybackPresenter voicemailPlaybackPresenter,
             View rootView,
@@ -165,7 +164,7 @@
 
         mContext = context;
         mExpandCollapseListener = expandCollapseListener;
-        mPhoneNumberUtilsWrapper = phoneNumberUtilsWrapper;
+        mTelecomCallLogCache = telecomCallLogCache;
         mCallLogListItemHelper = callLogListItemHelper;
         mVoicemailPlaybackPresenter = voicemailPlaybackPresenter;
 
@@ -194,14 +193,14 @@
             View view,
             Context context,
             View.OnClickListener expandCollapseListener,
-            PhoneNumberUtilsWrapper phoneNumberUtilsWrapper,
+            TelecomCallLogCache telecomCallLogCache,
             CallLogListItemHelper callLogListItemHelper,
             VoicemailPlaybackPresenter voicemailPlaybackPresenter) {
 
         return new CallLogListItemViewHolder(
                 context,
                 expandCollapseListener,
-                phoneNumberUtilsWrapper,
+                telecomCallLogCache,
                 callLogListItemHelper,
                 voicemailPlaybackPresenter,
                 view,
@@ -263,11 +262,11 @@
         } else {
             // Treat as normal list item; show call button, if possible.
             boolean canPlaceCallToNumber =
-                    PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation);
+                    PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation);
 
             if (canPlaceCallToNumber) {
                 boolean isVoicemailNumber =
-                        mPhoneNumberUtilsWrapper.isVoicemailNumber(accountHandle, number);
+                        mTelecomCallLogCache.isVoicemailNumber(accountHandle, number);
                 if (isVoicemailNumber) {
                     // Call to generic voicemail number, in case there are multiple accounts.
                     primaryActionButtonView.setTag(
@@ -294,8 +293,7 @@
      * buttons.
      */
     private void bindActionButtons() {
-        boolean canPlaceCallToNumber =
-                PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation);
+        boolean canPlaceCallToNumber = PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation);
 
         if (!TextUtils.isEmpty(voicemailUri) && canPlaceCallToNumber) {
             callButtonView.setTag(IntentProvider.getReturnCallIntentProvider(number));
@@ -309,7 +307,7 @@
         }
 
         // If one of the calls had video capabilities, show the video call button.
-        if (CallUtil.isVideoEnabled(mContext) && canPlaceCallToNumber &&
+        if (mTelecomCallLogCache.isVideoEnabled() && canPlaceCallToNumber &&
                 phoneCallDetailsViews.callTypeIcons.isVideoShown()) {
             videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number));
             videoCallButtonView.setVisibility(View.VISIBLE);
@@ -440,15 +438,15 @@
     @NeededForTesting
     public static CallLogListItemViewHolder createForTest(Context context) {
         Resources resources = context.getResources();
-        PhoneNumberUtilsWrapper phoneNumberUtilsWrapper = new PhoneNumberUtilsWrapper(context);
+        TelecomCallLogCache telecomCallLogCache = new TelecomCallLogCache(context);
         PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
-                context, resources, phoneNumberUtilsWrapper);
+                context, resources, telecomCallLogCache);
 
         CallLogListItemViewHolder viewHolder = new CallLogListItemViewHolder(
                 context,
                 null /* expandCollapseListener */,
-                phoneNumberUtilsWrapper,
-                new CallLogListItemHelper(phoneCallDetailsHelper, resources),
+                telecomCallLogCache,
+                new CallLogListItemHelper(phoneCallDetailsHelper, resources, telecomCallLogCache),
                 null /* voicemailPlaybackPresenter */,
                 new View(context),
                 new QuickContactBadge(context),
diff --git a/src/com/android/dialer/calllog/PhoneAccountUtils.java b/src/com/android/dialer/calllog/PhoneAccountUtils.java
index d63b940..7eaa523 100644
--- a/src/com/android/dialer/calllog/PhoneAccountUtils.java
+++ b/src/com/android/dialer/calllog/PhoneAccountUtils.java
@@ -27,7 +27,7 @@
 import java.util.List;
 
 /**
- * Methods to help extract {@code PhoneAccount} information from database and Telecomm sources
+ * Methods to help extract {@code PhoneAccount} information from database and Telecomm sources.
  */
 public class PhoneAccountUtils {
     /**
@@ -87,7 +87,7 @@
      * Retrieve the account metadata, but if the account does not exist or the device has only a
      * single registered and enabled account, return null.
      */
-    private static PhoneAccount getAccountOrNull(Context context,
+     static PhoneAccount getAccountOrNull(Context context,
             PhoneAccountHandle accountHandle) {
         TelecomManager telecomManager =
                 (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
diff --git a/src/com/android/dialer/PhoneCallDetailsHelper.java b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
similarity index 93%
rename from src/com/android/dialer/PhoneCallDetailsHelper.java
rename to src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
index 2dc0810..df5fe06 100644
--- a/src/com/android/dialer/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.dialer;
+package com.android.dialer.calllog;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -31,10 +31,10 @@
 
 import com.android.contacts.common.testing.NeededForTesting;
 import com.android.contacts.common.util.PhoneNumberHelper;
-import com.android.dialer.calllog.ContactInfo;
-import com.android.dialer.calllog.PhoneAccountUtils;
-import com.android.dialer.calllog.PhoneNumberUtilsWrapper;
+import com.android.dialer.PhoneCallDetails;
+import com.android.dialer.R;
 import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.PhoneNumberUtil;
 
 import com.google.common.collect.Lists;
 
@@ -51,8 +51,7 @@
     private final Resources mResources;
     /** The injected current time in milliseconds since the epoch. Used only by tests. */
     private Long mCurrentTimeMillisForTest;
-    // Helper classes.
-    private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper;
+    private final TelecomCallLogCache mTelecomCallLogCache;
 
     /**
      * List of items to be concatenated together for accessibility descriptions
@@ -66,11 +65,13 @@
      *
      * @param resources used to look up strings
      */
-    public PhoneCallDetailsHelper(Context context, Resources resources,
-            PhoneNumberUtilsWrapper phoneUtils) {
+    public PhoneCallDetailsHelper(
+            Context context,
+            Resources resources,
+            TelecomCallLogCache telecomCallLogCache) {
         mContext = context;
         mResources = resources;
-        mPhoneNumberUtilsWrapper = phoneUtils;
+        mTelecomCallLogCache = telecomCallLogCache;
     }
 
     /** Fills the call details views with content. */
@@ -106,7 +107,7 @@
         setCallCountAndDate(views, callCount, callLocationAndDate);
 
         // Set the account label if it exists.
-        String accountLabel = PhoneAccountUtils.getAccountLabel(mContext, details.accountHandle);
+        String accountLabel = mTelecomCallLogCache.getAccountLabel(details.accountHandle);
 
         if (accountLabel != null) {
             views.callAccountLabel.setVisibility(View.VISIBLE);
@@ -185,8 +186,7 @@
         // Only show a label if the number is shown and it is not a SIP address.
         if (!TextUtils.isEmpty(details.number)
                 && !PhoneNumberHelper.isUriNumber(details.number.toString())
-                && !mPhoneNumberUtilsWrapper.isVoicemailNumber(details.accountHandle,
-                        details.number)) {
+                && !mTelecomCallLogCache.isVoicemailNumber(details.accountHandle, details.number)) {
 
             if (TextUtils.isEmpty(details.name) && !TextUtils.isEmpty(details.geocode)) {
                 numberFormattedLabel = details.geocode;
diff --git a/src/com/android/dialer/PhoneCallDetailsViews.java b/src/com/android/dialer/calllog/PhoneCallDetailsViews.java
similarity index 96%
rename from src/com/android/dialer/PhoneCallDetailsViews.java
rename to src/com/android/dialer/calllog/PhoneCallDetailsViews.java
index 05026d6..94f4411 100644
--- a/src/com/android/dialer/PhoneCallDetailsViews.java
+++ b/src/com/android/dialer/calllog/PhoneCallDetailsViews.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.dialer;
+package com.android.dialer.calllog;
 
 import android.content.Context;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.dialer.calllog.CallTypeIconsView;
+import com.android.dialer.R;
 
 /**
  * Encapsulates the views that are used to display the details of a phone call in the call log.
diff --git a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
index f80c2bc..5030efd 100644
--- a/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
+++ b/src/com/android/dialer/calllog/PhoneNumberDisplayUtil.java
@@ -23,6 +23,7 @@
 import android.util.Log;
 
 import com.android.dialer.R;
+import com.android.dialer.util.PhoneNumberUtil;
 
 /**
  * Helper for formatting and managing the display of phone numbers.
@@ -49,7 +50,7 @@
         if (isVoicemail) {
             return context.getResources().getString(R.string.voicemail);
         }
-        if (PhoneNumberUtilsWrapper.isLegacyUnknownNumbers(number)) {
+        if (PhoneNumberUtil.isLegacyUnknownNumbers(number)) {
             return context.getResources().getString(R.string.unknown);
         }
         return "";
diff --git a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
deleted file mode 100644
index 6fa8143..0000000
--- a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.dialer.calllog;
-
-import android.content.Context;
-import android.provider.CallLog;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-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;
-
-/**
- *
- */
-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;
-    }
-
-    /** Returns true if it is possible to place a call to the given number. */
-    public static boolean canPlaceCallsTo(CharSequence number, int presentation) {
-        return presentation == CallLog.Calls.PRESENTATION_ALLOWED
-            && !TextUtils.isEmpty(number) && !isLegacyUnknownNumbers(number);
-    }
-
-    /**
-     * 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) {
-        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;
-        }
-    }
-
-    /**
-     * Returns true if the given number is a SIP address. To be able to mock-out this, it is not a
-     * static method.
-     */
-    public static boolean isSipNumber(CharSequence number) {
-        return number != null && PhoneNumberHelper.isUriNumber(number.toString());
-    }
-
-    public boolean isUnknownNumberThatCanBeLookedUp(PhoneAccountHandle accountHandle,
-            CharSequence number, int presentation) {
-        if (presentation == CallLog.Calls.PRESENTATION_UNKNOWN) {
-            return false;
-        }
-        if (presentation == CallLog.Calls.PRESENTATION_RESTRICTED) {
-            return false;
-        }
-        if (presentation == CallLog.Calls.PRESENTATION_PAYPHONE) {
-            return false;
-        }
-        if (TextUtils.isEmpty(number)) {
-            return false;
-        }
-        if (isVoicemailNumber(accountHandle, number)) {
-            return false;
-        }
-        if (isLegacyUnknownNumbers(number)) {
-            return false;
-        }
-        return true;
-    }
-
-    public static boolean isLegacyUnknownNumbers(CharSequence number) {
-        return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString());
-    }
-}
diff --git a/src/com/android/dialer/calllog/TelecomCallLogCache.java b/src/com/android/dialer/calllog/TelecomCallLogCache.java
new file mode 100644
index 0000000..ec1d241
--- /dev/null
+++ b/src/com/android/dialer/calllog/TelecomCallLogCache.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.calllog;
+
+import android.content.Context;
+import android.provider.CallLog;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.util.PhoneNumberHelper;
+import com.android.dialer.util.PhoneNumberUtil;
+import com.google.common.collect.Sets;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Keeps a cache of recently made queries to the Telecom process. The aim of this cache is to
+ * reduce the number of cross-process requests to TelecomManager, which can negatively affect
+ * performance.
+ *
+ * This is designed with the specific use case of the {@link CallLogAdapter} in mind.
+ */
+public class TelecomCallLogCache {
+    private final Context mContext;
+
+    // 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 final Map<PhoneAccountHandle, String> mPhoneAccountLabelCache = new HashMap<>();
+    private final Map<PhoneAccountHandle, Integer> mPhoneAccountColorCache = new HashMap<>();
+
+    private boolean mHasCheckedForVideoEnabled;
+    private boolean mIsVideoEnabled;
+
+    public TelecomCallLogCache(Context context) {
+        mContext = context;
+    }
+
+    public void reset() {
+        mVoicemailQueryCache.clear();
+        mPhoneAccountLabelCache.clear();
+        mPhoneAccountColorCache.clear();
+
+        mHasCheckedForVideoEnabled = false;
+        mIsVideoEnabled = false;
+    }
+
+    /**
+     * 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) {
+        if (TextUtils.isEmpty(number)) {
+            return false;
+        }
+
+        Pair<PhoneAccountHandle, CharSequence> key = new Pair<>(accountHandle, number);
+        if (mVoicemailQueryCache.containsKey(key)) {
+            return mVoicemailQueryCache.get(key);
+        } else {
+            Boolean isVoicemail =
+                    PhoneNumberUtil.isVoicemailNumber(mContext, accountHandle, number.toString());
+            mVoicemailQueryCache.put(key, isVoicemail);
+            return isVoicemail;
+        }
+    }
+
+    /**
+     * Extract account label from PhoneAccount object.
+     */
+    public String getAccountLabel(PhoneAccountHandle accountHandle) {
+        if (mPhoneAccountLabelCache.containsKey(accountHandle)) {
+            return mPhoneAccountLabelCache.get(accountHandle);
+        } else {
+            String label = PhoneAccountUtils.getAccountLabel(mContext, accountHandle);
+            mPhoneAccountLabelCache.put(accountHandle, label);
+            return label;
+        }
+    }
+
+    /**
+     * Extract account color from PhoneAccount object.
+     */
+    public int getAccountColor(PhoneAccountHandle accountHandle) {
+        if (mPhoneAccountColorCache.containsKey(accountHandle)) {
+            return mPhoneAccountColorCache.get(accountHandle);
+        } else {
+            Integer color = PhoneAccountUtils.getAccountColor(mContext, accountHandle);
+            mPhoneAccountColorCache.put(accountHandle, color);
+            return color;
+        }
+    }
+
+    public boolean isVideoEnabled() {
+        if (!mHasCheckedForVideoEnabled) {
+            mIsVideoEnabled = CallUtil.isVideoEnabled(mContext);
+        }
+        return mIsVideoEnabled;
+    }
+}
diff --git a/src/com/android/dialer/util/PhoneNumberUtil.java b/src/com/android/dialer/util/PhoneNumberUtil.java
new file mode 100644
index 0000000..84f58aa
--- /dev/null
+++ b/src/com/android/dialer/util/PhoneNumberUtil.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.util;
+
+import android.content.Context;
+import android.provider.CallLog;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+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;
+
+public class PhoneNumberUtil {
+    private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3");
+
+    /** Returns true if it is possible to place a call to the given number. */
+    public static boolean canPlaceCallsTo(CharSequence number, int presentation) {
+        return presentation == CallLog.Calls.PRESENTATION_ALLOWED
+            && !TextUtils.isEmpty(number) && !isLegacyUnknownNumbers(number);
+    }
+
+    /**
+     * 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 static boolean isVoicemailNumber(
+            Context context, PhoneAccountHandle accountHandle, CharSequence number) {
+        if (TextUtils.isEmpty(number)) {
+            return false;
+        }
+
+        final TelecomManager telecomManager =
+                (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+        return telecomManager.isVoiceMailNumber(accountHandle, number.toString());
+    }
+
+    /**
+     * Returns true if the given number is a SIP address. To be able to mock-out this, it is not a
+     * static method.
+     */
+    public static boolean isSipNumber(CharSequence number) {
+        return number != null && PhoneNumberHelper.isUriNumber(number.toString());
+    }
+
+    public static boolean isUnknownNumberThatCanBeLookedUp(
+            Context context,
+            PhoneAccountHandle accountHandle,
+            CharSequence number,
+            int presentation) {
+        if (presentation == CallLog.Calls.PRESENTATION_UNKNOWN) {
+            return false;
+        }
+        if (presentation == CallLog.Calls.PRESENTATION_RESTRICTED) {
+            return false;
+        }
+        if (presentation == CallLog.Calls.PRESENTATION_PAYPHONE) {
+            return false;
+        }
+        if (TextUtils.isEmpty(number)) {
+            return false;
+        }
+        if (isVoicemailNumber(context, accountHandle, number)) {
+            return false;
+        }
+        if (isLegacyUnknownNumbers(number)) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean isLegacyUnknownNumbers(CharSequence number) {
+        return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString());
+    }
+}
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index 8ee85a4..8c2d8e4 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -24,7 +24,6 @@
 
 import com.android.contacts.common.CallUtil;
 import com.android.dialer.PhoneCallDetails;
-import com.android.dialer.PhoneCallDetailsHelper;
 import com.android.dialer.R;
 
 /**
@@ -60,12 +59,13 @@
         super.setUp();
         mContext = getContext();
         mResources = mContext.getResources();
-        final TestPhoneNumberUtilsWrapper phoneUtils =
-                new TestPhoneNumberUtilsWrapper(mContext, TEST_VOICEMAIL_NUMBER);
+        final TestTelecomCallLogCache phoneUtils =
+                new TestTelecomCallLogCache(mContext, TEST_VOICEMAIL_NUMBER);
         PhoneCallDetailsHelper phoneCallDetailsHelper =
                 new PhoneCallDetailsHelper(mContext, mResources, phoneUtils);
-        mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mResources);
+        mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mResources, phoneUtils);
         mViewHolder = CallLogListItemViewHolder.createForTest(mContext);
+
     }
 
     @Override
@@ -104,13 +104,13 @@
 
     public void testSetPhoneCallDetails_ReadVoicemail() {
         PhoneCallDetails details = getPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        mHelper.setPhoneCallDetails(getContext(), mViewHolder, details);
+        mHelper.setPhoneCallDetails(mViewHolder, details);
         assertEquals(View.VISIBLE, mViewHolder.voicemailPlaybackView.getVisibility());
     }
 
     public void testSetPhoneCallDetails_UnreadVoicemail() {
         PhoneCallDetails details = getPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        mHelper.setPhoneCallDetails(getContext(), mViewHolder, details);
+        mHelper.setPhoneCallDetails(mViewHolder, details);
         assertEquals(View.VISIBLE, mViewHolder.voicemailPlaybackView.getVisibility());
     }
 
@@ -176,7 +176,7 @@
     public void testGetCallDescription_NoVoicemailOutgoing() {
         PhoneCallDetails details =
                 getPhoneCallDetailsWithTypes(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
     }
@@ -188,7 +188,7 @@
     public void testGetCallDescription_NoVoicemailIncoming() {
         PhoneCallDetails details =
                 getPhoneCallDetailsWithTypes(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
     }
@@ -200,7 +200,7 @@
     public void testGetCallDescription_NoVoicemailMissed() {
         PhoneCallDetails details =
                 getPhoneCallDetailsWithTypes(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         assertFalse(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
     }
@@ -212,7 +212,7 @@
     public void testGetCallDescription_Voicemail() {
         PhoneCallDetails details =
                 getPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         assertTrue(description.toString()
                 .contains(this.mResources.getString(R.string.description_new_voicemail)));
     }
@@ -223,7 +223,7 @@
      */
     public void testGetCallDescription_NumCallsSingle() {
         PhoneCallDetails details = getPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
 
         // Rather than hard coding the "X calls" string message, we'll generate it with an empty
         // number of calls, and trim the resulting string.  This gets us just the word "calls",
@@ -240,7 +240,7 @@
     public void testGetCallDescription_NumCallsMultiple() {
         PhoneCallDetails details =
                 getPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE);
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         assertTrue(description.toString()
                 .contains(this.mResources.getString(R.string.description_num_calls, 2)));
     }
@@ -254,7 +254,7 @@
                 getPhoneCallDetailsWithTypes(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE);
         details.features = Calls.FEATURES_VIDEO;
 
-        CharSequence description = mHelper.getCallDescription(getContext(), details);
+        CharSequence description = mHelper.getCallDescription(details);
         final boolean isVideoEnabled = CallUtil.isVideoEnabled(getContext());
         assertTrue(description.toString()
                 .contains(this.mResources.getString(
@@ -284,7 +284,7 @@
         PhoneCallDetails details = getPhoneCallDetails(
                 number, presentation, formattedNumber);
         details.callTypes = new int[]{ callType };
-        mHelper.setPhoneCallDetails(mContext, mViewHolder, details);
+        mHelper.setPhoneCallDetails(mViewHolder, details);
     }
 
     private PhoneCallDetails getPhoneCallDetails(
diff --git a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
similarity index 97%
rename from tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
rename to tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
index 2ee38cb..3182502 100644
--- a/tests/src/com/android/dialer/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.dialer;
+package com.android.dialer.calllog;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -25,15 +25,15 @@
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.dialer.calllog.ContactInfo;
-import com.android.dialer.calllog.TestPhoneNumberUtilsWrapper;
+import com.android.dialer.PhoneCallDetails;
+import com.android.dialer.R;
 import com.android.dialer.util.LocaleTestUtils;
 
 import java.util.GregorianCalendar;
 import java.util.Locale;
 
 /**
- * Unit tests for {@link PhoneCallDetailsHelper}.
+ * Unit tests for {@link PhoneCallDetailsHelper}.m
  */
 public class PhoneCallDetailsHelperTest extends AndroidTestCase {
     /** The number to be used to access the voicemail. */
@@ -60,7 +60,7 @@
     private PhoneCallDetailsViews mViews;
     private TextView mNameView;
     private LocaleTestUtils mLocaleTestUtils;
-    private TestPhoneNumberUtilsWrapper mPhoneUtils;
+    private TestTelecomCallLogCache mPhoneUtils;
 
     private Context mContext;
 
@@ -69,8 +69,8 @@
         super.setUp();
         mContext = getContext();
         Resources resources = mContext.getResources();
-        mPhoneUtils = new TestPhoneNumberUtilsWrapper(mContext, TEST_VOICEMAIL_NUMBER);
-        final TestPhoneNumberUtilsWrapper phoneUtils = new TestPhoneNumberUtilsWrapper(
+        mPhoneUtils = new TestTelecomCallLogCache(mContext, TEST_VOICEMAIL_NUMBER);
+        final TestTelecomCallLogCache phoneUtils = new TestTelecomCallLogCache(
                 mContext, TEST_VOICEMAIL_NUMBER);
         mHelper = new PhoneCallDetailsHelper(mContext, resources, phoneUtils);
         mHelper.setCurrentTimeForTest(
diff --git a/tests/src/com/android/dialer/calllog/TestPhoneNumberUtilsWrapper.java b/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java
similarity index 87%
rename from tests/src/com/android/dialer/calllog/TestPhoneNumberUtilsWrapper.java
rename to tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java
index 24916db..5475ec3 100644
--- a/tests/src/com/android/dialer/calllog/TestPhoneNumberUtilsWrapper.java
+++ b/tests/src/com/android/dialer/calllog/TestTelecomCallLogCache.java
@@ -23,10 +23,10 @@
  * Modified version of {@link com.android.dialer.calllog.PhoneNumberDisplayHelper} to be used in
  * tests that allows injecting the voicemail number.
  */
-public final class TestPhoneNumberUtilsWrapper extends PhoneNumberUtilsWrapper {
+public final class TestTelecomCallLogCache extends TelecomCallLogCache {
     private CharSequence mVoicemailNumber;
 
-    public TestPhoneNumberUtilsWrapper(Context context, CharSequence voicemailNumber) {
+    public TestTelecomCallLogCache(Context context, CharSequence voicemailNumber) {
         super(context);
         mVoicemailNumber = voicemailNumber;
     }
diff --git a/tests/src/com/android/dialer/util/DialerUtilsTest.java b/tests/src/com/android/dialer/util/DialerUtilsTest.java
index fdd02c1..ccd6dfd 100644
--- a/tests/src/com/android/dialer/util/DialerUtilsTest.java
+++ b/tests/src/com/android/dialer/util/DialerUtilsTest.java
@@ -16,7 +16,7 @@
 
 package com.android.dialer.util;
 
-import com.android.dialer.PhoneCallDetailsHelper;
+import com.android.dialer.calllog.PhoneCallDetailsHelper;
 import com.google.common.collect.Lists;
 
 import android.content.Context;