diff options
author | Danny Baumann <dannybaumann@web.de> | 2015-06-03 11:47:55 +0200 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-06-10 06:55:43 +0000 |
commit | b9bbfc413236c05feb2381be5c05a554d599b2ef (patch) | |
tree | 2cdce9298983e8aa0a2bb975c2f6a38422a3aaf5 | |
parent | f66a0fb56c03509215dd4519a9c69d36dbaea23a (diff) | |
download | android_packages_apps_Dialer-b9bbfc413236c05feb2381be5c05a554d599b2ef.tar.gz android_packages_apps_Dialer-b9bbfc413236c05feb2381be5c05a554d599b2ef.tar.bz2 android_packages_apps_Dialer-b9bbfc413236c05feb2381be5c05a554d599b2ef.zip |
Improve performance of call log.
Avoid binder calls in each layout pass by caching the results of
TelecomManager.getPhoneAccount() and TelecomManager.isVoiceMailNumber().
Do the latter by caching the actual voicemail number and doing the
comparison by ourselves.
Change-Id: I531cf7c9b3f0e99be8e1774605d6e0ee1ea229ab
11 files changed, 113 insertions, 44 deletions
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java index e6420dbf5..5f1b15d35 100644 --- a/src/com/android/dialer/CallDetailActivity.java +++ b/src/com/android/dialer/CallDetailActivity.java @@ -119,6 +119,7 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware private CallDetailHeader mCallDetailHeader; private CallTypeHelper mCallTypeHelper; + private PhoneNumberUtilsWrapper mUtilsWrapper; private PhoneNumberDisplayHelper mPhoneNumberHelper; private AsyncTaskExecutor mAsyncTaskExecutor; private ContactInfoHelper mContactInfoHelper; @@ -249,7 +250,8 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware mResources = getResources(); mCallTypeHelper = new CallTypeHelper(getResources()); - mPhoneNumberHelper = new PhoneNumberDisplayHelper(this, mResources); + mUtilsWrapper = new PhoneNumberUtilsWrapper(this); + mPhoneNumberHelper = new PhoneNumberDisplayHelper(this, mResources, mUtilsWrapper); mCallDetailHeader = new CallDetailHeader(this, mPhoneNumberHelper); mVoicemailStatusHelper = new VoicemailStatusHelperImpl(); mAsyncQueryHandler = new CallDetailActivityQueryHandler(this); @@ -390,11 +392,13 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware public PhoneCallDetails[] doInBackground(Void... params) { // TODO: All phone calls correspond to the same person, so we can make a single // lookup. + final PhoneNumberUtilsWrapper phoneUtils = + new PhoneNumberUtilsWrapper(CallDetailActivity.this); final int numCalls = callUris.length; PhoneCallDetails[] details = new PhoneCallDetails[numCalls]; try { for (int index = 0; index < numCalls; ++index) { - details[index] = getPhoneCallDetailsForUri(callUris[index]); + details[index] = getPhoneCallDetailsForUri(callUris[index], phoneUtils); } return details; } catch (IllegalArgumentException e) { @@ -432,9 +436,8 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware // Cache the details about the phone number. final boolean canPlaceCallsTo = PhoneNumberUtilsWrapper.canPlaceCallsTo(mNumber, numberPresentation); - final PhoneNumberUtilsWrapper phoneUtils = new PhoneNumberUtilsWrapper(context); final boolean isVoicemailNumber = - phoneUtils.isVoicemailNumber(accountHandle, mNumber); + mUtilsWrapper.isVoicemailNumber(accountHandle, mNumber); final boolean isSipNumber = PhoneNumberUtilsWrapper.isSipNumber(mNumber); final CharSequence callLocationOrType = getNumberTypeOrLocation(firstDetails); @@ -499,7 +502,8 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware } /** Return the phone call details for a given call log URI. */ - private PhoneCallDetails getPhoneCallDetailsForUri(Uri callUri) { + private PhoneCallDetails getPhoneCallDetailsForUri(Uri callUri, + PhoneNumberUtilsWrapper phoneUtils) { ContentResolver resolver = getContentResolver(); Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null); try { @@ -539,7 +543,7 @@ public class CallDetailActivity extends Activity implements ProximitySensorAware // If this is not a regular number, there is no point in looking it up in the contacts. ContactInfo info = PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation) - && !new PhoneNumberUtilsWrapper(this).isVoicemailNumber(accountHandle, number) + && !phoneUtils.isVoicemailNumber(accountHandle, number) ? mContactInfoHelper.lookupNumber(number, countryIso) : null; if (info == null) { diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index f33668386..7f8a33db2 100755 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -244,10 +244,11 @@ public class CallLogAdapter extends GroupingListAdapter mPhotoSize = resources.getDimensionPixelSize(R.dimen.contact_photo_size); mContactPhotoManager = ContactPhotoManager.getInstance(mContext); - mPhoneNumberHelper = new PhoneNumberDisplayHelper(mContext, resources); - mAdapterHelper = new CallLogAdapterHelper(context, this, - contactInfoHelper, mPhoneNumberHelper); mPhoneNumberUtilsWrapper = new PhoneNumberUtilsWrapper(mContext); + mPhoneNumberHelper = new PhoneNumberDisplayHelper(mContext, + resources, mPhoneNumberUtilsWrapper); + mAdapterHelper = new CallLogAdapterHelper(mContext, this, + contactInfoHelper, mPhoneNumberHelper, mPhoneNumberUtilsWrapper); PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(mContext, resources, mPhoneNumberUtilsWrapper); mCallLogViewsHelper = diff --git a/src/com/android/dialer/calllog/CallLogAdapterHelper.java b/src/com/android/dialer/calllog/CallLogAdapterHelper.java index 31f9c2799..f2aba510d 100644 --- a/src/com/android/dialer/calllog/CallLogAdapterHelper.java +++ b/src/com/android/dialer/calllog/CallLogAdapterHelper.java @@ -186,6 +186,7 @@ public class CallLogAdapterHelper implements ViewTreeObserver.OnPreDrawListener private Callback mCb; private final Context mContext; private final ContactInfoHelper mContactInfoHelper; + private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper; private final PhoneNumberDisplayHelper mPhoneNumberHelper; /** @@ -410,7 +411,7 @@ public class CallLogAdapterHelper implements ViewTreeObserver.OnPreDrawListener mContactInfoCache.getCachedValue(numberCountryIso); ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue(); if (!PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation) - || new PhoneNumberUtilsWrapper(mContext).isVoicemailNumber(accountHandle, number)) { + || mPhoneNumberUtilsWrapper.isVoicemailNumber(accountHandle, number)) { // If this is a number that cannot be dialed, there is no point in looking up a contact // for it. info = ContactInfo.EMPTY; @@ -446,11 +447,13 @@ public class CallLogAdapterHelper implements ViewTreeObserver.OnPreDrawListener public CallLogAdapterHelper(Context context, Callback cb, ContactInfoHelper contactInfoHelper, - PhoneNumberDisplayHelper phoneNumberHelper) { + PhoneNumberDisplayHelper phoneNumberHelper, + PhoneNumberUtilsWrapper utilsWrapper) { mContext = context; mCb = cb; mContactInfoHelper = contactInfoHelper; mPhoneNumberHelper = phoneNumberHelper; + mPhoneNumberUtilsWrapper = utilsWrapper; mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE); mRequests = new LinkedList<ContactInfoRequest>(); diff --git a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java index 970cad6a6..5cb1388a6 100644 --- a/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java +++ b/src/com/android/dialer/calllog/DefaultVoicemailNotifier.java @@ -357,6 +357,7 @@ public class DefaultVoicemailNotifier implements VoicemailNotifier { * called from the main thread. */ public static PhoneNumberDisplayHelper createPhoneNumberHelper(Context context) { - return new PhoneNumberDisplayHelper(context, context.getResources()); + return new PhoneNumberDisplayHelper(context, context.getResources(), + new PhoneNumberUtilsWrapper(context)); } } diff --git a/src/com/android/dialer/calllog/PhoneAccountUtils.java b/src/com/android/dialer/calllog/PhoneAccountUtils.java index f80ffd089..b197e69b3 100644 --- a/src/com/android/dialer/calllog/PhoneAccountUtils.java +++ b/src/com/android/dialer/calllog/PhoneAccountUtils.java @@ -23,6 +23,8 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.text.TextUtils; +import com.android.dialer.util.AgingCache; + import java.util.ArrayList; import java.util.List; @@ -74,27 +76,35 @@ public class PhoneAccountUtils { * Extract account color from PhoneAccount object. */ public static int getAccountColor(Context context, PhoneAccountHandle accountHandle) { - TelecomManager telecomManager = - (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); - final PhoneAccount account = telecomManager.getPhoneAccount(accountHandle); + final PhoneAccount account = getAccountOrNull(context, accountHandle); // For single-sim devices the PhoneAccount will be NO_HIGHLIGHT_COLOR by default, so it is // safe to always use the account highlight color. return account == null ? PhoneAccount.NO_HIGHLIGHT_COLOR : account.getHighlightColor(); } + private static final AgingCache<PhoneAccountHandle, PhoneAccount> sAccountCache = + new AgingCache<>(5000); + /** * 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, PhoneAccountHandle accountHandle) { + PhoneAccount account = sAccountCache.get(accountHandle); + if (account != null) { + return account; + } + TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); - final PhoneAccount account = telecomManager.getPhoneAccount(accountHandle); if (!telecomManager.hasMultipleCallCapableAccounts()) { - return null; + account = null; + } else { + account = telecomManager.getPhoneAccount(accountHandle); } + sAccountCache.put(accountHandle, account); return account; } } diff --git a/src/com/android/dialer/calllog/PhoneNumberDisplayHelper.java b/src/com/android/dialer/calllog/PhoneNumberDisplayHelper.java index d082b9d39..bb6fb3240 100644 --- a/src/com/android/dialer/calllog/PhoneNumberDisplayHelper.java +++ b/src/com/android/dialer/calllog/PhoneNumberDisplayHelper.java @@ -34,12 +34,6 @@ public class PhoneNumberDisplayHelper { private final Resources mResources; private final PhoneNumberUtilsWrapper mPhoneNumberUtilsWrapper; - public PhoneNumberDisplayHelper(Context context, Resources resources) { - mContext = context; - mResources = resources; - mPhoneNumberUtilsWrapper = new PhoneNumberUtilsWrapper(context); - } - public PhoneNumberDisplayHelper(Context context, Resources resources, PhoneNumberUtilsWrapper phoneNumberUtils) { mContext = context; diff --git a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java index 17cd1ff9f..9a76b1d7b 100644 --- a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java +++ b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java @@ -24,6 +24,7 @@ import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import com.android.contacts.common.util.PhoneNumberHelper; +import com.android.dialer.util.AgingCache; import com.google.common.collect.Sets; @@ -36,6 +37,8 @@ public class PhoneNumberUtilsWrapper { private static final Set<String> LEGACY_UNKNOWN_NUMBERS = Sets.newHashSet("-1", "-2", "-3"); private final Context mContext; + private AgingCache<PhoneAccountHandle, String> mVmNumberCache = new AgingCache<>(5000); + public PhoneNumberUtilsWrapper(Context context) { mContext = context; } @@ -50,19 +53,22 @@ 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 (number == null) { + return false; + } - /** - * Returns true if the given number is the number of the configured voicemail of the subId. - * To be able to mock-out this, it is not a static method. - */ - public boolean isVoicemailNumber(int subId, CharSequence number) { - return number!= null && PhoneNumberUtils.isVoiceMailNumber(subId, number.toString()); + String vmNumber = mVmNumberCache.get(accountHandle); + if (vmNumber == null) { + final TelecomManager telecomManager = + (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + vmNumber = telecomManager.getVoiceMailNumber(accountHandle); + mVmNumberCache.put(accountHandle, vmNumber != null ? vmNumber : ""); + } + + final String actualVmNumber = PhoneNumberUtils.extractNetworkPortionAlt(vmNumber); + return !TextUtils.isEmpty(actualVmNumber) + && PhoneNumberUtils.compare(number.toString(), actualVmNumber); } /** diff --git a/src/com/android/dialer/callstats/CallStatsAdapter.java b/src/com/android/dialer/callstats/CallStatsAdapter.java index 50d821b4f..eee11cea0 100644 --- a/src/com/android/dialer/callstats/CallStatsAdapter.java +++ b/src/com/android/dialer/callstats/CallStatsAdapter.java @@ -118,18 +118,17 @@ class CallStatsAdapter extends ArrayAdapter<CallStatsDetails> mInfoLookup = new ConcurrentHashMap<ContactInfo, CallStatsDetails>(); Resources resources = mContext.getResources(); - mPhoneNumberHelper = - new PhoneNumberDisplayHelper(mContext, resources); + PhoneNumberUtilsWrapper utilsWrapper = new PhoneNumberUtilsWrapper(mContext); + mPhoneNumberHelper = new PhoneNumberDisplayHelper(mContext, resources, utilsWrapper); final String currentCountryIso = GeoUtil.getCurrentCountryIso(mContext); final ContactInfoHelper contactInfoHelper = new ContactInfoHelper(mContext, currentCountryIso); mAdapterHelper = new CallLogAdapterHelper(mContext, this, - contactInfoHelper, mPhoneNumberHelper); + contactInfoHelper, mPhoneNumberHelper, utilsWrapper); mContactPhotoManager = ContactPhotoManager.getInstance(mContext); - mCallStatsDetailHelper = new CallStatsDetailHelper(mContext, resources, - new PhoneNumberUtilsWrapper(mContext)); + mCallStatsDetailHelper = new CallStatsDetailHelper(mContext, resources, utilsWrapper); } public void updateData(Map<ContactInfo, CallStatsDetails> calls, long from, long to) { diff --git a/src/com/android/dialer/callstats/CallStatsDetailActivity.java b/src/com/android/dialer/callstats/CallStatsDetailActivity.java index df4a0fd9a..d44db2964 100644 --- a/src/com/android/dialer/callstats/CallStatsDetailActivity.java +++ b/src/com/android/dialer/callstats/CallStatsDetailActivity.java @@ -96,10 +96,11 @@ public class CallStatsDetailActivity extends Activity { mResources = getResources(); - PhoneNumberDisplayHelper phoneNumberHelper = new PhoneNumberDisplayHelper(this, mResources); + PhoneNumberUtilsWrapper utilsWrapper = new PhoneNumberUtilsWrapper(this); + PhoneNumberDisplayHelper phoneNumberHelper = + new PhoneNumberDisplayHelper(this, mResources, utilsWrapper); mCallDetailHeader = new CallDetailHeader(this, phoneNumberHelper); - mCallStatsDetailHelper = new CallStatsDetailHelper(this, mResources, - new PhoneNumberUtilsWrapper(this)); + mCallStatsDetailHelper = new CallStatsDetailHelper(this, mResources, utilsWrapper); mContactInfoHelper = new ContactInfoHelper(this, GeoUtil.getCurrentCountryIso(this)); mTotalSummary = (TextView) findViewById(R.id.total_summary); diff --git a/src/com/android/dialer/callstats/CallStatsDetailHelper.java b/src/com/android/dialer/callstats/CallStatsDetailHelper.java index 8dd22c971..6d52c1f22 100644 --- a/src/com/android/dialer/callstats/CallStatsDetailHelper.java +++ b/src/com/android/dialer/callstats/CallStatsDetailHelper.java @@ -48,7 +48,7 @@ public class CallStatsDetailHelper { PhoneNumberUtilsWrapper phoneUtils) { mContext = context; mResources = resources; - mPhoneNumberHelper = new PhoneNumberDisplayHelper(context, resources); + mPhoneNumberHelper = new PhoneNumberDisplayHelper(context, resources, phoneUtils); mPhoneNumberUtilsWrapper = phoneUtils; } diff --git a/src/com/android/dialer/util/AgingCache.java b/src/com/android/dialer/util/AgingCache.java new file mode 100644 index 000000000..b1efb2bd0 --- /dev/null +++ b/src/com/android/dialer/util/AgingCache.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 The CyanogenMod 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.os.SystemClock; +import android.util.ArrayMap; +import android.util.Pair; + +public class AgingCache<K, V> { + private ArrayMap<K, Pair<V, Long>> mCache; + private long mMaxAge; + + public AgingCache(long maxAge) { + mCache = new ArrayMap<>(); + mMaxAge = maxAge; + } + + public V get(K key) { + Pair<V, Long> entry = mCache.get(key); + if (entry != null) { + long age = SystemClock.elapsedRealtime() - entry.second; + if (age < mMaxAge) { + return entry.first; + } + } + return null; + } + + public void put(K key, V value) { + mCache.put(key, Pair.create(value, SystemClock.elapsedRealtime())); + } + + public void clear() { + mCache.clear(); + } +} |