summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk13
-rw-r--r--libs/picasso-2.5.2.jarbin0 -> 120459 bytes
-rw-r--r--res/layout/call_log_list_item.xml12
-rw-r--r--res/values/cm_dimens.xml2
-rw-r--r--res/values/cm_strings.xml2
-rw-r--r--src/com/android/dialer/calllog/CallLogAdapter.java8
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemHelper.java7
-rw-r--r--src/com/android/dialer/calllog/CallLogListItemViewHolder.java20
-rw-r--r--src/com/android/dialer/calllog/ContactInfo.java12
-rw-r--r--src/com/android/dialer/calllog/ContactInfoHelper.java31
-rw-r--r--src/com/android/dialer/calllog/LookupInfoPresenter.java52
-rw-r--r--src/com/android/dialer/calllog/LookupInfoViews.java37
-rw-r--r--src/com/android/dialer/util/ImageUtils.java182
-rw-r--r--src/com/android/dialer/util/RoundedTransformation.java48
-rw-r--r--tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java4
15 files changed, 417 insertions, 13 deletions
diff --git a/Android.mk b/Android.mk
index 364d95564..3be5d73b2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -44,9 +44,6 @@ LOCAL_AAPT_FLAGS := \
--extra-packages com.android.phone.common \
--extra-packages com.cyanogen.ambient
-LOCAL_STATIC_JAVA_AAR_LIBRARIES := \
- ambientsdk
-
LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest_cm.xml
@@ -63,7 +60,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
guava \
libphonenumber \
org.cyanogenmod.platform.sdk \
- dialernext-android-support-design
+ dialernext-android-support-design \
+ picasso-dialer
LOCAL_PACKAGE_NAME := Dialer
LOCAL_CERTIFICATE := shared
@@ -71,6 +69,10 @@ LOCAL_PRIVILEGED_MODULE := true
LOCAL_PROGUARD_FLAG_FILES := proguard.flags $(incallui_dir)/proguard.flags
+# utilize ContactsCommon's phone-number-based contact-info lookup
+CONTACTS_COMMON_LOOKUP_PROVIDER ?= $(LOCAL_PATH)/$(contacts_common_dir)/info_lookup
+include $(CONTACTS_COMMON_LOOKUP_PROVIDER)/phonenumber_lookup_provider.mk
+
# Uncomment the following line to build against the current SDK
# This is required for building an unbundled app.
#LOCAL_SDK_VERSION := current
@@ -80,7 +82,8 @@ include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
dialernext-android-support-design:$(supportdesign_dir)/android-support-design.jar \
- dialernext-android-support-v7-appcompat:$(appcompat_dir)/android-support-v7-appcompat.jar
+ dialernext-android-support-v7-appcompat:$(appcompat_dir)/android-support-v7-appcompat.jar \
+ picasso-dialer:libs/picasso-2.5.2.jar
include $(BUILD_MULTI_PREBUILT)
diff --git a/libs/picasso-2.5.2.jar b/libs/picasso-2.5.2.jar
new file mode 100644
index 000000000..6acbaa14d
--- /dev/null
+++ b/libs/picasso-2.5.2.jar
Binary files differ
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
index 927152440..8a3d44f5b 100644
--- a/res/layout/call_log_list_item.xml
+++ b/res/layout/call_log_list_item.xml
@@ -98,6 +98,18 @@
android:singleLine="true" />
</LinearLayout>
+
+ <TextView
+ android:id="@+id/spamInfo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/call_log_name_margin_bottom"
+ android:layout_marginEnd="@dimen/call_log_icon_margin"
+ android:textColor="@color/spam_contact_color"
+ android:textSize="@dimen/call_log_spam_info_text_size"
+ android:singleLine="true"
+ android:visibility="gone" />
+
<TextView
android:id="@+id/voicemail_transcription"
android:layout_width="wrap_content"
diff --git a/res/values/cm_dimens.xml b/res/values/cm_dimens.xml
index b93f721f6..1cc5d1b41 100644
--- a/res/values/cm_dimens.xml
+++ b/res/values/cm_dimens.xml
@@ -2,4 +2,6 @@
<resources>
<dimen name="contact_list_badge_margin">1dp</dimen>
<dimen name="dialpad_credits_padding">14dp</dimen>
+
+ <dimen name="call_log_spam_info_text_size">10sp</dimen>
</resources> \ No newline at end of file
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 0177a0ee1..e74e6b348 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -170,4 +170,6 @@
<string name="provider_disable_title">Disable %1$s?</string>
<string name="provider_disable_message">By disabling %1$s, you will not have caller ID.</string>
<string name="provider_disable_spam_message">By disabling %1$s, you will not have spam protection or caller ID.</string>
+
+ <string name="powered_by_provider">Powered by <xliff:g id="provider">%s</xliff:g></string>
</resources>
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 5e89e8b72..cde87d0e4 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -320,8 +320,10 @@ public class CallLogAdapter extends GroupingListAdapter
mTelecomCallLogCache = new TelecomCallLogCache(mContext);
PhoneCallDetailsHelper phoneCallDetailsHelper =
new PhoneCallDetailsHelper(mContext, resources, mTelecomCallLogCache);
+ LookupInfoPresenter lookupInfoPresenter = new LookupInfoPresenter(mContext, resources);
mCallLogListItemHelper =
- new CallLogListItemHelper(phoneCallDetailsHelper, resources, mTelecomCallLogCache);
+ new CallLogListItemHelper(phoneCallDetailsHelper, lookupInfoPresenter,
+ resources, mTelecomCallLogCache);
mCallLogGroupBuilder = new CallLogGroupBuilder(this);
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
maybeShowVoicemailPromoCard();
@@ -407,7 +409,8 @@ public class CallLogAdapter extends GroupingListAdapter
mExpandCollapseListener,
mTelecomCallLogCache,
mCallLogListItemHelper,
- mVoicemailPlaybackPresenter);
+ mVoicemailPlaybackPresenter,
+ mContactInfoHelper);
viewHolder.callLogEntryView.setTag(viewHolder);
viewHolder.callLogEntryView.setAccessibilityDelegate(mAccessibilityDelegate);
@@ -580,6 +583,7 @@ public class CallLogAdapter extends GroupingListAdapter
views.setAttributionImage(views.inCallComponentName);
mCallLogListItemHelper.setPhoneCallDetails(views, details);
+ mCallLogListItemHelper.setLookupInfoDetails(views, info);
}
@Override
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index 1c8e397e4..938300a8c 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -37,6 +37,7 @@ import com.android.dialer.R;
/** Resources to look up strings. */
private final Resources mResources;
private final TelecomCallLogCache mTelecomCallLogCache;
+ private final LookupInfoPresenter mLookupInfoPresenter;
/**
* Creates a new helper instance.
@@ -46,9 +47,11 @@ import com.android.dialer.R;
*/
public CallLogListItemHelper(
PhoneCallDetailsHelper phoneCallDetailsHelper,
+ LookupInfoPresenter lookupInfoPresenter,
Resources resources,
TelecomCallLogCache telecomCallLogCache) {
mPhoneCallDetailsHelper = phoneCallDetailsHelper;
+ mLookupInfoPresenter = lookupInfoPresenter;
mResources = resources;
mTelecomCallLogCache = telecomCallLogCache;
}
@@ -76,6 +79,10 @@ import com.android.dialer.R;
views.nameOrNumber = getNameOrNumber(details);
}
+ public void setLookupInfoDetails(CallLogListItemViewHolder views, ContactInfo info) {
+ mLookupInfoPresenter.bindContactLookupInfo(views.lookupInfoViews, info);
+ }
+
/**
* Sets the accessibility descriptions for the action buttons in the action button ViewStub.
*
diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
index 21343c80b..2e45d3c3e 100644
--- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
+++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java
@@ -75,6 +75,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
public final View primaryActionView;
/** The details of the phone call. */
public final PhoneCallDetailsViews phoneCallDetailsViews;
+ public final LookupInfoViews lookupInfoViews;
/** The text of the header for a day grouping. */
public final TextView dayGroupHeader;
/** The view containing the details for the call log row, including the action buttons. */
@@ -203,10 +204,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
TelecomCallLogCache telecomCallLogCache,
CallLogListItemHelper callLogListItemHelper,
VoicemailPlaybackPresenter voicemailPlaybackPresenter,
+ ContactInfoHelper contactInfoHelper,
View rootView,
DialerQuickContact dialerQuickContact,
View primaryActionView,
PhoneCallDetailsViews phoneCallDetailsViews,
+ LookupInfoViews lookupInfoViews,
CardView callLogEntryView,
TextView dayGroupHeader,
ImageView primaryActionButtonView) {
@@ -217,11 +220,13 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
mTelecomCallLogCache = telecomCallLogCache;
mCallLogListItemHelper = callLogListItemHelper;
mVoicemailPlaybackPresenter = voicemailPlaybackPresenter;
+ mContactInfoHelper = contactInfoHelper;
this.rootView = rootView;
this.dialerQuickContact = dialerQuickContact;
this.primaryActionView = primaryActionView;
this.phoneCallDetailsViews = phoneCallDetailsViews;
+ this.lookupInfoViews = lookupInfoViews;
this.callLogEntryView = callLogEntryView;
this.dayGroupHeader = dayGroupHeader;
this.primaryActionButtonView = primaryActionButtonView;
@@ -238,9 +243,6 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
primaryActionButtonView.setOnClickListener(this);
primaryActionView.setOnClickListener(mExpandCollapseListener);
-
- mContactInfoHelper = new ContactInfoHelper(mContext,
- GeoUtil.getCurrentCountryIso(mContext));
}
public static CallLogListItemViewHolder create(
@@ -249,7 +251,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
View.OnClickListener expandCollapseListener,
TelecomCallLogCache telecomCallLogCache,
CallLogListItemHelper callLogListItemHelper,
- VoicemailPlaybackPresenter voicemailPlaybackPresenter) {
+ VoicemailPlaybackPresenter voicemailPlaybackPresenter,
+ ContactInfoHelper contactInfoHelper) {
return new CallLogListItemViewHolder(
context,
@@ -257,10 +260,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
telecomCallLogCache,
callLogListItemHelper,
voicemailPlaybackPresenter,
+ contactInfoHelper,
view,
(DialerQuickContact) view.findViewById(R.id.quick_contact_photo),
view.findViewById(R.id.primary_action_view),
PhoneCallDetailsViews.fromView(view),
+ LookupInfoViews.fromView(view),
(CardView) view.findViewById(R.id.call_log_row),
(TextView) view.findViewById(R.id.call_log_day_group_label),
(ImageView) view.findViewById(R.id.primary_action_button));
@@ -603,17 +608,22 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
TelecomCallLogCache telecomCallLogCache = new TelecomCallLogCache(context);
PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
context, resources, telecomCallLogCache);
+ LookupInfoPresenter lookupInfoPresenter = new LookupInfoPresenter(context,
+ context.getResources());
CallLogListItemViewHolder viewHolder = new CallLogListItemViewHolder(
context,
null /* expandCollapseListener */,
telecomCallLogCache,
- new CallLogListItemHelper(phoneCallDetailsHelper, resources, telecomCallLogCache),
+ new CallLogListItemHelper(phoneCallDetailsHelper, lookupInfoPresenter,
+ resources, telecomCallLogCache),
null /* voicemailPlaybackPresenter */,
+ null /* ContactInfoHelper */,
new View(context),
new DialerQuickContact(context),
new View(context),
PhoneCallDetailsViews.createForTest(context),
+ LookupInfoViews.createForText(context),
new CardView(context),
new TextView(context),
new ImageView(context));
diff --git a/src/com/android/dialer/calllog/ContactInfo.java b/src/com/android/dialer/calllog/ContactInfo.java
index 357c832cf..bbcf1b482 100644
--- a/src/com/android/dialer/calllog/ContactInfo.java
+++ b/src/com/android/dialer/calllog/ContactInfo.java
@@ -16,6 +16,7 @@
package com.android.dialer.calllog;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
@@ -46,6 +47,17 @@ public class ContactInfo {
public boolean isBadData;
public String objectId;
+ // the following fields are pertinent only in the presence of a
+ // valid {@link com.cyanogen.lookup.phonenumber.contract.LookupProvider}
+ public String city;
+ public String country;
+ public String address;
+ public boolean isSpam;
+ public int spamCount;
+ public String photoUrl;
+ public String lookupProviderName;
+ public Drawable attributionDrawable;
+
public static ContactInfo EMPTY = new ContactInfo();
public int sourceType = 0;
diff --git a/src/com/android/dialer/calllog/ContactInfoHelper.java b/src/com/android/dialer/calllog/ContactInfoHelper.java
index 7f82a3712..382680573 100644
--- a/src/com/android/dialer/calllog/ContactInfoHelper.java
+++ b/src/com/android/dialer/calllog/ContactInfoHelper.java
@@ -43,6 +43,10 @@ import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo;
import com.android.dialer.util.TelecomUtil;
import com.android.dialerbind.ObjectFactory;
+import com.cyanogen.lookup.phonenumber.contract.LookupProvider;
+import com.cyanogen.lookup.phonenumber.provider.LookupProviderImpl;
+import com.cyanogen.lookup.phonenumber.request.LookupRequest;
+import com.cyanogen.lookup.phonenumber.response.LookupResponse;
import org.json.JSONException;
import org.json.JSONObject;
@@ -56,6 +60,7 @@ public class ContactInfoHelper {
private final Context mContext;
private final String mCurrentCountryIso;
+ private final LookupProvider mLookupProvider;
private static final CachedNumberLookupService mCachedNumberLookupService =
ObjectFactory.newCachedNumberLookupService();
@@ -63,6 +68,12 @@ public class ContactInfoHelper {
public ContactInfoHelper(Context context, String currentCountryIso) {
mContext = context;
mCurrentCountryIso = currentCountryIso;
+ LookupProvider lookupProvider = new LookupProviderImpl(context);
+ if (lookupProvider.initialize()) {
+ mLookupProvider = lookupProvider;
+ } else {
+ mLookupProvider = null;
+ }
}
/**
@@ -287,6 +298,26 @@ public class ContactInfoHelper {
info = null;
}
}
+ // always do a LookupProvider search, if available
+ if (mLookupProvider != null) {
+ LookupResponse response = mLookupProvider.blockingFetchInfo(
+ new LookupRequest(PhoneNumberUtils.formatNumberToE164(number, countryIso), null));
+ if (response != null) {
+ // map LookupResponse to ContactInfo
+ ContactInfo contactInfo = new ContactInfo();
+ contactInfo.lookupProviderName = response.mProviderName;
+ contactInfo.name = response.mName;
+ contactInfo.number = formatPhoneNumber(response.mNumber, null, countryIso);
+ contactInfo.city = response.mCity;
+ contactInfo.country = response.mCountry;
+ contactInfo.address = response.mAddress;
+ contactInfo.photoUrl = response.mPhotoUrl;
+ contactInfo.isSpam = response.mIsSpam;
+ contactInfo.spamCount = response.mSpamCount;
+ contactInfo.attributionDrawable = response.mAttributionLogo;
+ info = contactInfo;
+ }
+ }
return info;
}
diff --git a/src/com/android/dialer/calllog/LookupInfoPresenter.java b/src/com/android/dialer/calllog/LookupInfoPresenter.java
new file mode 100644
index 000000000..ec8d7b6e1
--- /dev/null
+++ b/src/com/android/dialer/calllog/LookupInfoPresenter.java
@@ -0,0 +1,52 @@
+ package com.android.dialer.calllog;
+
+ import android.content.Context;
+ import android.content.res.Resources;
+ import android.content.res.TypedArray;
+ import android.text.TextUtils;
+ import android.view.View;
+ import com.android.dialer.R;
+ import com.android.dialer.util.ImageUtils;
+
+ /**
+ * Helper class that manages the call log list item based on the Lookup Response
+ */
+public class LookupInfoPresenter {
+ private final Context mContext;
+ private final Resources mResources;
+ private final int mNameColorAttributeId;
+
+ public LookupInfoPresenter(Context context, Resources res) {
+ mContext = context;
+ mResources = res;
+ TypedArray a = mContext.getTheme().obtainStyledAttributes(R.style.DialtactsTheme,
+ new int[]{R.attr.call_log_primary_text_color});
+ mNameColorAttributeId = a.getResourceId(0, 0);
+ a.recycle();
+ }
+
+ public void bindContactLookupInfo(LookupInfoViews views, ContactInfo info) {
+ if (info.isSpam) {
+ views.nameView.setTextColor(
+ mResources.getColor(R.color.spam_contact_color, mContext.getTheme()));
+
+ views.spamInfo.setVisibility(View.VISIBLE);
+ views.spamInfo.setText(mContext.getResources().getQuantityString(
+ R.plurals.spam_count_text, info.spamCount, info.spamCount));
+ } else {
+ // reset the views in case the ViewHolder was recycled
+ views.spamInfo.setVisibility(View.GONE);
+ views.nameView.setTextColor(mResources.getColor(mNameColorAttributeId,
+ mContext.getTheme()));
+ }
+
+ if (!TextUtils.isEmpty(info.photoUrl)) {
+ ImageUtils.loadBitampFromUrl(mContext, info.photoUrl,
+ views.contactPhotoView.getQuickContactBadge());
+ }
+
+ if (!TextUtils.isEmpty(info.lookupProviderName )) {
+ views.contactPhotoView.setAttributionBadge(info.attributionDrawable);
+ }
+ }
+}
diff --git a/src/com/android/dialer/calllog/LookupInfoViews.java b/src/com/android/dialer/calllog/LookupInfoViews.java
new file mode 100644
index 000000000..ebe03abb8
--- /dev/null
+++ b/src/com/android/dialer/calllog/LookupInfoViews.java
@@ -0,0 +1,37 @@
+package com.android.dialer.calllog;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.TextView;
+import com.android.dialer.R;
+import com.android.dialer.widget.DialerQuickContact;
+
+/**
+* ADT that stores the views affected by {@link com.cyanogen.lookup.phonenumber.contract.LookupProvider}
+*/
+public class LookupInfoViews {
+ public final TextView nameView;
+ public final DialerQuickContact contactPhotoView;
+ public final TextView spamInfo;
+
+ private LookupInfoViews(TextView nameView, DialerQuickContact contactPhotoView,
+ TextView spamInfo) {
+ this.nameView = nameView;
+ this.contactPhotoView = contactPhotoView;
+ this.spamInfo = spamInfo;
+ }
+
+ public static LookupInfoViews fromView(View view) {
+ return new LookupInfoViews(
+ (TextView) view.findViewById(R.id.name),
+ (DialerQuickContact) view.findViewById(R.id.quick_contact_photo),
+ (TextView) view.findViewById(R.id.spamInfo) );
+ }
+
+ public static LookupInfoViews createForText(Context context) {
+ return new LookupInfoViews(
+ new TextView(context),
+ new DialerQuickContact(context),
+ new TextView(context) );
+ }
+}
diff --git a/src/com/android/dialer/util/ImageUtils.java b/src/com/android/dialer/util/ImageUtils.java
new file mode 100644
index 000000000..65fe4a55e
--- /dev/null
+++ b/src/com/android/dialer/util/ImageUtils.java
@@ -0,0 +1,182 @@
+package com.android.dialer.util;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.TransitionDrawable;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import com.squareup.picasso.Picasso;
+import com.squareup.picasso.Target;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Utility class around Image loading and Bitmap effects
+ */
+public class ImageUtils {
+ private static boolean DEBUG = true;
+ private static String TAG = ImageUtils.class.getSimpleName();
+
+ public interface BitmapLoadRequest extends Target {}
+
+ public static void loadBitampFromUrl(Context ctx, String url, ImageView imageView) {
+ Picasso.with(ctx)
+ .load(url)
+ .noPlaceholder()
+ .fit()
+ .transform(new RoundedTransformation(ctx))
+ .into(imageView);
+ }
+
+ /**
+ * Since Picasso only maintains a weak reference to the target, the caller of this
+ * function MUST maintain a reference to the BitmapLoadRequest until the callback
+ * is invoked.
+ */
+ public static BitmapLoadRequest getBitmapFromUrl(Context ctx, String url,
+ final ImageLoadCallback<Bitmap> cb) {
+ BitmapLoadRequest t = new BitmapLoadRequest() {
+ @Override
+ public void onPrepareLoad(Drawable d){}
+
+ @Override
+ public void onBitmapLoaded(Bitmap result, Picasso.LoadedFrom from) {
+ cb.onCompleted(null, result);
+ }
+
+ @Override
+ public void onBitmapFailed(Drawable drawable) {
+ cb.onCompleted(null, null);
+ }
+ };
+
+ Picasso.with(ctx).load(url).into(t);
+ return t;
+ }
+
+ public static void cancelRequest(Context ctx, BitmapLoadRequest request) {
+ Picasso.with(ctx).cancelRequest(request);
+ }
+
+ public static void cancelRequest(ImageView contactImageSlot) {
+ Picasso.with(contactImageSlot.getContext()).cancelRequest(contactImageSlot);
+ }
+
+ // doesn't offer much besides encapsulation of img loading library for easy swapping later
+ public static abstract class ImageLoadCallback<T> {
+ public abstract void onCompleted(Exception e, T result);
+ }
+
+ /**
+ * Scale bitmap to the defined bounds. The bitmap will be scaled while maintaining the
+ * aspect ratio and center-cropped(vertically and horizontally) if it exceeds the
+ * defined bounds.
+ */
+ public static Bitmap scaleAndCropBitmapToTarget(Bitmap bitmap, int targetHeight,
+ int targetWidth) {
+ if (bitmap == null) {
+ return bitmap;
+ }
+ // get bitmap properties
+ int bitmapHeight = bitmap.getHeight();
+ int bitmapWidth = bitmap.getWidth();
+
+ int deltaWidth = targetWidth - bitmapWidth;
+ int deltaHeight = targetHeight - bitmapHeight;
+
+ // nothing to do if src bitmap is bigger than or equal to the target
+ if (deltaWidth <= 0 && deltaHeight <= 0)
+ return bitmap;
+
+ // scale bitmap along the dimension that is lacking the greatest
+ float scale = Math.max( ((float)targetWidth) / bitmapWidth,
+ ((float)targetHeight) / bitmapHeight);
+
+ // calculate the new bitmap dimensions
+ int newHeight = (int) Math.ceil(bitmapHeight * scale);
+ int newWidth = (int) Math.ceil(bitmapWidth * scale);
+ Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
+
+ // center the bitmap vertically and horizontally
+ int startX = Math.max(0, (newWidth - targetWidth) / 2);
+ int startY = Math.max(0, (newHeight - targetHeight) / 2);
+ if (DEBUG) {
+ Log.i(TAG, "bitmapWidth : " + bitmapWidth);
+ Log.i(TAG, "bitmapHeight : " + bitmapHeight);
+ Log.i(TAG, "deltaWidth : " + deltaWidth);
+ Log.i(TAG, "deltaHeight : " + deltaHeight);
+ Log.i(TAG, "newWidth : " + newWidth);
+ Log.i(TAG, "newHeight : " + newHeight);
+ Log.i(TAG, "startX : " + startX);
+ Log.i(TAG, "startY : " + startY);
+ }
+
+ return Bitmap.createBitmap(scaledBitmap, startX, startY, targetWidth, targetHeight);
+ }
+
+ /**
+ * Used to convert a drawable into a bitmap.
+ *
+ * Drawables that don't have intrinsic dimensions are excluded from this conversion. This
+ * includes drawables such as ColorDrawables
+ */
+ public static Bitmap drawableToBitmap (Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable)drawable).getBitmap();
+ }
+
+ if (drawable.getIntrinsicHeight() <= 0 || drawable.getIntrinsicWidth() <= 0) {
+ return null;
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+ drawable.getMinimumHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+
+ return bitmap;
+ }
+
+ public static byte[] bitmapToByteArray(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
+ byte[] result = stream.toByteArray();
+ try {
+ stream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ /**
+ * Sets the background for view(v) to a transition drawable that transitions from
+ * the current background to drawable(d)
+ */
+ public static void setBackgroundWithTransition(View v, Drawable d) {
+ Drawable from = v.getBackground();
+
+ // quick solution to prevent memory leak from chaining transition drawables
+ if (from instanceof TransitionDrawable) {
+ TransitionDrawable t = (TransitionDrawable)from;
+ from = t.getDrawable(t.getNumberOfLayers() - 1);
+ }
+
+ Drawable backgrounds[] = new Drawable[2];
+ backgrounds[0] = from;
+ backgrounds[1] = d;
+ TransitionDrawable transitionDrawable = new TransitionDrawable(backgrounds);
+ transitionDrawable.setCrossFadeEnabled(true);
+ v.setBackground(transitionDrawable);
+ transitionDrawable.startTransition(200);
+ }
+}
diff --git a/src/com/android/dialer/util/RoundedTransformation.java b/src/com/android/dialer/util/RoundedTransformation.java
new file mode 100644
index 000000000..4a5ffd50b
--- /dev/null
+++ b/src/com/android/dialer/util/RoundedTransformation.java
@@ -0,0 +1,48 @@
+package com.android.dialer.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import com.android.dialer.R;
+import com.squareup.picasso.Transformation;
+
+public class RoundedTransformation implements Transformation {
+ private static int sRadius = 0;
+
+ RoundedTransformation(Context context) {
+ if (sRadius == 0) {
+ Resources resources = context.getResources();
+ sRadius = resources.getDimensionPixelSize(R.dimen.contact_photo_size);
+ sRadius /= 2;
+ }
+ }
+
+ @Override
+ public Bitmap transform(final Bitmap source) {
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
+
+ Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+ canvas.drawRoundRect(new RectF(0, 0, source.getWidth(), source.getHeight()), sRadius,
+ sRadius, paint);
+
+ if (source != output) {
+ source.recycle();
+ }
+
+ return output;
+ }
+
+ @Override
+ public String key() {
+ return "RoundedTransformation(radius=" + sRadius + ")";
+ }
+} \ No newline at end of file
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index 8c2d8e443..57dc12c18 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -63,7 +63,9 @@ public class CallLogListItemHelperTest extends AndroidTestCase {
new TestTelecomCallLogCache(mContext, TEST_VOICEMAIL_NUMBER);
PhoneCallDetailsHelper phoneCallDetailsHelper =
new PhoneCallDetailsHelper(mContext, mResources, phoneUtils);
- mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mResources, phoneUtils);
+ LookupInfoPresenter lookupInfoPresenter = new LookupInfoPresenter(mContext, mResources);
+ mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, lookupInfoPresenter,
+ mResources, phoneUtils);
mViewHolder = CallLogListItemViewHolder.createForTest(mContext);
}