summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNathanielWaggoner <nwaggoner@cyngn.com>2016-05-24 11:20:29 -0700
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-06-09 10:06:28 -0700
commit209c67bac4e4783e55810b51474b3b7b489ce5db (patch)
treee5a1a565481882a597fd9041f46f1eb4941adc74 /src
parent52cab04f34c67b3e9e649fe1618a5161c90db1d2 (diff)
downloadandroid_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')
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java5
-rw-r--r--src/com/android/dialer/calllog/CallLogFragment.java2
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemViewHolder.java18
-rw-r--r--src/com/android/dialer/calllog/DeepLinkPresenter.java58
-rw-r--r--src/com/android/dialer/deeplink/DeepLinkCache.java96
-rw-r--r--src/com/android/dialer/deeplink/DeepLinkIntegrationManager.java22
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
+}