diff options
author | NathanielWaggoner <nwaggoner@cyngn.com> | 2016-05-24 11:20:29 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2016-06-09 10:06:28 -0700 |
commit | 209c67bac4e4783e55810b51474b3b7b489ce5db (patch) | |
tree | e5a1a565481882a597fd9041f46f1eb4941adc74 /src | |
parent | 52cab04f34c67b3e9e649fe1618a5161c90db1d2 (diff) | |
download | android_packages_apps_Dialer-209c67bac4e4783e55810b51474b3b7b489ce5db.tar.gz android_packages_apps_Dialer-209c67bac4e4783e55810b51474b3b7b489ce5db.tar.bz2 android_packages_apps_Dialer-209c67bac4e4783e55810b51474b3b7b489ce5db.zip |
Performance tweaks for DeepLinkCache and icon retrieval.
We are now caching icons to avoid hitting package manager on each
UI update. Also upped cache size to accomodate a larger number
of DeepLinks smoothly.
NOTES-149, NOTES-66
Change-Id: I6cfc9c2ff642ed129d619eb2861f32b4027e8367
Diffstat (limited to 'src')
6 files changed, 135 insertions, 66 deletions
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 1b2d3496d..43fa93e77 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -329,7 +329,7 @@ public class CallLogAdapter extends GroupingListAdapter mContactInfoCache = new ContactInfoCache( mContactInfoHelper, mOnContactInfoChangedListener); - mDeepLinkCache = new DeepLinkCache(mDeepLinkListener); + mDeepLinkCache = new DeepLinkCache(context, mDeepLinkListener); if (!PermissionsUtil.hasContactsPermissions(context)) { mContactInfoCache.disableRequestProcessing(); } @@ -434,7 +434,8 @@ public class CallLogAdapter extends GroupingListAdapter mCallLogListItemHelper, mVoicemailPlaybackPresenter, mBlockContactPresenter, - mContactInfoHelper); + mContactInfoHelper, + mDeepLinkCache); viewHolder.callLogEntryView.setTag(viewHolder); viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate); diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java index cecd76001..26ab52397 100644 --- a/src/com/android/dialer/calllog/CallLogFragment.java +++ b/src/com/android/dialer/calllog/CallLogFragment.java @@ -267,6 +267,8 @@ public class CallLogFragment extends Fragment implements CallLogQueryHandler.Lis // Return false; we did not take ownership of the cursor return false; } + + mAdapter.mDeepLinkCache.buildCache(); mAdapter.setLoading(false); mAdapter.changeCursor(cursor); // This will update the state of the "Clear call log" menu item. diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java index 2d8cc68ac..ce14ec907 100644 --- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java +++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java @@ -47,6 +47,7 @@ import com.android.contacts.common.dialog.CallSubjectDialog; import com.android.contacts.common.testing.NeededForTesting; import com.android.contacts.common.util.UriUtils; import com.android.dialer.R; +import com.android.dialer.deeplink.DeepLinkCache; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.PhoneNumberUtil; import com.android.dialer.voicemail.VoicemailPlaybackPresenter; @@ -212,6 +213,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder VoicemailPlaybackPresenter voicemailPlaybackPresenter, BlockContactPresenter blockContactPresenter, ContactInfoHelper contactInfoHelper, + DeepLinkCache deepLinkCache, View rootView, DialerQuickContact dialerQuickContact, View primaryActionView, @@ -228,8 +230,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mCallLogListItemHelper = callLogListItemHelper; mVoicemailPlaybackPresenter = voicemailPlaybackPresenter; mBlockContactPresenter = blockContactPresenter; - mDeepLinkPresenter = new DeepLinkPresenter(mContext); - mDeepLinkPresenter.setCallLogViewHolder(this); + mDeepLinkPresenter = new DeepLinkPresenter(mContext, this, deepLinkCache); mContactInfoHelper = contactInfoHelper; this.rootView = rootView; @@ -263,7 +264,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, BlockContactPresenter blockContactPresenter, - ContactInfoHelper contactInfoHelper) { + ContactInfoHelper contactInfoHelper, + DeepLinkCache deepLinkCache) { return new CallLogListItemViewHolder( context, @@ -273,6 +275,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder voicemailPlaybackPresenter, blockContactPresenter, contactInfoHelper, + deepLinkCache, view, (DialerQuickContact) view.findViewById(R.id.quick_contact_photo), view.findViewById(R.id.primary_action_view), @@ -400,12 +403,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder callButtonView.setVisibility(View.GONE); } - if (mDeepLinkPresenter.mDeepLink != null) { - ImageView icon = (ImageView) viewNoteButton.findViewById(R.id.view_note_action_icon); - icon.setImageDrawable(mDeepLinkPresenter.mDeepLink.getDrawableIcon(mContext)); - } else { - viewNoteButton.setVisibility(View.GONE); - } + mDeepLinkPresenter.bindActionButton(); + // If one of the calls had video capabilities, show the video call button. if (mTelecomCallLogCache.isVideoEnabled() && canPlaceCallToNumber && phoneCallDetailsViews.callTypeIcons.isVideoShown() || @@ -639,6 +638,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder null /* voicemailPlaybackPresenter */, null /* blockContactPresenter */, null /* ContactInfoHelper */, + null /* DeepLinkCache */, new View(context), new DialerQuickContact(context), new View(context), diff --git a/src/com/android/dialer/calllog/DeepLinkPresenter.java b/src/com/android/dialer/calllog/DeepLinkPresenter.java index 0e335ca04..787b6db2f 100644 --- a/src/com/android/dialer/calllog/DeepLinkPresenter.java +++ b/src/com/android/dialer/calllog/DeepLinkPresenter.java @@ -17,57 +17,61 @@ package com.android.dialer.calllog; import android.content.ComponentName; import android.content.Context; -import android.net.Uri; +import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageView; import com.android.dialer.R; +import com.android.dialer.deeplink.DeepLinkCache; import com.android.dialer.deeplink.DeepLinkRequest; -import com.cyanogen.ambient.common.api.ResultCallback; import com.cyanogen.ambient.deeplink.DeepLink; -import com.cyanogen.ambient.deeplink.DeepLink.DeepLinkResultList; -import com.cyanogen.ambient.deeplink.linkcontent.DeepLinkContentType; -import com.cyanogen.ambient.deeplink.applicationtype.DeepLinkApplicationType; import com.android.dialer.deeplink.DeepLinkIntegrationManager; -import java.util.List; -import java.util.ArrayList; - public class DeepLinkPresenter { + private final Context mContext; + private DeepLink mDeepLink; + private final CallLogListItemViewHolder mViews; + private final DeepLinkCache mCache; - Context mContext; - DeepLink mDeepLink; - private CallLogListItemViewHolder mViews; - - public DeepLinkPresenter(Context context) { + public DeepLinkPresenter(Context context, CallLogListItemViewHolder holder, + DeepLinkCache cache) { mContext = context; - } - - public void setCallLogViewHolder(CallLogListItemViewHolder holder) { mViews = holder; + mCache = cache; } - private void updateViews() { - if (mDeepLink != null && mDeepLink != DeepLinkRequest.EMPTY) { - if (canUpdateImageIconViews()) { - mViews.viewNoteActionIcon.setImageDrawable(mDeepLink.getDrawableIcon(mContext)); + public void bindActionButton() { + if (canUpdateImageIconViews()) { + if (hasValidLink()) { + mViews.viewNoteActionIcon.setImageDrawable(getLinkIcon()); mViews.viewNoteButton.setVisibility(View.VISIBLE); + } else { + mViews.viewNoteButton.setVisibility(View.GONE); } + } + } + + private void updateViews() { + if (hasValidLink()) { mViews.phoneCallDetailsViews.noteIconView.setVisibility(View.VISIBLE); - mViews.phoneCallDetailsViews.noteIconView - .setImageDrawable(mDeepLink.getDrawableIcon(mContext)); + mViews.phoneCallDetailsViews.noteIconView.setImageDrawable(getLinkIcon()); } else { - if (canUpdateImageIconViews()) { - mViews.viewNoteButton.setVisibility(View.GONE); - mViews.viewNoteActionIcon.setImageDrawable(null); - } mViews.phoneCallDetailsViews.noteIconView.setVisibility(View.GONE); } + bindActionButton(); + } + + private boolean hasValidLink() { + return mDeepLink != null && mDeepLink != DeepLinkRequest.EMPTY; + } + + private Drawable getLinkIcon() { + return mCache != null ? mCache.getDrawable(mDeepLink) : null; } private boolean canUpdateImageIconViews() { - return mViews.viewNoteButton != null && mViews.viewNoteActionIcon != null; + return mViews.viewNoteButton != null && mViews.viewNoteActionIcon != null; } public void setDeepLink(DeepLink deepLink) { diff --git a/src/com/android/dialer/deeplink/DeepLinkCache.java b/src/com/android/dialer/deeplink/DeepLinkCache.java index 868c6735d..9a941f3a7 100644 --- a/src/com/android/dialer/deeplink/DeepLinkCache.java +++ b/src/com/android/dialer/deeplink/DeepLinkCache.java @@ -16,14 +16,15 @@ package com.android.dialer.deeplink; +import android.content.Context; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Handler; import android.os.Message; +import android.provider.CallLog; import com.android.dialer.util.ExpirableCache; -import com.android.dialer.deeplink.DeepLinkIntegrationManager; - import com.cyanogen.ambient.common.api.PendingResult; import com.cyanogen.ambient.common.api.ResultCallback; import com.cyanogen.ambient.deeplink.DeepLink; @@ -59,11 +60,14 @@ public class DeepLinkCache { } + private static final int MAX_REQUEST_COUNT = 200; private static final int START_THREAD = 0; private static final int REDRAW = 1; - private static final int DEEP_LINK_CACHE_SIZE = 100; + private static final int DEEP_LINK_CACHE_SIZE = 1000; private static final int START_PROCESSING_REQUESTS_DELAY_MS = 1000; private static final int PROCESSING_THREAD_THROTTLE_LIMIT = 1000; + + private Context mContext; private DeepLinkListener mDeepLinkListener; private final LinkedList<DeepLinkRequest> mRequests; /** @@ -75,6 +79,10 @@ public class DeepLinkCache { * Cache for DeepLink queries we've already completed. */ private ExpirableCache<String, DeepLink> mCache; + /** + * Cache for fetched DeepLink drawables + */ + private HashMap<String, Drawable> mDrawableCache; private QueryThread mDeepLinkQueryThread; private boolean mRequestProcessingDisabled = false; @@ -117,8 +125,9 @@ public class DeepLinkCache { // Obtain next request, if any is available. // Keep synchronized section small. DeepLinkRequest req = null; + int pendingSize = mPendingRequests.size(); synchronized (mRequests) { - if (!mRequests.isEmpty()) { + if (!mRequests.isEmpty() && pendingSize < MAX_REQUEST_COUNT) { req = mRequests.removeFirst(); } } @@ -146,10 +155,12 @@ public class DeepLinkCache { } } - public DeepLinkCache(DeepLinkListener listener) { + public DeepLinkCache(Context context, DeepLinkListener listener) { + mContext = context; mRequests = new LinkedList<DeepLinkRequest>(); mPendingRequests = new HashMap<Uri, PendingResult<DeepLink.DeepLinkResultList>>(); mCache = ExpirableCache.create(DEEP_LINK_CACHE_SIZE); + mDrawableCache = new HashMap<String, Drawable>(); mDeepLinkListener = listener; } @@ -170,7 +181,6 @@ public class DeepLinkCache { DeepLink info = cachedInfo == null ? null : cachedInfo.getValue(); if (cachedInfo == null) { // if its null we need to add a uri to our requests - mCache.put(uriString, DeepLinkRequest.EMPTY); urisToRequest.add(uri); // if we get any uris that haven't been handled we need to immediately do this query immediate = true; @@ -194,7 +204,7 @@ public class DeepLinkCache { DeepLinkRequest request = new DeepLinkRequest(uris); synchronized (mRequests) { if (!mRequests.contains(request)) { - mRequests.add(request); + mRequests.addFirst(request); mRequests.notifyAll(); } } @@ -227,8 +237,17 @@ public class DeepLinkCache { if (mDeepLinkQueryThread != null) { // Stop the thread; we are finished with it. mDeepLinkQueryThread.stopProcessing(); + cancelAllPendingQueries(); mDeepLinkQueryThread = null; mRequests.clear(); + } + } + + private void cancelAllPendingQueries() { + synchronized (mPendingRequests) { + for (PendingResult<DeepLink.DeepLinkResultList> r : mPendingRequests.values()) { + r.cancel(); + } mPendingRequests.clear(); } } @@ -263,6 +282,9 @@ public class DeepLinkCache { } private void handleDeepLinkResults(List<DeepLink> results) { + if (results == null) { + return; + } for (DeepLink link : results) { if (shouldPlaceLinkInCache(link)) { mCache.put(link.getUri().toString(), link); @@ -290,38 +312,60 @@ public class DeepLinkCache { * @param request - the DeepLinkRequest to query against. */ private void queryDeepLinks(DeepLinkRequest request) { + final DeepLinkIntegrationManager dlim = DeepLinkIntegrationManager.getInstance(); final Uri uri = request.getUris().get(0); - synchronized (mPendingRequests) { - mPendingRequests.put(uri, - DeepLinkIntegrationManager.getInstance().getPreferredLinksForList( - new ResultCallback<DeepLink.DeepLinkResultList>() { - @Override - public void onResult(DeepLink.DeepLinkResultList result) { - List<DeepLink> results = result.getResults(); - if (results == null || results.size() == 0) { - return; - } - mPendingRequests.remove(uri); - handleDeepLinkResults(result.getResults()); - } - }, DeepLinkContentType.CALL, request.getUris())); + final PendingResult<DeepLink.DeepLinkResultList> pendingRequest = + dlim.getPreferredLinksForList(new ResultCallback<DeepLink.DeepLinkResultList>() { + @Override + public void onResult(DeepLink.DeepLinkResultList result) { + mPendingRequests.remove(uri); + handleDeepLinkResults(result.getResults()); + } + }, DeepLinkContentType.CALL, request.getUris()); + if (pendingRequest != null) { + synchronized (mPendingRequests) { + mPendingRequests.put(uri, pendingRequest); + } } } public void clearPendingQueries(String number, long[] calltimes) { synchronized (mPendingRequests) { Uri uri = DeepLinkIntegrationManager.generateCallUri(number, calltimes[0]); - if (mPendingRequests.containsKey(uri)) { - PendingResult<DeepLink.DeepLinkResultList> request = mPendingRequests.remove(uri); - if (request != null) { - request.cancel(); - } + PendingResult<DeepLink.DeepLinkResultList> request = mPendingRequests.remove(uri); + if (request != null) { + request.cancel(); } } } + public Drawable getDrawable(DeepLink deepLink) { + if (deepLink == null) { + return null; + } + String packageKey = deepLink.getPackageName(); + Drawable d = mDrawableCache.get(packageKey); + if (d == null) { + d = deepLink.getDrawableIcon(mContext); + mDrawableCache.put(packageKey, d); + } + + return d != null ? d.getConstantState().newDrawable() : null; + } + public void clearCache() { mCache.clearCache(); + mDrawableCache.clear(); + } + + public void buildCache() { + DeepLinkIntegrationManager dlim = DeepLinkIntegrationManager.getInstance(); + dlim.getLinksForAuthority(new ResultCallback<DeepLink.DeepLinkResultList>() { + @Override + public void onResult(DeepLink.DeepLinkResultList result) { + handleDeepLinkResults(result.getResults()); + } + }, DeepLinkContentType.CALL, CallLog.AUTHORITY); } } diff --git a/src/com/android/dialer/deeplink/DeepLinkIntegrationManager.java b/src/com/android/dialer/deeplink/DeepLinkIntegrationManager.java index 257d9ba59..803896e79 100644 --- a/src/com/android/dialer/deeplink/DeepLinkIntegrationManager.java +++ b/src/com/android/dialer/deeplink/DeepLinkIntegrationManager.java @@ -115,6 +115,24 @@ public class DeepLinkIntegrationManager { } /** + * Gets all links for the given authority, across all installed plugins.. + * @param callback Code to execute upon completion. + * @param category DeepLinkContentType to query for API defaults. + */ + + public PendingResult<DeepLink.DeepLinkResultList> getLinksForAuthority( + ResultCallback<DeepLink.DeepLinkResultList> callback, DeepLinkContentType category, + String authority) { + PendingResult<DeepLink.DeepLinkResultList> result = null; + if (mShouldQueueRequests) { + result = mApi.getLinksForAuthority(mAmbientApiClient, + DeepLinkApplicationType.NOTE, category, authority); + result.setResultCallback(callback); + } + return result; + } + + /** * Get's the default plugin information for display. * @param callback Code to execute upon completion. * @param category DeepLinkContentType to query for API defaults. @@ -191,7 +209,7 @@ public class DeepLinkIntegrationManager { */ public void viewNote(Context ctx, DeepLink deepLink, ComponentName cn) { if (deepLink != null && deepLink.getAlreadyHasContent()) { - sendContentSentEvent(ctx, deepLink, cn); + sendOpeningExistingEvent(ctx, deepLink, cn); ctx.startActivity(deepLink.createViewIntent()); } } @@ -262,4 +280,4 @@ public class DeepLinkIntegrationManager { mPendingResultArrayMap.remove(toCancel); } } -}
\ No newline at end of file +} |