Merge "Make the contact picture exactly half the height as it is wide"
diff --git a/res/layout/stream_item_text.xml b/res/layout/stream_item_text.xml
index 601dfb9..4c44100 100644
--- a/res/layout/stream_item_text.xml
+++ b/res/layout/stream_item_text.xml
@@ -25,9 +25,22 @@
android:textSize="16sp"
android:textColor="@color/social_update_text_color" />
- <TextView android:id="@+id/stream_item_attribution"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/social_update_attribution_color"/>
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView android:id="@+id/stream_item_attribution"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="@color/social_update_attribution_color" />
+
+ <TextView android:id="@+id/stream_item_comments"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="4dip"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="@color/social_update_comments_color" />
+ </LinearLayout>
+
</LinearLayout>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 325d2e7..b6b3f31 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -35,6 +35,8 @@
<color name="social_update_attribution_color">#ff777777</color>
+ <color name="social_update_comments_color">#ff777777</color>
+
<!-- Color used for the letter in the A-Z section header -->
<color name="section_header_text_color">#ff999999</color>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 69f7428..17b0836 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -58,6 +58,7 @@
</style>
<style name="CallDetailActivityTheme" parent="android:Theme.Holo.SplitActionBarWhenNarrow">
+ <item name="android:windowBackground">@android:color/black</item>
<item name="android:gravity">top</item>
<item name="call_detail_transparent_background">#CC000000</item>
<item name="call_detail_contact_background_overlay_alpha">0.25</item>
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index e9d75ef..d8ba995 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -25,6 +25,7 @@
import com.android.contacts.util.ContactBadgeUtil;
import com.android.contacts.util.StreamItemEntry;
import com.android.contacts.util.StreamItemPhotoEntry;
+import com.google.common.annotations.VisibleForTesting;
import android.content.ContentValues;
import android.content.Context;
@@ -327,14 +328,22 @@
streamContainer.addView(oneColumnView);
}
- private static View addStreamItemText(LayoutInflater inflater, Context context,
+ @VisibleForTesting
+ static View addStreamItemText(LayoutInflater inflater, Context context,
StreamItemEntry streamItem, ViewGroup parent) {
View textUpdate = inflater.inflate(R.layout.stream_item_text, parent, false);
TextView htmlView = (TextView) textUpdate.findViewById(R.id.stream_item_html);
TextView attributionView = (TextView) textUpdate.findViewById(
R.id.stream_item_attribution);
+ TextView commentsView = (TextView) textUpdate.findViewById(R.id.stream_item_comments);
htmlView.setText(Html.fromHtml(streamItem.getText()));
attributionView.setText(ContactBadgeUtil.getSocialDate(streamItem, context));
+ if (streamItem.getComments() != null) {
+ commentsView.setText(Html.fromHtml(streamItem.getComments()));
+ commentsView.setVisibility(View.VISIBLE);
+ } else {
+ commentsView.setVisibility(View.GONE);
+ }
parent.addView(textUpdate);
return textUpdate;
}
diff --git a/src/com/android/contacts/group/SuggestedMemberListAdapter.java b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
index e013665..653cc25 100644
--- a/src/com/android/contacts/group/SuggestedMemberListAdapter.java
+++ b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
@@ -355,5 +355,10 @@
public void setPhotoByteArray(byte[] photo) {
mPhoto = photo;
}
+
+ @Override
+ public String toString() {
+ return getDisplayName();
+ }
}
}
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 528b129..194b6ca 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -107,4 +107,9 @@
<item>Two short sections with headers</item>
<item>Five short sections with headers</item>
</string-array>
+
+ <string name="attribution_google_plus">Google+</string>
+ <string name="attribution_google_talk">Google Talk</string>
+ <string name="attribution_flicker">Flicker</string>
+ <string name="attribution_twitter">Twitter</string>
</resources>
diff --git a/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
new file mode 100644
index 0000000..f9b33e0
--- /dev/null
+++ b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.detail;
+
+import com.android.contacts.R;
+import com.android.contacts.util.StreamItemEntry;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Html;
+import android.text.Spanned;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Unit tests for {@link ContactDetailDisplayUtils}.
+ */
+@SmallTest
+public class ContactDetailDisplayUtilsTest extends AndroidTestCase {
+ private static final String TEST_STREAM_ITEM_TEXT = "text";
+
+ private ViewGroup mParent;
+ private LayoutInflater mLayoutInflater;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mParent = new LinearLayout(getContext());
+ mLayoutInflater =
+ (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testAddStreamItemText_IncludesComments() {
+ StreamItemEntry streamItem = getTestBuilder().setComment("1 comment").build();
+ View streamItemView = addStreamItemText(streamItem);
+ assertHasText(streamItemView, R.id.stream_item_comments, "1 comment");
+ }
+
+ public void testAddStreamItemText_IncludesHtmlComments() {
+ StreamItemEntry streamItem = getTestBuilder().setComment("1 <b>comment</b>").build();
+ View streamItemView = addStreamItemText(streamItem);
+ assertHasHtmlText(streamItemView, R.id.stream_item_comments, "1 <b>comment<b>");
+ }
+
+ public void testAddStreamItemText_NoComments() {
+ StreamItemEntry streamItem = getTestBuilder().setComment(null).build();
+ View streamItemView = addStreamItemText(streamItem);
+ assertGone(streamItemView, R.id.stream_item_comments);
+ }
+
+ /**
+ * Calls {@link ContactDetailDisplayUtils#addStreamItemText(LayoutInflater, Context,
+ * StreamItemEntry, ViewGroup)} with the default parameters and the given stream item.
+ */
+ private View addStreamItemText(StreamItemEntry streamItem) {
+ return ContactDetailDisplayUtils.addStreamItemText(
+ mLayoutInflater, getContext(), streamItem, mParent);
+ }
+
+ /** Checks that the given id corresponds to a visible text view with the expected text. */
+ private void assertHasText(View parent, int textViewId, String expectedText) {
+ TextView textView = (TextView) parent.findViewById(textViewId);
+ assertNotNull(textView);
+ assertEquals(View.VISIBLE, textView.getVisibility());
+ assertEquals(expectedText, textView.getText().toString());
+ }
+
+ /** Checks that the given id corresponds to a visible text view with the expected HTML. */
+ private void assertHasHtmlText(View parent, int textViewId, String expectedHtml) {
+ TextView textView = (TextView) parent.findViewById(textViewId);
+ assertNotNull(textView);
+ assertEquals(View.VISIBLE, textView.getVisibility());
+ assertSpannableEquals(Html.fromHtml(expectedHtml), textView.getText());
+ }
+
+ /**
+ * Asserts that a char sequence is actually a {@link Spanned} matching the one expected.
+ */
+ private void assertSpannableEquals(Spanned expected, CharSequence actualCharSequence) {
+ assertEquals(expected.toString(), actualCharSequence.toString());
+ assertTrue(actualCharSequence instanceof Spanned);
+ Spanned actual = (Spanned) actualCharSequence;
+ assertEquals(Html.toHtml(expected), Html.toHtml(actual));
+ }
+
+ /** Checks that the given id corresponds to a gone view. */
+ private void assertGone(View parent, int textId) {
+ View view = parent.findViewById(textId);
+ assertNotNull(view);
+ assertEquals(View.GONE, view.getVisibility());
+ }
+
+ private static class StreamItemEntryBuilder {
+ private long mId;
+ private String mText;
+ private String mComment;
+ private long mTimestamp;
+ private String mAction;
+ private String mActionUri;
+ private String mResPackage;
+ private int mIconRes;
+ private int mLabelRes;
+
+ public StreamItemEntryBuilder() {}
+
+ public StreamItemEntryBuilder setText(String text) {
+ mText = text;
+ return this;
+ }
+
+ public StreamItemEntryBuilder setComment(String comment) {
+ mComment = comment;
+ return this;
+ }
+
+ public StreamItemEntry build() {
+ return new StreamItemEntry(mId, mText, mComment, mTimestamp, mAction, mActionUri,
+ mResPackage, mIconRes, mLabelRes);
+ }
+ }
+
+ private StreamItemEntryBuilder getTestBuilder() {
+ return new StreamItemEntryBuilder().setText(TEST_STREAM_ITEM_TEXT);
+ }
+}
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index 67bf725..a6222db 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -105,26 +105,26 @@
}
public void testSingleWritableRawContact() {
- expectQuery().returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo");
+ expectQuery().returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo");
assertWithMessageId(R.string.deleteConfirmation);
}
public void testReadOnlyRawContacts() {
- expectQuery().returnRow(1, READONLY_ACCOUNT_TYPE, 13, "foo");
+ expectQuery().returnRow(1, READONLY_ACCOUNT_TYPE, null, 13, "foo");
assertWithMessageId(R.string.readOnlyContactWarning);
}
public void testMixOfWritableAndReadOnlyRawContacts() {
expectQuery()
- .returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo")
- .returnRow(2, READONLY_ACCOUNT_TYPE, 13, "foo");
+ .returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo")
+ .returnRow(2, READONLY_ACCOUNT_TYPE, null, 13, "foo");
assertWithMessageId(R.string.readOnlyContactDeleteConfirmation);
}
public void testMultipleWritableRawContacts() {
expectQuery()
- .returnRow(1, WRITABLE_ACCOUNT_TYPE, 13, "foo")
- .returnRow(2, WRITABLE_ACCOUNT_TYPE, 13, "foo");
+ .returnRow(1, WRITABLE_ACCOUNT_TYPE, null, 13, "foo")
+ .returnRow(2, WRITABLE_ACCOUNT_TYPE, null, 13, "foo");
assertWithMessageId(R.string.multipleContactDeleteConfirmation);
}
diff --git a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
index d70cb44..e0b443a 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -89,7 +89,7 @@
public void testSendSmsWhenOnlyOneNumberAvailable() {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
expectQuery(contactUri)
- .returnRow(1, "123", 0, null, Phone.TYPE_HOME, null);
+ .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
mContext, InteractionType.SMS, null);
@@ -107,7 +107,7 @@
public void testSendSmsWhenDataIdIsProvided() {
Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, 1);
expectQuery(dataUri, true /* isDataUri */ )
- .returnRow(1, "987", 0, null, Phone.TYPE_HOME, null);
+ .returnRow(1, "987", 0, null, null, Phone.TYPE_HOME, null);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
mContext, InteractionType.SMS, null);
@@ -125,8 +125,8 @@
public void testSendSmsWhenThereIsPrimaryNumber() {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
expectQuery(contactUri)
- .returnRow(1, "123", 0, null, Phone.TYPE_HOME, null)
- .returnRow(2, "456", 1, null, Phone.TYPE_HOME, null);
+ .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
+ .returnRow(2, "456", 1, null, null, Phone.TYPE_HOME, null);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
mContext, InteractionType.SMS, null);
@@ -164,8 +164,8 @@
public void testCallNumberWhenThereAreDuplicates() {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
expectQuery(contactUri)
- .returnRow(1, "123", 0, null, Phone.TYPE_HOME, null)
- .returnRow(2, "123", 0, null, Phone.TYPE_WORK, null);
+ .returnRow(1, "123", 0, null, null, Phone.TYPE_HOME, null)
+ .returnRow(2, "123", 0, null, null, Phone.TYPE_WORK, null);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
mContext, InteractionType.PHONE_CALL, null);
@@ -183,8 +183,8 @@
public void testShowDisambigDialogForCalling() {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
expectQuery(contactUri)
- .returnRow(1, "123", 0, "account", Phone.TYPE_HOME, "label")
- .returnRow(2, "456", 0, null, Phone.TYPE_WORK, null);
+ .returnRow(1, "123", 0, "account", null, Phone.TYPE_HOME, "label")
+ .returnRow(2, "456", 0, null, null, Phone.TYPE_WORK, null);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
mContext, InteractionType.PHONE_CALL, null);
diff --git a/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java b/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
index c984418..e27c767 100644
--- a/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
+++ b/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
@@ -83,6 +83,17 @@
"<i>24567</i> <font color='blue' size='+1'><b>likes</b></font>"
};
+ private Integer[] labelIds = new Integer[] {
+ R.string.attribution_google_plus,
+ R.string.attribution_google_talk,
+ R.string.attribution_flicker,
+ R.string.attribution_twitter
+ };
+
+ public Integer[] iconIds = new Integer[] {
+ R.drawable.default_icon,
+ };
+
// Photos to randomly select from.
private Integer[] imageIds = new Integer[]{
R.drawable.android,
@@ -242,6 +253,7 @@
}
private ContentValues buildStreamItemValues(String accountType, String accountName) {
+ boolean includeAttribution = randInt(100) < 70;
boolean includeComments = randInt(100) < 30;
boolean includeAction = randInt(100) < 30;
ContentValues values = new ContentValues();
@@ -250,6 +262,14 @@
String.format(pickRandom(snippetStrings) , place)
+ (includeComments ? " [c]" : "")
+ (includeAction ? " [a]" : ""));
+ if (includeAttribution) {
+ values.put(StreamItems.RES_PACKAGE, "com.android.contacts.tests");
+ int sourceIndex = randInt(labelIds.length);
+ values.put(StreamItems.RES_LABEL, labelIds[sourceIndex]);
+ if (sourceIndex < iconIds.length) {
+ values.put(StreamItems.RES_ICON, iconIds[sourceIndex]);
+ }
+ }
if (includeComments) {
values.put(StreamItems.COMMENTS, pickRandom(commentStrings));
} else {