Merge "Fix star/unstar on empty contacts by stopping caching them" into lmp-dev
diff --git a/res/layout-sw600dp/search_header.xml b/res/layout-sw600dp/search_header.xml
deleted file mode 100644
index 85f0169..0000000
--- a/res/layout-sw600dp/search_header.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/totalContactsText"
- android:minHeight="@dimen/contact_filter_header_min_height"
- android:paddingTop="24dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorTertiary" />
diff --git a/res/layout-sw720dp/quickcontact_activity.xml b/res/layout-sw720dp/quickcontact_activity.xml
index e8fcf54..efbb4d1 100644
--- a/res/layout-sw720dp/quickcontact_activity.xml
+++ b/res/layout-sw720dp/quickcontact_activity.xml
@@ -33,7 +33,8 @@
android:id="@+id/empty_start_column"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="@integer/contact_list_space_layout_weight"/>
+ android:layout_weight="@integer/contact_list_space_layout_weight"
+ android:contentDescription="@string/quickcontact_transparent_view_description" />
<LinearLayout
android:layout_width="0dp"
@@ -62,7 +63,8 @@
android:id="@+id/empty_end_column"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="@integer/contact_list_space_layout_weight"/>
+ android:layout_weight="@integer/contact_list_space_layout_weight"
+ android:contentDescription="@string/quickcontact_transparent_view_description" />
</LinearLayout>
diff --git a/res/values-sw600dp-land/colors.xml b/res/values-sw600dp-land/colors.xml
index e36bfa6..c5f846e 100644
--- a/res/values-sw600dp-land/colors.xml
+++ b/res/values-sw600dp-land/colors.xml
@@ -14,5 +14,6 @@
limitations under the License.
-->
<resources>
- <color name="list_item_pinned_header_color">#FFFFFF</color>
+ <!-- This needs to match the color of the background card, when the center card is visible. -->
+ <color name="list_item_pinned_header_color">@color/contact_all_list_background_color</color>
</resources>
diff --git a/res/values-sw720dp/colors.xml b/res/values-sw720dp/colors.xml
new file mode 100644
index 0000000..c5f846e
--- /dev/null
+++ b/res/values-sw720dp/colors.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<resources>
+ <!-- This needs to match the color of the background card, when the center card is visible. -->
+ <color name="list_item_pinned_header_color">@color/contact_all_list_background_color</color>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 6cd9c14..985a4e5 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -53,5 +53,5 @@
<color name="call_arrow_red">#ff2e58</color>
<!-- Background color of pinned header items. -->
- <color name="list_item_pinned_header_color">#f5f5f5</color>
+ <color name="list_item_pinned_header_color">@color/background_primary</color>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5497ee2..3d3fc36 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -317,7 +317,7 @@
<!-- Shown as a toast when the user taps on a QuickContact icon, and no application
was found that could perform the selected action. [CHAR LIMIT=NONE] -->
<string name="quickcontact_missing_app">No app was found to handle this action.</string>
- <!-- Content description for the transparent view above the visible section of QuickContacts.
+ <!-- Content description for the transparent views around the visible section of QuickContacts.
Clicking this view causes Quick Contacts to close. [CHAR LIMIT=NONE] -->
<string name="quickcontact_transparent_view_description">Click to return to previous screen</string>
@@ -702,6 +702,19 @@
<!-- Content description for directions secondary button [CHAR LIMIT=NONE] -->
<string name="content_description_directions">directions to location</string>
+ <!-- Content description for recent sms interaction [CHAR LIMIT=NONE] -->
+ <string name="content_description_recent_sms">recent sms. <xliff:g id="message_details">%s</xliff:g>. click to respond</string>
+
+ <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
+ <string name="content_description_recent_call_type_incoming">incoming</string>
+ <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
+ <string name="content_description_recent_call_type_outgoing">outgoing</string>
+ <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
+ <string name="content_description_recent_call_type_missed">missed</string>
+
+ <!-- Content description for recent sms interaction [CHAR LIMIT=NONE] -->
+ <string name="content_description_recent_call">recent call. <xliff:g id="call_details">%s</xliff:g>. click to call back</string>
+
<!-- Prefix for messages that you sent [CHAR LIMIT=40] -->
<string name="message_from_you_prefix">You: <xliff:g id="sms_body">%s</xliff:g></string>
diff --git a/src/com/android/contacts/interactions/CalendarInteraction.java b/src/com/android/contacts/interactions/CalendarInteraction.java
index b3862a2..12a968e 100644
--- a/src/com/android/contacts/interactions/CalendarInteraction.java
+++ b/src/com/android/contacts/interactions/CalendarInteraction.java
@@ -130,7 +130,7 @@
}
public Boolean getAllDay() {
- return mValues.getAsBoolean(Attendees.ALL_DAY);
+ return mValues.getAsInteger(Attendees.ALL_DAY) == 1 ? true : false;
}
public Integer getAvailability() {
@@ -276,4 +276,10 @@
public String getUid2445() {
return mValues.getAsString(Attendees.UID_2445);
}
+
+ @Override
+ public String getContentDescription(Context context) {
+ // The default TalkBack is good
+ return null;
+ }
}
diff --git a/src/com/android/contacts/interactions/CallLogInteraction.java b/src/com/android/contacts/interactions/CallLogInteraction.java
index 28b9655..4e5a143 100644
--- a/src/com/android/contacts/interactions/CallLogInteraction.java
+++ b/src/com/android/contacts/interactions/CallLogInteraction.java
@@ -173,4 +173,33 @@
public Integer getType() {
return mValues.getAsInteger(Calls.TYPE);
}
+
+ @Override
+ public String getContentDescription(Context context) {
+ String callDetails = getCallTypeString(context) + ". " + getViewFooter(context) + ". " +
+ getViewHeader(context) + ". " + getViewFooter(context);
+ return context.getResources().getString(R.string.content_description_recent_call,
+ callDetails);
+ }
+
+ private String getCallTypeString(Context context) {
+ String callType = "";
+ Resources res = context.getResources();
+ Integer type = getType();
+ if (type == null) {
+ return callType;
+ }
+ switch (type) {
+ case Calls.INCOMING_TYPE:
+ callType = res.getString(R.string.content_description_recent_call_type_incoming);
+ break;
+ case Calls.MISSED_TYPE:
+ callType = res.getString(R.string.content_description_recent_call_type_missed);
+ break;
+ case Calls.OUTGOING_TYPE:
+ callType = res.getString(R.string.content_description_recent_call_type_outgoing);
+ break;
+ }
+ return callType;
+ }
}
\ No newline at end of file
diff --git a/src/com/android/contacts/interactions/CallLogInteractionsLoader.java b/src/com/android/contacts/interactions/CallLogInteractionsLoader.java
index 9cbc0b4..14738be 100644
--- a/src/com/android/contacts/interactions/CallLogInteractionsLoader.java
+++ b/src/com/android/contacts/interactions/CallLogInteractionsLoader.java
@@ -23,6 +23,7 @@
import android.database.DatabaseUtils;
import android.net.Uri;
import android.provider.CallLog.Calls;
+import android.telephony.PhoneNumberUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -101,7 +102,8 @@
}
private List<ContactInteraction> getCallLogInteractions(String phoneNumber) {
- final Uri uri = Uri.withAppendedPath(Calls.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
+ final Uri uri = Uri.withAppendedPath(Calls.CONTENT_FILTER_URI,
+ Uri.encode(PhoneNumberUtils.normalizeNumber(phoneNumber)));
// Append the LIMIT clause onto the ORDER BY clause. This won't cause crashes as long
// as we don't also set the {@link android.provider.CallLog.Calls.LIMIT_PARAM_KEY} that
// becomes available in KK.
diff --git a/src/com/android/contacts/interactions/ContactInteraction.java b/src/com/android/contacts/interactions/ContactInteraction.java
index 3f7a842..af19984 100644
--- a/src/com/android/contacts/interactions/ContactInteraction.java
+++ b/src/com/android/contacts/interactions/ContactInteraction.java
@@ -32,4 +32,5 @@
Drawable getIcon(Context context);
Drawable getBodyIcon(Context context);
Drawable getFooterIcon(Context context);
+ String getContentDescription(Context context);
}
diff --git a/src/com/android/contacts/interactions/SmsInteraction.java b/src/com/android/contacts/interactions/SmsInteraction.java
index 3f86eef..bc55572 100644
--- a/src/com/android/contacts/interactions/SmsInteraction.java
+++ b/src/com/android/contacts/interactions/SmsInteraction.java
@@ -152,4 +152,12 @@
public Integer getType() {
return mValues.getAsInteger(Sms.TYPE);
}
+
+ @Override
+ public String getContentDescription(Context context) {
+ String messageDetails = getViewHeader(context) + ". " + getViewBody(context) + ". " +
+ getViewFooter(context);
+ return context.getResources().getString(R.string.content_description_recent_sms,
+ messageDetails);
+ }
}
diff --git a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
index b219988..db1f4a7 100644
--- a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
+++ b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
@@ -75,6 +75,7 @@
private final Drawable mSubHeaderIcon;
private final String mText;
private final Drawable mTextIcon;
+ private final String mPrimaryContentDescription;
private final Intent mIntent;
private final Drawable mAlternateIcon;
private final Intent mAlternateIntent;
@@ -87,17 +88,20 @@
private final String mThirdContentDescription;
public Entry(int id, Drawable icon, String header, String subHeader, String text,
- Intent intent, Drawable alternateIcon, Intent alternateIntent,
- String alternateContentDescription, boolean shouldApplyColor,
- boolean isEditable, EntryContextMenuInfo entryContextMenuInfo,
- Drawable thirdIcon, Intent thirdIntent, String thirdContentDescription) {
- this(id, icon, header, subHeader, null, text, null, intent, alternateIcon,
+ String primaryContentDescription, Intent intent, Drawable alternateIcon,
+ Intent alternateIntent, String alternateContentDescription,
+ boolean shouldApplyColor, boolean isEditable,
+ EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent,
+ String thirdContentDescription) {
+ this(id, icon, header, subHeader, null, text, null, primaryContentDescription, intent,
+ alternateIcon,
alternateIntent, alternateContentDescription, shouldApplyColor, isEditable,
entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
}
public Entry(int id, Drawable mainIcon, String header, String subHeader,
- Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
+ Drawable subHeaderIcon, String text, Drawable textIcon,
+ String primaryContentDescription, Intent intent,
Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription,
boolean shouldApplyColor, boolean isEditable,
EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent,
@@ -109,6 +113,7 @@
mSubHeaderIcon = subHeaderIcon;
mText = text;
mTextIcon = textIcon;
+ mPrimaryContentDescription = primaryContentDescription;
mIntent = intent;
mAlternateIcon = alternateIcon;
mAlternateIntent = alternateIntent;
@@ -145,6 +150,10 @@
return mTextIcon;
}
+ String getPrimaryContentDescription() {
+ return mPrimaryContentDescription;
+ }
+
Intent getIntent() {
return mIntent;
}
@@ -582,6 +591,9 @@
R.layout.expanding_entry_card_item, this, false);
view.setContextMenuInfo(entry.getEntryContextMenuInfo());
+ if (!TextUtils.isEmpty(entry.getPrimaryContentDescription())) {
+ view.setContentDescription(entry.getPrimaryContentDescription());
+ }
final ImageView icon = (ImageView) view.findViewById(R.id.icon);
icon.setVisibility(iconVisibility);
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index b791adc..d664464 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -31,6 +31,7 @@
import android.content.Loader;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
@@ -82,7 +83,6 @@
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.WindowManager;
-import android.widget.ImageView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -212,6 +212,7 @@
private MultiShrinkScroller mScroller;
private SelectAccountDialogFragmentListener mSelectAccountFragmentListener;
private AsyncTask<Void, Void, Cp2DataCardModel> mEntriesAndActionsTask;
+ private AsyncTask<Void, Void, Void> mRecentDataTask;
/**
* The last copy of Cp2DataCardModel that was passed to {@link #populateContactAndAboutCard}.
*/
@@ -942,6 +943,7 @@
getResources().getString(R.string.name_phonetic),
phoneticName,
/* text = */ null,
+ /* primaryContentDescription = */ null,
/* intent = */ null,
/* alternateIcon = */ null,
/* alternateIntent = */ null,
@@ -999,7 +1001,8 @@
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(),
+ /* subHeader = */ null, /* text = */ null, /* primaryContentDescription = */ null,
+ getEditContactIntent(),
/* alternateIcon = */ null, /* alternateIntent = */ null,
/* alternateContentDescription = */ null, /* shouldApplyColor = */ true,
/* isEditable = */ false, /* EntryContextMenuInfo = */ null,
@@ -1010,7 +1013,8 @@
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(), /* alternateIcon = */ null,
+ /* text = */ null, /* primaryContentDescription = */ null,
+ getEditContactIntent(), /* alternateIcon = */ null,
/* alternateIntent = */ null, /* alternateContentDescription = */ null,
/* shouldApplyColor = */ true, /* isEditable = */ false,
/* EntryContextMenuInfo = */ null, /* thirdIcon = */ null,
@@ -1168,11 +1172,12 @@
Drawable subHeaderIcon = null;
String text = null;
Drawable textIcon = null;
+ StringBuilder primaryContentDescription = new StringBuilder();
Intent intent = null;
boolean shouldApplyColor = true;
Drawable alternateIcon = null;
Intent alternateIntent = null;
- String alternateContentDescription = null;
+ StringBuilder alternateContentDescription = new StringBuilder();
final boolean isEditable = false;
EntryContextMenuInfo entryContextMenuInfo = null;
Drawable thirdIcon = null;
@@ -1180,6 +1185,7 @@
String thirdContentDescription = null;
context = context.getApplicationContext();
+ final Resources res = context.getResources();
DataKind kind = dataItem.getDataKind();
if (dataItem instanceof ImDataItem) {
@@ -1195,19 +1201,19 @@
if (protocol == Im.PROTOCOL_CUSTOM) {
// If the protocol is custom, display the "IM" entry header as well to distinguish
// this entry from other ones
- header = context.getResources().getString(R.string.header_im_entry);
- subHeader = Im.getProtocolLabel(context.getResources(), protocol,
+ header = res.getString(R.string.header_im_entry);
+ subHeader = Im.getProtocolLabel(res, protocol,
im.getCustomProtocol()).toString();
text = im.getData();
} else {
- header = Im.getProtocolLabel(context.getResources(), protocol,
+ header = Im.getProtocolLabel(res, protocol,
im.getCustomProtocol()).toString();
subHeader = im.getData();
}
entryContextMenuInfo = new EntryContextMenuInfo(im.getData(), header);
} else if (dataItem instanceof OrganizationDataItem) {
final OrganizationDataItem organization = (OrganizationDataItem) dataItem;
- header = context.getResources().getString(R.string.header_organization_entry);
+ header = res.getString(R.string.header_organization_entry);
subHeader = organization.getCompany();
entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
text = organization.getTitle();
@@ -1222,18 +1228,18 @@
&& contactData.getDisplayNameSource() == DisplayNameSources.NICKNAME;
if (!duplicatesTitle) {
- header = context.getResources().getString(R.string.header_nickname_entry);
+ header = res.getString(R.string.header_nickname_entry);
subHeader = nickname.getName();
entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
}
} else if (dataItem instanceof NoteDataItem) {
final NoteDataItem note = (NoteDataItem) dataItem;
- header = context.getResources().getString(R.string.header_note_entry);
+ header = res.getString(R.string.header_note_entry);
subHeader = note.getNote();
entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
} else if (dataItem instanceof WebsiteDataItem) {
final WebsiteDataItem website = (WebsiteDataItem) dataItem;
- header = context.getResources().getString(R.string.header_website_entry);
+ header = res.getString(R.string.header_website_entry);
subHeader = website.getUrl();
entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
try {
@@ -1255,9 +1261,9 @@
ContentUris.appendId(builder, nextAnniversary.getTime());
intent = new Intent(Intent.ACTION_VIEW).setData(builder.build());
}
- header = context.getResources().getString(R.string.header_event_entry);
+ header = res.getString(R.string.header_event_entry);
if (event.hasKindTypeColumn(kind)) {
- subHeader = Event.getTypeLabel(context.getResources(), event.getKindTypeColumn(kind),
+ subHeader = Event.getTypeLabel(res, event.getKindTypeColumn(kind),
event.getLabel()).toString();
}
text = DateUtils.formatDate(context, dataString);
@@ -1270,99 +1276,114 @@
intent.putExtra(SearchManager.QUERY, dataString);
intent.setType(Contacts.CONTENT_TYPE);
}
- header = context.getResources().getString(R.string.header_relation_entry);
+ header = res.getString(R.string.header_relation_entry);
subHeader = relation.getName();
entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
if (relation.hasKindTypeColumn(kind)) {
- text = Relation.getTypeLabel(context.getResources(),
+ text = Relation.getTypeLabel(res,
relation.getKindTypeColumn(kind),
relation.getLabel()).toString();
}
} else if (dataItem instanceof PhoneDataItem) {
final PhoneDataItem phone = (PhoneDataItem) dataItem;
if (!TextUtils.isEmpty(phone.getNumber())) {
+ primaryContentDescription.append(res.getString(R.string.call_other)).append(" ");
header = phone.buildDataString(context, kind);
entryContextMenuInfo = new EntryContextMenuInfo(header,
- context.getResources().getString(R.string.phoneLabelsGroup));
+ res.getString(R.string.phoneLabelsGroup));
if (phone.hasKindTypeColumn(kind)) {
- text = Phone.getTypeLabel(context.getResources(), phone.getKindTypeColumn(kind),
+ text = Phone.getTypeLabel(res, phone.getKindTypeColumn(kind),
phone.getLabel()).toString();
+ primaryContentDescription.append(text).append(" ");
}
- icon = context.getResources().getDrawable(R.drawable.ic_phone_24dp);
+ primaryContentDescription.append(header);
+ icon = res.getDrawable(R.drawable.ic_phone_24dp);
if (PhoneCapabilityTester.isPhone(context)) {
intent = CallUtil.getCallIntent(phone.getNumber());
}
alternateIntent = new Intent(Intent.ACTION_SENDTO,
Uri.fromParts(CallUtil.SCHEME_SMSTO, phone.getNumber(), null));
- alternateIcon = context.getResources().getDrawable(R.drawable.ic_message_24dp);
- alternateContentDescription = context.getResources().getString(R.string.sms_other);
+ alternateIcon = res.getDrawable(R.drawable.ic_message_24dp);
+ alternateContentDescription.append(res.getString(R.string.sms_custom, header));
// Add video call button if supported
if (CallUtil.isVideoEnabled(context)) {
- thirdIcon = context.getResources().getDrawable(R.drawable.ic_videocam);
+ thirdIcon = res.getDrawable(R.drawable.ic_videocam);
thirdIntent = CallUtil.getVideoCallIntent(phone.getNumber(),
CALL_ORIGIN_QUICK_CONTACTS_ACTIVITY);
thirdContentDescription =
- context.getResources().getString(R.string.description_video_call);
+ res.getString(R.string.description_video_call);
}
}
} else if (dataItem instanceof EmailDataItem) {
final EmailDataItem email = (EmailDataItem) dataItem;
final String address = email.getData();
if (!TextUtils.isEmpty(address)) {
+ primaryContentDescription.append(res.getString(R.string.email_other)).append(" ");
final Uri mailUri = Uri.fromParts(CallUtil.SCHEME_MAILTO, address, null);
intent = new Intent(Intent.ACTION_SENDTO, mailUri);
header = email.getAddress();
entryContextMenuInfo = new EntryContextMenuInfo(header,
- context.getResources().getString(R.string.emailLabelsGroup));
+ res.getString(R.string.emailLabelsGroup));
if (email.hasKindTypeColumn(kind)) {
- text = Email.getTypeLabel(context.getResources(), email.getKindTypeColumn(kind),
+ text = Email.getTypeLabel(res, email.getKindTypeColumn(kind),
email.getLabel()).toString();
+ primaryContentDescription.append(text).append(" ");
}
- icon = context.getResources().getDrawable(R.drawable.ic_email_24dp);
+ primaryContentDescription.append(header);
+ icon = res.getDrawable(R.drawable.ic_email_24dp);
}
} else if (dataItem instanceof StructuredPostalDataItem) {
StructuredPostalDataItem postal = (StructuredPostalDataItem) dataItem;
final String postalAddress = postal.getFormattedAddress();
if (!TextUtils.isEmpty(postalAddress)) {
+ primaryContentDescription.append(res.getString(R.string.map_other)).append(" ");
intent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
header = postal.getFormattedAddress();
entryContextMenuInfo = new EntryContextMenuInfo(header,
- context.getResources().getString(R.string.postalLabelsGroup));
+ res.getString(R.string.postalLabelsGroup));
if (postal.hasKindTypeColumn(kind)) {
- text = StructuredPostal.getTypeLabel(context.getResources(),
+ text = StructuredPostal.getTypeLabel(res,
postal.getKindTypeColumn(kind), postal.getLabel()).toString();
+ primaryContentDescription.append(text).append(" ");
}
+ primaryContentDescription.append(header);
alternateIntent =
StructuredPostalUtils.getViewPostalAddressDirectionsIntent(postalAddress);
- alternateIcon = context.getResources().getDrawable(R.drawable.ic_directions_24dp);
- icon = context.getResources().getDrawable(R.drawable.ic_place_24dp);
+ alternateIcon = res.getDrawable(R.drawable.ic_directions_24dp);
+ alternateContentDescription.append(res.getString(
+ R.string.content_description_directions)).append(" ").append(header);
+ icon = res.getDrawable(R.drawable.ic_place_24dp);
}
} else if (dataItem instanceof SipAddressDataItem) {
if (PhoneCapabilityTester.isSipPhone(context)) {
final SipAddressDataItem sip = (SipAddressDataItem) dataItem;
final String address = sip.getSipAddress();
if (!TextUtils.isEmpty(address)) {
+ primaryContentDescription.append(res.getString(R.string.call_other)).append(
+ " ");
final Uri callUri = Uri.fromParts(CallUtil.SCHEME_SIP, address, null);
intent = CallUtil.getCallIntent(callUri);
header = address;
entryContextMenuInfo = new EntryContextMenuInfo(header,
- context.getResources().getString(R.string.phoneLabelsGroup));
+ res.getString(R.string.phoneLabelsGroup));
if (sip.hasKindTypeColumn(kind)) {
- text = SipAddress.getTypeLabel(context.getResources(),
+ text = SipAddress.getTypeLabel(res,
sip.getKindTypeColumn(kind), sip.getLabel()).toString();
+ primaryContentDescription.append(text).append(" ");
}
- icon = context.getResources().getDrawable(R.drawable.ic_dialer_sip_black_24dp);
+ primaryContentDescription.append(header);
+ icon = res.getDrawable(R.drawable.ic_dialer_sip_black_24dp);
}
}
} else if (dataItem instanceof StructuredNameDataItem) {
final String givenName = ((StructuredNameDataItem) dataItem).getGivenName();
if (!TextUtils.isEmpty(givenName)) {
- aboutCardName.value = context.getResources().getString(R.string.about_card_title) +
+ aboutCardName.value = res.getString(R.string.about_card_title) +
" " + givenName;
} else {
- aboutCardName.value = context.getResources().getString(R.string.about_card_title);
+ aboutCardName.value = res.getString(R.string.about_card_title);
}
} else {
// Custom DataItem
@@ -1380,17 +1401,17 @@
case MIMETYPE_GPLUS_PROFILE:
if (INTENT_DATA_GPLUS_PROFILE_ADD_TO_CIRCLE.equals(
intent.getDataString())) {
- icon = context.getResources().getDrawable(
+ icon = res.getDrawable(
R.drawable.ic_add_to_circles_black_24);
} else {
- icon = context.getResources().getDrawable(R.drawable.ic_google_plus_24dp);
+ icon = res.getDrawable(R.drawable.ic_google_plus_24dp);
}
break;
case MIMETYPE_HANGOUTS:
if (INTENT_DATA_HANGOUTS_VIDEO.equals(intent.getDataString())) {
- icon = context.getResources().getDrawable(R.drawable.ic_hangout_video_24dp);
+ icon = res.getDrawable(R.drawable.ic_hangout_video_24dp);
} else {
- icon = context.getResources().getDrawable(R.drawable.ic_hangout_24dp);
+ icon = res.getDrawable(R.drawable.ic_hangout_24dp);
}
break;
default:
@@ -1417,11 +1438,9 @@
// Do not set the alternate intent is there are no resolves
if (!PhoneCapabilityTester.isIntentRegistered(context, alternateIntent)) {
alternateIntent = null;
- }
-
- // Attempt to use package manager to find a suitable content description if needed
- if (TextUtils.isEmpty(alternateContentDescription)) {
- alternateContentDescription = getIntentResolveLabel(alternateIntent, context);
+ } else if (TextUtils.isEmpty(alternateContentDescription)) {
+ // Attempt to use package manager to find a suitable content description if needed
+ alternateContentDescription.append(getIntentResolveLabel(alternateIntent, context));
}
}
@@ -1435,9 +1454,10 @@
final int dataId = dataItem.getId() > Integer.MAX_VALUE ?
-1 : (int) dataItem.getId();
- return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon, intent,
- alternateIcon, alternateIntent, alternateContentDescription, shouldApplyColor,
- isEditable, entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
+ return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon,
+ primaryContentDescription.toString(), intent, alternateIcon, alternateIntent,
+ alternateContentDescription.toString(), shouldApplyColor, isEditable,
+ entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
}
private List<Entry> dataItemsToEntries(List<DataItem> dataItems,
@@ -1610,6 +1630,7 @@
interaction.getBodyIcon(this),
interaction.getViewFooter(this),
interaction.getFooterIcon(this),
+ interaction.getContentDescription(this),
interaction.getIntent(),
/* alternateIcon = */ null,
/* alternateIntent = */ null,
@@ -1753,41 +1774,66 @@
private void bindRecentData() {
final List<ContactInteraction> allInteractions = new ArrayList<>();
- for (List<ContactInteraction> loaderInteractions : mRecentLoaderResults.values()) {
- allInteractions.addAll(loaderInteractions);
- }
+ final List<List<Entry>> interactionsWrapper = new ArrayList<>();
- // Sort the interactions by most recent
- Collections.sort(allInteractions, new Comparator<ContactInteraction>() {
+ mRecentDataTask = new AsyncTask<Void, Void, Void>() {
@Override
- public int compare(ContactInteraction a, ContactInteraction b) {
- return a.getInteractionDate() >= b.getInteractionDate() ? -1 : 1;
- }
- });
+ protected Void doInBackground(Void... params) {
+ Trace.beginSection("sort recent loader results");
- // Wrap each interaction in its own list so that an icon is displayed for each entry
- List<List<Entry>> interactionsWrapper = new ArrayList<>();
- for (Entry contactInteraction : contactInteractionsToEntries(allInteractions)) {
- List<Entry> entryListWrapper = new ArrayList<>(1);
- entryListWrapper.add(contactInteraction);
- interactionsWrapper.add(entryListWrapper);
- }
- if (allInteractions.size() > 0) {
- mRecentCard.initialize(interactionsWrapper,
+ for (List<ContactInteraction> loaderInteractions : mRecentLoaderResults.values()) {
+ allInteractions.addAll(loaderInteractions);
+ }
+
+ // Sort the interactions by most recent
+ Collections.sort(allInteractions, new Comparator<ContactInteraction>() {
+ @Override
+ public int compare(ContactInteraction a, ContactInteraction b) {
+ return a.getInteractionDate() >= b.getInteractionDate() ? -1 : 1;
+ }
+ });
+
+ Trace.endSection();
+ Trace.beginSection("contactInteractionsToEntries");
+
+ // Wrap each interaction in its own list so that an icon is displayed for each entry
+ for (Entry contactInteraction : contactInteractionsToEntries(allInteractions)) {
+ List<Entry> entryListWrapper = new ArrayList<>(1);
+ entryListWrapper.add(contactInteraction);
+ interactionsWrapper.add(entryListWrapper);
+ }
+
+ Trace.endSection();
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Void aVoid) {
+ super.onPostExecute(aVoid);
+ Trace.beginSection("initialize recents card");
+
+ if (allInteractions.size() > 0) {
+ mRecentCard.initialize(interactionsWrapper,
/* numInitialVisibleEntries = */ MIN_NUM_COLLAPSED_RECENT_ENTRIES_SHOWN,
/* isExpanded = */ mRecentCard.isExpanded(), /* isAlwaysExpanded = */ false,
- mExpandingEntryCardViewListener, mScroller);
- mRecentCard.setVisibility(View.VISIBLE);
- }
+ mExpandingEntryCardViewListener, mScroller);
+ mRecentCard.setVisibility(View.VISIBLE);
+ }
- // About card is initialized along with the contact card, but since it appears after
- // the recent card in the UI, we hold off until making it visible until the recent card
- // is also ready to avoid stuttering.
- if (mAboutCard.shouldShow()) {
- mAboutCard.setVisibility(View.VISIBLE);
- } else {
- mAboutCard.setVisibility(View.GONE);
- }
+ Trace.endSection();
+
+ // About card is initialized along with the contact card, but since it appears after
+ // the recent card in the UI, we hold off until making it visible until the recent
+ // card is also ready to avoid stuttering.
+ if (mAboutCard.shouldShow()) {
+ mAboutCard.setVisibility(View.VISIBLE);
+ } else {
+ mAboutCard.setVisibility(View.GONE);
+ }
+ mRecentDataTask = null;
+ }
+ };
+ mRecentDataTask.execute();
}
@Override
@@ -1801,6 +1847,9 @@
// the entire process will be killed.
mEntriesAndActionsTask.cancel(/* mayInterruptIfRunning = */ false);
}
+ if (mRecentDataTask != null) {
+ mRecentDataTask.cancel(/* mayInterruptIfRunning = */ false);
+ }
}
/**