summaryrefslogtreecommitdiffstats
path: root/java/com/android/contacts/common
diff options
context:
space:
mode:
authorTobias Thierer <tobiast@google.com>2017-06-09 14:16:05 +0000
committerTobias Thierer <tobiast@google.com>2017-06-09 14:16:05 +0000
commitcded3beaf28a703e1ef8f71bbc6836e6806c3736 (patch)
treec1b5e8199b5996fc848e7455d04126b9cdbb3c39 /java/com/android/contacts/common
parentc67d658e7daa453fe9ad9fd1a37f81eaf2048c44 (diff)
downloadandroid_packages_apps_Dialer-cded3beaf28a703e1ef8f71bbc6836e6806c3736.tar.gz
android_packages_apps_Dialer-cded3beaf28a703e1ef8f71bbc6836e6806c3736.tar.bz2
android_packages_apps_Dialer-cded3beaf28a703e1ef8f71bbc6836e6806c3736.zip
Revert "Update AOSP Dialer source from internal google3 repository at cl/158012278. am: 91ce7d2a47"
This reverts commit c67d658e7daa453fe9ad9fd1a37f81eaf2048c44. Reason for revert: This CL broke the sailfish-userdebug_javac-all target on master. Change-Id: I9b54333a654c00154ca84f4ece84bea4f07cc19b
Diffstat (limited to 'java/com/android/contacts/common')
-rw-r--r--java/com/android/contacts/common/ClipboardUtils.java2
-rw-r--r--java/com/android/contacts/common/ContactPhotoManager.java31
-rw-r--r--java/com/android/contacts/common/ContactPhotoManagerImpl.java5
-rw-r--r--java/com/android/contacts/common/ContactStatusUtil.java2
-rw-r--r--java/com/android/contacts/common/ContactsUtils.java185
-rw-r--r--java/com/android/contacts/common/GeoUtil.java55
-rw-r--r--java/com/android/contacts/common/MoreContactUtils.java36
-rw-r--r--java/com/android/contacts/common/compat/ContactsCompat.java16
-rw-r--r--java/com/android/contacts/common/compat/PhoneAccountCompat.java55
-rw-r--r--java/com/android/contacts/common/compat/PhoneNumberUtilsCompat.java132
-rw-r--r--java/com/android/contacts/common/compat/TelephonyManagerCompat.java71
-rw-r--r--java/com/android/contacts/common/compat/telecom/TelecomManagerCompat.java260
-rw-r--r--java/com/android/contacts/common/dialog/CallSubjectDialog.java12
-rw-r--r--java/com/android/contacts/common/format/FormatUtils.java181
-rw-r--r--java/com/android/contacts/common/format/TextHighlighter.java55
-rw-r--r--java/com/android/contacts/common/format/testing/SpannedTestUtils.java85
-rw-r--r--java/com/android/contacts/common/lettertiles/LetterTileDrawable.java28
-rw-r--r--java/com/android/contacts/common/list/ContactEntryListAdapter.java9
-rw-r--r--java/com/android/contacts/common/list/ContactEntryListFragment.java1
-rw-r--r--java/com/android/contacts/common/list/ContactListItemView.java216
-rw-r--r--java/com/android/contacts/common/list/ContactTileView.java19
-rw-r--r--java/com/android/contacts/common/list/PhoneNumberListAdapter.java56
-rw-r--r--java/com/android/contacts/common/list/PhoneNumberPickerFragment.java66
-rw-r--r--java/com/android/contacts/common/list/ViewPagerTabs.java29
-rw-r--r--java/com/android/contacts/common/location/CountryDetector.java221
-rw-r--r--java/com/android/contacts/common/location/UpdateCountryService.java104
-rw-r--r--java/com/android/contacts/common/model/ContactLoader.java1
-rw-r--r--java/com/android/contacts/common/model/account/BaseAccountType.java4
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_ab_search.pngbin0 -> 1115 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_arrow_back_24dp.pngbin0 -> 612 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_business_white_120dp.pngbin0 -> 2477 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_call_24dp.pngbin0 -> 340 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_close_dk.pngbin0 -> 609 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_create_24dp.pngbin0 -> 370 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_group_white_24dp.pngbin0 -> 389 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_history_white_drawable_24dp.pngbin0 -> 525 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_info_outline_24dp.pngbin0 -> 485 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_back.pngbin0 -> 799 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_dk.pngbin0 -> 1954 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_lt.pngbin0 -> 1922 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_overflow_lt.pngbin0 -> 220 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_dk.pngbin0 -> 1439 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_lt.pngbin0 -> 1416 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_remove_field_holo_light.pngbin0 -> 515 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_dk.pngbin0 -> 1438 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_holo_light.pngbin0 -> 1211 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_lt.pngbin0 -> 1414 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_person_24dp.pngbin0 -> 273 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_rx_videocam.pngbin0 -> 413 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_tx_videocam.pngbin0 -> 370 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_videocam.pngbin0 -> 269 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/ic_voicemail_avatar.pngbin0 -> 2856 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_activated_holo.9.pngbin0 -> 154 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_background_holo.9.pngbin0 -> 224 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_focused_holo.9.pngbin0 -> 235 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_longpressed_holo_light.9.pngbin0 -> 158 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_pressed_holo_light.9.pngbin0 -> 159 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_section_divider_holo_custom.9.pngbin0 -> 205 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-hdpi/list_title_holo.9.pngbin0 -> 267 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_focused_holo.9.pngbin0 -> 234 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_section_divider_holo_custom.9.pngbin0 -> 191 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_title_holo.9.pngbin0 -> 258 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_focused_holo.9.pngbin0 -> 234 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_section_divider_holo_custom.9.pngbin0 -> 180 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_title_holo.9.pngbin0 -> 186 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-hdpi/list_activated_holo.9.pngbin0 -> 1666 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-mdpi/list_activated_holo.9.pngbin0 -> 1034 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-xhdpi/list_activated_holo.9.pngbin0 -> 2486 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_focused_holo.9.pngbin0 -> 234 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_section_divider_holo_custom.9.pngbin0 -> 196 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_title_holo.9.pngbin0 -> 255 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-mdpi/list_activated_holo.9.pngbin0 -> 151 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-mdpi/list_focused_holo.9.pngbin0 -> 235 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-mdpi/list_longpressed_holo_light.9.pngbin0 -> 155 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-mdpi/list_pressed_holo_light.9.pngbin0 -> 158 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-mdpi/list_section_divider_holo_custom.9.pngbin0 -> 198 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-sw600dp-hdpi/list_activated_holo.9.pngbin0 -> 1659 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-sw600dp-mdpi/list_activated_holo.9.pngbin0 -> 1005 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-sw600dp-xhdpi/list_activated_holo.9.pngbin0 -> 2478 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xhdpi/list_activated_holo.9.pngbin0 -> 158 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xhdpi/list_focused_holo.9.pngbin0 -> 235 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xhdpi/list_longpressed_holo_light.9.pngbin0 -> 162 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xhdpi/list_pressed_holo_light.9.pngbin0 -> 163 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xhdpi/list_section_divider_holo_custom.9.pngbin0 -> 210 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xxhdpi/list_activated_holo.9.pngbin0 -> 1140 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xxhdpi/list_focused_holo.9.pngbin0 -> 1147 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xxhdpi/list_longpressed_holo_light.9.pngbin0 -> 1051 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable-xxhdpi/list_pressed_holo_light.9.pngbin0 -> 1051 bytes
-rw-r--r--java/com/android/contacts/common/res/drawable/ic_back_arrow.xml20
-rw-r--r--java/com/android/contacts/common/res/drawable/ic_call_and_share.xml22
-rw-r--r--java/com/android/contacts/common/res/drawable/ic_person_add_tinted_24dp.xml20
-rw-r--r--java/com/android/contacts/common/res/drawable/ic_search_add_contact.xml20
-rw-r--r--java/com/android/contacts/common/res/drawable/ic_search_video_call.xml22
-rw-r--r--java/com/android/contacts/common/res/drawable/list_selector_background_transition_holo_light.xml20
-rw-r--r--java/com/android/contacts/common/res/layout/dialog_call_subject.xml2
-rw-r--r--java/com/android/contacts/common/res/layout/search_bar_expanded.xml4
-rw-r--r--java/com/android/contacts/common/res/values-af/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-am/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ar/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-az/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-b+sr+Latn/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-be/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-bg/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-bn/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-bs/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ca/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-cs/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-da/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-de/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-el/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-en-rAU/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-en-rGB/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-en-rIN/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-es-rUS/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-es/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-et/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-eu/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-fa/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-fi/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-fr-rCA/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-fr/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-gl/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-gu/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-hi/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-hr/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-hu/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-hy/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-in/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-is/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-it/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-iw/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ja/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ka/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-kk/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-km/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-kn/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ko/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ky/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-lo/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-lt/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-lv/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-mk/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ml/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-mn/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-mr/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ms/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-my/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-nb/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ne/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-nl/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-no/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-pa/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-pl/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-pt-rBR/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-pt-rPT/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-pt/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ro/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ru/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-si/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sk/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sl/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sq/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sr/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sv/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-sw/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ta/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-te/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-th/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-tl/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-tr/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-uk/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-ur/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-uz/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-vi/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-zh-rCN/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-zh-rHK/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-zh-rTW/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values-zu/strings.xml2
-rw-r--r--java/com/android/contacts/common/res/values/ids.xml1
-rw-r--r--java/com/android/contacts/common/res/values/strings.xml6
-rw-r--r--java/com/android/contacts/common/res/values/styles.xml1
-rw-r--r--java/com/android/contacts/common/util/AccountFilterUtil.java42
-rw-r--r--java/com/android/contacts/common/util/BitmapUtil.java26
-rw-r--r--java/com/android/contacts/common/util/ContactDisplayUtils.java12
-rw-r--r--java/com/android/contacts/common/util/DateUtils.java241
-rw-r--r--java/com/android/contacts/common/util/MaterialColorMapUtils.java8
-rw-r--r--java/com/android/contacts/common/util/NameConverter.java242
-rw-r--r--java/com/android/contacts/common/util/StopWatch.java28
-rw-r--r--java/com/android/contacts/common/util/TelephonyManagerUtils.java9
-rw-r--r--java/com/android/contacts/common/util/TrafficStatsTags.java22
190 files changed, 2472 insertions, 397 deletions
diff --git a/java/com/android/contacts/common/ClipboardUtils.java b/java/com/android/contacts/common/ClipboardUtils.java
index 3d7683941..9345b0f9c 100644
--- a/java/com/android/contacts/common/ClipboardUtils.java
+++ b/java/com/android/contacts/common/ClipboardUtils.java
@@ -24,6 +24,8 @@ import android.widget.Toast;
public class ClipboardUtils {
+ private static final String TAG = "ClipboardUtils";
+
private ClipboardUtils() {}
/**
diff --git a/java/com/android/contacts/common/ContactPhotoManager.java b/java/com/android/contacts/common/ContactPhotoManager.java
index 3e1a78f63..169348b25 100644
--- a/java/com/android/contacts/common/ContactPhotoManager.java
+++ b/java/com/android/contacts/common/ContactPhotoManager.java
@@ -36,6 +36,14 @@ import com.android.dialer.util.PermissionsUtil;
/** Asynchronously loads contact photos and maintains a cache of photos. */
public abstract class ContactPhotoManager implements ComponentCallbacks2 {
+ /** Contact type constants used for default letter images */
+ public static final int TYPE_PERSON = LetterTileDrawable.TYPE_PERSON;
+
+ public static final int TYPE_SPAM = LetterTileDrawable.TYPE_SPAM;
+ public static final int TYPE_BUSINESS = LetterTileDrawable.TYPE_BUSINESS;
+ public static final int TYPE_VOICEMAIL = LetterTileDrawable.TYPE_VOICEMAIL;
+ public static final int TYPE_DEFAULT = LetterTileDrawable.TYPE_DEFAULT;
+ public static final int TYPE_GENERIC_AVATAR = LetterTileDrawable.TYPE_GENERIC_AVATAR;
/** Scale and offset default constants used for default letter images */
public static final float SCALE_DEFAULT = 1.0f;
@@ -80,7 +88,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
if (!TextUtils.isEmpty(request.identifier)) {
builder.appendQueryParameter(IDENTIFIER_PARAM_KEY, request.identifier);
}
- if (request.contactType != LetterTileDrawable.TYPE_DEFAULT) {
+ if (request.contactType != TYPE_DEFAULT) {
builder.appendQueryParameter(CONTACT_TYPE_PARAM_KEY, String.valueOf(request.contactType));
}
if (request.scale != SCALE_DEFAULT) {
@@ -106,7 +114,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
public static String appendBusinessContactType(String photoUrl) {
Uri uri = Uri.parse(photoUrl);
Builder builder = uri.buildUpon();
- builder.encodedFragment(String.valueOf(LetterTileDrawable.TYPE_BUSINESS));
+ builder.encodedFragment(String.valueOf(TYPE_BUSINESS));
return builder.build().toString();
}
@@ -139,7 +147,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
String encodedFragment = photoUri.getEncodedFragment();
return !TextUtils.isEmpty(encodedFragment)
- && encodedFragment.equals(String.valueOf(LetterTileDrawable.TYPE_BUSINESS));
+ && encodedFragment.equals(String.valueOf(TYPE_BUSINESS));
}
protected static DefaultImageRequest getDefaultImageRequestFromUri(Uri uri) {
@@ -370,7 +378,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
* be returned.
*/
public static final DefaultImageRequest EMPTY_DEFAULT_BUSINESS_IMAGE_REQUEST =
- new DefaultImageRequest(null, null, LetterTileDrawable.TYPE_BUSINESS, false);
+ new DefaultImageRequest(null, null, TYPE_BUSINESS, false);
/**
* Used to indicate that a circular drawable that represents a contact without any contact
* details should be returned.
@@ -382,7 +390,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
* should be returned.
*/
public static final DefaultImageRequest EMPTY_CIRCULAR_BUSINESS_IMAGE_REQUEST =
- new DefaultImageRequest(null, null, LetterTileDrawable.TYPE_BUSINESS, true);
+ new DefaultImageRequest(null, null, TYPE_BUSINESS, true);
/** The contact's display name. The display name is used to */
public String displayName;
/**
@@ -395,9 +403,10 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
/**
* The type of this contact. This contact type may be used to decide the kind of image to use in
* the case where a unique letter cannot be generated from the contact's display name and
- * identifier.
+ * identifier. See: {@link #TYPE_PERSON} {@link #TYPE_BUSINESS} {@link #TYPE_PERSON} {@link
+ * #TYPE_DEFAULT}
*/
- public @LetterTileDrawable.ContactType int contactType = LetterTileDrawable.TYPE_DEFAULT;
+ public int contactType = TYPE_DEFAULT;
/**
* The amount to scale the letter or bitmap to, as a ratio of its default size (from a range of
* 0.0f to 2.0f). The default value is 1.0f.
@@ -420,13 +429,7 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 {
public DefaultImageRequest() {}
public DefaultImageRequest(String displayName, String identifier, boolean isCircular) {
- this(
- displayName,
- identifier,
- LetterTileDrawable.TYPE_DEFAULT,
- SCALE_DEFAULT,
- OFFSET_DEFAULT,
- isCircular);
+ this(displayName, identifier, TYPE_DEFAULT, SCALE_DEFAULT, OFFSET_DEFAULT, isCircular);
}
public DefaultImageRequest(
diff --git a/java/com/android/contacts/common/ContactPhotoManagerImpl.java b/java/com/android/contacts/common/ContactPhotoManagerImpl.java
index 28ecf3421..2e6ff9fdc 100644
--- a/java/com/android/contacts/common/ContactPhotoManagerImpl.java
+++ b/java/com/android/contacts/common/ContactPhotoManagerImpl.java
@@ -53,9 +53,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.android.contacts.common.util.BitmapUtil;
+import com.android.contacts.common.util.TrafficStatsTags;
import com.android.contacts.common.util.UriUtils;
import com.android.dialer.common.LogUtil;
-import com.android.dialer.constants.TrafficStatsTags;
import com.android.dialer.util.PermissionsUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -634,9 +634,8 @@ class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback {
}
return true;
}
- default:
- return false;
}
+ return false;
}
public void ensureLoaderThread() {
diff --git a/java/com/android/contacts/common/ContactStatusUtil.java b/java/com/android/contacts/common/ContactStatusUtil.java
index c5347e778..97d84c876 100644
--- a/java/com/android/contacts/common/ContactStatusUtil.java
+++ b/java/com/android/contacts/common/ContactStatusUtil.java
@@ -23,6 +23,8 @@ import android.provider.ContactsContract.StatusUpdates;
/** Provides static function to get default contact status message. */
public class ContactStatusUtil {
+ private static final String TAG = "ContactStatusUtil";
+
public static String getStatusString(Context context, int presence) {
Resources resources = context.getResources();
switch (presence) {
diff --git a/java/com/android/contacts/common/ContactsUtils.java b/java/com/android/contacts/common/ContactsUtils.java
index 66ccc90e7..60af44b9a 100644
--- a/java/com/android/contacts/common/ContactsUtils.java
+++ b/java/com/android/contacts/common/ContactsUtils.java
@@ -16,17 +16,184 @@
package com.android.contacts.common;
-import android.provider.ContactsContract.Contacts;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.DisplayPhoto;
import android.support.annotation.IntDef;
+import android.text.TextUtils;
+import android.util.Pair;
+import com.android.contacts.common.compat.ContactsCompat;
import com.android.contacts.common.compat.DirectoryCompat;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.model.dataitem.ImDataItem;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
public class ContactsUtils {
// Telecomm related schemes are in CallUtil
+ public static final String SCHEME_IMTO = "imto";
+ public static final String SCHEME_MAILTO = "mailto";
+ public static final String SCHEME_SMSTO = "smsto";
public static final long USER_TYPE_CURRENT = 0;
public static final long USER_TYPE_WORK = 1;
+ private static final String TAG = "ContactsUtils";
+ private static final int DEFAULT_THUMBNAIL_SIZE = 96;
+ private static int sThumbnailSize = -1;
+
+ /**
+ * This looks up the provider name defined in ProviderNames from the predefined IM protocol id.
+ * This is used for interacting with the IM application.
+ *
+ * @param protocol the protocol ID
+ * @return the provider name the IM app uses for the given protocol, or null if no provider is
+ * defined for the given protocol
+ * @hide
+ */
+ public static String lookupProviderNameFromId(int protocol) {
+ switch (protocol) {
+ case Im.PROTOCOL_GOOGLE_TALK:
+ return ProviderNames.GTALK;
+ case Im.PROTOCOL_AIM:
+ return ProviderNames.AIM;
+ case Im.PROTOCOL_MSN:
+ return ProviderNames.MSN;
+ case Im.PROTOCOL_YAHOO:
+ return ProviderNames.YAHOO;
+ case Im.PROTOCOL_ICQ:
+ return ProviderNames.ICQ;
+ case Im.PROTOCOL_JABBER:
+ return ProviderNames.JABBER;
+ case Im.PROTOCOL_SKYPE:
+ return ProviderNames.SKYPE;
+ case Im.PROTOCOL_QQ:
+ return ProviderNames.QQ;
+ }
+ return null;
+ }
+
+ /**
+ * Test if the given {@link CharSequence} contains any graphic characters, first checking {@link
+ * TextUtils#isEmpty(CharSequence)} to handle null.
+ */
+ public static boolean isGraphic(CharSequence str) {
+ return !TextUtils.isEmpty(str) && TextUtils.isGraphic(str);
+ }
+
+ /** Returns true if two objects are considered equal. Two null references are equal here. */
+ public static boolean areObjectsEqual(Object a, Object b) {
+ return a == b || (a != null && a.equals(b));
+ }
+
+ /** Returns true if two {@link Intent}s are both null, or have the same action. */
+ public static final boolean areIntentActionEqual(Intent a, Intent b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ return TextUtils.equals(a.getAction(), b.getAction());
+ }
+
+ public static boolean areGroupWritableAccountsAvailable(Context context) {
+ final List<AccountWithDataSet> accounts =
+ AccountTypeManager.getInstance(context).getGroupWritableAccounts();
+ return !accounts.isEmpty();
+ }
+
+ /**
+ * Returns the size (width and height) of thumbnail pictures as configured in the provider. This
+ * can safely be called from the UI thread, as the provider can serve this without performing a
+ * database access
+ */
+ public static int getThumbnailSize(Context context) {
+ if (sThumbnailSize == -1) {
+ final Cursor c =
+ context
+ .getContentResolver()
+ .query(
+ DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
+ new String[] {DisplayPhoto.THUMBNAIL_MAX_DIM},
+ null,
+ null,
+ null);
+ if (c != null) {
+ try {
+ if (c.moveToFirst()) {
+ sThumbnailSize = c.getInt(0);
+ }
+ } finally {
+ c.close();
+ }
+ }
+ }
+ return sThumbnailSize != -1 ? sThumbnailSize : DEFAULT_THUMBNAIL_SIZE;
+ }
+
+ private static Intent getCustomImIntent(ImDataItem im, int protocol) {
+ String host = im.getCustomProtocol();
+ final String data = im.getData();
+ if (TextUtils.isEmpty(data)) {
+ return null;
+ }
+ if (protocol != Im.PROTOCOL_CUSTOM) {
+ // Try bringing in a well-known host for specific protocols
+ host = ContactsUtils.lookupProviderNameFromId(protocol);
+ }
+ if (TextUtils.isEmpty(host)) {
+ return null;
+ }
+ final String authority = host.toLowerCase();
+ final Uri imUri =
+ new Uri.Builder().scheme(SCHEME_IMTO).authority(authority).appendPath(data).build();
+ final Intent intent = new Intent(Intent.ACTION_SENDTO, imUri);
+ return intent;
+ }
+
+ /**
+ * Returns the proper Intent for an ImDatItem. If available, a secondary intent is stored in the
+ * second Pair slot
+ */
+ public static Pair<Intent, Intent> buildImIntent(Context context, ImDataItem im) {
+ Intent intent = null;
+ Intent secondaryIntent = null;
+ final boolean isEmail = im.isCreatedFromEmail();
+
+ if (!isEmail && !im.isProtocolValid()) {
+ return new Pair<>(null, null);
+ }
+
+ final String data = im.getData();
+ if (TextUtils.isEmpty(data)) {
+ return new Pair<>(null, null);
+ }
+
+ final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : im.getProtocol();
+
+ if (protocol == Im.PROTOCOL_GOOGLE_TALK) {
+ final int chatCapability = im.getChatCapability();
+ if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
+ intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+ secondaryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
+ } else if ((chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
+ // Allow Talking and Texting
+ intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+ secondaryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
+ } else {
+ intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+ }
+ } else {
+ // Build an IM Intent
+ intent = getCustomImIntent(im, protocol);
+ }
+ return new Pair<>(intent, secondaryIntent);
+ }
/**
* Determine UserType from directory id and contact id.
@@ -65,13 +232,27 @@ public class ContactsUtils {
: USER_TYPE_CURRENT;
}
// Only check contact id if directory id is null
- if (contactId != null && contactId != 0L && Contacts.isEnterpriseContactId(contactId)) {
+ if (contactId != null && contactId != 0L && ContactsCompat.isEnterpriseContactId(contactId)) {
return USER_TYPE_WORK;
} else {
return USER_TYPE_CURRENT;
}
}
+ // TODO find a proper place for the canonical version of these
+ public interface ProviderNames {
+
+ String YAHOO = "Yahoo";
+ String GTALK = "GTalk";
+ String MSN = "MSN";
+ String ICQ = "ICQ";
+ String AIM = "AIM";
+ String XMPP = "XMPP";
+ String JABBER = "JABBER";
+ String SKYPE = "SKYPE";
+ String QQ = "QQ";
+ }
+
/**
* UserType indicates the user type of the contact. If the contact is from Work User (Work Profile
* in Android Multi-User System), it's {@link #USER_TYPE_WORK}, otherwise, {@link
diff --git a/java/com/android/contacts/common/GeoUtil.java b/java/com/android/contacts/common/GeoUtil.java
new file mode 100644
index 000000000..50b0cd9e3
--- /dev/null
+++ b/java/com/android/contacts/common/GeoUtil.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 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
+ */
+
+package com.android.contacts.common;
+
+import android.app.Application;
+import android.content.Context;
+import com.android.contacts.common.location.CountryDetector;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.Phonenumber;
+import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
+import java.util.Locale;
+
+/** Static methods related to Geo. */
+public class GeoUtil {
+
+ /**
+ * Returns the country code of the country the user is currently in. Before calling this method,
+ * make sure that {@link CountryDetector#initialize(Context)} has already been called in {@link
+ * Application#onCreate()}.
+ *
+ * @return The ISO 3166-1 two letters country code of the country the user is in.
+ */
+ public static String getCurrentCountryIso(Context context) {
+ // The {@link CountryDetector} should never return null so this is safe to return as-is.
+ return CountryDetector.getInstance(context).getCurrentCountryIso();
+ }
+
+ public static String getGeocodedLocationFor(Context context, String phoneNumber) {
+ final PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
+ final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
+ try {
+ final Phonenumber.PhoneNumber structuredPhoneNumber =
+ phoneNumberUtil.parse(phoneNumber, getCurrentCountryIso(context));
+ final Locale locale = context.getResources().getConfiguration().locale;
+ return geocoder.getDescriptionForNumber(structuredPhoneNumber, locale);
+ } catch (NumberParseException e) {
+ return null;
+ }
+ }
+}
diff --git a/java/com/android/contacts/common/MoreContactUtils.java b/java/com/android/contacts/common/MoreContactUtils.java
index 26241b34f..028f89971 100644
--- a/java/com/android/contacts/common/MoreContactUtils.java
+++ b/java/com/android/contacts/common/MoreContactUtils.java
@@ -16,6 +16,7 @@
package com.android.contacts.common;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
@@ -23,6 +24,7 @@ import android.provider.ContactsContract;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.view.View;
+import android.widget.TextView;
import com.android.contacts.common.model.account.AccountType;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
@@ -192,6 +194,40 @@ public class MoreContactUtils {
}
/**
+ * Returns a header view based on the R.layout.list_separator, where the containing {@link
+ * android.widget.TextView} is set using the given textResourceId.
+ */
+ public static TextView createHeaderView(Context context, int textResourceId) {
+ final TextView textView = (TextView) View.inflate(context, R.layout.list_separator, null);
+ textView.setText(context.getString(textResourceId));
+ return textView;
+ }
+
+ /**
+ * Set the top padding on the header view dynamically, based on whether the header is in the first
+ * row or not.
+ */
+ public static void setHeaderViewBottomPadding(
+ Context context, TextView textView, boolean isFirstRow) {
+ final int topPadding;
+ if (isFirstRow) {
+ topPadding =
+ (int)
+ context
+ .getResources()
+ .getDimension(R.dimen.frequently_contacted_title_top_margin_when_first_row);
+ } else {
+ topPadding =
+ (int) context.getResources().getDimension(R.dimen.frequently_contacted_title_top_margin);
+ }
+ textView.setPaddingRelative(
+ textView.getPaddingStart(),
+ topPadding,
+ textView.getPaddingEnd(),
+ textView.getPaddingBottom());
+ }
+
+ /**
* Returns the intent to launch for the given invitable account type and contact lookup URI. This
* will return null if the account type is not invitable (i.e. there is no {@link
* AccountType#getInviteContactActivityClassName()} or {@link
diff --git a/java/com/android/contacts/common/compat/ContactsCompat.java b/java/com/android/contacts/common/compat/ContactsCompat.java
index e0c9b7e53..39d0b55d3 100644
--- a/java/com/android/contacts/common/compat/ContactsCompat.java
+++ b/java/com/android/contacts/common/compat/ContactsCompat.java
@@ -21,6 +21,7 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
+import com.android.dialer.compat.CompatUtils;
/** Compatibility class for {@link ContactsContract.Contacts} */
public class ContactsCompat {
@@ -28,6 +29,8 @@ public class ContactsCompat {
// TODO: Use N APIs
private static final Uri ENTERPRISE_CONTENT_FILTER_URI =
Uri.withAppendedPath(Contacts.CONTENT_URI, "filter_enterprise");
+ // Copied from ContactsContract.Contacts#ENTERPRISE_CONTACT_ID_BASE, which is hidden.
+ private static final long ENTERPRISE_CONTACT_ID_BASE = 1000000000;
/** Not instantiable. */
private ContactsCompat() {}
@@ -38,4 +41,17 @@ public class ContactsCompat {
}
return Contacts.CONTENT_FILTER_URI;
}
+
+ /**
+ * Return {@code true} if a contact ID is from the contacts provider on the enterprise profile.
+ */
+ public static boolean isEnterpriseContactId(long contactId) {
+ if (CompatUtils.isLollipopCompatible()) {
+ return Contacts.isEnterpriseContactId(contactId);
+ } else {
+ // copied from ContactsContract.Contacts.isEnterpriseContactId
+ return (contactId >= ENTERPRISE_CONTACT_ID_BASE)
+ && (contactId < ContactsContract.Profile.MIN_ID);
+ }
+ }
}
diff --git a/java/com/android/contacts/common/compat/PhoneAccountCompat.java b/java/com/android/contacts/common/compat/PhoneAccountCompat.java
index aa22c6861..6a24ec033 100644
--- a/java/com/android/contacts/common/compat/PhoneAccountCompat.java
+++ b/java/com/android/contacts/common/compat/PhoneAccountCompat.java
@@ -20,10 +20,33 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccount;
+import android.util.Log;
+import com.android.dialer.compat.CompatUtils;
/** Compatiblity class for {@link android.telecom.PhoneAccount} */
public class PhoneAccountCompat {
+ private static final String TAG = PhoneAccountCompat.class.getSimpleName();
+
+ /**
+ * Gets the {@link Icon} associated with the given {@link PhoneAccount}
+ *
+ * @param phoneAccount the PhoneAccount from which to retrieve the Icon
+ * @return the Icon, or null
+ */
+ @Nullable
+ public static Icon getIcon(@Nullable PhoneAccount phoneAccount) {
+ if (phoneAccount == null) {
+ return null;
+ }
+
+ if (CompatUtils.isMarshmallowCompatible()) {
+ return phoneAccount.getIcon();
+ }
+
+ return null;
+ }
+
/**
* Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user
* interface.
@@ -38,16 +61,44 @@ public class PhoneAccountCompat {
if (phoneAccount == null || context == null) {
return null;
}
- return createIconDrawableMarshmallow(phoneAccount, context);
+
+ if (CompatUtils.isMarshmallowCompatible()) {
+ return createIconDrawableMarshmallow(phoneAccount, context);
+ }
+
+ if (CompatUtils.isLollipopMr1Compatible()) {
+ return createIconDrawableLollipopMr1(phoneAccount, context);
+ }
+ return null;
}
@Nullable
private static Drawable createIconDrawableMarshmallow(
PhoneAccount phoneAccount, Context context) {
- Icon accountIcon = phoneAccount.getIcon();
+ Icon accountIcon = getIcon(phoneAccount);
if (accountIcon == null) {
return null;
}
return accountIcon.loadDrawable(context);
}
+
+ @Nullable
+ private static Drawable createIconDrawableLollipopMr1(
+ PhoneAccount phoneAccount, Context context) {
+ try {
+ return (Drawable)
+ PhoneAccount.class
+ .getMethod("createIconDrawable", Context.class)
+ .invoke(phoneAccount, context);
+ } catch (ReflectiveOperationException e) {
+ return null;
+ } catch (Throwable t) {
+ Log.e(
+ TAG,
+ "Unexpected exception when attempting to call "
+ + "android.telecom.PhoneAccount#createIconDrawable",
+ t);
+ return null;
+ }
+ }
}
diff --git a/java/com/android/contacts/common/compat/PhoneNumberUtilsCompat.java b/java/com/android/contacts/common/compat/PhoneNumberUtilsCompat.java
index a6cfe07cd..960b340d8 100644
--- a/java/com/android/contacts/common/compat/PhoneNumberUtilsCompat.java
+++ b/java/com/android/contacts/common/compat/PhoneNumberUtilsCompat.java
@@ -17,7 +17,13 @@
package com.android.contacts.common.compat;
import android.telephony.PhoneNumberUtils;
+import android.text.Spannable;
+import android.text.TextUtils;
import android.text.style.TtsSpan;
+import com.android.dialer.compat.CompatUtils;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
/**
* This class contains static utility methods extracted from PhoneNumberUtils, and the methods were
@@ -31,16 +37,138 @@ public class PhoneNumberUtilsCompat {
/** Not instantiable. */
private PhoneNumberUtilsCompat() {}
+ public static String normalizeNumber(String phoneNumber) {
+ if (CompatUtils.isLollipopCompatible()) {
+ return PhoneNumberUtils.normalizeNumber(phoneNumber);
+ } else {
+ return normalizeNumberInternal(phoneNumber);
+ }
+ }
+
+ /** Implementation copied from {@link PhoneNumberUtils#normalizeNumber} */
+ private static String normalizeNumberInternal(String phoneNumber) {
+ if (TextUtils.isEmpty(phoneNumber)) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ int len = phoneNumber.length();
+ for (int i = 0; i < len; i++) {
+ char c = phoneNumber.charAt(i);
+ // Character.digit() supports ASCII and Unicode digits (fullwidth, Arabic-Indic, etc.)
+ int digit = Character.digit(c, 10);
+ if (digit != -1) {
+ sb.append(digit);
+ } else if (sb.length() == 0 && c == '+') {
+ sb.append(c);
+ } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
+ }
+ }
+ return sb.toString();
+ }
+
public static String formatNumber(
String phoneNumber, String phoneNumberE164, String defaultCountryIso) {
+ if (CompatUtils.isLollipopCompatible()) {
return PhoneNumberUtils.formatNumber(phoneNumber, phoneNumberE164, defaultCountryIso);
+ } else {
+ // This method was deprecated in API level 21, so it's only used on pre-L SDKs.
+ return PhoneNumberUtils.formatNumber(phoneNumber);
+ }
}
public static CharSequence createTtsSpannable(CharSequence phoneNumber) {
- return PhoneNumberUtils.createTtsSpannable(phoneNumber);
+ if (CompatUtils.isMarshmallowCompatible()) {
+ return PhoneNumberUtils.createTtsSpannable(phoneNumber);
+ } else {
+ return createTtsSpannableInternal(phoneNumber);
+ }
}
public static TtsSpan createTtsSpan(String phoneNumber) {
- return PhoneNumberUtils.createTtsSpan(phoneNumber);
+ if (CompatUtils.isMarshmallowCompatible()) {
+ return PhoneNumberUtils.createTtsSpan(phoneNumber);
+ } else if (CompatUtils.isLollipopCompatible()) {
+ return createTtsSpanLollipop(phoneNumber);
+ } else {
+ return null;
+ }
+ }
+
+ /** Copied from {@link PhoneNumberUtils#createTtsSpannable} */
+ private static CharSequence createTtsSpannableInternal(CharSequence phoneNumber) {
+ if (phoneNumber == null) {
+ return null;
+ }
+ Spannable spannable = Spannable.Factory.getInstance().newSpannable(phoneNumber);
+ addTtsSpanInternal(spannable, 0, spannable.length());
+ return spannable;
+ }
+
+ /** Compat method for addTtsSpan, see {@link PhoneNumberUtils#addTtsSpan} */
+ public static void addTtsSpan(Spannable s, int start, int endExclusive) {
+ if (CompatUtils.isMarshmallowCompatible()) {
+ PhoneNumberUtils.addTtsSpan(s, start, endExclusive);
+ } else {
+ addTtsSpanInternal(s, start, endExclusive);
+ }
+ }
+
+ /** Copied from {@link PhoneNumberUtils#addTtsSpan} */
+ private static void addTtsSpanInternal(Spannable s, int start, int endExclusive) {
+ s.setSpan(
+ createTtsSpan(s.subSequence(start, endExclusive).toString()),
+ start,
+ endExclusive,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
+ /** Copied from {@link PhoneNumberUtils#createTtsSpan} */
+ private static TtsSpan createTtsSpanLollipop(String phoneNumberString) {
+ if (phoneNumberString == null) {
+ return null;
+ }
+
+ // Parse the phone number
+ final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
+ PhoneNumber phoneNumber = null;
+ try {
+ // Don't supply a defaultRegion so this fails for non-international numbers because
+ // we don't want to TalkBalk to read a country code (e.g. +1) if it is not already
+ // present
+ phoneNumber = phoneNumberUtil.parse(phoneNumberString, /* defaultRegion */ null);
+ } catch (NumberParseException ignored) {
+ }
+
+ // Build a telephone tts span
+ final TtsSpan.TelephoneBuilder builder = new TtsSpan.TelephoneBuilder();
+ if (phoneNumber == null) {
+ // Strip separators otherwise TalkBack will be silent
+ // (this behavior was observed with TalkBalk 4.0.2 from their alpha channel)
+ builder.setNumberParts(splitAtNonNumerics(phoneNumberString));
+ } else {
+ if (phoneNumber.hasCountryCode()) {
+ builder.setCountryCode(Integer.toString(phoneNumber.getCountryCode()));
+ }
+ builder.setNumberParts(Long.toString(phoneNumber.getNationalNumber()));
+ }
+ return builder.build();
+ }
+
+ /**
+ * Split a phone number using spaces, ignoring anything that is not a digit
+ *
+ * @param number A {@code CharSequence} before splitting, e.g., "+20(123)-456#"
+ * @return A {@code String} after splitting, e.g., "20 123 456".
+ */
+ private static String splitAtNonNumerics(CharSequence number) {
+ StringBuilder sb = new StringBuilder(number.length());
+ for (int i = 0; i < number.length(); i++) {
+ sb.append(PhoneNumberUtils.isISODigit(number.charAt(i)) ? number.charAt(i) : " ");
+ }
+ // It is very important to remove extra spaces. At time of writing, any leading or trailing
+ // spaces, or any sequence of more than one space, will confuse TalkBack and cause the TTS
+ // span to be non-functional!
+ return sb.toString().replaceAll(" +", " ").trim();
}
}
diff --git a/java/com/android/contacts/common/compat/TelephonyManagerCompat.java b/java/com/android/contacts/common/compat/TelephonyManagerCompat.java
index 4a16fb855..7e4803ca5 100644
--- a/java/com/android/contacts/common/compat/TelephonyManagerCompat.java
+++ b/java/com/android/contacts/common/compat/TelephonyManagerCompat.java
@@ -27,6 +27,7 @@ import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.compat.CompatUtils;
import java.lang.reflect.InvocationTargetException;
public class TelephonyManagerCompat {
@@ -48,6 +49,31 @@ public class TelephonyManagerCompat {
private static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
/**
+ * @param telephonyManager The telephony manager instance to use for method calls.
+ * @return true if the current device is "voice capable".
+ * <p>"Voice capable" means that this device supports circuit-switched (i.e. voice) phone
+ * calls over the telephony network, and is allowed to display the in-call UI while a cellular
+ * voice call is active. This will be false on "data only" devices which can't make voice
+ * calls and don't support any in-call UI.
+ * <p>Note: the meaning of this flag is subtly different from the
+ * PackageManager.FEATURE_TELEPHONY system feature, which is available on any device with a
+ * telephony radio, even if the device is data-only.
+ */
+ public static boolean isVoiceCapable(@Nullable TelephonyManager telephonyManager) {
+ if (telephonyManager == null) {
+ return false;
+ }
+ if (CompatUtils.isLollipopMr1Compatible()
+ || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "isVoiceCapable")) {
+ // isVoiceCapable was unhidden in L-MR1
+ return telephonyManager.isVoiceCapable();
+ }
+ final int phoneType = telephonyManager.getPhoneType();
+ return phoneType == TelephonyManager.PHONE_TYPE_CDMA
+ || phoneType == TelephonyManager.PHONE_TYPE_GSM;
+ }
+
+ /**
* Returns the number of phones available. Returns 1 for Single standby mode (Single SIM
* functionality) Returns 2 for Dual standby mode.(Dual SIM functionality)
*
@@ -59,7 +85,31 @@ public class TelephonyManagerCompat {
if (telephonyManager == null) {
return 1;
}
- return telephonyManager.getPhoneCount();
+ if (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "getPhoneCount")) {
+ return telephonyManager.getPhoneCount();
+ }
+ return 1;
+ }
+
+ /**
+ * Returns the unique device ID of a subscription, for example, the IMEI for GSM and the MEID for
+ * CDMA phones. Return null if device ID is not available.
+ *
+ * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
+ * @param telephonyManager The telephony manager instance to use for method calls.
+ * @param slotId of which deviceID is returned
+ */
+ public static String getDeviceId(@Nullable TelephonyManager telephonyManager, int slotId) {
+ if (telephonyManager == null) {
+ return null;
+ }
+ if (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "getDeviceId", Integer.class)) {
+ return telephonyManager.getDeviceId(slotId);
+ }
+ return null;
}
/**
@@ -69,7 +119,14 @@ public class TelephonyManagerCompat {
* @return {@code true} if the device supports TTY mode, and {@code false} otherwise.
*/
public static boolean isTtyModeSupported(@Nullable TelephonyManager telephonyManager) {
- return telephonyManager != null && telephonyManager.isTtyModeSupported();
+ if (telephonyManager == null) {
+ return false;
+ }
+ if (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "isTtyModeSupported")) {
+ return telephonyManager.isTtyModeSupported();
+ }
+ return false;
}
/**
@@ -81,7 +138,15 @@ public class TelephonyManagerCompat {
*/
public static boolean isHearingAidCompatibilitySupported(
@Nullable TelephonyManager telephonyManager) {
- return telephonyManager != null && telephonyManager.isHearingAidCompatibilitySupported();
+ if (telephonyManager == null) {
+ return false;
+ }
+ if (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(
+ TELEPHONY_MANAGER_CLASS, "isHearingAidCompatibilitySupported")) {
+ return telephonyManager.isHearingAidCompatibilitySupported();
+ }
+ return false;
}
/**
diff --git a/java/com/android/contacts/common/compat/telecom/TelecomManagerCompat.java b/java/com/android/contacts/common/compat/telecom/TelecomManagerCompat.java
index 43eae589d..5687f6fbf 100644
--- a/java/com/android/contacts/common/compat/telecom/TelecomManagerCompat.java
+++ b/java/com/android/contacts/common/compat/telecom/TelecomManagerCompat.java
@@ -15,19 +15,275 @@
*/
package com.android.contacts.common.compat.telecom;
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
import android.support.annotation.Nullable;
+import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import com.android.dialer.compat.CompatUtils;
+import java.util.ArrayList;
+import java.util.List;
/** Compatibility class for {@link android.telecom.TelecomManager}. */
public class TelecomManagerCompat {
+ public static final String TELECOM_MANAGER_CLASS = "android.telecom.TelecomManager";
+
// TODO: remove once this is available in android.telecom.Call
// b/33779976
public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS =
"android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
/**
+ * Places a new outgoing call to the provided address using the system telecom service with the
+ * specified intent.
+ *
+ * @param activity {@link Activity} used to start another activity for the given intent
+ * @param telecomManager the {@link TelecomManager} used to place a call, if possible
+ * @param intent the intent for the call
+ */
+ public static void placeCall(
+ @Nullable Activity activity,
+ @Nullable TelecomManager telecomManager,
+ @Nullable Intent intent) {
+ if (activity == null || telecomManager == null || intent == null) {
+ return;
+ }
+ if (CompatUtils.isMarshmallowCompatible()) {
+ telecomManager.placeCall(intent.getData(), intent.getExtras());
+ return;
+ }
+ activity.startActivityForResult(intent, 0);
+ }
+
+ /**
+ * Get the URI for running an adn query.
+ *
+ * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
+ * @param accountHandle The handle for the account to derive an adn query URI for or {@code null}
+ * to return a URI which will use the default account.
+ * @return The URI (with the content:// scheme) specific to the specified {@link PhoneAccount} for
+ * the the content retrieve.
+ */
+ public static Uri getAdnUriForPhoneAccount(
+ @Nullable TelecomManager telecomManager, PhoneAccountHandle accountHandle) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS, "getAdnUriForPhoneAccount", PhoneAccountHandle.class))) {
+ return telecomManager.getAdnUriForPhoneAccount(accountHandle);
+ }
+ return Uri.parse("content://icc/adn");
+ }
+
+ /**
+ * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
+ * calls. The returned list includes only those accounts which have been explicitly enabled by the
+ * user.
+ *
+ * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
+ * @return A list of PhoneAccountHandle objects.
+ */
+ public static List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+ @Nullable TelecomManager telecomManager) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS, "getCallCapablePhoneAccounts"))) {
+ return telecomManager.getCallCapablePhoneAccounts();
+ }
+ return new ArrayList<>();
+ }
+
+ /**
+ * Used to determine the currently selected default dialer package.
+ *
+ * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
+ * @return package name for the default dialer package or null if no package has been selected as
+ * the default dialer.
+ */
+ @Nullable
+ public static String getDefaultDialerPackage(@Nullable TelecomManager telecomManager) {
+ if (telecomManager != null && CompatUtils.isDefaultDialerCompatible()) {
+ return telecomManager.getDefaultDialerPackage();
+ }
+ return null;
+ }
+
+ /**
+ * Return the {@link PhoneAccount} which will be used to place outgoing calls to addresses with
+ * the specified {@code uriScheme}. This PhoneAccount will always be a member of the list which is
+ * returned from invoking {@link TelecomManager#getCallCapablePhoneAccounts()}. The specific
+ * account returned depends on the following priorities:
+ *
+ * <p>1. If the user-selected default PhoneAccount supports the specified scheme, it will be
+ * returned. 2. If there exists only one PhoneAccount that supports the specified scheme, it will
+ * be returned.
+ *
+ * <p>If no PhoneAccount fits the criteria above, this method will return {@code null}.
+ *
+ * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
+ * @param uriScheme The URI scheme.
+ * @return The {@link PhoneAccountHandle} corresponding to the account to be used.
+ */
+ @Nullable
+ public static PhoneAccountHandle getDefaultOutgoingPhoneAccount(
+ @Nullable TelecomManager telecomManager, @Nullable String uriScheme) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS, "getDefaultOutgoingPhoneAccount", String.class))) {
+ return telecomManager.getDefaultOutgoingPhoneAccount(uriScheme);
+ }
+ return null;
+ }
+
+ /**
+ * Return the line 1 phone number for given phone account.
+ *
+ * @param telecomManager the {@link TelecomManager} to use in the event that {@link
+ * TelecomManager#getLine1Number(PhoneAccountHandle)} is available
+ * @param telephonyManager the {@link TelephonyManager} to use if TelecomManager#getLine1Number is
+ * unavailable
+ * @param phoneAccountHandle the phoneAccountHandle upon which to check the line one number
+ * @return the line one number
+ */
+ @Nullable
+ public static String getLine1Number(
+ @Nullable TelecomManager telecomManager,
+ @Nullable TelephonyManager telephonyManager,
+ @Nullable PhoneAccountHandle phoneAccountHandle) {
+ if (telecomManager != null && CompatUtils.isMarshmallowCompatible()) {
+ return telecomManager.getLine1Number(phoneAccountHandle);
+ }
+ if (telephonyManager != null) {
+ return telephonyManager.getLine1Number();
+ }
+ return null;
+ }
+
+ /**
+ * Return whether a given phone number is the configured voicemail number for a particular phone
+ * account.
+ *
+ * @param telecomManager the {@link TelecomManager} to use for checking the number.
+ * @param accountHandle The handle for the account to check the voicemail number against
+ * @param number The number to look up.
+ */
+ public static boolean isVoiceMailNumber(
+ @Nullable TelecomManager telecomManager,
+ @Nullable PhoneAccountHandle accountHandle,
+ @Nullable String number) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS,
+ "isVoiceMailNumber",
+ PhoneAccountHandle.class,
+ String.class))) {
+ return telecomManager.isVoiceMailNumber(accountHandle, number);
+ }
+ return PhoneNumberUtils.isVoiceMailNumber(number);
+ }
+
+ /**
+ * Return the {@link PhoneAccount} for a specified {@link PhoneAccountHandle}. Object includes
+ * resources which can be used in a user interface.
+ *
+ * @param telecomManager the {@link TelecomManager} used for method calls, if possible.
+ * @param account The {@link PhoneAccountHandle}.
+ * @return The {@link PhoneAccount} object or null if it doesn't exist.
+ */
+ @Nullable
+ public static PhoneAccount getPhoneAccount(
+ @Nullable TelecomManager telecomManager, @Nullable PhoneAccountHandle accountHandle) {
+ if (telecomManager != null
+ && (CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS, "getPhoneAccount", PhoneAccountHandle.class))) {
+ return telecomManager.getPhoneAccount(accountHandle);
+ }
+ return null;
+ }
+
+ /**
+ * Return the voicemail number for a given phone account.
+ *
+ * @param telecomManager The {@link TelecomManager} object to use for retrieving the voicemail
+ * number if accountHandle is specified.
+ * @param telephonyManager The {@link TelephonyManager} object to use for retrieving the voicemail
+ * number if accountHandle is null.
+ * @param accountHandle The handle for the phone account.
+ * @return The voicemail number for the phone account, and {@code null} if one has not been
+ * configured.
+ */
+ @Nullable
+ public static String getVoiceMailNumber(
+ @Nullable TelecomManager telecomManager,
+ @Nullable TelephonyManager telephonyManager,
+ @Nullable PhoneAccountHandle accountHandle) {
+ if (telecomManager != null
+ && (CompatUtils.isMethodAvailable(
+ TELECOM_MANAGER_CLASS, "getVoiceMailNumber", PhoneAccountHandle.class))) {
+ return telecomManager.getVoiceMailNumber(accountHandle);
+ } else if (telephonyManager != null) {
+ return telephonyManager.getVoiceMailNumber();
+ }
+ return null;
+ }
+
+ /**
+ * Processes the specified dial string as an MMI code. MMI codes are any sequence of characters
+ * entered into the dialpad that contain a "*" or "#". Some of these sequences launch special
+ * behavior through handled by Telephony.
+ *
+ * @param telecomManager The {@link TelecomManager} object to use for handling MMI.
+ * @param dialString The digits to dial.
+ * @return {@code true} if the digits were processed as an MMI code, {@code false} otherwise.
+ */
+ public static boolean handleMmi(
+ @Nullable TelecomManager telecomManager,
+ @Nullable String dialString,
+ @Nullable PhoneAccountHandle accountHandle) {
+ if (telecomManager == null || TextUtils.isEmpty(dialString)) {
+ return false;
+ }
+ if (CompatUtils.isMarshmallowCompatible()) {
+ return telecomManager.handleMmi(dialString, accountHandle);
+ }
+
+ Object handleMmiResult =
+ CompatUtils.invokeMethod(
+ telecomManager,
+ "handleMmi",
+ new Class<?>[] {PhoneAccountHandle.class, String.class},
+ new Object[] {accountHandle, dialString});
+ if (handleMmiResult != null) {
+ return (boolean) handleMmiResult;
+ }
+
+ return telecomManager.handleMmi(dialString);
+ }
+
+ /**
+ * Silences the ringer if a ringing call exists. Noop if {@link TelecomManager#silenceRinger()} is
+ * unavailable.
+ *
+ * @param telecomManager the TelecomManager to use to silence the ringer.
+ */
+ public static void silenceRinger(@Nullable TelecomManager telecomManager) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "silenceRinger"))) {
+ telecomManager.silenceRinger();
+ }
+ }
+
+ /**
* Returns the current SIM call manager. Apps must be prepared for this method to return null,
* indicating that there currently exists no registered SIM call manager.
*
@@ -36,7 +292,9 @@ public class TelecomManagerCompat {
*/
@Nullable
public static PhoneAccountHandle getSimCallManager(TelecomManager telecomManager) {
- if (telecomManager != null) {
+ if (telecomManager != null
+ && (CompatUtils.isMarshmallowCompatible()
+ || CompatUtils.isMethodAvailable(TELECOM_MANAGER_CLASS, "getSimCallManager"))) {
return telecomManager.getSimCallManager();
}
return null;
diff --git a/java/com/android/contacts/common/dialog/CallSubjectDialog.java b/java/com/android/contacts/common/dialog/CallSubjectDialog.java
index 88fac0256..0e7937102 100644
--- a/java/com/android/contacts/common/dialog/CallSubjectDialog.java
+++ b/java/com/android/contacts/common/dialog/CallSubjectDialog.java
@@ -45,7 +45,7 @@ import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.R;
-import com.android.contacts.common.lettertiles.LetterTileDrawable;
+import com.android.contacts.common.compat.telecom.TelecomManagerCompat;
import com.android.dialer.animation.AnimUtils;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
@@ -154,7 +154,11 @@ public class CallSubjectDialog extends Activity {
.setCallSubject(subject)
.build();
- getSystemService(TelecomManager.class).placeCall(intent.getData(), intent.getExtras());
+ TelecomManagerCompat.placeCall(
+ CallSubjectDialog.this,
+ (TelecomManager) getSystemService(Context.TELECOM_SERVICE),
+ intent);
+
mSubjectHistory.add(subject);
saveSubjectHistory(mSubjectHistory);
finish();
@@ -198,7 +202,7 @@ public class CallSubjectDialog extends Activity {
number /* number */,
null /* displayNumber */,
null /* numberLabel */,
- LetterTileDrawable.TYPE_DEFAULT,
+ ContactPhotoManager.TYPE_DEFAULT,
null /* phoneAccountHandle */);
}
@@ -352,7 +356,7 @@ public class CallSubjectDialog extends Activity {
mNumber = arguments.getString(ARG_NUMBER);
mDisplayNumber = arguments.getString(ARG_DISPLAY_NUMBER);
mNumberLabel = arguments.getString(ARG_NUMBER_LABEL);
- mContactType = arguments.getInt(ARG_CONTACT_TYPE, LetterTileDrawable.TYPE_DEFAULT);
+ mContactType = arguments.getInt(ARG_CONTACT_TYPE, ContactPhotoManager.TYPE_DEFAULT);
mPhoneAccountHandle = arguments.getParcelable(ARG_PHONE_ACCOUNT_HANDLE);
}
diff --git a/java/com/android/contacts/common/format/FormatUtils.java b/java/com/android/contacts/common/format/FormatUtils.java
new file mode 100644
index 000000000..727c15b83
--- /dev/null
+++ b/java/com/android/contacts/common/format/FormatUtils.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+package com.android.contacts.common.format;
+
+import android.database.CharArrayBuffer;
+import android.graphics.Typeface;
+import android.support.annotation.VisibleForTesting;
+import android.text.SpannableString;
+import android.text.style.StyleSpan;
+import java.util.Arrays;
+
+/** Assorted utility methods related to text formatting in Contacts. */
+public class FormatUtils {
+
+ /**
+ * Finds the earliest point in buffer1 at which the first part of buffer2 matches. For example,
+ * overlapPoint("abcd", "cdef") == 2.
+ */
+ public static int overlapPoint(CharArrayBuffer buffer1, CharArrayBuffer buffer2) {
+ if (buffer1 == null || buffer2 == null) {
+ return -1;
+ }
+ return overlapPoint(
+ Arrays.copyOfRange(buffer1.data, 0, buffer1.sizeCopied),
+ Arrays.copyOfRange(buffer2.data, 0, buffer2.sizeCopied));
+ }
+
+ /**
+ * Finds the earliest point in string1 at which the first part of string2 matches. For example,
+ * overlapPoint("abcd", "cdef") == 2.
+ */
+ @VisibleForTesting
+ public static int overlapPoint(String string1, String string2) {
+ if (string1 == null || string2 == null) {
+ return -1;
+ }
+ return overlapPoint(string1.toCharArray(), string2.toCharArray());
+ }
+
+ /**
+ * Finds the earliest point in array1 at which the first part of array2 matches. For example,
+ * overlapPoint("abcd", "cdef") == 2.
+ */
+ public static int overlapPoint(char[] array1, char[] array2) {
+ if (array1 == null || array2 == null) {
+ return -1;
+ }
+ int count1 = array1.length;
+ int count2 = array2.length;
+
+ // Ignore matching tails of the two arrays.
+ while (count1 > 0 && count2 > 0 && array1[count1 - 1] == array2[count2 - 1]) {
+ count1--;
+ count2--;
+ }
+
+ int size = count2;
+ for (int i = 0; i < count1; i++) {
+ if (i + size > count1) {
+ size = count1 - i;
+ }
+ int j;
+ for (j = 0; j < size; j++) {
+ if (array1[i + j] != array2[j]) {
+ break;
+ }
+ }
+ if (j == size) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Applies the given style to a range of the input CharSequence.
+ *
+ * @param style The style to apply (see the style constants in {@link Typeface}).
+ * @param input The CharSequence to style.
+ * @param start Starting index of the range to style (will be clamped to be a minimum of 0).
+ * @param end Ending index of the range to style (will be clamped to a maximum of the input
+ * length).
+ * @param flags Bitmask for configuring behavior of the span. See {@link android.text.Spanned}.
+ * @return The styled CharSequence.
+ */
+ public static CharSequence applyStyleToSpan(
+ int style, CharSequence input, int start, int end, int flags) {
+ // Enforce bounds of the char sequence.
+ start = Math.max(0, start);
+ end = Math.min(input.length(), end);
+ SpannableString text = new SpannableString(input);
+ text.setSpan(new StyleSpan(style), start, end, flags);
+ return text;
+ }
+
+ @VisibleForTesting
+ public static void copyToCharArrayBuffer(String text, CharArrayBuffer buffer) {
+ if (text != null) {
+ char[] data = buffer.data;
+ if (data == null || data.length < text.length()) {
+ buffer.data = text.toCharArray();
+ } else {
+ text.getChars(0, text.length(), data, 0);
+ }
+ buffer.sizeCopied = text.length();
+ } else {
+ buffer.sizeCopied = 0;
+ }
+ }
+
+ /** Returns a String that represents the content of the given {@link CharArrayBuffer}. */
+ @VisibleForTesting
+ public static String charArrayBufferToString(CharArrayBuffer buffer) {
+ return new String(buffer.data, 0, buffer.sizeCopied);
+ }
+
+ /**
+ * Finds the index of the first word that starts with the given prefix.
+ *
+ * <p>If not found, returns -1.
+ *
+ * @param text the text in which to search for the prefix
+ * @param prefix the text to find, in upper case letters
+ */
+ public static int indexOfWordPrefix(CharSequence text, String prefix) {
+ if (prefix == null || text == null) {
+ return -1;
+ }
+
+ int textLength = text.length();
+ int prefixLength = prefix.length();
+
+ if (prefixLength == 0 || textLength < prefixLength) {
+ return -1;
+ }
+
+ int i = 0;
+ while (i < textLength) {
+ // Skip non-word characters
+ while (i < textLength && !Character.isLetterOrDigit(text.charAt(i))) {
+ i++;
+ }
+
+ if (i + prefixLength > textLength) {
+ return -1;
+ }
+
+ // Compare the prefixes
+ int j;
+ for (j = 0; j < prefixLength; j++) {
+ if (Character.toUpperCase(text.charAt(i + j)) != prefix.charAt(j)) {
+ break;
+ }
+ }
+ if (j == prefixLength) {
+ return i;
+ }
+
+ // Skip this word
+ while (i < textLength && Character.isLetterOrDigit(text.charAt(i))) {
+ i++;
+ }
+ }
+
+ return -1;
+ }
+}
diff --git a/java/com/android/contacts/common/format/TextHighlighter.java b/java/com/android/contacts/common/format/TextHighlighter.java
index f397f0429..30c03fdf3 100644
--- a/java/com/android/contacts/common/format/TextHighlighter.java
+++ b/java/com/android/contacts/common/format/TextHighlighter.java
@@ -24,6 +24,8 @@ import android.widget.TextView;
/** Highlights the text in a text field. */
public class TextHighlighter {
+ private static final boolean DEBUG = false;
+ private final String TAG = TextHighlighter.class.getSimpleName();
private int mTextStyle;
private CharacterStyle mTextStyleSpan;
@@ -79,7 +81,7 @@ public class TextHighlighter {
}
final String trimmedPrefix = prefix.substring(prefixStart);
- int index = indexOfWordPrefix(text, trimmedPrefix);
+ int index = FormatUtils.indexOfWordPrefix(text, trimmedPrefix);
if (index != -1) {
final SpannableString result = new SpannableString(text);
result.setSpan(mTextStyleSpan, index, index + trimmedPrefix.length(), 0 /* flags */);
@@ -88,55 +90,4 @@ public class TextHighlighter {
return text;
}
}
-
- /**
- * Finds the index of the first word that starts with the given prefix.
- *
- * <p>If not found, returns -1.
- *
- * @param text the text in which to search for the prefix
- * @param prefix the text to find, in upper case letters
- */
- public static int indexOfWordPrefix(CharSequence text, String prefix) {
- if (prefix == null || text == null) {
- return -1;
- }
-
- int textLength = text.length();
- int prefixLength = prefix.length();
-
- if (prefixLength == 0 || textLength < prefixLength) {
- return -1;
- }
-
- int i = 0;
- while (i < textLength) {
- // Skip non-word characters
- while (i < textLength && !Character.isLetterOrDigit(text.charAt(i))) {
- i++;
- }
-
- if (i + prefixLength > textLength) {
- return -1;
- }
-
- // Compare the prefixes
- int j;
- for (j = 0; j < prefixLength; j++) {
- if (Character.toUpperCase(text.charAt(i + j)) != prefix.charAt(j)) {
- break;
- }
- }
- if (j == prefixLength) {
- return i;
- }
-
- // Skip this word
- while (i < textLength && Character.isLetterOrDigit(text.charAt(i))) {
- i++;
- }
- }
-
- return -1;
- }
}
diff --git a/java/com/android/contacts/common/format/testing/SpannedTestUtils.java b/java/com/android/contacts/common/format/testing/SpannedTestUtils.java
new file mode 100644
index 000000000..293d9d5ad
--- /dev/null
+++ b/java/com/android/contacts/common/format/testing/SpannedTestUtils.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.contacts.common.format.testing;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Html;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.StyleSpan;
+import android.widget.TextView;
+import junit.framework.Assert;
+
+/** Utility class to check the value of spanned text in text views. */
+@SmallTest
+public class SpannedTestUtils {
+
+ /**
+ * Checks that the text contained in the text view matches the given HTML text.
+ *
+ * @param expectedHtmlText the expected text to be in the text view
+ * @param textView the text view from which to get the text
+ */
+ public static void checkHtmlText(String expectedHtmlText, TextView textView) {
+ String actualHtmlText = Html.toHtml((Spanned) textView.getText());
+ if (TextUtils.isEmpty(expectedHtmlText)) {
+ // If the text is empty, it does not add the <p></p> bits to it.
+ Assert.assertEquals("", actualHtmlText);
+ } else {
+ Assert.assertEquals("<p dir=ltr>" + expectedHtmlText + "</p>\n", actualHtmlText);
+ }
+ }
+
+ /**
+ * Assert span exists in the correct location.
+ *
+ * @param seq The spannable string to check.
+ * @param start The starting index.
+ * @param end The ending index.
+ */
+ public static void assertPrefixSpan(CharSequence seq, int start, int end) {
+ Assert.assertTrue(seq instanceof Spanned);
+ Spanned spannable = (Spanned) seq;
+
+ if (start > 0) {
+ Assert.assertEquals(0, getNumForegroundColorSpansBetween(spannable, 0, start - 1));
+ }
+ Assert.assertEquals(1, getNumForegroundColorSpansBetween(spannable, start, end));
+ Assert.assertEquals(
+ 0, getNumForegroundColorSpansBetween(spannable, end + 1, spannable.length() - 1));
+ }
+
+ private static int getNumForegroundColorSpansBetween(Spanned value, int start, int end) {
+ return value.getSpans(start, end, StyleSpan.class).length;
+ }
+
+ /**
+ * Asserts that the given character sequence is not a Spanned object and text is correct.
+ *
+ * @param seq The sequence to check.
+ * @param expected The expected text.
+ */
+ public static void assertNotSpanned(CharSequence seq, String expected) {
+ Assert.assertFalse(seq instanceof Spanned);
+ Assert.assertEquals(expected, seq);
+ }
+
+ public static int getNextTransition(SpannableString seq, int start) {
+ return seq.nextSpanTransition(start, seq.length(), StyleSpan.class);
+ }
+}
diff --git a/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java b/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
index 5e77b696b..88522c44b 100644
--- a/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
+++ b/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
@@ -30,10 +30,8 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
-import android.telecom.TelecomManager;
import android.text.TextUtils;
import com.android.contacts.common.R;
-import com.android.contacts.common.lettertiles.LetterTileDrawable.ContactType;
import com.android.dialer.common.Assert;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -408,30 +406,4 @@ public class LetterTileDrawable extends Drawable {
}
return this;
}
-
- /**
- * Returns the appropriate LetterTileDrawable.TYPE_ based on the given primitive conditions.
- *
- * <p>If no special state is detected, yields TYPE_DEFAULT
- */
- public static @ContactType int getContactTypeFromPrimitives(
- boolean isVoicemailNumber,
- boolean isSpam,
- boolean isBusiness,
- int numberPresentation,
- boolean isConference) {
- if (isVoicemailNumber) {
- return LetterTileDrawable.TYPE_VOICEMAIL;
- } else if (isSpam) {
- return LetterTileDrawable.TYPE_SPAM;
- } else if (isBusiness) {
- return LetterTileDrawable.TYPE_BUSINESS;
- } else if (numberPresentation == TelecomManager.PRESENTATION_RESTRICTED) {
- return LetterTileDrawable.TYPE_GENERIC_AVATAR;
- } else if (isConference) {
- return LetterTileDrawable.TYPE_CONFERENCE;
- } else {
- return LetterTileDrawable.TYPE_DEFAULT;
- }
- }
}
diff --git a/java/com/android/contacts/common/list/ContactEntryListAdapter.java b/java/com/android/contacts/common/list/ContactEntryListAdapter.java
index 064214ef2..18bbae382 100644
--- a/java/com/android/contacts/common/list/ContactEntryListAdapter.java
+++ b/java/com/android/contacts/common/list/ContactEntryListAdapter.java
@@ -26,6 +26,7 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Directory;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -38,10 +39,7 @@ import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.R;
import com.android.contacts.common.compat.DirectoryCompat;
import com.android.contacts.common.util.SearchUtil;
-import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
-import com.android.dialer.logging.InteractionEvent;
-import com.android.dialer.logging.Logger;
import java.util.HashSet;
/**
@@ -356,7 +354,7 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter {
if (cursor.getCount() == 0) {
// Directory table must have at least local directory, without which this adapter will
// enter very weird state.
- LogUtil.e(
+ Log.e(
TAG,
"Directory search loader returned an empty cursor, which implies we have "
+ "no directory entries.",
@@ -680,9 +678,6 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter {
// mimetype here is reasonable.
quickContact.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);
}
- Logger.get(mContext)
- .logQuickContactOnTouch(
- quickContact, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_SEARCH, true);
if (photoId != 0 || photoUriColumn == -1) {
getPhotoLoader().loadThumbnail(quickContact, photoId, mDarkTheme, mCircularPhotos, null);
diff --git a/java/com/android/contacts/common/list/ContactEntryListFragment.java b/java/com/android/contacts/common/list/ContactEntryListFragment.java
index 146986f75..278175c0b 100644
--- a/java/com/android/contacts/common/list/ContactEntryListFragment.java
+++ b/java/com/android/contacts/common/list/ContactEntryListFragment.java
@@ -555,6 +555,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter
protected void setSearchMode(boolean flag) {
if (mSearchMode != flag) {
mSearchMode = flag;
+ setSectionHeaderDisplayEnabled(!mSearchMode);
if (!flag) {
mDirectoryListStatus = STATUS_NOT_LOADED;
diff --git a/java/com/android/contacts/common/list/ContactListItemView.java b/java/com/android/contacts/common/list/ContactListItemView.java
index 5a2749178..7a3194720 100644
--- a/java/com/android/contacts/common/list/ContactListItemView.java
+++ b/java/com/android/contacts/common/list/ContactListItemView.java
@@ -30,8 +30,8 @@ import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.SearchSnippets;
import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -55,6 +55,7 @@ import com.android.contacts.common.format.TextHighlighter;
import com.android.contacts.common.list.PhoneNumberListAdapter.Listener;
import com.android.contacts.common.util.ContactDisplayUtils;
import com.android.contacts.common.util.SearchUtil;
+import com.android.dialer.compat.CompatUtils;
import com.android.dialer.util.ViewUtil;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -80,15 +81,13 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
/** IntDef for indices of ViewPager tabs. */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({NONE, VIDEO, LIGHTBRINGER, CALL_AND_SHARE})
+ @IntDef({NONE, VIDEO, CALL_AND_SHARE})
public @interface CallToAction {}
public static final int NONE = 0;
public static final int VIDEO = 1;
- public static final int LIGHTBRINGER = 2;
- public static final int CALL_AND_SHARE = 3;
+ public static final int CALL_AND_SHARE = 2;
- private final PhotoPosition mPhotoPosition = getDefaultPhotoPosition();
private static final Pattern SPLIT_PATTERN =
Pattern.compile("([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+");
static final char SNIPPET_START_MATCH = '[';
@@ -107,7 +106,7 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
private int mNameTextViewTextSize;
private int mHeaderWidth;
private Drawable mActivatedBackgroundDrawable;
- private int mCallToActionSize = 48;
+ private int mCallToActionSize = 32;
private int mCallToActionMargin = 16;
// Set in onLayout. Represent left and right position of the View on the screen.
private int mLeftOffset;
@@ -123,7 +122,10 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
private String mHighlightedPrefix;
/** Indicates whether the view should leave room for the "video call" icon. */
private boolean mSupportVideoCall;
+ /** Indicates whether the view should leave room for the "call and share" icon. */
+ private boolean mSupportCallAndShare;
+ private PhotoPosition mPhotoPosition = getDefaultPhotoPosition(false /* normal/non opposite */);
// Header layout data
private TextView mHeaderTextView;
private boolean mIsSectionHeaderEnabled;
@@ -137,7 +139,7 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
private TextView mSnippetView;
private TextView mStatusView;
private ImageView mPresenceIcon;
- @NonNull private final ImageView mCallToActionView;
+ private ImageView mCallToAction;
private ImageView mWorkProfileIcon;
private ColorStateList mSecondaryTextColor;
private int mDefaultPhotoViewSize = 0;
@@ -179,14 +181,23 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
private Rect mBoundsWithoutHeader = new Rect();
private CharSequence mUnknownNameText;
- private String mPhoneNumber;
- private int mPosition = -1;
- private @CallToAction int mCallToAction = NONE;
+ public ContactListItemView(Context context) {
+ super(context);
- public ContactListItemView(Context context, AttributeSet attrs, boolean supportVideoCallIcon) {
+ mTextHighlighter = new TextHighlighter(Typeface.BOLD);
+ mNameHighlightSequence = new ArrayList<>();
+ mNumberHighlightSequence = new ArrayList<>();
+ }
+
+ public ContactListItemView(
+ Context context,
+ AttributeSet attrs,
+ boolean supportVideoCallIcon,
+ boolean supportCallAndShare) {
this(context, attrs);
mSupportVideoCall = supportVideoCallIcon;
+ mSupportCallAndShare = supportCallAndShare;
}
public ContactListItemView(Context context, AttributeSet attrs) {
@@ -273,20 +284,19 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
mNameHighlightSequence = new ArrayList<>();
mNumberHighlightSequence = new ArrayList<>();
- mCallToActionView = new ImageView(getContext());
- mCallToActionView.setId(R.id.call_to_action);
- mCallToActionView.setLayoutParams(new LayoutParams(mCallToActionSize, mCallToActionSize));
- mCallToActionView.setScaleType(ScaleType.CENTER);
- mCallToActionView.setImageTintList(
- ContextCompat.getColorStateList(getContext(), R.color.search_video_call_icon_tint));
- addView(mCallToActionView);
-
setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
}
- public static PhotoPosition getDefaultPhotoPosition() {
- int layoutDirection = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
- return layoutDirection == View.LAYOUT_DIRECTION_RTL ? PhotoPosition.RIGHT : PhotoPosition.LEFT;
+ public static PhotoPosition getDefaultPhotoPosition(boolean opposite) {
+ final Locale locale = Locale.getDefault();
+ final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
+ switch (layoutDirection) {
+ case View.LAYOUT_DIRECTION_RTL:
+ return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT);
+ case View.LAYOUT_DIRECTION_LTR:
+ default:
+ return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT);
+ }
}
/**
@@ -323,47 +333,35 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
* @param position The position in the adapter of the call to action.
*/
public void setCallToAction(@CallToAction int action, Listener listener, int position) {
- mCallToAction = action;
- mPosition = position;
-
- Drawable drawable;
+ int drawable;
int description;
OnClickListener onClickListener;
- if (action == CALL_AND_SHARE) {
- drawable = getContext().getResources().getDrawable(R.drawable.ic_phone_attach);
- drawable.setAutoMirrored(true);
- description = R.string.description_search_call_and_share;
+ if (action == CALL_AND_SHARE && mSupportCallAndShare) {
+ drawable = R.drawable.ic_call_and_share;
+ description = R.string.description_search_video_call;
onClickListener = v -> listener.onCallAndShareIconClicked(position);
} else if (action == VIDEO && mSupportVideoCall) {
- drawable =
- getContext().getResources().getDrawable(R.drawable.quantum_ic_videocam_vd_theme_24);
- drawable.setAutoMirrored(true);
- description = R.string.description_search_video_call;
+ drawable = R.drawable.ic_search_video_call;
+ description = R.string.description_search_call_and_share;
onClickListener = v -> listener.onVideoCallIconClicked(position);
- } else if (action == LIGHTBRINGER) {
- drawable =
- getContext().getResources().getDrawable(R.drawable.quantum_ic_videocam_vd_theme_24);
- drawable.setAutoMirrored(true);
- description = R.string.description_search_video_call;
- onClickListener = v -> listener.onLightbringerIconClicked(position);
} else {
- mCallToActionView.setVisibility(View.GONE);
- mCallToActionView.setOnClickListener(null);
+ if (mCallToAction != null) {
+ mCallToAction.setVisibility(View.GONE);
+ mCallToAction.setOnClickListener(null);
+ }
return;
}
- mCallToActionView.setContentDescription(getContext().getString(description));
- mCallToActionView.setOnClickListener(onClickListener);
- mCallToActionView.setImageDrawable(drawable);
- mCallToActionView.setVisibility(View.VISIBLE);
- }
-
- public @CallToAction int getCallToAction() {
- return mCallToAction;
- }
-
- public int getPosition() {
- return mPosition;
+ if (mCallToAction == null) {
+ mCallToAction = new ImageView(getContext());
+ mCallToAction.setLayoutParams(new LayoutParams(mCallToActionSize, mCallToActionSize));
+ mCallToAction.setScaleType(ScaleType.CENTER);
+ addView(mCallToAction);
+ }
+ mCallToAction.setContentDescription(getContext().getString(description));
+ mCallToAction.setOnClickListener(onClickListener);
+ mCallToAction.setImageResource(drawable);
+ mCallToAction.setVisibility(View.VISIBLE);
}
/**
@@ -378,6 +376,18 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
mSupportVideoCall = supportVideoCall;
}
+ /**
+ * Sets whether the view supports a call and share icon. This is independent of whether the view
+ * is actually showing an icon. Support for the icon ensures that the layout leaves space for it,
+ * should it be shown.
+ *
+ * @param supportCallAndShare {@code true} if the call and share icon is supported, {@code false}
+ * otherwise.
+ */
+ public void setSupportCallAndShareIcon(boolean supportCallAndShare) {
+ mSupportCallAndShare = supportCallAndShare;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We will match parent's width and wrap content vertically, but make sure
@@ -413,7 +423,9 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
effectiveWidth -= mHeaderWidth + mGapBetweenImageAndText;
}
- effectiveWidth -= (mCallToActionSize + mCallToActionMargin);
+ if (mSupportVideoCall || mSupportCallAndShare) {
+ effectiveWidth -= (mCallToActionSize + mCallToActionMargin);
+ }
// Go over all visible text views and measure actual width of each of them.
// Also calculate their heights to get the total height for this entire view.
@@ -484,9 +496,11 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight();
}
- mCallToActionView.measure(
- MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY));
+ if ((mSupportVideoCall || mSupportCallAndShare) && isVisible(mCallToAction)) {
+ mCallToAction.measure(
+ MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mCallToActionSize, MeasureSpec.EXACTLY));
+ }
if (isVisible(mWorkProfileIcon)) {
mWorkProfileIcon.measure(
@@ -615,30 +629,34 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
leftBound += mTextIndent;
}
- // Place the call to action at the end of the list (e.g. take into account RTL mode).
- // Center the icon vertically
- final int callToActionTop = topBound + (height - topBound - mCallToActionSize) / 2;
+ if (mSupportVideoCall || mSupportCallAndShare) {
+ // Place the call to action at the end of the list (e.g. take into account RTL mode).
+ if (isVisible(mCallToAction)) {
+ // Center the icon vertically
+ final int callToActionTop = topBound + (height - topBound - mCallToActionSize) / 2;
- if (!isLayoutRtl) {
- // When photo is on left, icon is placed on the right edge.
- mCallToActionView.layout(
- rightBound - mCallToActionSize,
- callToActionTop,
- rightBound,
- callToActionTop + mCallToActionSize);
- } else {
- // When photo is on right, icon is placed on the left edge.
- mCallToActionView.layout(
- leftBound,
- callToActionTop,
- leftBound + mCallToActionSize,
- callToActionTop + mCallToActionSize);
- }
+ if (!isLayoutRtl) {
+ // When photo is on left, icon is placed on the right edge.
+ mCallToAction.layout(
+ rightBound - mCallToActionSize,
+ callToActionTop,
+ rightBound,
+ callToActionTop + mCallToActionSize);
+ } else {
+ // When photo is on right, icon is placed on the left edge.
+ mCallToAction.layout(
+ leftBound,
+ callToActionTop,
+ leftBound + mCallToActionSize,
+ callToActionTop + mCallToActionSize);
+ }
+ }
- if (mPhotoPosition == PhotoPosition.LEFT) {
- rightBound -= (mCallToActionSize + mCallToActionMargin);
- } else {
- leftBound += mCallToActionSize + mCallToActionMargin;
+ if (mPhotoPosition == PhotoPosition.LEFT) {
+ rightBound -= (mCallToActionSize + mCallToActionMargin);
+ } else {
+ leftBound += mCallToActionSize + mCallToActionMargin;
+ }
}
// Center text vertically, then apply the top offset.
@@ -883,7 +901,9 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
}
if (mQuickContact == null) {
mQuickContact = new QuickContactBadge(getContext());
- mQuickContact.setOverlay(null);
+ if (CompatUtils.isLollipopCompatible()) {
+ mQuickContact.setOverlay(null);
+ }
mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams());
if (mNameTextView != null) {
mQuickContact.setContentDescription(
@@ -988,7 +1008,9 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
mNameTextView.setGravity(Gravity.CENTER_VERTICAL);
mNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
mNameTextView.setId(R.id.cliv_name_textview);
- mNameTextView.setElegantTextHeight(false);
+ if (CompatUtils.isLollipopCompatible()) {
+ mNameTextView.setElegantTextHeight(false);
+ }
addView(mNameTextView);
}
return mNameTextView;
@@ -1034,7 +1056,6 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
* exists.
*/
public void setPhoneNumber(String text) {
- mPhoneNumber = text;
if (text == null) {
if (mDataView != null) {
mDataView.setVisibility(View.GONE);
@@ -1065,10 +1086,6 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
}
}
- public String getPhoneNumber() {
- return mPhoneNumber;
- }
-
private void setMarqueeText(TextView textView, CharSequence text) {
if (getTextEllipsis() == TruncateAt.MARQUEE) {
// To show MARQUEE correctly (with END effect during non-active state), we need
@@ -1092,7 +1109,9 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
mDataView.setActivated(isActivated());
mDataView.setId(R.id.cliv_data_view);
- mDataView.setElegantTextHeight(false);
+ if (CompatUtils.isLollipopCompatible()) {
+ mDataView.setElegantTextHeight(false);
+ }
addView(mDataView);
}
return mDataView;
@@ -1450,17 +1469,28 @@ public class ContactListItemView extends ViewGroup implements SelectionBoundsAdj
forceLayout();
}
+ public void setPhotoPosition(PhotoPosition photoPosition) {
+ mPhotoPosition = photoPosition;
+ }
+
/**
* Set drawable resources directly for the drawable resource of the photo view.
*
- * @param drawable A drawable resource.
+ * @param drawableId Id of drawable resource.
*/
- public void setDrawable(Drawable drawable) {
+ public void setDrawableResource(int drawableId) {
ImageView photo = getPhotoView();
photo.setScaleType(ImageView.ScaleType.CENTER);
- int iconColor = ContextCompat.getColor(getContext(), R.color.search_shortcut_icon_color);
- photo.setImageDrawable(drawable);
- photo.setImageTintList(ColorStateList.valueOf(iconColor));
+ final Drawable drawable = ContextCompat.getDrawable(getContext(), drawableId);
+ final int iconColor = ContextCompat.getColor(getContext(), R.color.search_shortcut_icon_color);
+ if (CompatUtils.isLollipopCompatible()) {
+ photo.setImageDrawable(drawable);
+ photo.setImageTintList(ColorStateList.valueOf(iconColor));
+ } else {
+ final Drawable drawableWrapper = DrawableCompat.wrap(drawable).mutate();
+ DrawableCompat.setTint(drawableWrapper, iconColor);
+ photo.setImageDrawable(drawableWrapper);
+ }
}
@Override
diff --git a/java/com/android/contacts/common/list/ContactTileView.java b/java/com/android/contacts/common/list/ContactTileView.java
index 15582d684..9273b0583 100644
--- a/java/com/android/contacts/common/list/ContactTileView.java
+++ b/java/com/android/contacts/common/list/ContactTileView.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.graphics.Rect;
import android.net.Uri;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -27,9 +28,6 @@ import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.common.R;
-import com.android.dialer.callintent.CallInitiationType;
-import com.android.dialer.callintent.CallSpecificAppData;
-import com.android.dialer.common.LogUtil;
/** A ContactTile displays a contact's picture and name */
public abstract class ContactTileView extends FrameLayout {
@@ -62,14 +60,8 @@ public abstract class ContactTileView extends FrameLayout {
if (mListener == null) {
return;
}
- CallSpecificAppData callSpecificAppData =
- CallSpecificAppData.newBuilder()
- .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
- .build();
mListener.onContactSelected(
- getLookupUri(),
- MoreContactUtils.getTargetRectFromView(ContactTileView.this),
- callSpecificAppData);
+ getLookupUri(), MoreContactUtils.getTargetRectFromView(ContactTileView.this));
}
};
}
@@ -105,7 +97,7 @@ public abstract class ContactTileView extends FrameLayout {
}
} else {
- LogUtil.w(TAG, "contactPhotoManager not set");
+ Log.w(TAG, "contactPhotoManager not set");
}
} else {
setVisibility(View.INVISIBLE);
@@ -171,10 +163,9 @@ public abstract class ContactTileView extends FrameLayout {
public interface Listener {
/** Notification that the contact was selected; no specific action is dictated. */
- void onContactSelected(
- Uri contactLookupUri, Rect viewRect, CallSpecificAppData callSpecificAppData);
+ void onContactSelected(Uri contactLookupUri, Rect viewRect);
/** Notification that the specified number is to be called. */
- void onCallNumberDirectly(String phoneNumber, CallSpecificAppData callSpecificAppData);
+ void onCallNumberDirectly(String phoneNumber);
}
}
diff --git a/java/com/android/contacts/common/list/PhoneNumberListAdapter.java b/java/com/android/contacts/common/list/PhoneNumberListAdapter.java
index 65e6f2da2..9a490d78a 100644
--- a/java/com/android/contacts/common/list/PhoneNumberListAdapter.java
+++ b/java/com/android/contacts/common/list/PhoneNumberListAdapter.java
@@ -30,6 +30,7 @@ import android.provider.ContactsContract.Directory;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.R;
@@ -37,17 +38,15 @@ import com.android.contacts.common.compat.CallableCompat;
import com.android.contacts.common.compat.DirectoryCompat;
import com.android.contacts.common.compat.PhoneCompat;
import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor;
-import com.android.contacts.common.lettertiles.LetterTileDrawable;
import com.android.contacts.common.list.ContactListItemView.CallToAction;
import com.android.contacts.common.preference.ContactsPreferences;
import com.android.contacts.common.util.Constants;
+import com.android.dialer.callcomposer.CallComposerContact;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
-import com.android.dialer.dialercontact.DialerContact;
import com.android.dialer.enrichedcall.EnrichedCallCapabilities;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.enrichedcall.EnrichedCallManager;
-import com.android.dialer.lightbringer.LightbringerComponent;
import com.android.dialer.location.GeoUtil;
import com.android.dialer.util.CallUtil;
import java.util.ArrayList;
@@ -69,15 +68,16 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
// A list of extended directories to add to the directories from the database
private final List<DirectoryPartition> mExtendedDirectories;
private final CharSequence mUnknownNameText;
- private final boolean mIsPresenceEnabled;
- protected final boolean mIsImsVideoEnabled;
-
+ private final boolean mCallAndShareEnabled;
// Extended directories will have ID's that are higher than any of the id's from the database,
// so that we can identify them and set them up properly. If no extended directories
// exist, this will be Long.MAX_VALUE
private long mFirstExtendedDirectoryId = Long.MAX_VALUE;
+ private ContactListItemView.PhotoPosition mPhotoPosition;
private boolean mUseCallableUri;
private Listener mListener;
+ private boolean mIsVideoEnabled;
+ private boolean mIsPresenceEnabled;
public PhoneNumberListAdapter(Context context) {
super(context);
@@ -88,8 +88,11 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
PhoneDirectoryExtenderAccessor.get(mContext).getExtendedDirectories(mContext);
int videoCapabilities = CallUtil.getVideoCallingAvailability(context);
- mIsImsVideoEnabled = CallUtil.isVideoEnabled(context);
+ mIsVideoEnabled = (videoCapabilities & CallUtil.VIDEO_CALLING_ENABLED) != 0;
mIsPresenceEnabled = (videoCapabilities & CallUtil.VIDEO_CALLING_PRESENCE) != 0;
+
+ // TODO
+ mCallAndShareEnabled = true;
}
@Override
@@ -246,10 +249,10 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
return item != null ? item.getString(PhoneQuery.LOOKUP_KEY) : null;
}
- public DialerContact getDialerContact(int position) {
+ public CallComposerContact getCallComposerContact(int position) {
Cursor cursor = (Cursor) getItem(position);
if (cursor == null) {
- LogUtil.e("PhoneNumberListAdapter.getDialerContact", "cursor was null.");
+ LogUtil.e("PhoneNumberListAdapter.getCallComposerContact", "cursor was null.");
return null;
}
@@ -260,11 +263,11 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
Contacts.getLookupUri(
cursor.getLong(PhoneQuery.CONTACT_ID), cursor.getString(PhoneQuery.LOOKUP_KEY));
- DialerContact.Builder contact = DialerContact.newBuilder();
+ CallComposerContact.Builder contact = CallComposerContact.newBuilder();
contact
.setNumber(number)
.setPhotoId(cursor.getLong(PhoneQuery.PHOTO_ID))
- .setContactType(LetterTileDrawable.TYPE_DEFAULT)
+ .setContactType(ContactPhotoManager.TYPE_DEFAULT)
.setNameOrNumber(displayName)
.setNumberLabel(
Phone.getTypeLabel(
@@ -294,6 +297,7 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
ContactListItemView view = super.newView(context, partition, cursor, position, parent);
view.setUnknownNameText(mUnknownNameText);
view.setQuickContactEnabled(isQuickContactEnabled());
+ view.setPhotoPosition(mPhotoPosition);
return view;
}
@@ -397,17 +401,13 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
int carrierPresence = cursor.getInt(PhoneQuery.CARRIER_PRESENCE);
boolean isPresent = (carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) != 0;
- boolean isVideoIconShown = mIsImsVideoEnabled && (!mIsPresenceEnabled || isPresent);
+ boolean isVideoIconShown = mIsVideoEnabled && (!mIsPresenceEnabled || isPresent);
if (isVideoIconShown) {
action = ContactListItemView.VIDEO;
}
}
- if (LightbringerComponent.get(mContext).getLightbringer().isReachable(mContext, number)) {
- action = ContactListItemView.LIGHTBRINGER;
- }
-
- if (action == ContactListItemView.NONE) {
+ if (isCallAndShareEnabled() && action == ContactListItemView.NONE && number != null) {
EnrichedCallManager manager = EnrichedCallComponent.get(mContext).getEnrichedCallManager();
EnrichedCallCapabilities capabilities = manager.getCapabilities(number);
if (capabilities != null && capabilities.supportsCallComposer()) {
@@ -481,6 +481,14 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
}
}
+ public ContactListItemView.PhotoPosition getPhotoPosition() {
+ return mPhotoPosition;
+ }
+
+ public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
+ mPhotoPosition = photoPosition;
+ }
+
public void setUseCallableUri(boolean useCallableUri) {
mUseCallableUri = useCallableUri;
}
@@ -562,12 +570,14 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
mListener = listener;
}
+ public boolean isCallAndShareEnabled() {
+ return mCallAndShareEnabled;
+ }
+
public interface Listener {
void onVideoCallIconClicked(int position);
- void onLightbringerIconClicked(int position);
-
void onCallAndShareIconClicked(int position);
}
@@ -632,14 +642,18 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter {
static {
final List<String> projectionList =
new ArrayList<>(Arrays.asList(PROJECTION_PRIMARY_INTERNAL));
- projectionList.add(Phone.CARRIER_PRESENCE); // 9
+ if (CompatUtils.isMarshmallowCompatible()) {
+ projectionList.add(Phone.CARRIER_PRESENCE); // 9
+ }
PROJECTION_PRIMARY = projectionList.toArray(new String[projectionList.size()]);
}
static {
final List<String> projectionList =
new ArrayList<>(Arrays.asList(PROJECTION_ALTERNATIVE_INTERNAL));
- projectionList.add(Phone.CARRIER_PRESENCE); // 9
+ if (CompatUtils.isMarshmallowCompatible()) {
+ projectionList.add(Phone.CARRIER_PRESENCE); // 9
+ }
PROJECTION_ALTERNATIVE = projectionList.toArray(new String[projectionList.size()]);
}
}
diff --git a/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java b/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java
index 79e670010..8f25f82a5 100644
--- a/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java
+++ b/java/com/android/contacts/common/list/PhoneNumberPickerFragment.java
@@ -29,18 +29,15 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.android.contacts.common.R;
-import com.android.contacts.common.list.PhoneNumberListAdapter.Listener;
import com.android.contacts.common.util.AccountFilterUtil;
+import com.android.dialer.callcomposer.CallComposerContact;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallInitiationType.Type;
import com.android.dialer.callintent.CallSpecificAppData;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
-import com.android.dialer.dialercontact.DialerContact;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.enrichedcall.EnrichedCallManager;
-import com.android.dialer.lightbringer.LightbringerComponent;
-import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.protos.ProtoParsers;
import java.util.Set;
@@ -64,6 +61,9 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
private boolean mUseCallableUri;
+ private ContactListItemView.PhotoPosition mPhotoPosition =
+ ContactListItemView.getDefaultPhotoPosition(false /* normal/non opposite */);
+
private final Set<OnLoadFinishedListener> mLoadFinishedListeners = new ArraySet<>();
private CursorReranker mCursorReranker;
@@ -71,7 +71,7 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
public PhoneNumberPickerFragment() {
setQuickContactEnabled(false);
setPhotoLoaderEnabled(true);
- setSectionHeaderDisplayEnabled(false);
+ setSectionHeaderDisplayEnabled(true);
setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
// Show nothing instead of letting caller Activity show something.
@@ -85,32 +85,17 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
*/
@Override
public void onVideoCallIconClicked(int position) {
- Logger.get(getContext()).logImpression(DialerImpression.Type.IMS_VIDEO_REQUESTED_FROM_SEARCH);
callNumber(position, true /* isVideoCall */);
}
@Override
- public void onLightbringerIconClicked(int position) {
- String phoneNumber = getPhoneNumber(position);
- Intent intent =
- LightbringerComponent.get(getContext())
- .getLightbringer()
- .getIntent(getContext(), phoneNumber);
- // DialtactsActivity.ACTIVITY_REQUEST_CODE_LIGHTBRINGER
- // Cannot reference because of cyclic dependencies
- Logger.get(getContext())
- .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_SEARCH);
- int dialactsActivityRequestCode = 3;
- getActivity().startActivityForResult(intent, dialactsActivityRequestCode);
- }
-
- @Override
public void onCallAndShareIconClicked(int position) {
// Required because of cyclic dependencies of everything depending on contacts/common.
String componentName = "com.android.dialer.callcomposer.CallComposerActivity";
Intent intent = new Intent();
intent.setComponent(new ComponentName(getContext(), componentName));
- DialerContact contact = ((PhoneNumberListAdapter) getAdapter()).getDialerContact(position);
+ CallComposerContact contact =
+ ((PhoneNumberListAdapter) getAdapter()).getCallComposerContact(position);
ProtoParsers.put(intent, "CALL_COMPOSER_CONTACT", contact);
startActivity(intent);
}
@@ -335,27 +320,7 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
@Override
public void onCapabilitiesUpdated() {
if (getAdapter() != null) {
- EnrichedCallManager manager =
- EnrichedCallComponent.get(getContext()).getEnrichedCallManager();
- Listener listener = ((PhoneNumberListAdapter) getAdapter()).getListener();
-
- for (int i = 0; i < getListView().getChildCount(); i++) {
- if (!(getListView().getChildAt(i) instanceof ContactListItemView)) {
- continue;
- }
-
- // Since call and share is the lowest priority call to action, if any others are set,
- // do not reset the call to action. Also do not set the call and share call to action if
- // the number doesn't support call composer.
- ContactListItemView view = (ContactListItemView) getListView().getChildAt(i);
- if (view.getCallToAction() != ContactListItemView.NONE
- || view.getPhoneNumber() == null
- || manager.getCapabilities(view.getPhoneNumber()) == null
- || !manager.getCapabilities(view.getPhoneNumber()).supportsCallComposer()) {
- continue;
- }
- view.setCallToAction(ContactListItemView.CALL_AND_SHARE, listener, view.getPosition());
- }
+ getAdapter().notifyDataSetChanged();
}
}
@@ -395,6 +360,12 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
if (!isSearchMode() && mFilter != null) {
adapter.setFilter(mFilter);
}
+
+ setPhotoPosition(adapter);
+ }
+
+ protected void setPhotoPosition(ContactEntryListAdapter adapter) {
+ ((PhoneNumberListAdapter) adapter).setPhotoPosition(mPhotoPosition);
}
@Override
@@ -418,6 +389,15 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE
updateFilterHeaderView();
}
+ public void setPhotoPosition(ContactListItemView.PhotoPosition photoPosition) {
+ mPhotoPosition = photoPosition;
+
+ final PhoneNumberListAdapter adapter = (PhoneNumberListAdapter) getAdapter();
+ if (adapter != null) {
+ adapter.setPhotoPosition(photoPosition);
+ }
+ }
+
/**
* @param isRemoteDirectory {@code true} if the call was initiated using a contact/phone number
* not in the local contacts database
diff --git a/java/com/android/contacts/common/list/ViewPagerTabs.java b/java/com/android/contacts/common/list/ViewPagerTabs.java
index 1e6cf1354..34f623ef4 100644
--- a/java/com/android/contacts/common/list/ViewPagerTabs.java
+++ b/java/com/android/contacts/common/list/ViewPagerTabs.java
@@ -33,6 +33,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.contacts.common.R;
+import com.android.dialer.compat.CompatUtils;
/**
* Lightweight implementation of ViewPager tabs. This looks similar to traditional actionBar tabs,
@@ -42,13 +43,7 @@ import com.android.contacts.common.R;
*/
public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
- private static final ViewOutlineProvider VIEW_BOUNDS_OUTLINE_PROVIDER =
- new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRect(0, 0, view.getWidth(), view.getHeight());
- }
- };
+ private static final ViewOutlineProvider VIEW_BOUNDS_OUTLINE_PROVIDER;
private static final int TAB_SIDE_PADDING_IN_DPS = 10;
// TODO: This should use <declare-styleable> in the future
private static final int[] ATTRS =
@@ -59,6 +54,20 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
android.R.attr.textAllCaps
};
+ static {
+ if (CompatUtils.isLollipopCompatible()) {
+ VIEW_BOUNDS_OUTLINE_PROVIDER =
+ new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRect(0, 0, view.getWidth(), view.getHeight());
+ }
+ };
+ } else {
+ VIEW_BOUNDS_OUTLINE_PROVIDER = null;
+ }
+ }
+
/**
* Linearlayout that will contain the TextViews serving as tabs. This is the only child of the
* parent HorizontalScrollView.
@@ -102,8 +111,10 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
a.recycle();
- // enable shadow casting from view bounds
- setOutlineProvider(VIEW_BOUNDS_OUTLINE_PROVIDER);
+ if (CompatUtils.isLollipopCompatible()) {
+ // enable shadow casting from view bounds
+ setOutlineProvider(VIEW_BOUNDS_OUTLINE_PROVIDER);
+ }
}
public void setViewPager(ViewPager viewPager) {
diff --git a/java/com/android/contacts/common/location/CountryDetector.java b/java/com/android/contacts/common/location/CountryDetector.java
new file mode 100644
index 000000000..7d9e42b38
--- /dev/null
+++ b/java/com/android/contacts/common/location/CountryDetector.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.contacts.common.location;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationManager;
+import android.preference.PreferenceManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.dialer.util.PermissionsUtil;
+import java.util.Locale;
+
+/**
+ * This class is used to detect the country where the user is. It is a simplified version of the
+ * country detector service in the framework. The sources of country location are queried in the
+ * following order of reliability:
+ *
+ * <ul>
+ * <li>Mobile network
+ * <li>Location manager
+ * <li>SIM's country
+ * <li>User's default locale
+ * </ul>
+ *
+ * As far as possible this class tries to replicate the behavior of the system's country detector
+ * service: 1) Order in priority of sources of country location 2) Mobile network information
+ * provided by CDMA phones is ignored 3) Location information is updated every 12 hours (instead of
+ * 24 hours in the system) 4) Location updates only uses the {@link
+ * LocationManager#PASSIVE_PROVIDER} to avoid active use of the GPS 5) If a location is successfully
+ * obtained and geocoded, we never fall back to use of the SIM's country (for the system, the
+ * fallback never happens without a reboot) 6) Location is not used if the device does not implement
+ * a {@link android.location.Geocoder}
+ */
+public class CountryDetector {
+
+ public static final String KEY_PREFERENCE_TIME_UPDATED = "preference_time_updated";
+ public static final String KEY_PREFERENCE_CURRENT_COUNTRY = "preference_current_country";
+ private static final String TAG = "CountryDetector";
+ // Wait 12 hours between updates
+ private static final long TIME_BETWEEN_UPDATES_MS = 1000L * 60 * 60 * 12;
+ // Minimum distance before an update is triggered, in meters. We don't need this to be too
+ // exact because all we care about is what country the user is in.
+ private static final long DISTANCE_BETWEEN_UPDATES_METERS = 5000;
+ private static CountryDetector sInstance;
+ private final TelephonyManager mTelephonyManager;
+ private final LocationManager mLocationManager;
+ private final LocaleProvider mLocaleProvider;
+ // Used as a default country code when all the sources of country data have failed in the
+ // exceedingly rare event that the device does not have a default locale set for some reason.
+ private static final String DEFAULT_COUNTRY_ISO = "US";
+ private final Context mContext;
+
+ private CountryDetector(Context context) {
+ this(
+ context,
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
+ (LocationManager) context.getSystemService(Context.LOCATION_SERVICE),
+ new LocaleProvider());
+ }
+
+ private CountryDetector(
+ Context context,
+ TelephonyManager telephonyManager,
+ LocationManager locationManager,
+ LocaleProvider localeProvider) {
+ mTelephonyManager = telephonyManager;
+ mLocationManager = locationManager;
+ mLocaleProvider = localeProvider;
+ mContext = context;
+
+ registerForLocationUpdates(context, mLocationManager);
+ }
+
+ public static void registerForLocationUpdates(Context context, LocationManager locationManager) {
+ if (!PermissionsUtil.hasLocationPermissions(context)) {
+ Log.w(TAG, "No location permissions, not registering for location updates.");
+ return;
+ }
+
+ if (!Geocoder.isPresent()) {
+ // Certain devices do not have an implementation of a geocoder - in that case there is
+ // no point trying to get location updates because we cannot retrieve the country based
+ // on the location anyway.
+ return;
+ }
+ final Intent activeIntent = new Intent(context, LocationChangedReceiver.class);
+ final PendingIntent pendingIntent =
+ PendingIntent.getBroadcast(context, 0, activeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ locationManager.requestLocationUpdates(
+ LocationManager.PASSIVE_PROVIDER,
+ TIME_BETWEEN_UPDATES_MS,
+ DISTANCE_BETWEEN_UPDATES_METERS,
+ pendingIntent);
+ }
+
+ /**
+ * Returns the instance of the country detector. {@link #initialize(Context)} must have been
+ * called previously.
+ *
+ * @return the initialized country detector.
+ */
+ public static synchronized CountryDetector getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new CountryDetector(context.getApplicationContext());
+ }
+ return sInstance;
+ }
+
+ /** Factory method for {@link CountryDetector} that allows the caller to provide mock objects. */
+ public CountryDetector getInstanceForTest(
+ Context context,
+ TelephonyManager telephonyManager,
+ LocationManager locationManager,
+ LocaleProvider localeProvider,
+ Geocoder geocoder) {
+ return new CountryDetector(context, telephonyManager, locationManager, localeProvider);
+ }
+
+ public String getCurrentCountryIso() {
+ String result = null;
+ if (isNetworkCountryCodeAvailable()) {
+ result = getNetworkBasedCountryIso();
+ }
+ if (TextUtils.isEmpty(result)) {
+ result = getLocationBasedCountryIso();
+ }
+ if (TextUtils.isEmpty(result)) {
+ result = getSimBasedCountryIso();
+ }
+ if (TextUtils.isEmpty(result)) {
+ result = getLocaleBasedCountryIso();
+ }
+ if (TextUtils.isEmpty(result)) {
+ result = DEFAULT_COUNTRY_ISO;
+ }
+ return result.toUpperCase(Locale.US);
+ }
+
+ /** @return the country code of the current telephony network the user is connected to. */
+ private String getNetworkBasedCountryIso() {
+ return mTelephonyManager.getNetworkCountryIso();
+ }
+
+ /** @return the geocoded country code detected by the {@link LocationManager}. */
+ private String getLocationBasedCountryIso() {
+ if (!Geocoder.isPresent() || !PermissionsUtil.hasLocationPermissions(mContext)) {
+ return null;
+ }
+ final SharedPreferences sharedPreferences =
+ PreferenceManager.getDefaultSharedPreferences(mContext);
+ return sharedPreferences.getString(KEY_PREFERENCE_CURRENT_COUNTRY, null);
+ }
+
+ /** @return the country code of the SIM card currently inserted in the device. */
+ private String getSimBasedCountryIso() {
+ return mTelephonyManager.getSimCountryIso();
+ }
+
+ /** @return the country code of the user's currently selected locale. */
+ private String getLocaleBasedCountryIso() {
+ Locale defaultLocale = mLocaleProvider.getDefaultLocale();
+ if (defaultLocale != null) {
+ return defaultLocale.getCountry();
+ }
+ return null;
+ }
+
+ private boolean isNetworkCountryCodeAvailable() {
+ // On CDMA TelephonyManager.getNetworkCountryIso() just returns the SIM's country code.
+ // In this case, we want to ignore the value returned and fallback to location instead.
+ return mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM;
+ }
+
+ /**
+ * Class that can be used to return the user's default locale. This is in its own class so that it
+ * can be mocked out.
+ */
+ public static class LocaleProvider {
+
+ public Locale getDefaultLocale() {
+ return Locale.getDefault();
+ }
+ }
+
+ public static class LocationChangedReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ if (!intent.hasExtra(LocationManager.KEY_LOCATION_CHANGED)) {
+ return;
+ }
+
+ final Location location =
+ (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
+
+ UpdateCountryService.updateCountry(context, location);
+ }
+ }
+}
diff --git a/java/com/android/contacts/common/location/UpdateCountryService.java b/java/com/android/contacts/common/location/UpdateCountryService.java
new file mode 100644
index 000000000..f23e09e20
--- /dev/null
+++ b/java/com/android/contacts/common/location/UpdateCountryService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.contacts.common.location;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.location.Address;
+import android.location.Geocoder;
+import android.location.Location;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Service used to perform asynchronous geocoding from within a broadcast receiver. Given a {@link
+ * Location}, convert it into a country code, and save it in shared preferences.
+ */
+public class UpdateCountryService extends IntentService {
+
+ private static final String TAG = UpdateCountryService.class.getSimpleName();
+
+ private static final String ACTION_UPDATE_COUNTRY = "saveCountry";
+
+ private static final String KEY_INTENT_LOCATION = "location";
+
+ public UpdateCountryService() {
+ super(TAG);
+ }
+
+ public static void updateCountry(Context context, Location location) {
+ final Intent serviceIntent = new Intent(context, UpdateCountryService.class);
+ serviceIntent.setAction(ACTION_UPDATE_COUNTRY);
+ serviceIntent.putExtra(UpdateCountryService.KEY_INTENT_LOCATION, location);
+ context.startService(serviceIntent);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ if (intent == null) {
+ Log.d(TAG, "onHandleIntent: could not handle null intent");
+ return;
+ }
+ if (ACTION_UPDATE_COUNTRY.equals(intent.getAction())) {
+ final Location location = intent.getParcelableExtra(KEY_INTENT_LOCATION);
+ final String country = getCountryFromLocation(getApplicationContext(), location);
+
+ if (country == null) {
+ return;
+ }
+
+ final SharedPreferences prefs =
+ PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+
+ final Editor editor = prefs.edit();
+ editor.putLong(CountryDetector.KEY_PREFERENCE_TIME_UPDATED, System.currentTimeMillis());
+ editor.putString(CountryDetector.KEY_PREFERENCE_CURRENT_COUNTRY, country);
+ editor.commit();
+ }
+ }
+
+ /**
+ * Given a {@link Location}, return a country code.
+ *
+ * @return the ISO 3166-1 two letter country code
+ */
+ private String getCountryFromLocation(Context context, Location location) {
+ final Geocoder geocoder = new Geocoder(context);
+ String country = null;
+ try {
+ double latitude = location.getLatitude();
+ // Latitude has to be between 90 and -90 (latitude of north and south poles wrt equator)
+ if (latitude <= 90 && latitude >= -90) {
+ final List<Address> addresses =
+ geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
+ if (addresses != null && addresses.size() > 0) {
+ country = addresses.get(0).getCountryCode();
+ }
+ } else {
+ Log.w(TAG, "Invalid latitude");
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Exception occurred when getting geocoded country from location");
+ }
+ return country;
+ }
+}
diff --git a/java/com/android/contacts/common/model/ContactLoader.java b/java/com/android/contacts/common/model/ContactLoader.java
index 7ef3b73a0..55464b161 100644
--- a/java/com/android/contacts/common/model/ContactLoader.java
+++ b/java/com/android/contacts/common/model/ContactLoader.java
@@ -522,7 +522,6 @@ public class ContactLoader extends AsyncTaskLoader<Contact> {
cursorColumnToContentValues(cursor, cv, ContactQuery.TIMES_USED);
cursorColumnToContentValues(cursor, cv, ContactQuery.LAST_TIME_USED);
cursorColumnToContentValues(cursor, cv, ContactQuery.CARRIER_PRESENCE);
-
return cv;
}
diff --git a/java/com/android/contacts/common/model/account/BaseAccountType.java b/java/com/android/contacts/common/model/account/BaseAccountType.java
index ccdad3641..8e9ba738c 100644
--- a/java/com/android/contacts/common/model/account/BaseAccountType.java
+++ b/java/com/android/contacts/common/model/account/BaseAccountType.java
@@ -307,7 +307,7 @@ public abstract class BaseAccountType extends AccountType {
DataKind kind =
addKind(
new DataKind(Phone.CONTENT_ITEM_TYPE, R.string.phoneLabelsGroup, Weight.PHONE, true));
- kind.iconAltRes = R.drawable.quantum_ic_message_vd_theme_24;
+ kind.iconAltRes = R.drawable.quantum_ic_message_white_24;
kind.iconAltDescriptionRes = R.string.sms;
kind.actionHeader = new PhoneActionInflater();
kind.actionAltHeader = new PhoneActionAltInflater();
@@ -1228,7 +1228,7 @@ public abstract class BaseAccountType extends AccountType {
new PhoneActionInflater(),
new SimpleInflater(Phone.NUMBER));
- kind.iconAltRes = R.drawable.quantum_ic_message_vd_theme_24;
+ kind.iconAltRes = R.drawable.quantum_ic_message_white_24;
kind.iconAltDescriptionRes = R.string.sms;
kind.actionAltHeader = new PhoneActionAltInflater();
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_ab_search.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_ab_search.png
new file mode 100644
index 000000000..d86b2195a
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_ab_search.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_arrow_back_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_arrow_back_24dp.png
new file mode 100644
index 000000000..ddbb2c459
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_arrow_back_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_business_white_120dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_business_white_120dp.png
new file mode 100644
index 000000000..d5942dcad
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_business_white_120dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_call_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_call_24dp.png
new file mode 100644
index 000000000..4dc506515
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_call_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_close_dk.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_close_dk.png
new file mode 100644
index 000000000..969552935
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_close_dk.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_create_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_create_24dp.png
new file mode 100644
index 000000000..540ab4dee
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_create_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_group_white_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_group_white_24dp.png
new file mode 100644
index 000000000..017e4bbf7
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_group_white_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_history_white_drawable_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_history_white_drawable_24dp.png
new file mode 100644
index 000000000..703d30b92
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_history_white_drawable_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_info_outline_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_info_outline_24dp.png
new file mode 100644
index 000000000..c7b1113cf
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_info_outline_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_back.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_back.png
new file mode 100644
index 000000000..deb3a6dc1
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_back.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_dk.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_dk.png
new file mode 100644
index 000000000..06bd18fbb
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_dk.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_lt.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_lt.png
new file mode 100644
index 000000000..d829d11e2
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_group_lt.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_overflow_lt.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_overflow_lt.png
new file mode 100644
index 000000000..1ba12950c
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_overflow_lt.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_dk.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_dk.png
new file mode 100644
index 000000000..5ff3ac574
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_dk.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_lt.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_lt.png
new file mode 100644
index 000000000..b4ebfc7b2
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_person_lt.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_remove_field_holo_light.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_remove_field_holo_light.png
new file mode 100644
index 000000000..03fd2fb10
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_remove_field_holo_light.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_dk.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_dk.png
new file mode 100644
index 000000000..e8cb0f5fe
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_dk.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_holo_light.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_holo_light.png
new file mode 100644
index 000000000..45137967c
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_holo_light.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_lt.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_lt.png
new file mode 100644
index 000000000..1c9bb81fa
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_menu_star_lt.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_person_24dp.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_person_24dp.png
new file mode 100644
index 000000000..56708b0ba
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_person_24dp.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_rx_videocam.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_rx_videocam.png
new file mode 100644
index 000000000..ccdda6701
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_rx_videocam.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_tx_videocam.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_tx_videocam.png
new file mode 100644
index 000000000..603ddc895
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_tx_videocam.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_videocam.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_videocam.png
new file mode 100644
index 000000000..97905c9f5
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_videocam.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/ic_voicemail_avatar.png b/java/com/android/contacts/common/res/drawable-hdpi/ic_voicemail_avatar.png
new file mode 100644
index 000000000..2121878ae
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/ic_voicemail_avatar.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..4ea7afa00
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_background_holo.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_background_holo.9.png
new file mode 100644
index 000000000..cddf9be75
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_background_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..86578be45
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_longpressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_longpressed_holo_light.9.png
new file mode 100644
index 000000000..e9afcc924
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_longpressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_pressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_pressed_holo_light.9.png
new file mode 100644
index 000000000..2054530ed
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_pressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..a0f17568e
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-hdpi/list_title_holo.9.png b/java/com/android/contacts/common/res/drawable-hdpi/list_title_holo.9.png
new file mode 100644
index 000000000..ae937176e
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-hdpi/list_title_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..4139942d6
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..569d28f54
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_title_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_title_holo.9.png
new file mode 100644
index 000000000..5ec4c96a7
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-hdpi/list_title_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..4139942d6
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..065ff62ce
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_title_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_title_holo.9.png
new file mode 100644
index 000000000..013d5e711
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-mdpi/list_title_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-hdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-hdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..947f03cec
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-hdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-mdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-mdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..6d09d7278
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-mdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-xhdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-xhdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..63c7456f0
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-sw600dp-xhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..4139942d6
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..af5855420
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_title_holo.9.png b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_title_holo.9.png
new file mode 100644
index 000000000..cb801ac1b
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-ldrtl-xhdpi/list_title_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-mdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-mdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..3bf8e0362
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-mdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-mdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-mdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..86578be45
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-mdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-mdpi/list_longpressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-mdpi/list_longpressed_holo_light.9.png
new file mode 100644
index 000000000..3226ab760
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-mdpi/list_longpressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-mdpi/list_pressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-mdpi/list_pressed_holo_light.9.png
new file mode 100644
index 000000000..061904c42
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-mdpi/list_pressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-mdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-mdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..1d9371de0
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-mdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-sw600dp-hdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-sw600dp-hdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..046b24a96
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-sw600dp-hdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-sw600dp-mdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-sw600dp-mdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..1ff337370
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-sw600dp-mdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-sw600dp-xhdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-sw600dp-xhdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..2eb7c7ebc
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-sw600dp-xhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xhdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-xhdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..eda10e612
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xhdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-xhdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..86578be45
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xhdpi/list_longpressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-xhdpi/list_longpressed_holo_light.9.png
new file mode 100644
index 000000000..5532e88c2
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xhdpi/list_longpressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xhdpi/list_pressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-xhdpi/list_pressed_holo_light.9.png
new file mode 100644
index 000000000..f4af92657
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xhdpi/list_pressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xhdpi/list_section_divider_holo_custom.9.png b/java/com/android/contacts/common/res/drawable-xhdpi/list_section_divider_holo_custom.9.png
new file mode 100644
index 000000000..8fb0636cf
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xhdpi/list_section_divider_holo_custom.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xxhdpi/list_activated_holo.9.png b/java/com/android/contacts/common/res/drawable-xxhdpi/list_activated_holo.9.png
new file mode 100644
index 000000000..52c00ddcd
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xxhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xxhdpi/list_focused_holo.9.png b/java/com/android/contacts/common/res/drawable-xxhdpi/list_focused_holo.9.png
new file mode 100644
index 000000000..3e4ca684e
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xxhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xxhdpi/list_longpressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-xxhdpi/list_longpressed_holo_light.9.png
new file mode 100644
index 000000000..230d649bf
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xxhdpi/list_longpressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable-xxhdpi/list_pressed_holo_light.9.png b/java/com/android/contacts/common/res/drawable-xxhdpi/list_pressed_holo_light.9.png
new file mode 100644
index 000000000..1352a1702
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable-xxhdpi/list_pressed_holo_light.9.png
Binary files differ
diff --git a/java/com/android/contacts/common/res/drawable/ic_back_arrow.xml b/java/com/android/contacts/common/res/drawable/ic_back_arrow.xml
new file mode 100644
index 000000000..ecf704e8e
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/ic_back_arrow.xml
@@ -0,0 +1,20 @@
+<?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
+ -->
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
+ android:src="@drawable/quantum_ic_arrow_back_white_24"
+ android:tint="@color/actionbar_icon_color"/> \ No newline at end of file
diff --git a/java/com/android/contacts/common/res/drawable/ic_call_and_share.xml b/java/com/android/contacts/common/res/drawable/ic_call_and_share.xml
new file mode 100644
index 000000000..be0cdd358
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/ic_call_and_share.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
+ android:src="@drawable/ic_phone_attach"
+ android:tint="@color/search_video_call_icon_tint"
+ android:background="?attr/selectableItemBackgroundBorderless"/> \ No newline at end of file
diff --git a/java/com/android/contacts/common/res/drawable/ic_person_add_tinted_24dp.xml b/java/com/android/contacts/common/res/drawable/ic_person_add_tinted_24dp.xml
new file mode 100644
index 000000000..c2538cfd1
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/ic_person_add_tinted_24dp.xml
@@ -0,0 +1,20 @@
+<?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
+ -->
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
+ android:src="@drawable/quantum_ic_person_add_white_24"
+ android:tint="@color/actionbar_icon_color"/>
diff --git a/java/com/android/contacts/common/res/drawable/ic_search_add_contact.xml b/java/com/android/contacts/common/res/drawable/ic_search_add_contact.xml
new file mode 100644
index 000000000..476212d24
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/ic_search_add_contact.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
+ android:src="@drawable/quantum_ic_person_add_white_24"/>
diff --git a/java/com/android/contacts/common/res/drawable/ic_search_video_call.xml b/java/com/android/contacts/common/res/drawable/ic_search_video_call.xml
new file mode 100644
index 000000000..0fe0367e1
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/ic_search_video_call.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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
+ -->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
+ android:src="@drawable/quantum_ic_videocam_white_24"
+ android:tint="@color/search_video_call_icon_tint"
+ android:background="?attr/selectableItemBackgroundBorderless"/>
diff --git a/java/com/android/contacts/common/res/drawable/list_selector_background_transition_holo_light.xml b/java/com/android/contacts/common/res/drawable/list_selector_background_transition_holo_light.xml
new file mode 100644
index 000000000..35fff99c2
--- /dev/null
+++ b/java/com/android/contacts/common/res/drawable/list_selector_background_transition_holo_light.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<transition xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/list_pressed_holo_light"/>
+ <item android:drawable="@drawable/list_longpressed_holo_light"/>
+</transition>
diff --git a/java/com/android/contacts/common/res/layout/dialog_call_subject.xml b/java/com/android/contacts/common/res/layout/dialog_call_subject.xml
index df8e8d299..a33b2ac85 100644
--- a/java/com/android/contacts/common/res/layout/dialog_call_subject.xml
+++ b/java/com/android/contacts/common/res/layout/dialog_call_subject.xml
@@ -129,7 +129,7 @@
android:layout_height="25dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
- android:src="@drawable/quantum_ic_history_vd_theme_24"
+ android:src="@drawable/quantum_ic_history_white_24"
android:tint="@color/call_subject_history_icon"/>
<TextView
diff --git a/java/com/android/contacts/common/res/layout/search_bar_expanded.xml b/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
index 7192eb030..fa16083e2 100644
--- a/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
+++ b/java/com/android/contacts/common/res/layout/search_bar_expanded.xml
@@ -29,7 +29,7 @@
android:layout_margin="@dimen/search_box_navigation_icon_margin"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_menu_back_from_search"
- android:src="@drawable/quantum_ic_arrow_back_vd_theme_24"
+ android:src="@drawable/ic_back_arrow"
android:tint="@color/contactscommon_actionbar_background_color"/>
<EditText
@@ -56,7 +56,7 @@
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/description_clear_search"
- android:src="@drawable/quantum_ic_close_vd_theme_24"
+ android:src="@drawable/quantum_ic_close_white_24"
android:tint="@color/searchbox_icon_tint"/>
</LinearLayout>
diff --git a/java/com/android/contacts/common/res/values-af/strings.xml b/java/com/android/contacts/common/res/values-af/strings.xml
index 48e4158f0..52e612da9 100644
--- a/java/com/android/contacts/common/res/values-af/strings.xml
+++ b/java/com/android/contacts/common/res/values-af/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Tik \'n nota om saam met oproep te stuur …"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"STUUR EN BEL"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>-oortjie"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>-oortjie <xliff:g id="COUNT_3">%2$d</xliff:g> ongelese items. </item>
diff --git a/java/com/android/contacts/common/res/values-am/strings.xml b/java/com/android/contacts/common/res/values-am/strings.xml
index 4121474f0..0283fbb0a 100644
--- a/java/com/android/contacts/common/res/values-am/strings.xml
+++ b/java/com/android/contacts/common/res/values-am/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ከጥሪ ጋር ለመላክ የማስታወሻ ጽሑፍ ይተይቡ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ላክ እና ደውል"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g><xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"የ<xliff:g id="TITLE">%1$s</xliff:g> ትር።"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> የ<xliff:g id="TITLE_2">%1$s</xliff:g> ትር። <xliff:g id="COUNT_3">%2$d</xliff:g> ያልተነበቡ ንጥሎች። </item>
diff --git a/java/com/android/contacts/common/res/values-ar/strings.xml b/java/com/android/contacts/common/res/values-ar/strings.xml
index 98fb057d4..a3862fe09 100644
--- a/java/com/android/contacts/common/res/values-ar/strings.xml
+++ b/java/com/android/contacts/common/res/values-ar/strings.xml
@@ -252,7 +252,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"اكتب ملاحظة لإرسالها مع المكالمة ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"إرسال واتصال"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"علامة تبويب <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="zero"> <xliff:g id="TITLE_2">%1$s</xliff:g> علامة تبويب. <xliff:g id="COUNT_3">%2$d</xliff:g> عناصر غير مقروءة. </item>
diff --git a/java/com/android/contacts/common/res/values-az/strings.xml b/java/com/android/contacts/common/res/values-az/strings.xml
index 813ada7f7..943377127 100644
--- a/java/com/android/contacts/common/res/values-az/strings.xml
+++ b/java/com/android/contacts/common/res/values-az/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Zəng ilə göndərmək üçün qeyd yazın..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"GÖNDƏRİN VƏ ZƏNG EDİN"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> tabel."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> tabel. <xliff:g id="COUNT_3">%2$d</xliff:g> oxunmamış element. </item>
diff --git a/java/com/android/contacts/common/res/values-b+sr+Latn/strings.xml b/java/com/android/contacts/common/res/values-b+sr+Latn/strings.xml
index 3eccfc654..fc99567f1 100644
--- a/java/com/android/contacts/common/res/values-b+sr+Latn/strings.xml
+++ b/java/com/android/contacts/common/res/values-b+sr+Latn/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Unesite belešku koju ćete poslati uz poziv..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"POŠALJI I POZOVI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Kartica <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Kartica <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
diff --git a/java/com/android/contacts/common/res/values-be/strings.xml b/java/com/android/contacts/common/res/values-be/strings.xml
index 99922a874..a9652a1c1 100644
--- a/java/com/android/contacts/common/res/values-be/strings.xml
+++ b/java/com/android/contacts/common/res/values-be/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Увесці нататку для адпраўкі з выклікам…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"АДПРАВІЦЬ І ВЫКЛІКАЦЬ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Укладка <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one">Укладка <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрачытаны элемент. </item>
diff --git a/java/com/android/contacts/common/res/values-bg/strings.xml b/java/com/android/contacts/common/res/values-bg/strings.xml
index c2ebd2736..0b57eb6a5 100644
--- a/java/com/android/contacts/common/res/values-bg/strings.xml
+++ b/java/com/android/contacts/common/res/values-bg/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Напишете придружаваща бележка, която ще се изпрати при извършване на обаждането..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ИЗПРАЩАНЕ И ОБАЖДАНЕ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Раздел „<xliff:g id="TITLE">%1$s</xliff:g>“."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Раздел „<xliff:g id="TITLE_2">%1$s</xliff:g>“. <xliff:g id="COUNT_3">%2$d</xliff:g> непрочетени елемента. </item>
diff --git a/java/com/android/contacts/common/res/values-bn/strings.xml b/java/com/android/contacts/common/res/values-bn/strings.xml
index 47e9b020e..8e783d129 100644
--- a/java/com/android/contacts/common/res/values-bn/strings.xml
+++ b/java/com/android/contacts/common/res/values-bn/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"কলের সাথে পাঠানোর জন্য একটি নোট লিখুন ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"পাঠান এবং কল করুন"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ট্যাব৷"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> ট্যাব৷ <xliff:g id="COUNT_3">%2$d</xliff:g>টি অপঠিত আইটেম৷ </item>
diff --git a/java/com/android/contacts/common/res/values-bs/strings.xml b/java/com/android/contacts/common/res/values-bs/strings.xml
index 305a7468a..278f6a8d0 100644
--- a/java/com/android/contacts/common/res/values-bs/strings.xml
+++ b/java/com/android/contacts/common/res/values-bs/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Upišite bilješku koja će se poslati uz poziv ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"POŠALJI I POZOVI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Kartica <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Kartica <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
diff --git a/java/com/android/contacts/common/res/values-ca/strings.xml b/java/com/android/contacts/common/res/values-ca/strings.xml
index 8e8068695..ad31a01b6 100644
--- a/java/com/android/contacts/common/res/values-ca/strings.xml
+++ b/java/com/android/contacts/common/res/values-ca/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escriu una nota per enviar-la juntament amb la trucada..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIA I TRUCA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Pestanya <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Pestanya <xliff:g id="TITLE_2">%1$s</xliff:g>: <xliff:g id="COUNT_3">%2$d</xliff:g> elements no llegits </item>
diff --git a/java/com/android/contacts/common/res/values-cs/strings.xml b/java/com/android/contacts/common/res/values-cs/strings.xml
index 7aea200b1..ab54be93a 100644
--- a/java/com/android/contacts/common/res/values-cs/strings.xml
+++ b/java/com/android/contacts/common/res/values-cs/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Zadejte poznámku, která se odešle pomocí volání…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ODESLAT A ZAVOLAT"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Karta <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="few"> Karta <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepřečtené položky. </item>
diff --git a/java/com/android/contacts/common/res/values-da/strings.xml b/java/com/android/contacts/common/res/values-da/strings.xml
index 430895a71..965d04a73 100644
--- a/java/com/android/contacts/common/res/values-da/strings.xml
+++ b/java/com/android/contacts/common/res/values-da/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Indtast en note, som skal sendes ved opkald..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND OG RING"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Fanen <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Fanen <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> ulæst element. </item>
diff --git a/java/com/android/contacts/common/res/values-de/strings.xml b/java/com/android/contacts/common/res/values-de/strings.xml
index a46f278c1..60c5e6806 100644
--- a/java/com/android/contacts/common/res/values-de/strings.xml
+++ b/java/com/android/contacts/common/res/values-de/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Notiz eingeben, die beim Anrufen gesendet wird..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SENDEN UND ANRUFEN"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tab \"<xliff:g id="TITLE">%1$s</xliff:g>\"."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Tab \"<xliff:g id="TITLE_2">%1$s</xliff:g>\". <xliff:g id="COUNT_3">%2$d</xliff:g> ungelesene Elemente. </item>
diff --git a/java/com/android/contacts/common/res/values-el/strings.xml b/java/com/android/contacts/common/res/values-el/strings.xml
index 567b8fb52..9af3bc55a 100644
--- a/java/com/android/contacts/common/res/values-el/strings.xml
+++ b/java/com/android/contacts/common/res/values-el/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Πληκτρολογήστε μια σημείωση για αποστολή με την κλήση…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ΑΠΟΣΤΟΛΗ ΚΑΙ ΚΛΗΣΗ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Καρτέλα <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Καρτέλα <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> μη αναγνωσμένα στοιχεία. </item>
diff --git a/java/com/android/contacts/common/res/values-en-rAU/strings.xml b/java/com/android/contacts/common/res/values-en-rAU/strings.xml
index 660993d2e..996c6ee18 100644
--- a/java/com/android/contacts/common/res/values-en-rAU/strings.xml
+++ b/java/com/android/contacts/common/res/values-en-rAU/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Type a note to send with call ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND &amp; CALL"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> tab."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> tab. <xliff:g id="COUNT_3">%2$d</xliff:g> unread items. </item>
diff --git a/java/com/android/contacts/common/res/values-en-rGB/strings.xml b/java/com/android/contacts/common/res/values-en-rGB/strings.xml
index 660993d2e..996c6ee18 100644
--- a/java/com/android/contacts/common/res/values-en-rGB/strings.xml
+++ b/java/com/android/contacts/common/res/values-en-rGB/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Type a note to send with call ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND &amp; CALL"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> tab."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> tab. <xliff:g id="COUNT_3">%2$d</xliff:g> unread items. </item>
diff --git a/java/com/android/contacts/common/res/values-en-rIN/strings.xml b/java/com/android/contacts/common/res/values-en-rIN/strings.xml
index 660993d2e..996c6ee18 100644
--- a/java/com/android/contacts/common/res/values-en-rIN/strings.xml
+++ b/java/com/android/contacts/common/res/values-en-rIN/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Type a note to send with call ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND &amp; CALL"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> tab."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> tab. <xliff:g id="COUNT_3">%2$d</xliff:g> unread items. </item>
diff --git a/java/com/android/contacts/common/res/values-es-rUS/strings.xml b/java/com/android/contacts/common/res/values-es-rUS/strings.xml
index 1c0339a6a..acb563cab 100644
--- a/java/com/android/contacts/common/res/values-es-rUS/strings.xml
+++ b/java/com/android/contacts/common/res/values-es-rUS/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escribe una nota para enviar con la llamada…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR Y LLAMAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Pestaña <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Pestaña <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> elementos no leídos. </item>
diff --git a/java/com/android/contacts/common/res/values-es/strings.xml b/java/com/android/contacts/common/res/values-es/strings.xml
index b0956ec6a..def7a447c 100644
--- a/java/com/android/contacts/common/res/values-es/strings.xml
+++ b/java/com/android/contacts/common/res/values-es/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escribe una nota para enviarla con la llamada..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR Y LLAMAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Pestaña <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Pestaña <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> elementos no leídos. </item>
diff --git a/java/com/android/contacts/common/res/values-et/strings.xml b/java/com/android/contacts/common/res/values-et/strings.xml
index e152f595a..c80d54214 100644
--- a/java/com/android/contacts/common/res/values-et/strings.xml
+++ b/java/com/android/contacts/common/res/values-et/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Sisestage märkus, mis koos kõnega saata ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SAADA JA HELISTA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Vahekaart <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Vahekaart <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> lugemata üksust. </item>
diff --git a/java/com/android/contacts/common/res/values-eu/strings.xml b/java/com/android/contacts/common/res/values-eu/strings.xml
index 967b63540..868d668b5 100644
--- a/java/com/android/contacts/common/res/values-eu/strings.xml
+++ b/java/com/android/contacts/common/res/values-eu/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Idatzi deiarekin batera bidali beharreko oharra…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"BIDALI ETA DEITU"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g>: <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> fitxa."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> fitxa. Irakurri gabeko <xliff:g id="COUNT_3">%2$d</xliff:g> elementu. </item>
diff --git a/java/com/android/contacts/common/res/values-fa/strings.xml b/java/com/android/contacts/common/res/values-fa/strings.xml
index 3650e4671..dda10647c 100644
--- a/java/com/android/contacts/common/res/values-fa/strings.xml
+++ b/java/com/android/contacts/common/res/values-fa/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"یادداشتی بنویسید که همراه تماس ارسال شود…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ارسال و تماس"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / ‏<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"برگه «<xliff:g id="TITLE">%1$s</xliff:g>»."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> برگه «<xliff:g id="TITLE_2">%1$s</xliff:g>». <xliff:g id="COUNT_3">%2$d</xliff:g> مورد خوانده‌نشده. </item>
diff --git a/java/com/android/contacts/common/res/values-fi/strings.xml b/java/com/android/contacts/common/res/values-fi/strings.xml
index b7739dee8..b8065b2bf 100644
--- a/java/com/android/contacts/common/res/values-fi/strings.xml
+++ b/java/com/android/contacts/common/res/values-fi/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Kirjoita muistiinpano lähetettäväksi puhelun kanssa…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"LÄHETÄ JA SOITA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>-välilehti."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>-välilehti. <xliff:g id="COUNT_3">%2$d</xliff:g> lukematonta kohdetta. </item>
diff --git a/java/com/android/contacts/common/res/values-fr-rCA/strings.xml b/java/com/android/contacts/common/res/values-fr-rCA/strings.xml
index c20b8827e..82f549292 100644
--- a/java/com/android/contacts/common/res/values-fr-rCA/strings.xml
+++ b/java/com/android/contacts/common/res/values-fr-rCA/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Tapez une note à envoyer avec l\'appel..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVOYER ET APPELER"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> : <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Onglet <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Onglet <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> élément non lu. </item>
diff --git a/java/com/android/contacts/common/res/values-fr/strings.xml b/java/com/android/contacts/common/res/values-fr/strings.xml
index 93b52dcf9..474d721dc 100644
--- a/java/com/android/contacts/common/res/values-fr/strings.xml
+++ b/java/com/android/contacts/common/res/values-fr/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Saisissez une note pour accompagner l\'appel..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVOYER ET APPELER"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Onglet <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Onglet <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> élément non lu. </item>
diff --git a/java/com/android/contacts/common/res/values-gl/strings.xml b/java/com/android/contacts/common/res/values-gl/strings.xml
index 4aa1fc1f7..4a3262a2b 100644
--- a/java/com/android/contacts/common/res/values-gl/strings.xml
+++ b/java/com/android/contacts/common/res/values-gl/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escribe unha nota para enviala coa chamada…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR E CHAMAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Pestana <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Pestana <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> elementos non lidos. </item>
diff --git a/java/com/android/contacts/common/res/values-gu/strings.xml b/java/com/android/contacts/common/res/values-gu/strings.xml
index 8bbfb3a2b..536aceb9c 100644
--- a/java/com/android/contacts/common/res/values-gu/strings.xml
+++ b/java/com/android/contacts/common/res/values-gu/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"કૉલ સાથે મોકલવા માટે એક નોંધ લખો ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"મોકલો અને કૉલ કરો"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ટૅબ."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> ટૅબ. <xliff:g id="COUNT_3">%2$d</xliff:g> વાંચ્યા વગરની આઇટમ. </item>
diff --git a/java/com/android/contacts/common/res/values-hi/strings.xml b/java/com/android/contacts/common/res/values-hi/strings.xml
index c1af9b7ff..c61e195cb 100644
--- a/java/com/android/contacts/common/res/values-hi/strings.xml
+++ b/java/com/android/contacts/common/res/values-hi/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"कॉल के साथ भेजने के लिए नोट लिखें ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"भेजें और कॉल करें"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> टैब."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> टैब. <xliff:g id="COUNT_3">%2$d</xliff:g> नहीं पढ़े गए आइटम. </item>
diff --git a/java/com/android/contacts/common/res/values-hr/strings.xml b/java/com/android/contacts/common/res/values-hr/strings.xml
index a60c884c1..66986dd38 100644
--- a/java/com/android/contacts/common/res/values-hr/strings.xml
+++ b/java/com/android/contacts/common/res/values-hr/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Napišite bilješku koju ćete poslati uz poziv..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"POŠALJI I NAZOVI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Kartica <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Kartica <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nepročitana stavka. </item>
diff --git a/java/com/android/contacts/common/res/values-hu/strings.xml b/java/com/android/contacts/common/res/values-hu/strings.xml
index 19fbbe844..22bf5094c 100644
--- a/java/com/android/contacts/common/res/values-hu/strings.xml
+++ b/java/com/android/contacts/common/res/values-hu/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Írjon üzenetet, amelyet elküldhetünk a hívással együtt…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"KÜLDÉS ÉS HÍVÁS"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="LIMIT">%2$s</xliff:g>/<xliff:g id="COUNT">%1$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> lap."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> lap. <xliff:g id="COUNT_3">%2$d</xliff:g> olvasatlan elem. </item>
diff --git a/java/com/android/contacts/common/res/values-hy/strings.xml b/java/com/android/contacts/common/res/values-hy/strings.xml
index b3ed5e531..85c902347 100644
--- a/java/com/android/contacts/common/res/values-hy/strings.xml
+++ b/java/com/android/contacts/common/res/values-hy/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Մուտքագրեք նշում՝ զանգի հետ ուղարկելու համար ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ՈՒՂԱՐԿԵԼ ԵՎ ԶԱՆԳԵԼ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ներդիր:"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> tab. <xliff:g id="COUNT_3">%2$d</xliff:g> unread items. </item>
diff --git a/java/com/android/contacts/common/res/values-in/strings.xml b/java/com/android/contacts/common/res/values-in/strings.xml
index 13252a5b0..d7ee8bfb9 100644
--- a/java/com/android/contacts/common/res/values-in/strings.xml
+++ b/java/com/android/contacts/common/res/values-in/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Ketik catatan untuk dikirim dengan panggilan telepon ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"KIRIM &amp; TELEPON"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tab <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Tab <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> item belum dibaca. </item>
diff --git a/java/com/android/contacts/common/res/values-is/strings.xml b/java/com/android/contacts/common/res/values-is/strings.xml
index 569c10f3e..26c1aefd1 100644
--- a/java/com/android/contacts/common/res/values-is/strings.xml
+++ b/java/com/android/contacts/common/res/values-is/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Sláðu inn texta til að senda með símtalinu..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SENDA OG HRINGJA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Flipinn <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Flipinn <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> ólesið atriði. </item>
diff --git a/java/com/android/contacts/common/res/values-it/strings.xml b/java/com/android/contacts/common/res/values-it/strings.xml
index 342cd61df..8ea564854 100644
--- a/java/com/android/contacts/common/res/values-it/strings.xml
+++ b/java/com/android/contacts/common/res/values-it/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Digita una nota da inviare con la chiamata..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"INVIA E CHIAMA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Scheda <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Scheda <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> elementi da leggere. </item>
diff --git a/java/com/android/contacts/common/res/values-iw/strings.xml b/java/com/android/contacts/common/res/values-iw/strings.xml
index e0d8e5dfb..2a6b2c189 100644
--- a/java/com/android/contacts/common/res/values-iw/strings.xml
+++ b/java/com/android/contacts/common/res/values-iw/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"הקלד הערה לשליחה עם השיחה..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"שלח והתקשר"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"‎<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>‎"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"הכרטיסייה <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="two">הכרטיסייה <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> פריטים שלא נקראו. </item>
diff --git a/java/com/android/contacts/common/res/values-ja/strings.xml b/java/com/android/contacts/common/res/values-ja/strings.xml
index e224a38a2..3271b46bb 100644
--- a/java/com/android/contacts/common/res/values-ja/strings.xml
+++ b/java/com/android/contacts/common/res/values-ja/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"発信時に送信するメモを入力..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"送信 / 通話"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g>、<xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> タブ。"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> タブ。<xliff:g id="COUNT_3">%2$d</xliff:g> 件の未読項目。</item>
diff --git a/java/com/android/contacts/common/res/values-ka/strings.xml b/java/com/android/contacts/common/res/values-ka/strings.xml
index 86273b32e..ebbee6e33 100644
--- a/java/com/android/contacts/common/res/values-ka/strings.xml
+++ b/java/com/android/contacts/common/res/values-ka/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"აკრიფეთ შენიშვნა ზართან ერთად გასაგზავნად ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"გაგზავნა და დარეკვა"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ცხრ."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ცხრ. <xliff:g id="COUNT_3">%2$d</xliff:g> წაუკითხავი ერთეული. </item>
diff --git a/java/com/android/contacts/common/res/values-kk/strings.xml b/java/com/android/contacts/common/res/values-kk/strings.xml
index 45df334f9..327532abc 100644
--- a/java/com/android/contacts/common/res/values-kk/strings.xml
+++ b/java/com/android/contacts/common/res/values-kk/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Қоңыраумен жіберу үшін ескертпе теріңіз ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ЖІБЕРУ ЖӘНЕ ҚОҢЫРАУ ШАЛУ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> қойындысы."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> қойындысы. <xliff:g id="COUNT_3">%2$d</xliff:g> оқылмаған элемент. </item>
diff --git a/java/com/android/contacts/common/res/values-km/strings.xml b/java/com/android/contacts/common/res/values-km/strings.xml
index 8d4ba2aff..503016792 100644
--- a/java/com/android/contacts/common/res/values-km/strings.xml
+++ b/java/com/android/contacts/common/res/values-km/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"វាយបញ្ចូលចំណាំដែលត្រូវផ្ញើជាមួយការហៅទូរស័ព្ទ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ផ្ញើ &amp; ហៅ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"ផ្ទាំង <xliff:g id="TITLE">%1$s</xliff:g>។"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">ផ្ទាំង <xliff:g id="TITLE_2">%1$s</xliff:g>។ ធាតុមិនទាន់​អាន <xliff:g id="COUNT_3">%2$d</xliff:g> </item>
diff --git a/java/com/android/contacts/common/res/values-kn/strings.xml b/java/com/android/contacts/common/res/values-kn/strings.xml
index 0dfdaa609..446e078a6 100644
--- a/java/com/android/contacts/common/res/values-kn/strings.xml
+++ b/java/com/android/contacts/common/res/values-kn/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ಕರೆ ಕಳುಹಿಸಲು ಟಿಪ್ಪಣಿಯನ್ನು ಟೈಪ್ ಮಾಡಿ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ಕಳುಹಿಸು ಮತ್ತು ಕರೆಮಾಡು"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ಟ್ಯಾಬ್."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> ಟ್ಯಾಬ್. <xliff:g id="COUNT_3">%2$d</xliff:g> ಓದದಿರುವ ಐಟಂಗಳು. </item>
diff --git a/java/com/android/contacts/common/res/values-ko/strings.xml b/java/com/android/contacts/common/res/values-ko/strings.xml
index 13edcc11e..4c2bd4f62 100644
--- a/java/com/android/contacts/common/res/values-ko/strings.xml
+++ b/java/com/android/contacts/common/res/values-ko/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"통화에 함께 전송할 메모를 입력하세요..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"보내기 및 전화 걸기"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> 탭"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> 탭. 읽지 않은 항목 <xliff:g id="COUNT_3">%2$d</xliff:g>개 </item>
diff --git a/java/com/android/contacts/common/res/values-ky/strings.xml b/java/com/android/contacts/common/res/values-ky/strings.xml
index 43e12e77e..e5bab4550 100644
--- a/java/com/android/contacts/common/res/values-ky/strings.xml
+++ b/java/com/android/contacts/common/res/values-ky/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Чалуу менен жөнөтүлө турган кыска жазууну териңиз …"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ЖӨНӨТҮҮ ЖАНА ЧАЛУУ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"\"<xliff:g id="TITLE">%1$s</xliff:g>\" өтмөгү."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> \"<xliff:g id="TITLE_2">%1$s</xliff:g>\" өтмөгү. <xliff:g id="COUNT_3">%2$d</xliff:g> нерсе окула элек. </item>
diff --git a/java/com/android/contacts/common/res/values-lo/strings.xml b/java/com/android/contacts/common/res/values-lo/strings.xml
index d98ec8b90..c649539d4 100644
--- a/java/com/android/contacts/common/res/values-lo/strings.xml
+++ b/java/com/android/contacts/common/res/values-lo/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ພິມ​ບັນ​ທຶກ ເພື່ອ​ສົ່ງ​ກັບ​ການ​ໂທ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ສົ່ງ ແລະ ໂທ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"ແຖບ <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">ແຖບ <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> ລາຍການບໍ່ທັນໄດ້ອ່ານ. </item>
diff --git a/java/com/android/contacts/common/res/values-lt/strings.xml b/java/com/android/contacts/common/res/values-lt/strings.xml
index 53773b25a..b74bd99ee 100644
--- a/java/com/android/contacts/common/res/values-lt/strings.xml
+++ b/java/com/android/contacts/common/res/values-lt/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Įveskite užrašą, kurį galima išsiųsti skambinant..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SIŲSTI IR SKAMBINTI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Skirtukas „<xliff:g id="TITLE">%1$s</xliff:g>“."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Skirtukas „<xliff:g id="TITLE_2">%1$s</xliff:g>“. <xliff:g id="COUNT_3">%2$d</xliff:g> neskaitytas elementas. </item>
diff --git a/java/com/android/contacts/common/res/values-lv/strings.xml b/java/com/android/contacts/common/res/values-lv/strings.xml
index cc5690176..c09a27f5d 100644
--- a/java/com/android/contacts/common/res/values-lv/strings.xml
+++ b/java/com/android/contacts/common/res/values-lv/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Ierakstiet piezīmi, ko nosūtīt ar zvanu..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SŪTĪT UN ZVANĪT"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> no <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g>: <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Cilne “<xliff:g id="TITLE">%1$s</xliff:g>”"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="zero"> Cilne “<xliff:g id="TITLE_2">%1$s</xliff:g>”. <xliff:g id="COUNT_3">%2$d</xliff:g> nelasīti vienumi. </item>
diff --git a/java/com/android/contacts/common/res/values-mk/strings.xml b/java/com/android/contacts/common/res/values-mk/strings.xml
index f6a4af8b1..da1530f2a 100644
--- a/java/com/android/contacts/common/res/values-mk/strings.xml
+++ b/java/com/android/contacts/common/res/values-mk/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Напишете белешка да се испрати со повикот..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ИСПРАТИ И ПОВИКАЈ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Картичка <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Картичка <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрочитана ставка. </item>
diff --git a/java/com/android/contacts/common/res/values-ml/strings.xml b/java/com/android/contacts/common/res/values-ml/strings.xml
index dfc21ffb9..7e927499a 100644
--- a/java/com/android/contacts/common/res/values-ml/strings.xml
+++ b/java/com/android/contacts/common/res/values-ml/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"കോളിനൊപ്പം അയയ്ക്കുന്നതിന് ഒരു കുറിപ്പ് ടൈപ്പുചെയ്യുക ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"അയയ്‌ക്കുകയും വിളിക്കുകയും ചെയ്യുക"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ടാബ്."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ടാബ്. <xliff:g id="COUNT_3">%2$d</xliff:g> വായിക്കാത്ത ഇനങ്ങൾ. </item>
diff --git a/java/com/android/contacts/common/res/values-mn/strings.xml b/java/com/android/contacts/common/res/values-mn/strings.xml
index a5c2afd2c..f0a8c9245 100644
--- a/java/com/android/contacts/common/res/values-mn/strings.xml
+++ b/java/com/android/contacts/common/res/values-mn/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Дуудлаганд илгээх тэмдэглэл бичнэ үү..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ИЛГЭЭХ, ДУУДЛАГА"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> таб."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> таб. <xliff:g id="COUNT_3">%2$d</xliff:g> уншаагүй зүйл. </item>
diff --git a/java/com/android/contacts/common/res/values-mr/strings.xml b/java/com/android/contacts/common/res/values-mr/strings.xml
index d632bb1be..96504c7bc 100644
--- a/java/com/android/contacts/common/res/values-mr/strings.xml
+++ b/java/com/android/contacts/common/res/values-mr/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"कॉलसह पाठविण्‍यासाठी एक टीप टाइप करा..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"पाठवा आणि कॉल करा"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> टॅब."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> टॅब. <xliff:g id="COUNT_3">%2$d</xliff:g> न वाचलेला आयटम. </item>
diff --git a/java/com/android/contacts/common/res/values-ms/strings.xml b/java/com/android/contacts/common/res/values-ms/strings.xml
index 24ff73767..60d2b7acc 100644
--- a/java/com/android/contacts/common/res/values-ms/strings.xml
+++ b/java/com/android/contacts/common/res/values-ms/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Taip nota untuk dihantar dengan panggilan…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"HANTAR &amp; PANGGIL"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tab <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Tab <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> item belum dibaca. </item>
diff --git a/java/com/android/contacts/common/res/values-my/strings.xml b/java/com/android/contacts/common/res/values-my/strings.xml
index c0cb020f8..d81e8950d 100644
--- a/java/com/android/contacts/common/res/values-my/strings.xml
+++ b/java/com/android/contacts/common/res/values-my/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ခေါ်ဆိုမှုဖြင့် ပေးပို့ရန် မှတ်စုတစ်ခု ရိုက်ပါ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ပေးပို့ပြီး ခေါ်ပါ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> တဘ်။"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> တဘ်။ မဖတ်ရသေးသည့် အရာ <xliff:g id="COUNT_3">%2$d</xliff:g> ခု။ </item>
diff --git a/java/com/android/contacts/common/res/values-nb/strings.xml b/java/com/android/contacts/common/res/values-nb/strings.xml
index 80507fce1..7085cb381 100644
--- a/java/com/android/contacts/common/res/values-nb/strings.xml
+++ b/java/com/android/contacts/common/res/values-nb/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Skriv et notat du vil sende med anropet …"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND OG RING"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>-fanen."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>-fanen. <xliff:g id="COUNT_3">%2$d</xliff:g> uleste elementer. </item>
diff --git a/java/com/android/contacts/common/res/values-ne/strings.xml b/java/com/android/contacts/common/res/values-ne/strings.xml
index 2459c8aba..1f54232af 100644
--- a/java/com/android/contacts/common/res/values-ne/strings.xml
+++ b/java/com/android/contacts/common/res/values-ne/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"यस कलसँग पठाउन एक टिप्पणी टाइप गर्नुहोस्"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"पठाउनुहोस् र कल गर्नुहोस्"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ट्याब।"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ट्याब। <xliff:g id="COUNT_3">%2$d</xliff:g> नपढिएका वस्तुहरू। </item>
diff --git a/java/com/android/contacts/common/res/values-nl/strings.xml b/java/com/android/contacts/common/res/values-nl/strings.xml
index c92249b61..9d41899f1 100644
--- a/java/com/android/contacts/common/res/values-nl/strings.xml
+++ b/java/com/android/contacts/common/res/values-nl/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Typ een notitie om te verzenden met de oproep..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"VERZENDEN EN BELLEN"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tabblad <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Tabblad <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> ongelezen items. </item>
diff --git a/java/com/android/contacts/common/res/values-no/strings.xml b/java/com/android/contacts/common/res/values-no/strings.xml
index 80507fce1..7085cb381 100644
--- a/java/com/android/contacts/common/res/values-no/strings.xml
+++ b/java/com/android/contacts/common/res/values-no/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Skriv et notat du vil sende med anropet …"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SEND OG RING"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>-fanen."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>-fanen. <xliff:g id="COUNT_3">%2$d</xliff:g> uleste elementer. </item>
diff --git a/java/com/android/contacts/common/res/values-pa/strings.xml b/java/com/android/contacts/common/res/values-pa/strings.xml
index 6401993c2..c96510cc7 100644
--- a/java/com/android/contacts/common/res/values-pa/strings.xml
+++ b/java/com/android/contacts/common/res/values-pa/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ਕਾਲ ਦੇ ਨਾਲ ਭੇਜਣ ਲਈ ਕੋਈ ਨੋਟ ਟਾਈਪ ਕਰੋ ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ਭੇਜੋ ਅਤੇ ਕਾਲ ਕਰੋ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ਟੈਬ।"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> ਟੈਬ। <xliff:g id="COUNT_3">%2$d</xliff:g> ਅਣ-ਪੜ੍ਹੀਆਂ ਆਈਟਮਾਂ। </item>
diff --git a/java/com/android/contacts/common/res/values-pl/strings.xml b/java/com/android/contacts/common/res/values-pl/strings.xml
index c10bb1fd9..c4e65f556 100644
--- a/java/com/android/contacts/common/res/values-pl/strings.xml
+++ b/java/com/android/contacts/common/res/values-pl/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Wpisz notatkę, którą chcesz wysłać razem z połączeniem..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"WYŚLIJ I ZADZWOŃ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Karta <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="few"> Karta <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> nieprzeczytane elementy. </item>
diff --git a/java/com/android/contacts/common/res/values-pt-rBR/strings.xml b/java/com/android/contacts/common/res/values-pt-rBR/strings.xml
index 95bbb0b5d..ee2b87c68 100644
--- a/java/com/android/contacts/common/res/values-pt-rBR/strings.xml
+++ b/java/com/android/contacts/common/res/values-pt-rBR/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escreva uma nota para enviar com a chamada..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR E LIGAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Guia \"<xliff:g id="TITLE">%1$s</xliff:g>\"."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one">Guia \"<xliff:g id="TITLE_2">%1$s</xliff:g>\". <xliff:g id="COUNT_3">%2$d</xliff:g> item não lido. </item>
diff --git a/java/com/android/contacts/common/res/values-pt-rPT/strings.xml b/java/com/android/contacts/common/res/values-pt-rPT/strings.xml
index c3b50e0bb..44bba149d 100644
--- a/java/com/android/contacts/common/res/values-pt-rPT/strings.xml
+++ b/java/com/android/contacts/common/res/values-pt-rPT/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escrever uma nota para enviar com a chamada..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR E LIGAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Separador <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> tab. <xliff:g id="COUNT_3">%2$d</xliff:g> unread items. </item>
diff --git a/java/com/android/contacts/common/res/values-pt/strings.xml b/java/com/android/contacts/common/res/values-pt/strings.xml
index 95bbb0b5d..ee2b87c68 100644
--- a/java/com/android/contacts/common/res/values-pt/strings.xml
+++ b/java/com/android/contacts/common/res/values-pt/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Escreva uma nota para enviar com a chamada..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ENVIAR E LIGAR"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Guia \"<xliff:g id="TITLE">%1$s</xliff:g>\"."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one">Guia \"<xliff:g id="TITLE_2">%1$s</xliff:g>\". <xliff:g id="COUNT_3">%2$d</xliff:g> item não lido. </item>
diff --git a/java/com/android/contacts/common/res/values-ro/strings.xml b/java/com/android/contacts/common/res/values-ro/strings.xml
index da0d5da95..358e7af93 100644
--- a/java/com/android/contacts/common/res/values-ro/strings.xml
+++ b/java/com/android/contacts/common/res/values-ro/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Introduceți o notă ca să o trimiteți împreună cu apelul..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"TRIMITEȚI ȘI APELAȚI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Fila <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="few"> Fila <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> elemente necitite. </item>
diff --git a/java/com/android/contacts/common/res/values-ru/strings.xml b/java/com/android/contacts/common/res/values-ru/strings.xml
index f4e1d847b..3442f2c60 100644
--- a/java/com/android/contacts/common/res/values-ru/strings.xml
+++ b/java/com/android/contacts/common/res/values-ru/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Введите текст…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ОТПРАВИТЬ И ПОЗВОНИТЬ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Вкладка \"<xliff:g id="TITLE">%1$s</xliff:g>\"."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one">Вкладка <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрочитанный элемент. </item>
diff --git a/java/com/android/contacts/common/res/values-si/strings.xml b/java/com/android/contacts/common/res/values-si/strings.xml
index fc121f6af..72ca32d9c 100644
--- a/java/com/android/contacts/common/res/values-si/strings.xml
+++ b/java/com/android/contacts/common/res/values-si/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"ඇමතුම සමග යැවීමට සටහනක් ටයිප් කරන්න ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"යවන්න සහ අමතන්න"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ටැබය."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> <xliff:g id="TITLE_2">%1$s</xliff:g> ටැබය. නොකියවූ අයිතම <xliff:g id="COUNT_3">%2$d</xliff:g>. </item>
diff --git a/java/com/android/contacts/common/res/values-sk/strings.xml b/java/com/android/contacts/common/res/values-sk/strings.xml
index 90a4752fd..b85f63f1b 100644
--- a/java/com/android/contacts/common/res/values-sk/strings.xml
+++ b/java/com/android/contacts/common/res/values-sk/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Napíšte poznámku, ktorá sa odošle s hovorom..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ODOSLAŤ A VOLAŤ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Karta <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="few"> Karta <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> neprečítané položky. </item>
diff --git a/java/com/android/contacts/common/res/values-sl/strings.xml b/java/com/android/contacts/common/res/values-sl/strings.xml
index ef2e1a3f0..f4c39dea9 100644
--- a/java/com/android/contacts/common/res/values-sl/strings.xml
+++ b/java/com/android/contacts/common/res/values-sl/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Vnesite zapisek, ki ga želite poslati s klicem ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"POŠLJI IN KLIČI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g>: <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Zavihek »<xliff:g id="TITLE">%1$s</xliff:g>«."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Zavihek »<xliff:g id="TITLE_2">%1$s</xliff:g>«. <xliff:g id="COUNT_3">%2$d</xliff:g> neprebran element. </item>
diff --git a/java/com/android/contacts/common/res/values-sq/strings.xml b/java/com/android/contacts/common/res/values-sq/strings.xml
index 301149201..553c46df5 100644
--- a/java/com/android/contacts/common/res/values-sq/strings.xml
+++ b/java/com/android/contacts/common/res/values-sq/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Shkruaj një shënim për të dërguar një telefonatë..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"DËRGO DHE TELEFONO"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Skeda <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Skeda <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> artikuj të palexuar. </item>
diff --git a/java/com/android/contacts/common/res/values-sr/strings.xml b/java/com/android/contacts/common/res/values-sr/strings.xml
index 25adf7bc5..99997e656 100644
--- a/java/com/android/contacts/common/res/values-sr/strings.xml
+++ b/java/com/android/contacts/common/res/values-sr/strings.xml
@@ -249,7 +249,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Унесите белешку коју ћете послати уз позив..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ПОШАЉИ И ПОЗОВИ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Картица <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Картица <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> непрочитана ставка. </item>
diff --git a/java/com/android/contacts/common/res/values-sv/strings.xml b/java/com/android/contacts/common/res/values-sv/strings.xml
index ee748a42c..79e56e504 100644
--- a/java/com/android/contacts/common/res/values-sv/strings.xml
+++ b/java/com/android/contacts/common/res/values-sv/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Gör en anteckning som skickas när du ringer …"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"SKICKA OCH RING"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Fliken <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">Fliken <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> olästa poster. </item>
diff --git a/java/com/android/contacts/common/res/values-sw/strings.xml b/java/com/android/contacts/common/res/values-sw/strings.xml
index 7bd08353f..4d30271f3 100644
--- a/java/com/android/contacts/common/res/values-sw/strings.xml
+++ b/java/com/android/contacts/common/res/values-sw/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Andika dokezo litakaloambatana na simu utakayopiga ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"TUMA na UPIGE SIMU"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Kichupo cha <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Kichupo cha <xliff:g id="TITLE_2">%1$s</xliff:g>. Vipengee <xliff:g id="COUNT_3">%2$d</xliff:g> havijasomwa. </item>
diff --git a/java/com/android/contacts/common/res/values-ta/strings.xml b/java/com/android/contacts/common/res/values-ta/strings.xml
index d5b3f9305..e041a999d 100644
--- a/java/com/android/contacts/common/res/values-ta/strings.xml
+++ b/java/com/android/contacts/common/res/values-ta/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"அழைப்புடன் சேர்த்து அனுப்ப, குறிப்பை உள்ளிடவும்..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"அனுப்பி அழை"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> தாவல்."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> தாவல். படிக்காதவை (<xliff:g id="COUNT_3">%2$d</xliff:g>). </item>
diff --git a/java/com/android/contacts/common/res/values-te/strings.xml b/java/com/android/contacts/common/res/values-te/strings.xml
index 4126ddc0f..6dd0e2143 100644
--- a/java/com/android/contacts/common/res/values-te/strings.xml
+++ b/java/com/android/contacts/common/res/values-te/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"కాల్‌తో పాటు పంపడానికి గమనికను టైప్ చేయండి ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"పంపు &amp; కాల్ చేయి"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ట్యాబ్."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ట్యాబ్. <xliff:g id="COUNT_3">%2$d</xliff:g> చదవని అంశాలు. </item>
diff --git a/java/com/android/contacts/common/res/values-th/strings.xml b/java/com/android/contacts/common/res/values-th/strings.xml
index 2d52f34fb..b979e7424 100644
--- a/java/com/android/contacts/common/res/values-th/strings.xml
+++ b/java/com/android/contacts/common/res/values-th/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"พิมพ์โน้ตเพื่อส่งพร้อมการโทร ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ส่งและโทร"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"แท็บ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> แท็บ <xliff:g id="TITLE_2">%1$s</xliff:g> ยังไม่อ่าน <xliff:g id="COUNT_3">%2$d</xliff:g> รายการ </item>
diff --git a/java/com/android/contacts/common/res/values-tl/strings.xml b/java/com/android/contacts/common/res/values-tl/strings.xml
index 30978db4e..62caef820 100644
--- a/java/com/android/contacts/common/res/values-tl/strings.xml
+++ b/java/com/android/contacts/common/res/values-tl/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Mag-type ng isang tala na ipadadala kasama ng tawag ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"IPADALA AT TAWAGAN"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tab ng <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Tab ng <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> hindi pa nababasang item. </item>
diff --git a/java/com/android/contacts/common/res/values-tr/strings.xml b/java/com/android/contacts/common/res/values-tr/strings.xml
index c18097aac..ce3c109d2 100644
--- a/java/com/android/contacts/common/res/values-tr/strings.xml
+++ b/java/com/android/contacts/common/res/values-tr/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Çağrıyla göndermek için bir not yazın..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"GÖNDER VE ARA"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> sekmesi."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> sekmesi. <xliff:g id="COUNT_3">%2$d</xliff:g> okunmamış öğe. </item>
diff --git a/java/com/android/contacts/common/res/values-uk/strings.xml b/java/com/android/contacts/common/res/values-uk/strings.xml
index 94d09db12..f6d1e4731 100644
--- a/java/com/android/contacts/common/res/values-uk/strings.xml
+++ b/java/com/android/contacts/common/res/values-uk/strings.xml
@@ -250,7 +250,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Введіть нотатку, яку хочете надіслати під час дзвінка…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"ЗАТЕЛЕФОНУВАТИ Й НАДІСЛАТИ"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> з <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Вкладка \"<xliff:g id="TITLE">%1$s</xliff:g>\"."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"> Вкладка \"<xliff:g id="TITLE_2">%1$s</xliff:g>\". <xliff:g id="COUNT_3">%2$d</xliff:g> непрочитаний елемент. </item>
diff --git a/java/com/android/contacts/common/res/values-ur/strings.xml b/java/com/android/contacts/common/res/values-ur/strings.xml
index 75c761f2d..b34c78d95 100644
--- a/java/com/android/contacts/common/res/values-ur/strings.xml
+++ b/java/com/android/contacts/common/res/values-ur/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"کال کے ساتھ بھیجنے کیلئے ایک نوٹ ٹائپ کریں…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"بھیجیں اور کال کریں"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ٹیب۔"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ٹیب۔ <xliff:g id="COUNT_3">%2$d</xliff:g> بغیر پڑھی ہوئی آئٹمز۔ </item>
diff --git a/java/com/android/contacts/common/res/values-uz/strings.xml b/java/com/android/contacts/common/res/values-uz/strings.xml
index 69b07d135..44bfd9999 100644
--- a/java/com/android/contacts/common/res/values-uz/strings.xml
+++ b/java/com/android/contacts/common/res/values-uz/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Qo‘ng‘iroqqa qo‘shib yuborish uchun izoh yozing ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"YUBORISH va QO‘NG‘IROQ QILISH"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ichki oynasi."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g> ichki oynasi. <xliff:g id="COUNT_3">%2$d</xliff:g> ta o‘qilmagan narsa. </item>
diff --git a/java/com/android/contacts/common/res/values-vi/strings.xml b/java/com/android/contacts/common/res/values-vi/strings.xml
index c1675738a..dadb78a7d 100644
--- a/java/com/android/contacts/common/res/values-vi/strings.xml
+++ b/java/com/android/contacts/common/res/values-vi/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Nhập ghi chú để gửi kèm cuộc gọi..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"GỬI và GỌI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"Tab <xliff:g id="TITLE">%1$s</xliff:g>."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> Tab <xliff:g id="TITLE_2">%1$s</xliff:g>. <xliff:g id="COUNT_3">%2$d</xliff:g> mục chưa đọc. </item>
diff --git a/java/com/android/contacts/common/res/values-zh-rCN/strings.xml b/java/com/android/contacts/common/res/values-zh-rCN/strings.xml
index 367b78f1c..161638e66 100644
--- a/java/com/android/contacts/common/res/values-zh-rCN/strings.xml
+++ b/java/com/android/contacts/common/res/values-zh-rCN/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"输入要在拨打电话时发送的备注…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"发送并拨打电话"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g>:<xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>标签。"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>标签。<xliff:g id="COUNT_3">%2$d</xliff:g> 项未读内容。</item>
diff --git a/java/com/android/contacts/common/res/values-zh-rHK/strings.xml b/java/com/android/contacts/common/res/values-zh-rHK/strings.xml
index 733d9809c..9952ab626 100644
--- a/java/com/android/contacts/common/res/values-zh-rHK/strings.xml
+++ b/java/com/android/contacts/common/res/values-zh-rHK/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"撥號時可以書寫和傳送筆記…"</string>
<string name="send_and_call_button" msgid="4735168294120154013">"傳送和撥號"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"「<xliff:g id="TITLE">%1$s</xliff:g>」標籤。"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other">「<xliff:g id="TITLE_2">%1$s</xliff:g>」標籤 (<xliff:g id="COUNT_3">%2$d</xliff:g> 個未讀取項目)。</item>
diff --git a/java/com/android/contacts/common/res/values-zh-rTW/strings.xml b/java/com/android/contacts/common/res/values-zh-rTW/strings.xml
index af7843ffd..e5ad61fac 100644
--- a/java/com/android/contacts/common/res/values-zh-rTW/strings.xml
+++ b/java/com/android/contacts/common/res/values-zh-rTW/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"輸入可在撥號時傳送的備註..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"傳送並撥打"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g>/<xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g>分頁。"</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="other"> <xliff:g id="TITLE_2">%1$s</xliff:g>分頁。<xliff:g id="COUNT_3">%2$d</xliff:g> 個未讀項目。</item>
diff --git a/java/com/android/contacts/common/res/values-zu/strings.xml b/java/com/android/contacts/common/res/values-zu/strings.xml
index 5906ee175..adca1399c 100644
--- a/java/com/android/contacts/common/res/values-zu/strings.xml
+++ b/java/com/android/contacts/common/res/values-zu/strings.xml
@@ -248,7 +248,7 @@
<string name="call_subject_hint" msgid="7233138753650420800">"Thayipha inothi ukuthumela nekholi ..."</string>
<string name="send_and_call_button" msgid="4735168294120154013">"THUMELA FUTHI YENZA IKHOLI"</string>
<string name="call_subject_limit" msgid="8273208736191593939">"<xliff:g id="COUNT">%1$s</xliff:g> / <xliff:g id="LIMIT">%2$s</xliff:g>"</string>
- <string name="call_subject_type_and_number" msgid="6338030032554019678">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
+ <string name="call_subject_type_and_number" msgid="8726132674272173486">"<xliff:g id="TYPE">%1$s</xliff:g> • <xliff:g id="NUMBER">%2$s</xliff:g>"</string>
<string name="tab_title" msgid="3387876802026074288">"<xliff:g id="TITLE">%1$s</xliff:g> ithebhu."</string>
<plurals name="tab_title_with_unread_items" formatted="false" msgid="8548492980702182785">
<item quantity="one"><xliff:g id="TITLE_2">%1$s</xliff:g> ithebhu. <xliff:g id="COUNT_3">%2$d</xliff:g> izinto ezingafundiwe. </item>
diff --git a/java/com/android/contacts/common/res/values/ids.xml b/java/com/android/contacts/common/res/values/ids.xml
index 65969c43f..871f5a636 100644
--- a/java/com/android/contacts/common/res/values/ids.xml
+++ b/java/com/android/contacts/common/res/values/ids.xml
@@ -27,5 +27,4 @@
<item name="contact_tile_image" type="id"/>
<item name="contact_tile_name" type="id"/>
- <item name="call_to_action" type="id"/>
</resources>
diff --git a/java/com/android/contacts/common/res/values/strings.xml b/java/com/android/contacts/common/res/values/strings.xml
index 371d5b424..9ac9fef28 100644
--- a/java/com/android/contacts/common/res/values/strings.xml
+++ b/java/com/android/contacts/common/res/values/strings.xml
@@ -744,9 +744,9 @@
compared to the character limit. Example: 2 / 64 -->
<string name="call_subject_limit"><xliff:g example="4" id="count">%1$s</xliff:g> / <xliff:g example="64" id="limit">%2$s</xliff:g></string>
- <!-- String used to build a phone number type and phone number string.
- Example: Mobile 650-555-1212 -->
- <string name="call_subject_type_and_number"><xliff:g example="Mobile" id="type">%1$s</xliff:g> <xliff:g example="(650) 555-1212" id="number">%2$s</xliff:g></string>
+ <!-- String used to build a phone number bype and phone number string.
+ Example: Mobile • 650-555-1212 -->
+ <string name="call_subject_type_and_number"><xliff:g example="Mobile" id="type">%1$s</xliff:g> • <xliff:g example="(650) 555-1212" id="number">%2$s</xliff:g></string>
<!-- String format to describe a tab e.g.call history tab. -->
<string name="tab_title"><xliff:g id="title">%1$s</xliff:g> tab.</string>
diff --git a/java/com/android/contacts/common/res/values/styles.xml b/java/com/android/contacts/common/res/values/styles.xml
index bb19afe82..07d4a0225 100644
--- a/java/com/android/contacts/common/res/values/styles.xml
+++ b/java/com/android/contacts/common/res/values/styles.xml
@@ -43,6 +43,7 @@ background and text color. See also android:style/Widget.Holo.TextView.ListSepar
<item name="android:layout_height">wrap_content</item>
<!-- See comments for @dimen/list_section_divider_min_height -->
<item name="android:minHeight">@dimen/list_section_divider_min_height</item>
+ <item name="android:background">@drawable/list_section_divider_holo_custom</item>
<item name="android:textAppearance">@style/DirectoryHeaderStyle</item>
<item name="android:gravity">center_vertical</item>
<item name="android:paddingLeft">8dip</item>
diff --git a/java/com/android/contacts/common/util/AccountFilterUtil.java b/java/com/android/contacts/common/util/AccountFilterUtil.java
index 25f937c5e..18743c65e 100644
--- a/java/com/android/contacts/common/util/AccountFilterUtil.java
+++ b/java/com/android/contacts/common/util/AccountFilterUtil.java
@@ -16,15 +16,35 @@
package com.android.contacts.common.util;
+import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.android.contacts.common.R;
import com.android.contacts.common.list.ContactListFilter;
+import com.android.contacts.common.list.ContactListFilterController;
/** Utility class for account filter manipulation. */
public class AccountFilterUtil {
+ public static final String EXTRA_CONTACT_LIST_FILTER = "contactListFilter";
+ private static final String TAG = AccountFilterUtil.class.getSimpleName();
+
+ /**
+ * Find TextView with the id "account_filter_header" and set correct text for the account filter
+ * header.
+ *
+ * @param filterContainer View containing TextView with id "account_filter_header"
+ * @return true when header text is set in the call. You may use this for conditionally showing or
+ * hiding this entire view.
+ */
+ public static boolean updateAccountFilterTitleForPeople(
+ View filterContainer, ContactListFilter filter, boolean showTitleForAllAccounts) {
+ return updateAccountFilterTitle(filterContainer, filter, showTitleForAllAccounts, false);
+ }
+
/**
* Similar to {@link #updateAccountFilterTitleForPeople(View, ContactListFilter, boolean,
* boolean)}, but for Phone UI.
@@ -58,6 +78,8 @@ public class AccountFilterUtil {
} else if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
headerTextView.setText(R.string.listCustomView);
textWasSet = true;
+ } else {
+ Log.w(TAG, "Filter type \"" + filter.filterType + "\" isn't expected.");
}
} else {
if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
@@ -75,9 +97,29 @@ public class AccountFilterUtil {
} else if (filter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
headerTextView.setText(R.string.listSingleContact);
textWasSet = true;
+ } else {
+ Log.w(TAG, "Filter type \"" + filter.filterType + "\" isn't expected.");
}
}
+ } else {
+ Log.w(TAG, "Filter is null.");
}
return textWasSet;
}
+
+ /** This will update filter via a given ContactListFilterController. */
+ public static void handleAccountFilterResult(
+ ContactListFilterController filterController, int resultCode, Intent data) {
+ if (resultCode == Activity.RESULT_OK) {
+ final ContactListFilter filter = data.getParcelableExtra(EXTRA_CONTACT_LIST_FILTER);
+ if (filter == null) {
+ return;
+ }
+ if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
+ filterController.selectCustomFilter();
+ } else {
+ filterController.setContactListFilter(filter, true);
+ }
+ }
+ }
}
diff --git a/java/com/android/contacts/common/util/BitmapUtil.java b/java/com/android/contacts/common/util/BitmapUtil.java
index 51f65f280..20f916a3f 100644
--- a/java/com/android/contacts/common/util/BitmapUtil.java
+++ b/java/com/android/contacts/common/util/BitmapUtil.java
@@ -24,6 +24,8 @@ import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
/** Provides static functions to decode bitmaps at the optimal size */
public class BitmapUtil {
@@ -89,6 +91,30 @@ public class BitmapUtil {
}
/**
+ * Retrieves a copy of the specified drawable resource, rotated by a specified angle.
+ *
+ * @param resources The current resources.
+ * @param resourceId The resource ID of the drawable to rotate.
+ * @param angle The angle of rotation.
+ * @return Rotated drawable.
+ */
+ public static Drawable getRotatedDrawable(
+ android.content.res.Resources resources, int resourceId, float angle) {
+
+ // Get the original drawable and make a copy which will be rotated.
+ Bitmap original = BitmapFactory.decodeResource(resources, resourceId);
+ Bitmap rotated =
+ Bitmap.createBitmap(original.getWidth(), original.getHeight(), Bitmap.Config.ARGB_8888);
+
+ // Perform the rotation.
+ Canvas tempCanvas = new Canvas(rotated);
+ tempCanvas.rotate(angle, original.getWidth() / 2, original.getHeight() / 2);
+ tempCanvas.drawBitmap(original, 0, 0, null);
+
+ return new BitmapDrawable(resources, rotated);
+ }
+
+ /**
* Given an input bitmap, scales it to the given width/height and makes it round.
*
* @param input {@link Bitmap} to scale and crop
diff --git a/java/com/android/contacts/common/util/ContactDisplayUtils.java b/java/com/android/contacts/common/util/ContactDisplayUtils.java
index ff22f2880..1586784db 100644
--- a/java/com/android/contacts/common/util/ContactDisplayUtils.java
+++ b/java/com/android/contacts/common/util/ContactDisplayUtils.java
@@ -16,20 +16,21 @@
package com.android.contacts.common.util;
+import static android.provider.ContactsContract.CommonDataKinds.Phone;
+
import android.content.Context;
import android.content.res.Resources;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.TtsSpan;
+import android.util.Log;
import android.util.Patterns;
import com.android.contacts.common.R;
import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.dialer.common.LogUtil;
import java.util.Objects;
/** Methods for handling various contact data labels. */
@@ -37,6 +38,7 @@ public class ContactDisplayUtils {
public static final int INTERACTION_CALL = 1;
public static final int INTERACTION_SMS = 2;
+ private static final String TAG = ContactDisplayUtils.class.getSimpleName();
/**
* Checks if the given data type is a custom type.
@@ -72,9 +74,9 @@ public class ContactDisplayUtils {
} else {
resId = getPhoneLabelResourceId(type);
if (interactionType != INTERACTION_CALL) {
- LogUtil.e(
- "ContactDisplayUtils.getLabelForCallOrSms",
- "un-recognized interaction type: "
+ Log.e(
+ TAG,
+ "Un-recognized interaction type: "
+ interactionType
+ ". Defaulting to ContactDisplayUtils.INTERACTION_CALL.");
}
diff --git a/java/com/android/contacts/common/util/DateUtils.java b/java/com/android/contacts/common/util/DateUtils.java
index 09d52bce8..1935d727a 100644
--- a/java/com/android/contacts/common/util/DateUtils.java
+++ b/java/com/android/contacts/common/util/DateUtils.java
@@ -16,11 +16,252 @@
package com.android.contacts.common.util;
+import android.content.Context;
+import android.text.format.DateFormat;
import android.text.format.Time;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
/** Utility methods for processing dates. */
public class DateUtils {
+ public static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
+
+ /**
+ * When parsing a date without a year, the system assumes 1970, which wasn't a leap-year. Let's
+ * add a one-off hack for that day of the year
+ */
+ public static final String NO_YEAR_DATE_FEB29TH = "--02-29";
+
+ // Variations of ISO 8601 date format. Do not change the order - it does affect the
+ // result in ambiguous cases.
+ private static final SimpleDateFormat[] DATE_FORMATS = {
+ CommonDateUtils.FULL_DATE_FORMAT,
+ CommonDateUtils.DATE_AND_TIME_FORMAT,
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US),
+ new SimpleDateFormat("yyyyMMdd", Locale.US),
+ new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'", Locale.US),
+ new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US),
+ new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'", Locale.US),
+ };
+
+ static {
+ for (SimpleDateFormat format : DATE_FORMATS) {
+ format.setLenient(true);
+ format.setTimeZone(UTC_TIMEZONE);
+ }
+ CommonDateUtils.NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE);
+ }
+
+ /**
+ * Parses the supplied string to see if it looks like a date.
+ *
+ * @param string The string representation of the provided date
+ * @param mustContainYear If true, the string is parsed as a date containing a year. If false, the
+ * string is parsed into a valid date even if the year field is missing.
+ * @return A Calendar object corresponding to the date if the string is successfully parsed. If
+ * not, null is returned.
+ */
+ public static Calendar parseDate(String string, boolean mustContainYear) {
+ ParsePosition parsePosition = new ParsePosition(0);
+ Date date;
+ if (!mustContainYear) {
+ final boolean noYearParsed;
+ // Unfortunately, we can't parse Feb 29th correctly, so let's handle this day seperately
+ if (NO_YEAR_DATE_FEB29TH.equals(string)) {
+ return getUtcDate(0, Calendar.FEBRUARY, 29);
+ } else {
+ synchronized (CommonDateUtils.NO_YEAR_DATE_FORMAT) {
+ date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
+ }
+ noYearParsed = parsePosition.getIndex() == string.length();
+ }
+
+ if (noYearParsed) {
+ return getUtcDate(date, true);
+ }
+ }
+ for (int i = 0; i < DATE_FORMATS.length; i++) {
+ SimpleDateFormat f = DATE_FORMATS[i];
+ synchronized (f) {
+ parsePosition.setIndex(0);
+ date = f.parse(string, parsePosition);
+ if (parsePosition.getIndex() == string.length()) {
+ return getUtcDate(date, false);
+ }
+ }
+ }
+ return null;
+ }
+
+ private static final Calendar getUtcDate(Date date, boolean noYear) {
+ final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
+ calendar.setTime(date);
+ if (noYear) {
+ calendar.set(Calendar.YEAR, 0);
+ }
+ return calendar;
+ }
+
+ private static final Calendar getUtcDate(int year, int month, int dayOfMonth) {
+ final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
+ calendar.clear();
+ calendar.set(Calendar.YEAR, year);
+ calendar.set(Calendar.MONTH, month);
+ calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+ return calendar;
+ }
+
+ public static boolean isYearSet(Calendar cal) {
+ // use the Calendar.YEAR field to track whether or not the year is set instead of
+ // Calendar.isSet() because doing Calendar.get() causes Calendar.isSet() to become
+ // true irregardless of what the previous value was
+ return cal.get(Calendar.YEAR) > 1;
+ }
+
+ /**
+ * Same as {@link #formatDate(Context context, String string, boolean longForm)}, with longForm
+ * set to {@code true} by default.
+ *
+ * @param context Valid context
+ * @param string String representation of a date to parse
+ * @return Returns the same date in a cleaned up format. If the supplied string does not look like
+ * a date, return it unchanged.
+ */
+ public static String formatDate(Context context, String string) {
+ return formatDate(context, string, true);
+ }
+
+ /**
+ * Parses the supplied string to see if it looks like a date.
+ *
+ * @param context Valid context
+ * @param string String representation of a date to parse
+ * @param longForm If true, return the date formatted into its long string representation. If
+ * false, return the date formatted using its short form representation (i.e. 12/11/2012)
+ * @return Returns the same date in a cleaned up format. If the supplied string does not look like
+ * a date, return it unchanged.
+ */
+ public static String formatDate(Context context, String string, boolean longForm) {
+ if (string == null) {
+ return null;
+ }
+
+ string = string.trim();
+ if (string.length() == 0) {
+ return string;
+ }
+ final Calendar cal = parseDate(string, false);
+
+ // we weren't able to parse the string successfully so just return it unchanged
+ if (cal == null) {
+ return string;
+ }
+
+ final boolean isYearSet = isYearSet(cal);
+ final java.text.DateFormat outFormat;
+ if (!isYearSet) {
+ outFormat = getLocalizedDateFormatWithoutYear(context);
+ } else {
+ outFormat =
+ longForm ? DateFormat.getLongDateFormat(context) : DateFormat.getDateFormat(context);
+ }
+ synchronized (outFormat) {
+ outFormat.setTimeZone(UTC_TIMEZONE);
+ return outFormat.format(cal.getTime());
+ }
+ }
+
+ public static boolean isMonthBeforeDay(Context context) {
+ char[] dateFormatOrder = DateFormat.getDateFormatOrder(context);
+ for (int i = 0; i < dateFormatOrder.length; i++) {
+ if (dateFormatOrder[i] == 'd') {
+ return false;
+ }
+ if (dateFormatOrder[i] == 'M') {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a SimpleDateFormat object without the year fields by using a regular expression to
+ * eliminate the year in the string pattern. In the rare occurence that the resulting pattern
+ * cannot be reconverted into a SimpleDateFormat, it uses the provided context to determine
+ * whether the month field should be displayed before the day field, and returns either "MMMM dd"
+ * or "dd MMMM" converted into a SimpleDateFormat.
+ */
+ public static java.text.DateFormat getLocalizedDateFormatWithoutYear(Context context) {
+ final String pattern =
+ ((SimpleDateFormat) SimpleDateFormat.getDateInstance(java.text.DateFormat.LONG))
+ .toPattern();
+ // Determine the correct regex pattern for year.
+ // Special case handling for Spanish locale by checking for "de"
+ final String yearPattern =
+ pattern.contains("de") ? "[^Mm]*[Yy]+[^Mm]*" : "[^DdMm]*[Yy]+[^DdMm]*";
+ try {
+ // Eliminate the substring in pattern that matches the format for that of year
+ return new SimpleDateFormat(pattern.replaceAll(yearPattern, ""));
+ } catch (IllegalArgumentException e) {
+ return new SimpleDateFormat(DateUtils.isMonthBeforeDay(context) ? "MMMM dd" : "dd MMMM");
+ }
+ }
+
+ /**
+ * Given a calendar (possibly containing only a day of the year), returns the earliest possible
+ * anniversary of the date that is equal to or after the current point in time if the date does
+ * not contain a year, or the date converted to the local time zone (if the date contains a year.
+ *
+ * @param target The date we wish to convert(in the UTC time zone).
+ * @return If date does not contain a year (year < 1900), returns the next earliest anniversary
+ * that is after the current point in time (in the local time zone). Otherwise, returns the
+ * adjusted Date in the local time zone.
+ */
+ public static Date getNextAnnualDate(Calendar target) {
+ final Calendar today = Calendar.getInstance();
+ today.setTime(new Date());
+
+ // Round the current time to the exact start of today so that when we compare
+ // today against the target date, both dates are set to exactly 0000H.
+ today.set(Calendar.HOUR_OF_DAY, 0);
+ today.set(Calendar.MINUTE, 0);
+ today.set(Calendar.SECOND, 0);
+ today.set(Calendar.MILLISECOND, 0);
+
+ final boolean isYearSet = isYearSet(target);
+ final int targetYear = target.get(Calendar.YEAR);
+ final int targetMonth = target.get(Calendar.MONTH);
+ final int targetDay = target.get(Calendar.DAY_OF_MONTH);
+ final boolean isFeb29 = (targetMonth == Calendar.FEBRUARY && targetDay == 29);
+ final GregorianCalendar anniversary = new GregorianCalendar();
+ // Convert from the UTC date to the local date. Set the year to today's year if the
+ // there is no provided year (targetYear < 1900)
+ anniversary.set(!isYearSet ? today.get(Calendar.YEAR) : targetYear, targetMonth, targetDay);
+ // If the anniversary's date is before the start of today and there is no year set,
+ // increment the year by 1 so that the returned date is always equal to or greater than
+ // today. If the day is a leap year, keep going until we get the next leap year anniversary
+ // Otherwise if there is already a year set, simply return the exact date.
+ if (!isYearSet) {
+ int anniversaryYear = today.get(Calendar.YEAR);
+ if (anniversary.before(today) || (isFeb29 && !anniversary.isLeapYear(anniversaryYear))) {
+ // If the target date is not Feb 29, then set the anniversary to the next year.
+ // Otherwise, keep going until we find the next leap year (this is not guaranteed
+ // to be in 4 years time).
+ do {
+ anniversaryYear += 1;
+ } while (isFeb29 && !anniversary.isLeapYear(anniversaryYear));
+ anniversary.set(anniversaryYear, targetMonth, targetDay);
+ }
+ }
+ return anniversary.getTime();
+ }
+
/**
* Determine the difference, in days between two dates. Uses similar logic as the {@link
* android.text.format.DateUtils.getRelativeTimeSpanString} method.
diff --git a/java/com/android/contacts/common/util/MaterialColorMapUtils.java b/java/com/android/contacts/common/util/MaterialColorMapUtils.java
index bd32faa51..a2d9847ec 100644
--- a/java/com/android/contacts/common/util/MaterialColorMapUtils.java
+++ b/java/com/android/contacts/common/util/MaterialColorMapUtils.java
@@ -21,6 +21,7 @@ import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
+import com.android.contacts.common.R;
public class MaterialColorMapUtils {
@@ -34,6 +35,13 @@ public class MaterialColorMapUtils {
resources.obtainTypedArray(com.android.contacts.common.R.array.letter_tile_colors_dark);
}
+ public static MaterialPalette getDefaultPrimaryAndSecondaryColors(Resources resources) {
+ final int primaryColor = resources.getColor(R.color.quickcontact_default_photo_tint_color);
+ final int secondaryColor =
+ resources.getColor(R.color.quickcontact_default_photo_tint_color_dark);
+ return new MaterialPalette(primaryColor, secondaryColor);
+ }
+
/**
* Returns the hue component of a color int.
*
diff --git a/java/com/android/contacts/common/util/NameConverter.java b/java/com/android/contacts/common/util/NameConverter.java
new file mode 100644
index 000000000..ae3275d14
--- /dev/null
+++ b/java/com/android/contacts/common/util/NameConverter.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+package com.android.contacts.common.util;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.net.Uri.Builder;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.text.TextUtils;
+import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Utility class for converting between a display name and structured name (and vice-versa), via
+ * calls to the contact provider.
+ */
+public class NameConverter {
+
+ /** The array of fields that comprise a structured name. */
+ public static final String[] STRUCTURED_NAME_FIELDS =
+ new String[] {
+ StructuredName.PREFIX,
+ StructuredName.GIVEN_NAME,
+ StructuredName.MIDDLE_NAME,
+ StructuredName.FAMILY_NAME,
+ StructuredName.SUFFIX
+ };
+
+ /**
+ * Converts the given structured name (provided as a map from {@link StructuredName} fields to
+ * corresponding values) into a display name string.
+ *
+ * <p>Note that this operates via a call back to the ContactProvider, but it does not access the
+ * database, so it should be safe to call from the UI thread. See ContactsProvider2.completeName()
+ * for the underlying method call.
+ *
+ * @param context Activity context.
+ * @param structuredName The structured name map to convert.
+ * @return The display name computed from the structured name map.
+ */
+ public static String structuredNameToDisplayName(
+ Context context, Map<String, String> structuredName) {
+ Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
+ for (String key : STRUCTURED_NAME_FIELDS) {
+ if (structuredName.containsKey(key)) {
+ appendQueryParameter(builder, key, structuredName.get(key));
+ }
+ }
+ return fetchDisplayName(context, builder.build());
+ }
+
+ /**
+ * Converts the given structured name (provided as ContentValues) into a display name string.
+ *
+ * @param context Activity context.
+ * @param values The content values containing values comprising the structured name.
+ */
+ public static String structuredNameToDisplayName(Context context, ContentValues values) {
+ Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
+ for (String key : STRUCTURED_NAME_FIELDS) {
+ if (values.containsKey(key)) {
+ appendQueryParameter(builder, key, values.getAsString(key));
+ }
+ }
+ return fetchDisplayName(context, builder.build());
+ }
+
+ /** Helper method for fetching the display name via the given URI. */
+ private static String fetchDisplayName(Context context, Uri uri) {
+ String displayName = null;
+ Cursor cursor =
+ context
+ .getContentResolver()
+ .query(
+ uri,
+ new String[] {
+ StructuredName.DISPLAY_NAME,
+ },
+ null,
+ null,
+ null);
+
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst()) {
+ displayName = cursor.getString(0);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ return displayName;
+ }
+
+ /**
+ * Converts the given display name string into a structured name (as a map from {@link
+ * StructuredName} fields to corresponding values).
+ *
+ * <p>Note that this operates via a call back to the ContactProvider, but it does not access the
+ * database, so it should be safe to call from the UI thread.
+ *
+ * @param context Activity context.
+ * @param displayName The display name to convert.
+ * @return The structured name map computed from the display name.
+ */
+ public static Map<String, String> displayNameToStructuredName(
+ Context context, String displayName) {
+ Map<String, String> structuredName = new TreeMap<String, String>();
+ Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
+
+ appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName);
+ Cursor cursor =
+ context
+ .getContentResolver()
+ .query(builder.build(), STRUCTURED_NAME_FIELDS, null, null, null);
+
+ if (cursor != null) {
+ try {
+ if (cursor.moveToFirst()) {
+ for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
+ structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ return structuredName;
+ }
+
+ /**
+ * Converts the given display name string into a structured name (inserting the structured values
+ * into a new or existing ContentValues object).
+ *
+ * <p>Note that this operates via a call back to the ContactProvider, but it does not access the
+ * database, so it should be safe to call from the UI thread.
+ *
+ * @param context Activity context.
+ * @param displayName The display name to convert.
+ * @param contentValues The content values object to place the structured name values into. If
+ * null, a new one will be created and returned.
+ * @return The ContentValues object containing the structured name fields derived from the display
+ * name.
+ */
+ public static ContentValues displayNameToStructuredName(
+ Context context, String displayName, ContentValues contentValues) {
+ if (contentValues == null) {
+ contentValues = new ContentValues();
+ }
+ Map<String, String> mapValues = displayNameToStructuredName(context, displayName);
+ for (String key : mapValues.keySet()) {
+ contentValues.put(key, mapValues.get(key));
+ }
+ return contentValues;
+ }
+
+ private static void appendQueryParameter(Builder builder, String field, String value) {
+ if (!TextUtils.isEmpty(value)) {
+ builder.appendQueryParameter(field, value);
+ }
+ }
+
+ /**
+ * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues. Parsed
+ * data should be {@link StructuredName#PHONETIC_FAMILY_NAME}, {@link
+ * StructuredName#PHONETIC_MIDDLE_NAME}, and {@link StructuredName#PHONETIC_GIVEN_NAME}. If this
+ * method cannot parse given phoneticName, null values will be stored.
+ *
+ * @param phoneticName Phonetic name to be parsed
+ * @param values ContentValues to be used for storing data. If null, new instance will be created.
+ * @return ContentValues with parsed data. Those data can be null.
+ */
+ public static StructuredNameDataItem parsePhoneticName(
+ String phoneticName, StructuredNameDataItem item) {
+ String family = null;
+ String middle = null;
+ String given = null;
+
+ if (!TextUtils.isEmpty(phoneticName)) {
+ String[] strings = phoneticName.split(" ", 3);
+ switch (strings.length) {
+ case 1:
+ family = strings[0];
+ break;
+ case 2:
+ family = strings[0];
+ given = strings[1];
+ break;
+ case 3:
+ family = strings[0];
+ middle = strings[1];
+ given = strings[2];
+ break;
+ }
+ }
+
+ if (item == null) {
+ item = new StructuredNameDataItem();
+ }
+ item.setPhoneticFamilyName(family);
+ item.setPhoneticMiddleName(middle);
+ item.setPhoneticGivenName(given);
+ return item;
+ }
+
+ /** Constructs and returns a phonetic full name from given parts. */
+ public static String buildPhoneticName(String family, String middle, String given) {
+ if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle) || !TextUtils.isEmpty(given)) {
+ StringBuilder sb = new StringBuilder();
+ if (!TextUtils.isEmpty(family)) {
+ sb.append(family.trim()).append(' ');
+ }
+ if (!TextUtils.isEmpty(middle)) {
+ sb.append(middle.trim()).append(' ');
+ }
+ if (!TextUtils.isEmpty(given)) {
+ sb.append(given.trim()).append(' ');
+ }
+ sb.setLength(sb.length() - 1); // Yank the last space
+ return sb.toString();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/java/com/android/contacts/common/util/StopWatch.java b/java/com/android/contacts/common/util/StopWatch.java
index 7986d1081..b944b9867 100644
--- a/java/com/android/contacts/common/util/StopWatch.java
+++ b/java/com/android/contacts/common/util/StopWatch.java
@@ -16,7 +16,7 @@
package com.android.contacts.common.util;
-import com.android.dialer.common.LogUtil;
+import android.util.Log;
import java.util.ArrayList;
/** A {@link StopWatch} records start, laps and stop, and print them to logcat. */
@@ -37,6 +37,11 @@ public class StopWatch {
return new StopWatch(label);
}
+ /** Return a dummy instance that does no operations. */
+ public static StopWatch getNullStopWatch() {
+ return NullStopWatch.INSTANCE;
+ }
+
/** Record a lap. */
public void lap(String lapLabel) {
mTimes.add(System.currentTimeMillis());
@@ -71,6 +76,25 @@ public class StopWatch {
sb.append(" ");
last = current;
}
- LogUtil.v(TAG, sb.toString());
+ Log.v(TAG, sb.toString());
+ }
+
+ private static class NullStopWatch extends StopWatch {
+
+ public static final NullStopWatch INSTANCE = new NullStopWatch();
+
+ public NullStopWatch() {
+ super(null);
+ }
+
+ @Override
+ public void lap(String lapLabel) {
+ // noop
+ }
+
+ @Override
+ public void stopAndLog(String TAG, int timeThresholdToLog) {
+ // noop
+ }
}
}
diff --git a/java/com/android/contacts/common/util/TelephonyManagerUtils.java b/java/com/android/contacts/common/util/TelephonyManagerUtils.java
index e4c2c6373..b664268ca 100644
--- a/java/com/android/contacts/common/util/TelephonyManagerUtils.java
+++ b/java/com/android/contacts/common/util/TelephonyManagerUtils.java
@@ -33,4 +33,13 @@ public class TelephonyManagerUtils {
final String voiceMailLabel = telephonyManager.getVoiceMailAlphaTag();
return voiceMailLabel;
}
+
+ /**
+ * @param context Current application context.
+ * @return True if there is a subscription which supports video calls. False otherwise.
+ */
+ public static boolean hasVideoCallSubscription(Context context) {
+ // TODO: Check the telephony manager's subscriptions to see if any support video calls.
+ return true;
+ }
}
diff --git a/java/com/android/contacts/common/util/TrafficStatsTags.java b/java/com/android/contacts/common/util/TrafficStatsTags.java
new file mode 100644
index 000000000..b0e7fb583
--- /dev/null
+++ b/java/com/android/contacts/common/util/TrafficStatsTags.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+package com.android.contacts.common.util;
+
+public class TrafficStatsTags {
+
+ public static final int CONTACT_PHOTO_DOWNLOAD_TAG = 0x0001;
+ public static final int TAG_MAX = 0x9999;
+}