diff options
author | Matt Garnes <matt@cyngn.com> | 2015-06-09 13:59:40 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-09-21 15:02:49 -0700 |
commit | 4cf2e2ced55b675a7629ae74a61faffa96378656 (patch) | |
tree | 8b32e44341d43b19b24bb4f2838c0b2eaa279348 | |
parent | 6c3c58900bccea7a96b1435e0e0466a6b99dab36 (diff) | |
download | packages_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.mk | 3 | ||||
-rw-r--r-- | AndroidManifest.xml | 6 | ||||
-rw-r--r-- | proguard.flags | 4 | ||||
-rw-r--r-- | res/layout-land/quickcontact_title.xml | 59 | ||||
-rw-r--r-- | res/layout/quickcontact_title.xml | 45 | ||||
-rw-r--r-- | res/values/cm_plurals.xml | 5 | ||||
-rw-r--r-- | res/values/cm_strings.xml | 2 | ||||
-rw-r--r-- | src/com/android/contacts/quickcontact/QuickContactActivity.java | 65 | ||||
-rw-r--r-- | src/com/android/contacts/widget/MultiShrinkScroller.java | 73 |
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}. */ |