summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Garnes <matt@cyngn.com>2015-06-09 13:59:40 -0700
committerGerrit Code Review <gerrit@cyanogenmod.org>2015-09-21 15:02:49 -0700
commit4cf2e2ced55b675a7629ae74a61faffa96378656 (patch)
tree8b32e44341d43b19b24bb4f2838c0b2eaa279348
parent6c3c58900bccea7a96b1435e0e0466a6b99dab36 (diff)
downloadpackages_apps_Contacts-4cf2e2ced55b675a7629ae74a61faffa96378656.tar.gz
packages_apps_Contacts-4cf2e2ced55b675a7629ae74a61faffa96378656.tar.bz2
packages_apps_Contacts-4cf2e2ced55b675a7629ae74a61faffa96378656.zip
Contacts: Add contact lookup with attribution to quick contacts
MMS-86 Change-Id: Ib85ebfd3da14da6f6e04e9a4ec751460a85eeeec
-rw-r--r--Android.mk3
-rw-r--r--AndroidManifest.xml6
-rw-r--r--proguard.flags4
-rw-r--r--res/layout-land/quickcontact_title.xml59
-rw-r--r--res/layout/quickcontact_title.xml45
-rw-r--r--res/values/cm_plurals.xml5
-rw-r--r--res/values/cm_strings.xml2
-rw-r--r--src/com/android/contacts/quickcontact/QuickContactActivity.java65
-rw-r--r--src/com/android/contacts/widget/MultiShrinkScroller.java73
9 files changed, 228 insertions, 34 deletions
diff --git a/Android.mk b/Android.mk
index 124549b50..f724156bd 100644
--- a/Android.mk
+++ b/Android.mk
@@ -29,7 +29,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-v7-palette \
android-support-v4 \
libphonenumber \
- libgeocoding
+ libgeocoding \
+ contacts-picaso
LOCAL_PACKAGE_NAME := Contacts
LOCAL_CERTIFICATE := shared
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4749f5460..d81363e62 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -267,6 +267,12 @@
</intent-filter>
<intent-filter>
+ <action android:name="com.android.contacts.action.QUICK_CONTACT" />
+ <action android:name="android.provider.action.QUICK_CONTACT" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+
+ <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/person" />
diff --git a/proguard.flags b/proguard.flags
index 05071dfe8..fd02097ea 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1,3 +1,7 @@
+-dontwarn com.cyanogen.**
+-dontwarn com.squareup.**
+-dontwarn com.squareup.okhttp.**
+
-keep class com.android.contacts.model.Sources {
public <init>(...);
}
diff --git a/res/layout-land/quickcontact_title.xml b/res/layout-land/quickcontact_title.xml
new file mode 100644
index 000000000..0c704d505
--- /dev/null
+++ b/res/layout-land/quickcontact_title.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/contact_info"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/quickcontact_title_initial_margin"
+ android:layout_marginEnd="@dimen/quickcontact_title_initial_margin"
+ android:layout_marginBottom="@dimen/quickcontact_title_initial_margin"
+ android:layout_gravity="bottom|start"
+ android:orientation="vertical">
+ <!-- The importantForAccessibility is set to "no" since we want the ViewGroup that pretends to be
+ this View's parent (contact photo overlay) to provide the content description for Talkback. -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/actionbar_text_color"
+ android:maxLines="@integer/quickcontact_title_lines"
+ android:textSize="@dimen/quickcontact_maximum_title_size"
+ android:textAlignment="viewStart"
+ android:ellipsize="end"
+ android:importantForAccessibility="no"
+ android:id="@+id/large_title"/>
+
+ <TextView
+ android:id="@+id/contact_spam_count"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14dp"
+ android:textColor="@android:color/white"
+ android:visibility="gone"/>
+
+ <TextView
+ android:id="@+id/contact_info_attribution"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14dp"
+ android:textColor="@android:color/white"
+ android:alpha="0.5"
+ android:visibility="gone"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/quickcontact_title.xml b/res/layout/quickcontact_title.xml
index 3f4886df5..0c40edccd 100644
--- a/res/layout/quickcontact_title.xml
+++ b/res/layout/quickcontact_title.xml
@@ -15,20 +15,45 @@
limitations under the License.
-->
-<!-- The importantForAccessibility is set to "no" since we want the ViewGroup that pretends to be
- this View's parent (contact photo overlay) to provide the content description for Talkback. -->
-<TextView
+
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/contact_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/quickcontact_title_initial_margin"
android:layout_marginEnd="@dimen/quickcontact_title_initial_margin"
android:layout_marginBottom="@dimen/quickcontact_title_initial_margin"
android:layout_gravity="top|start"
- android:textColor="@color/actionbar_text_color"
- android:maxLines="@integer/quickcontact_title_lines"
- android:textSize="@dimen/quickcontact_maximum_title_size"
- android:textAlignment="viewStart"
- android:ellipsize="end"
- android:importantForAccessibility="no"
- android:id="@+id/large_title"/> \ No newline at end of file
+ android:orientation="vertical">
+ <!-- The importantForAccessibility is set to "no" since we want the ViewGroup that pretends to be
+ this View's parent (contact photo overlay) to provide the content description for Talkback. -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/actionbar_text_color"
+ android:maxLines="@integer/quickcontact_title_lines"
+ android:textSize="@dimen/quickcontact_maximum_title_size"
+ android:textAlignment="viewStart"
+ android:ellipsize="end"
+ android:importantForAccessibility="no"
+ android:id="@+id/large_title"/>
+
+ <TextView
+ android:id="@+id/contact_spam_count"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14dp"
+ android:textColor="@android:color/white"
+ android:visibility="gone"/>
+
+ <TextView
+ android:id="@+id/contact_info_attribution"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14dp"
+ android:textColor="@android:color/white"
+ android:alpha="0.5"
+ android:visibility="gone"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/values/cm_plurals.xml b/res/values/cm_plurals.xml
index 78b466bce..a59d2d2ff 100644
--- a/res/values/cm_plurals.xml
+++ b/res/values/cm_plurals.xml
@@ -33,4 +33,9 @@
<item quantity="one">%d contact will be deleted.</item>
<item quantity="other">%d contacts will be deleted.</item>
</plurals>
+
+ <plurals name="spam_count_text">
+ <item quantity="one">%d person marked this as spam</item>
+ <item quantity="other">%d people marked this as spam</item>
+ </plurals>
</resources>
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 313358fae..4b86f01d9 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -73,4 +73,6 @@
<string name="delete_call_message">Deleting call logs\u2026</string>
<string name="delete_call_alert">Delete selected call logs?</string>
<string name="title_del_call">Delete</string>
+
+ <string name="powered_by_provider">Powered by <xliff:g id="provider">%s</xliff:g></string>
</resources>
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 0d154904a..5a095a1e3 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -159,6 +159,8 @@ import com.android.contacts.util.StructuredPostalUtils;
import com.android.contacts.widget.MultiShrinkScroller;
import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
import com.android.contacts.widget.QuickContactImageView;
+import com.squareup.picasso.Picasso;
+
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableList;
@@ -216,6 +218,9 @@ public class QuickContactActivity extends ContactsActivity {
private static final String CALL_ORIGIN_QUICK_CONTACTS_ACTIVITY =
"com.android.contacts.quickcontact.QuickContactActivity";
+ // URI for contact lookup
+ public static final String CONTACT_URI_EXTRA = "contact_uri_extra";
+
/**
* The URI used to load the the Contact. Once the contact is loaded, use Contact#getLookupUri()
* instead of referencing this URI.
@@ -659,7 +664,6 @@ public class QuickContactActivity extends ContactsActivity {
getWindow().setStatusBarColor(Color.TRANSPARENT);
- processIntent(getIntent());
// Show QuickContact in front of soft input
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
@@ -774,7 +778,7 @@ public class QuickContactActivity extends ContactsActivity {
}
});
}
-
+ processIntent(getIntent());
Trace.endSection();
}
@@ -822,15 +826,28 @@ public class QuickContactActivity extends ContactsActivity {
}
mExtraMode = getIntent().getIntExtra(QuickContact.EXTRA_MODE,
QuickContact.MODE_LARGE);
+
final Uri oldLookupUri = mLookupUri;
- if (lookupUri == null) {
+ mLookupUri = lookupUri;
+ mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
+
+ Contact contact = null;
+ if (mLookupUri == null) {
+ // See if a URI has been attached as an extra
+ mLookupUri = intent.getParcelableExtra(CONTACT_URI_EXTRA);
+ contact = ContactLoader.parseEncodedContactEntity(mLookupUri,
+ ContactLoader.EncodedContactEntitySchemaVersion.ENHANCED_CALLER_META_DATA);
+ }
+
+ if (mLookupUri == null) {
finish();
return;
}
- mLookupUri = lookupUri;
- mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
- if (oldLookupUri == null) {
+
+ if (contact != null) {
+ bindContactData(contact);
+ } else if (oldLookupUri == null) {
mContactLoader = (ContactLoader) getLoaderManager().initLoader(
LOADER_CONTACT_ID, null, mLoaderContactCallbacks);
} else if (oldLookupUri != mLookupUri) {
@@ -875,6 +892,21 @@ public class QuickContactActivity extends ContactsActivity {
}
}
+ private void setAttributionText(String value) {
+ if (!TextUtils.isEmpty(value)) {
+ if (mScroller != null) {
+ mScroller.setAttributionText(getString(R.string.powered_by_provider, value));
+ }
+ }
+ }
+
+ private void setSpamCountText(int value) {
+ if (mScroller != null && value > 0) {
+ mScroller.setSpamCountText(
+ getResources().getQuantityString(R.plurals.spam_count_text, value, value));
+ }
+ }
+
/**
* Check if the given MIME-type appears in the list of excluded MIME-types
* that the most-recent caller requested.
@@ -901,10 +933,27 @@ public class QuickContactActivity extends ContactsActivity {
Trace.beginSection("Set display photo & name");
mPhotoView.setIsBusiness(mContactData.isDisplayNameFromOrganization());
- mPhotoSetter.setupContactPhoto(data, mPhotoView);
+ if (mContactData.getPhotoBinaryData() == null && mContactData.getPhotoUri() != null) {
+ Picasso.with(getApplicationContext())
+ .load(mContactData.getPhotoUri())
+ .noPlaceholder()
+ .centerCrop()
+ .resize(480, 640) // Just a reasonable default
+ .into(mPhotoView);
+ } else {
+ mPhotoSetter.setupContactPhoto(data, mPhotoView);
+ }
extractAndApplyTintFromPhotoViewAsynchronously();
setHeaderNameText(ContactDisplayUtils.getDisplayName(this, data).toString());
-
+ setAttributionText(data.getProviderName());
+ final int spamCount = data.getSpamCount();
+ if (spamCount > 0) {
+ mHasComputedThemeColor = true;
+ setThemeColor(mMaterialColorMapUtils
+ .calculatePrimaryAndSecondaryColor(getResources()
+ .getColor(R.color.letter_tile_red_color)));
+ setSpamCountText(spamCount);
+ }
Trace.endSection();
mEntriesAndActionsTask = new AsyncTask<Void, Void, Cp2DataCardModel>() {
diff --git a/src/com/android/contacts/widget/MultiShrinkScroller.java b/src/com/android/contacts/widget/MultiShrinkScroller.java
index 095198ae8..cf9a69834 100644
--- a/src/com/android/contacts/widget/MultiShrinkScroller.java
+++ b/src/com/android/contacts/widget/MultiShrinkScroller.java
@@ -21,7 +21,9 @@ import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Trace;
+import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayInfo;
@@ -110,6 +112,9 @@ public class MultiShrinkScroller extends FrameLayout {
private View mTransparentView;
private MultiShrinkScrollerListener mListener;
private TextView mLargeTextView;
+ private TextView mAttributionTextView;
+ private TextView mSpamCountTextView;
+ private View mContactInfo;
private View mPhotoTouchInterceptOverlay;
/** Contains desired size & vertical offset of the title, once the header is fully compressed */
private TextView mInvisiblePlaceholderTextView;
@@ -132,6 +137,7 @@ public class MultiShrinkScroller extends FrameLayout {
*/
private boolean mIsOpenContactSquare;
private int mMaximumHeaderTextSize;
+ private int mMaximumHeaderInfoSize;
private int mCollapsedTitleBottomMargin;
private int mCollapsedTitleStartMargin;
private int mMinimumPortraitHeaderHeight;
@@ -177,7 +183,7 @@ public class MultiShrinkScroller extends FrameLayout {
};
private final PathInterpolator mTextSizePathInterpolator
- = new PathInterpolator(0.16f, 0.4f, 0.2f, 1);
+ = new PathInterpolator(0.19f, 0.0f, 0.2f, 1);
private final int[] mGradientColors = new int[] {0,0x88000000};
private GradientDrawable mTitleGradientDrawable = new GradientDrawable(
@@ -289,7 +295,10 @@ public class MultiShrinkScroller extends FrameLayout {
mToolbar = findViewById(R.id.toolbar_parent);
mPhotoViewContainer = findViewById(R.id.toolbar_parent);
mTransparentView = findViewById(R.id.transparent_view);
+ mContactInfo = findViewById(R.id.contact_info);
mLargeTextView = (TextView) findViewById(R.id.large_title);
+ mAttributionTextView = (TextView) findViewById(R.id.contact_info_attribution);
+ mSpamCountTextView = (TextView) findViewById(R.id.contact_spam_count);
mInvisiblePlaceholderTextView = (TextView) findViewById(R.id.placeholder_textview);
mStartColumn = findViewById(R.id.empty_start_column);
// Touching the empty space should close the card
@@ -341,6 +350,7 @@ public class MultiShrinkScroller extends FrameLayout {
: mPhotoViewContainer.getWidth();
setHeaderHeight(getMaximumScrollableHeaderHeight());
mMaximumHeaderTextSize = mLargeTextView.getHeight();
+ mMaximumHeaderInfoSize = mContactInfo.getHeight();
if (mIsTwoPanel) {
mMaximumHeaderHeight = getHeight();
mMinimumHeaderHeight = mMaximumHeaderHeight;
@@ -354,8 +364,8 @@ public class MultiShrinkScroller extends FrameLayout {
mPhotoViewContainer.setLayoutParams(photoLayoutParams);
// Permanently set title width and margin.
- final FrameLayout.LayoutParams largeTextLayoutParams
- = (FrameLayout.LayoutParams) mLargeTextView.getLayoutParams();
+ final LinearLayout.LayoutParams largeTextLayoutParams
+ = (LinearLayout.LayoutParams) mLargeTextView.getLayoutParams();
largeTextLayoutParams.width = photoLayoutParams.width -
largeTextLayoutParams.leftMargin - largeTextLayoutParams.rightMargin;
largeTextLayoutParams.gravity = Gravity.BOTTOM | Gravity.START;
@@ -383,8 +393,8 @@ public class MultiShrinkScroller extends FrameLayout {
= (FrameLayout.LayoutParams) mTitleGradientView.getLayoutParams();
final float TITLE_GRADIENT_SIZE_COEFFICIENT = 1.25f;
final FrameLayout.LayoutParams largeTextLayoutParms
- = (FrameLayout.LayoutParams) mLargeTextView.getLayoutParams();
- titleGradientLayoutParams.height = (int) ((mLargeTextView.getHeight()
+ = (FrameLayout.LayoutParams) mContactInfo.getLayoutParams();
+ titleGradientLayoutParams.height = (int) ((mContactInfo.getHeight()
+ largeTextLayoutParms.bottomMargin) * TITLE_GRADIENT_SIZE_COEFFICIENT);
mTitleGradientView.setLayoutParams(titleGradientLayoutParams);
}
@@ -394,6 +404,24 @@ public class MultiShrinkScroller extends FrameLayout {
mPhotoTouchInterceptOverlay.setContentDescription(title);
}
+ public void setAttributionText(String attribution) {
+ if (!TextUtils.isEmpty(attribution)) {
+ mAttributionTextView.setText(attribution);
+ mAttributionTextView.setVisibility(View.VISIBLE);
+ } else {
+ mAttributionTextView.setVisibility(View.GONE);
+ }
+ }
+
+ public void setSpamCountText(String spamCount) {
+ if (!TextUtils.isEmpty(spamCount)) {
+ mSpamCountTextView.setText(spamCount);
+ mSpamCountTextView.setVisibility(View.VISIBLE);
+ } else {
+ mSpamCountTextView.setVisibility(View.GONE);
+ }
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
@@ -997,7 +1025,7 @@ public class MultiShrinkScroller extends FrameLayout {
} else {
mLargeTextView.setPivotX(0);
}
- mLargeTextView.setPivotY(mLargeTextView.getHeight() / 2);
+ mLargeTextView.setPivotY(mContactInfo.getHeight() / 2);
final int toolbarHeight = mToolbar.getLayoutParams().height;
mPhotoTouchInterceptOverlay.setClickable(toolbarHeight != mMaximumHeaderHeight);
@@ -1009,7 +1037,7 @@ public class MultiShrinkScroller extends FrameLayout {
setInterpolatedTitleMargins(1);
return;
}
-
+ mMaximumHeaderInfoSize = mContactInfo.getHeight();
final float ratio = (toolbarHeight - mMinimumHeaderHeight)
/ (float)(mMaximumHeaderHeight - mMinimumHeaderHeight);
final float minimumSize = mInvisiblePlaceholderTextView.getHeight();
@@ -1019,8 +1047,8 @@ public class MultiShrinkScroller extends FrameLayout {
// Clamp to reasonable/finite values before passing into framework. The values
// can be wacky before the first pre-render.
- bezierOutput = (float) Math.min(bezierOutput, 1.0f);
- scale = (float) Math.min(scale, 1.0f);
+ bezierOutput = Math.min(bezierOutput, 1.0f);
+ scale = Math.min(scale, 1.0f);
mLargeTextView.setScaleX(scale);
mLargeTextView.setScaleY(scale);
@@ -1051,7 +1079,7 @@ public class MultiShrinkScroller extends FrameLayout {
*/
private void setInterpolatedTitleMargins(float x) {
final FrameLayout.LayoutParams titleLayoutParams
- = (FrameLayout.LayoutParams) mLargeTextView.getLayoutParams();
+ = (FrameLayout.LayoutParams) mContactInfo.getLayoutParams();
final LinearLayout.LayoutParams toolbarLayoutParams
= (LinearLayout.LayoutParams) mToolbar.getLayoutParams();
@@ -1067,11 +1095,12 @@ public class MultiShrinkScroller extends FrameLayout {
// calling mLargeTextView.getHeight() use the mMaximumHeaderTextSize for this calculation.
// The getHeight() value acts unexpectedly when mLargeTextView is partially clipped by
// its parent.
- titleLayoutParams.topMargin = getTransparentViewHeight()
- + toolbarLayoutParams.height - pretendBottomMargin
- - mMaximumHeaderTextSize;
+ final int minHeaderInfoTopMargin = getTransparentViewHeight()
+ + toolbarLayoutParams.height - pretendBottomMargin - mMaximumHeaderInfoSize;
+ final int topMargin = Math.max(minHeaderInfoTopMargin, 0);
+ titleLayoutParams.topMargin = topMargin;
titleLayoutParams.bottomMargin = 0;
- mLargeTextView.setLayoutParams(titleLayoutParams);
+ mContactInfo.setLayoutParams(titleLayoutParams);
}
private void updatePhotoTintAndDropShadow() {
@@ -1148,7 +1177,11 @@ public class MultiShrinkScroller extends FrameLayout {
mPhotoView.setTint(mHeaderTintColor);
mTitleGradientDrawable.setAlpha(gradientAlpha);
mActionBarGradientDrawable.setAlpha(gradientAlpha);
-
+ final int attributionAlpha = calculateAttributionTextAlpha(toolbarHeight);
+ mAttributionTextView
+ .setTextColor(mAttributionTextView.getTextColors().withAlpha(attributionAlpha));
+ mSpamCountTextView
+ .setTextColor(mSpamCountTextView.getTextColors().withAlpha(attributionAlpha));
Trace.endSection();
}
@@ -1167,6 +1200,16 @@ public class MultiShrinkScroller extends FrameLayout {
return (intermediateHeight - height) / interpolatingHeightRange;
}
+ private int calculateAttributionTextAlpha(int height) {
+ final float ratio = calculateHeightRatioToBlendingStartHeight(height);
+ final float alpha = 1.0f - (float) Math.min(Math.pow(ratio, 1.5f) * 2f, 1f);
+ final float tint = (float) Math.min(Math.pow(ratio, 1.5f) * 3f, 1f);
+ mColorMatrix.setSaturation(alpha);
+ mColorMatrix.postConcat(alphaMatrix(alpha, Color.WHITE));
+ mColorMatrix.postConcat(multiplyBlendMatrix(mHeaderTintColor, tint));
+ return (int) (255 * alpha);
+ }
+
/**
* Simulates alpha blending an image with {@param color}.
*/