Adds secondary icons and intents to entries if they exist
Bug: 16206384
Change-Id: I759c842d3be6e7c7b28bc4ef52d2d3935dd7931c
diff --git a/res/layout/expanding_entry_card_item.xml b/res/layout/expanding_entry_card_item.xml
index dcf3b02..9195800 100644
--- a/res/layout/expanding_entry_card_item.xml
+++ b/res/layout/expanding_entry_card_item.xml
@@ -31,7 +31,8 @@
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="@dimen/expanding_entry_card_item_image_spacing"
- android:scaleType="fitCenter" />
+ android:scaleType="fitCenter"
+ android:layout_marginTop="@dimen/expanding_entry_card_item_icon_margin_top" />
<TextView
android:id="@+id/header"
@@ -76,4 +77,15 @@
android:layout_marginTop="@dimen/expanding_entry_card_item_text_icon_margin_top"
android:layout_marginEnd="@dimen/expanding_entry_card_item_text_icon_margin_right" />
-</RelativeLayout>
\ No newline at end of file
+ <ImageView
+ android:id="@+id/icon_alternate"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentTop="true"
+ android:visibility="gone"
+ android:layout_marginEnd="@dimen/expanding_entry_card_item_alternate_icon_margin_end"
+ android:layout_marginTop="@dimen/expanding_entry_card_item_icon_margin_top"
+ android:layout_marginBottom="@dimen/expanding_entry_card_item_alternate_icon_margin_bottom" />
+
+</RelativeLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3f3f31c..877a68f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -183,6 +183,10 @@
<dimen name="expanding_entry_card_item_sub_header_icon_margin_right">4dp</dimen>
<dimen name="expanding_entry_card_item_sub_header_icon_margin_bottom">14dp</dimen>
+ <dimen name="expanding_entry_card_item_icon_margin_top">8dp</dimen>
+ <dimen name="expanding_entry_card_item_alternate_icon_margin_end">0dp</dimen>
+ <dimen name="expanding_entry_card_item_alternate_icon_margin_bottom">10dp</dimen>
+
<dimen name="people_activity_card_elevation">2dp</dimen>
<dimen name="expanding_entry_card_item_icon_height">24dp</dimen>
diff --git a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
index e3c8354..69b0d49 100644
--- a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
+++ b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
@@ -24,11 +24,13 @@
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.ColorFilter;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -60,17 +62,23 @@
private final String mText;
private final Drawable mTextIcon;
private final Intent mIntent;
+ private final Drawable mAlternateIcon;
+ private final Intent mAlternateIntent;
+ private final String mAlternateContentDescription;
private final boolean mShouldApplyColor;
private final boolean mIsEditable;
public Entry(int viewId, Drawable icon, String header, String subHeader, String text,
- Intent intent, boolean shouldApplyColor, boolean isEditable) {
- this(viewId, icon, header, subHeader, null, text, null, intent, shouldApplyColor,
- isEditable);
+ Intent intent, Drawable alternateIcon, Intent alternateIntent,
+ String alternateContentDescription, boolean shouldApplyColor,
+ boolean isEditable) {
+ this(viewId, icon, header, subHeader, null, text, null, intent, alternateIcon,
+ alternateIntent, alternateContentDescription, shouldApplyColor, isEditable);
}
public Entry(int viewId, Drawable mainIcon, String header, String subHeader,
Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
+ Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription,
boolean shouldApplyColor, boolean isEditable) {
mViewId = viewId;
mIcon = mainIcon;
@@ -80,6 +88,9 @@
mText = text;
mTextIcon = textIcon;
mIntent = intent;
+ mAlternateIcon = alternateIcon;
+ mAlternateIntent = alternateIntent;
+ mAlternateContentDescription = alternateContentDescription;
mShouldApplyColor = shouldApplyColor;
mIsEditable = isEditable;
}
@@ -112,6 +123,18 @@
return mIntent;
}
+ Drawable getAlternateIcon() {
+ return mAlternateIcon;
+ }
+
+ Intent getAlternateIntent() {
+ return mAlternateIntent;
+ }
+
+ String getAlternateContentDescription() {
+ return mAlternateContentDescription;
+ }
+
boolean shouldApplyColor() {
return mShouldApplyColor;
}
@@ -397,6 +420,10 @@
icon.setColorFilter(mThemeColorFilter);
}
}
+ Drawable alternateIcon = entry.getAlternateIcon();
+ if (alternateIcon != null) {
+ alternateIcon.setColorFilter(mThemeColorFilter);
+ }
}
}
}
@@ -410,47 +437,47 @@
// TODO add accessibility content descriptions
private View createEntryView(LayoutInflater layoutInflater, Entry entry) {
- View view = layoutInflater.inflate(
+ final View view = layoutInflater.inflate(
R.layout.expanding_entry_card_item, this, false);
view.setId(entry.getViewId());
- ImageView icon = (ImageView) view.findViewById(R.id.icon);
+ final ImageView icon = (ImageView) view.findViewById(R.id.icon);
if (entry.getIcon() != null) {
icon.setImageDrawable(entry.getIcon());
} else {
icon.setVisibility(View.GONE);
}
- TextView header = (TextView) view.findViewById(R.id.header);
+ final TextView header = (TextView) view.findViewById(R.id.header);
if (entry.getHeader() != null) {
header.setText(entry.getHeader());
} else {
header.setVisibility(View.GONE);
}
- TextView subHeader = (TextView) view.findViewById(R.id.sub_header);
+ final TextView subHeader = (TextView) view.findViewById(R.id.sub_header);
if (entry.getSubHeader() != null) {
subHeader.setText(entry.getSubHeader());
} else {
subHeader.setVisibility(View.GONE);
}
- ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header);
+ final ImageView subHeaderIcon = (ImageView) view.findViewById(R.id.icon_sub_header);
if (entry.getSubHeaderIcon() != null) {
subHeaderIcon.setImageDrawable(entry.getSubHeaderIcon());
} else {
subHeaderIcon.setVisibility(View.GONE);
}
- TextView text = (TextView) view.findViewById(R.id.text);
+ final TextView text = (TextView) view.findViewById(R.id.text);
if (entry.getText() != null) {
text.setText(entry.getText());
} else {
text.setVisibility(View.GONE);
}
- ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text);
+ final ImageView textIcon = (ImageView) view.findViewById(R.id.icon_text);
if (entry.getTextIcon() != null) {
textIcon.setImageDrawable(entry.getTextIcon());
} else {
@@ -462,6 +489,35 @@
view.setTag(entry.getIntent());
}
+ final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate);
+ if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) {
+ alternateIcon.setImageDrawable(entry.getAlternateIcon());
+ alternateIcon.setOnClickListener(mOnClickListener);
+ alternateIcon.setTag(entry.getAlternateIntent());
+ alternateIcon.setId(entry.getViewId());
+ alternateIcon.setVisibility(View.VISIBLE);
+ alternateIcon.setContentDescription(entry.getAlternateContentDescription());
+
+ // Expand the clickable area for alternate icon to be top to bottom and to right edge
+ // of the entry view
+ view.post(new Runnable() {
+ @Override
+ public void run() {
+ final Rect entryRect = new Rect();
+ view.getHitRect(entryRect);
+
+ final Rect alternateIconRect = new Rect();
+ alternateIcon.getHitRect(alternateIconRect);
+ alternateIconRect.right = entryRect.right;
+ alternateIconRect.bottom = entryRect.bottom;
+ alternateIconRect.top = entryRect.top;
+ final TouchDelegate touchDelegate =
+ new TouchDelegate(alternateIconRect, alternateIcon);
+ view.setTouchDelegate(touchDelegate);
+ }
+ });
+ }
+
return view;
}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 1868d87..6548b7c 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -31,6 +31,8 @@
import android.content.ContentValues;
import android.content.Intent;
import android.content.Loader;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
@@ -127,7 +129,6 @@
import com.android.contacts.util.StructuredPostalUtils;
import com.android.contacts.widget.MultiShrinkScroller;
import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
-
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@@ -162,7 +163,6 @@
private static final int ANIMATION_STATUS_BAR_COLOR_CHANGE_DURATION = 150;
private static final int REQUEST_CODE_CONTACT_EDITOR_ACTIVITY = 1;
private static final int SCRIM_COLOR = Color.argb(0xB2, 0, 0, 0);
- private static final String SCHEME_SMSTO = "smsto";
private static final String MIMETYPE_SMS = "vnd.android-dir/mms-sms";
/** This is the Intent action to install a shortcut in the launcher. */
@@ -210,7 +210,6 @@
private boolean mIsWaitingForOtherPieceOfExitAnimation;
private boolean mIsExitAnimationInProgress;
private boolean mHasComputedThemeColor;
- private ComponentName mSmsComponent;
private Contact mContactData;
private ContactLoader mContactLoader;
@@ -299,7 +298,7 @@
String usageType = DataUsageFeedback.USAGE_TYPE_CALL;
final String scheme = intent.getData().getScheme();
- if ((scheme != null && scheme.equals(SCHEME_SMSTO)) ||
+ if ((scheme != null && scheme.equals(CallUtil.SCHEME_SMSTO)) ||
(intent.getType() != null && intent.getType().equals(MIMETYPE_SMS))) {
usageType = DataUsageFeedback.USAGE_TYPE_SHORT_TEXT;
}
@@ -502,8 +501,6 @@
setContentView(R.layout.quickcontact_activity);
- mSmsComponent = PhoneCapabilityTester.getSmsComponent(this);
-
mContactCard = (ExpandingEntryCardView) findViewById(R.id.communication_card);
mNoContactDetailsCard = (ExpandingEntryCardView) findViewById(R.id.no_contact_data_card);
mRecentCard = (ExpandingEntryCardView) findViewById(R.id.recent_card);
@@ -852,15 +849,18 @@
R.drawable.ic_phone_24dp).mutate();
final Entry phonePromptEntry = new Entry(CARD_ENTRY_ID_EDIT_CONTACT,
phoneIcon, getString(R.string.quickcontact_add_phone_number),
- /* subHeader = */ null, /* text = */ null,
- getEditContactIntent(), /* shouldApplyColor = */ false, /* isEditable = */ false);
+ /* subHeader = */ null, /* text = */ null, getEditContactIntent(),
+ /* alternateIcon = */ null, /* alternateIntent = */ null,
+ /* alternateContentDescription = */ null, /* shouldApplyColor = */ false,
+ /* isEditable = */ false);
final Drawable emailIcon = getResources().getDrawable(
R.drawable.ic_email_24dp).mutate();
final Entry emailPromptEntry = new Entry(CARD_ENTRY_ID_EDIT_CONTACT,
emailIcon, getString(R.string.quickcontact_add_email), /* subHeader = */ null,
- /* text = */ null, getEditContactIntent(), /* shouldApplyColor = */ false,
- /* isEditable = */ false);
+ /* text = */ null, getEditContactIntent(), /* alternateIcon = */ null,
+ /* alternateIntent = */ null, /* alternateContentDescription = */ null,
+ /* shouldApplyColor = */ false, /* isEditable = */ false);
final List<List<Entry>> promptEntries = new ArrayList<>();
promptEntries.add(new ArrayList<Entry>(1));
@@ -963,6 +963,9 @@
Drawable textIcon = null;
Intent intent = null;
boolean shouldApplyColor = true;
+ Drawable alternateIcon = null;
+ Intent alternateIntent = null;
+ String alternateContentDescription = null;
final boolean isEditable = false;
DataKind kind = dataItem.getDataKind();
@@ -1052,6 +1055,10 @@
if (PhoneCapabilityTester.isPhone(this)) {
intent = CallUtil.getCallIntent(phone.getNumber());
}
+ alternateIntent = new Intent(Intent.ACTION_SENDTO,
+ Uri.fromParts(CallUtil.SCHEME_SMSTO, phone.getNumber(), null));
+ alternateIcon = getResources().getDrawable(R.drawable.ic_message_24dp);
+ alternateContentDescription = getResources().getString(R.string.sms_other);
}
} else if (dataItem instanceof EmailDataItem) {
final EmailDataItem email = (EmailDataItem) dataItem;
@@ -1154,6 +1161,18 @@
}
}
+ if (alternateIntent != null) {
+ // Do not set the alternate intent is there are no resolves
+ if (!PhoneCapabilityTester.isIntentRegistered(this, alternateIntent)) {
+ alternateIntent = null;
+ }
+
+ // Attempt to use package manager to find a suitable content description if needed
+ if (TextUtils.isEmpty(alternateContentDescription)) {
+ alternateContentDescription = getIntentResolveLabel(alternateIntent);
+ }
+ }
+
// If the Entry has no visual elements, return null
if (icon == null && TextUtils.isEmpty(header) && TextUtils.isEmpty(subHeader) &&
subHeaderIcon == null && TextUtils.isEmpty(text) && textIcon == null) {
@@ -1163,8 +1182,9 @@
final int dataId = dataItem.getId() > Integer.MAX_VALUE ?
-1 : (int) dataItem.getId();
- return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon,
- intent, shouldApplyColor, isEditable);
+ return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon, intent,
+ alternateIcon, alternateIntent, alternateContentDescription, shouldApplyColor,
+ isEditable);
}
private List<Entry> dataItemsToEntries(List<DataItem> dataItems) {
@@ -1174,31 +1194,30 @@
if (entry != null) {
entries.add(entry);
}
- // TODO merge secondary intents
- if (dataItem instanceof PhoneDataItem) {
- final PhoneDataItem phone = (PhoneDataItem) dataItem;
- Intent smsIntent = null;
- if (mSmsComponent != null) {
- smsIntent = new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts(CallUtil.SCHEME_SMSTO, phone.getNumber(), null));
- smsIntent.setComponent(mSmsComponent);
- }
- final int dataId = dataItem.getId() > Integer.MAX_VALUE ?
- -1 : (int) dataItem.getId();
- entries.add(new Entry(dataId,
- getResources().getDrawable(R.drawable.ic_message_24dp),
- getResources().getString(R.string.send_message),
- /* subHeader = */ null,
- /* text = */ phone.buildDataString(this,
- dataItem.getDataKind()),
- smsIntent,
- /* shouldApplyColor = */ true,
- /* isEditable = */ false));
- }
}
return entries;
}
+ private String getIntentResolveLabel(Intent intent) {
+ final List<ResolveInfo> matches = getPackageManager().queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+
+ // Pick first match, otherwise best found
+ ResolveInfo bestResolve = null;
+ final int size = matches.size();
+ if (size == 1) {
+ bestResolve = matches.get(0);
+ } else if (size > 1) {
+ bestResolve = ResolveCache.getInstance(this).getBestResolve(intent, matches);
+ }
+
+ if (bestResolve == null) {
+ return null;
+ }
+
+ return String.valueOf(bestResolve.loadLabel(getPackageManager()));
+ }
+
/**
* Asynchronously extract the most vibrant color from the PhotoView. Once extracted,
* apply this tint to {@link MultiShrinkScroller}. This operation takes about 20-30ms
@@ -1330,6 +1349,9 @@
interaction.getViewFooter(this),
interaction.getFooterIcon(this),
interaction.getIntent(),
+ /* alternateIcon = */ null,
+ /* alternateIntent = */ null,
+ /* alternateContentDescription = */ null,
/* shouldApplyColor = */ true,
/* isEditable = */ false));
}