Merge "Fix stale conversation list after undo." into jb-ub-mail-ur10
diff --git a/res/drawable-hdpi/ic_draft.png b/res/drawable-hdpi/ic_draft.png
new file mode 100644
index 0000000..a0fa5ce
--- /dev/null
+++ b/res/drawable-hdpi/ic_draft.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_edit_holo_light.png b/res/drawable-hdpi/ic_edit_holo_light.png
index 5eab332..75141ab 100644
--- a/res/drawable-hdpi/ic_edit_holo_light.png
+++ b/res/drawable-hdpi/ic_edit_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_email_draft.png b/res/drawable-hdpi/ic_email_draft.png
deleted file mode 100644
index 5f62183..0000000
--- a/res/drawable-hdpi/ic_email_draft.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_forward_holo_light.png b/res/drawable-hdpi/ic_forward_holo_light.png
index 5d987b5..9ab9441 100644
--- a/res/drawable-hdpi/ic_forward_holo_light.png
+++ b/res/drawable-hdpi/ic_forward_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_reply_all_holo_light.png b/res/drawable-hdpi/ic_reply_all_holo_light.png
index 6122e56..c800701 100644
--- a/res/drawable-hdpi/ic_reply_all_holo_light.png
+++ b/res/drawable-hdpi/ic_reply_all_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_reply_holo_light.png b/res/drawable-hdpi/ic_reply_holo_light.png
index 7143fa8..a18cf9b 100644
--- a/res/drawable-hdpi/ic_reply_holo_light.png
+++ b/res/drawable-hdpi/ic_reply_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png
new file mode 100644
index 0000000..8289a76
--- /dev/null
+++ b/res/drawable-hdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png
new file mode 100644
index 0000000..544b076
--- /dev/null
+++ b/res/drawable-hdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_draft.png b/res/drawable-mdpi/ic_draft.png
new file mode 100644
index 0000000..0336fe7
--- /dev/null
+++ b/res/drawable-mdpi/ic_draft.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_edit_holo_light.png b/res/drawable-mdpi/ic_edit_holo_light.png
index ae76531..d344424 100644
--- a/res/drawable-mdpi/ic_edit_holo_light.png
+++ b/res/drawable-mdpi/ic_edit_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_email_draft.png b/res/drawable-mdpi/ic_email_draft.png
deleted file mode 100644
index 2392d6f..0000000
--- a/res/drawable-mdpi/ic_email_draft.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_forward_holo_light.png b/res/drawable-mdpi/ic_forward_holo_light.png
index 6ea945a..7adcbe5 100644
--- a/res/drawable-mdpi/ic_forward_holo_light.png
+++ b/res/drawable-mdpi/ic_forward_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_reply_all_holo_light.png b/res/drawable-mdpi/ic_reply_all_holo_light.png
index d840c3e..18b0cb0 100644
--- a/res/drawable-mdpi/ic_reply_all_holo_light.png
+++ b/res/drawable-mdpi/ic_reply_all_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_reply_holo_light.png b/res/drawable-mdpi/ic_reply_holo_light.png
index cf75fde..b64cd6d 100644
--- a/res/drawable-mdpi/ic_reply_holo_light.png
+++ b/res/drawable-mdpi/ic_reply_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png
new file mode 100644
index 0000000..d01da9f
--- /dev/null
+++ b/res/drawable-mdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png
new file mode 100644
index 0000000..683258e
--- /dev/null
+++ b/res/drawable-mdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_draft.png b/res/drawable-xhdpi/ic_draft.png
new file mode 100644
index 0000000..2ec9899
--- /dev/null
+++ b/res/drawable-xhdpi/ic_draft.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_edit_holo_light.png b/res/drawable-xhdpi/ic_edit_holo_light.png
index 9e6db8e..88c7fc9 100644
--- a/res/drawable-xhdpi/ic_edit_holo_light.png
+++ b/res/drawable-xhdpi/ic_edit_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_email_draft.png b/res/drawable-xhdpi/ic_email_draft.png
deleted file mode 100644
index 5133625..0000000
--- a/res/drawable-xhdpi/ic_email_draft.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_forward_holo_light.png b/res/drawable-xhdpi/ic_forward_holo_light.png
index 1462aa8..62da4a4 100644
--- a/res/drawable-xhdpi/ic_forward_holo_light.png
+++ b/res/drawable-xhdpi/ic_forward_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_reply_all_holo_light.png b/res/drawable-xhdpi/ic_reply_all_holo_light.png
index c71e65e..dee1b02 100644
--- a/res/drawable-xhdpi/ic_reply_all_holo_light.png
+++ b/res/drawable-xhdpi/ic_reply_all_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_reply_holo_light.png b/res/drawable-xhdpi/ic_reply_holo_light.png
index 3a4d3db..bfb021c 100644
--- a/res/drawable-xhdpi/ic_reply_holo_light.png
+++ b/res/drawable-xhdpi/ic_reply_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png b/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png
new file mode 100644
index 0000000..23fe0ba
--- /dev/null
+++ b/res/drawable-xhdpi/ic_star_off_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png b/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png
new file mode 100644
index 0000000..e54a509
--- /dev/null
+++ b/res/drawable-xhdpi/ic_star_on_convo_view_holo_light.png
Binary files differ
diff --git a/res/drawable/message_header_star.xml b/res/drawable/message_header_star.xml
index 7018315..9e71e1c 100644
--- a/res/drawable/message_header_star.xml
+++ b/res/drawable/message_header_star.xml
@@ -16,6 +16,7 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:drawable="@drawable/ic_star_on" />
-    <item android:drawable="@drawable/ic_star_off" />
+    <item android:state_selected="true"
+          android:drawable="@drawable/ic_star_on_convo_view_holo_light" />
+    <item android:drawable="@drawable/ic_star_off_convo_view_holo_light" />
 </selector>
diff --git a/res/layout/conversation_list_progress.xml b/res/layout/conversation_list_progress.xml
index c8218ca..8e8a407 100644
--- a/res/layout/conversation_list_progress.xml
+++ b/res/layout/conversation_list_progress.xml
@@ -37,7 +37,6 @@
         android:layout_gravity="top"
         butterbar:barColor="@android:color/holo_blue_dark"
         butterbar:barHeight="2.5dp"
-        butterbar:detentWidth="4dp"
         android:visibility="gone" />
 
 </merge>
diff --git a/res/layout/conversation_message_upper_header.xml b/res/layout/conversation_message_upper_header.xml
index d4a22e0..3742a32 100644
--- a/res/layout/conversation_message_upper_header.xml
+++ b/res/layout/conversation_message_upper_header.xml
@@ -44,7 +44,7 @@
         android:layout_height="@dimen/contact_photo_height"
         android:visibility="gone"
         android:scaleType="center"
-        android:src="@drawable/ic_email_draft" />
+        android:src="@drawable/ic_draft" />
     <include layout="@layout/conversation_message_upper_header_text" />
     <include layout="@layout/conversation_message_upper_header_actions" />
 
diff --git a/res/layout/conversation_view_header.xml b/res/layout/conversation_view_header.xml
index f4f71f4..b63f88b 100644
--- a/res/layout/conversation_view_header.xml
+++ b/res/layout/conversation_view_header.xml
@@ -20,20 +20,23 @@
     android:id="@+id/conversation_header"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:orientation="vertical"
     android:paddingTop="@dimen/conversation_header_vertical_padding"
     android:paddingBottom="@dimen/conversation_header_vertical_padding"
     android:layout_marginLeft="@dimen/conversation_view_margin_side"
-    android:layout_marginRight="@dimen/conversation_view_margin_side" >
+    android:layout_marginRight="@dimen/conversation_view_margin_side"
+    android:layout_marginStart="@dimen/conversation_view_margin_side"
+    android:layout_marginEnd="@dimen/conversation_view_margin_side" >
 
     <TextView
         android:id="@+id/subject"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
         android:paddingTop="@dimen/conversation_header_vertical_item_padding"
-        android:paddingBottom="@dimen/conversation_header_vertical_item_padding"
         android:paddingLeft="@dimen/conversation_header_side_padding"
-        android:paddingRight="10dp"
+        android:paddingRight="@dimen/conversation_header_side_padding"
+        android:paddingStart="@dimen/conversation_header_side_padding"
+        android:paddingEnd="@dimen/conversation_header_side_padding"
         android:includeFontPadding="false"
         style="@style/ConversationSubjectStyle" />
 
@@ -41,15 +44,13 @@
         android:id="@+id/folders"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_alignBaseline="@id/subject"
+        android:layout_gravity="right|end"
         android:background="?android:attr/selectableItemBackground"
-        android:paddingTop="@dimen/conversation_header_vertical_item_padding"
-        android:paddingBottom="@dimen/conversation_header_vertical_item_padding"
-        android:paddingLeft="@dimen/conversation_header_side_padding"
-        android:paddingRight="@dimen/conversation_header_side_padding"
+        android:gravity="right|end"
         android:includeFontPadding="false"
-        android:textSize="@dimen/conversation_folder_font_size"
-        android:gravity="right" />
+        android:lineSpacingExtra="4dp"
+        android:paddingLeft="@dimen/conversation_header_side_padding"
+        android:paddingStart="@dimen/conversation_header_side_padding"
+        android:textSize="@dimen/conversation_folder_font_size" />
 
 </com.android.mail.browse.ConversationViewHeader>
diff --git a/res/layout/super_collapsed_block.xml b/res/layout/super_collapsed_block.xml
index f730d31..1875dfa 100644
--- a/res/layout/super_collapsed_block.xml
+++ b/res/layout/super_collapsed_block.xml
@@ -19,41 +19,23 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/super_collapsed_block"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/super_collapsed_height"
     android:layout_marginLeft="@dimen/conversation_view_margin_side"
     android:layout_marginRight="@dimen/conversation_view_margin_side"
-    android:paddingBottom="@dimen/message_header_vertical_margin">
-    <RelativeLayout
-        android:id="@+id/super_collapsed_background"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/super_collapsed_height"
-        android:paddingRight="@dimen/message_header_padding_right">
-        <View
-            android:id="@+id/super_collapsed_icon"
-            android:layout_width="@dimen/contact_photo_width"
-            android:layout_height="match_parent"
-            android:layout_alignParentLeft="true"
-            android:background="@drawable/super_collapsed_icon" />
-        <TextView
-            android:id="@+id/super_collapsed_count"
-            android:layout_width="@dimen/message_header_action_button_width"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:gravity="center_horizontal"
-            android:textSize="14sp"
-            android:textStyle="bold"
-            android:textColor="@color/message_sender_name" />
-        <TextView
-            android:id="@+id/super_collapsed_label"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/super_collapsed_icon"
-            android:layout_toLeftOf="@id/super_collapsed_count"
-            android:layout_centerVertical="true"
-            android:paddingLeft="@dimen/message_header_inner_side_padding"
-            android:text="@string/show_messages_read"
-            android:textSize="14sp"
-            android:textColor="@color/message_sender_name" />
-    </RelativeLayout>
+    android:layout_marginStart="@dimen/conversation_view_margin_side"
+    android:layout_marginEnd="@dimen/conversation_view_margin_side"
+    android:layout_marginBottom="@dimen/message_header_vertical_margin"
+    android:background="@color/collapsed_message_header_background_color"
+    android:gravity="center"
+    android:orientation="horizontal"
+    android:paddingLeft="@dimen/message_header_padding"
+    android:paddingRight="@dimen/message_header_padding"
+    android:paddingStart="@dimen/message_header_padding"
+    android:paddingEnd="@dimen/message_header_padding">
+    <TextView
+        android:id="@+id/super_collapsed_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="14sp"
+        android:textColor="@color/dark_gray_text_color" />
 </com.android.mail.browse.SuperCollapsedBlock>
diff --git a/res/values-sw600dp/dimen.xml b/res/values-sw600dp/dimen.xml
index 892b845..7dd594c 100644
--- a/res/values-sw600dp/dimen.xml
+++ b/res/values-sw600dp/dimen.xml
@@ -32,7 +32,6 @@
     <dimen name="message_header_height">64sp</dimen>
     <dimen name="message_header_padding_right">4dip</dimen>
     <dimen name="message_header_action_button_width">56dip</dimen>
-    <dimen name="super_collapsed_height">32sp</dimen>
     <dimen name="attachment_tile_min_size">180dp</dimen>
     <dimen name="attachment_tile_max_size">254dp</dimen>
     <dimen name="wait_padding">32dp</dimen>
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index 216327e..aaebc9c 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -20,12 +20,6 @@
         <item name="android:layout_width">match_parent</item>
     </style>
 
-    <style name="ConversationSubjectStyle">
-        <item name="android:textSize">18sp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textColor">@color/conv_header_text_light</item>
-    </style>
-
     <style name="UnreadCountActionBar" parent="UnreadCountActionBarBase">
         <item name="android:gravity">center_vertical|left</item>
     </style>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 1937ae5..fbd1534 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -41,13 +41,17 @@
     <dimen name="conversation_page_gutter">16dp</dimen>
     <dimen name="conversation_message_content_margin_side">16dp</dimen>
     <dimen name="conversation_view_margin_side">0dp</dimen>
-    <dimen name="conversation_header_vertical_item_padding">8dip</dimen>
+    <dimen name="conversation_header_font_size">18sp</dimen>
+    <dimen name="conversation_header_font_size_condensed">14sp</dimen>
+    <dimen name="conversation_header_vertical_item_padding">16dip</dimen>
+    <dimen name="conversation_header_vertical_item_padding_condensed">12dip</dimen>
     <dimen name="conversation_header_vertical_padding">0dip</dimen>
-    <dimen name="conversation_header_side_padding">8dip</dimen>
+    <dimen name="conversation_header_side_padding">16dip</dimen>
     <dimen name="conversation_folder_font_size">12sp</dimen>
     <dimen name="conversation_folder_padding">1dip</dimen>
-    <dimen name="conversation_folder_padding_extra_width">3dip</dimen>
-    <dimen name="conversation_folder_padding_before">1dip</dimen>
+    <dimen name="conversation_folder_padding_extra_width">14dip</dimen>
+    <dimen name="conversation_folder_padding_before">8dip</dimen>
+    <dimen name="conversation_folder_padding_above">4dip</dimen>
     <dimen name="message_details_header_collapsed_height">48sp</dimen>
     <dimen name="message_details_header_bottom_border_height">1dip</dimen>
     <dimen name="message_details_header_date_margin_right">4dip</dimen>
@@ -57,11 +61,11 @@
     <dimen name="message_header_height">48sp</dimen>
     <dimen name="message_header_presence_top_margin">-4dp</dimen>
     <dimen name="message_header_action_button_width">48dip</dimen>
-    <dimen name="message_header_padding_right">0dip</dimen>
+    <dimen name="message_header_padding">16dip</dimen>
     <dimen name="message_header_padding_start">16dp</dimen>
     <dimen name="message_header_padding_end">4dp</dimen>
     <dimen name="message_header_title_container_margin_end_collapsed">12dp</dimen>
-    <dimen name="super_collapsed_height">24sp</dimen>
+    <dimen name="super_collapsed_height">34sp</dimen>
     <dimen name="notification_view_height">36dip</dimen>
     <dimen name="contact_photo_width">48sp</dimen>
     <dimen name="contact_photo_height">48sp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a674dd2..69c675c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -520,7 +520,9 @@
     <string name="contact_info_string_default">Show contact information</string>
     <!-- Shown in collapsed mode when a conversation has more than one read message.
          The message count is shown to the right of this text. [CHAR LIMIT=70] -->
-    <string name="show_messages_read">Previously read messages</string>
+    <plurals name="show_messages_read">
+        <item quantity="other"><xliff:g id="count" example="4">%1$d</xliff:g> previously read messages</item>
+    </plurals>
     <!-- Shown to display the date of the message [CHAR LIMIT=10] -->
     <string name="date_heading">Date:</string>
     <!-- Shown to display the from address of the message [CHAR LIMIT=10] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e46e20a..19d7447 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -235,8 +235,9 @@
     </style>
 
     <style name="ConversationSubjectStyle">
-        <item name="android:textSize">14sp</item>
+        <item name="android:textSize">@dimen/conversation_header_font_size</item>
         <item name="android:textStyle">bold</item>
+        <item name="android:textColor">@color/conv_header_text_dark</item>
     </style>
 
     <!-- Conversation view message header styles -->
diff --git a/src/com/android/mail/browse/ConversationViewHeader.java b/src/com/android/mail/browse/ConversationViewHeader.java
index 261adfa..221b2a2 100644
--- a/src/com/android/mail/browse/ConversationViewHeader.java
+++ b/src/com/android/mail/browse/ConversationViewHeader.java
@@ -19,16 +19,18 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Build;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.style.BackgroundColorSpan;
 import android.text.style.ForegroundColorSpan;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
-import android.widget.RelativeLayout;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.mail.R;
@@ -48,7 +50,7 @@
  * there is enough room to fit both without wrapping. If they overlap, it
  * adjusts the layout to position the folders below the subject.
  */
-public class ConversationViewHeader extends RelativeLayout implements OnClickListener {
+public class ConversationViewHeader extends LinearLayout implements OnClickListener {
 
     public interface ConversationViewHeaderCallbacks {
         /**
@@ -72,6 +74,10 @@
     private ConversationFolderDisplayer mFolderDisplayer;
     private ConversationHeaderItem mHeaderItem;
 
+    private boolean mLargeText;
+    private final float mCondensedTextSize;
+    private final int mCondensedTopPadding;
+
     /**
      * Instantiated from this layout: conversation_view_header.xml
      * @param context
@@ -82,6 +88,12 @@
 
     public ConversationViewHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mLargeText = true;
+        final Resources resources = getResources();
+        mCondensedTextSize =
+                resources.getDimensionPixelSize(R.dimen.conversation_header_font_size_condensed);
+        mCondensedTopPadding = resources.getDimensionPixelSize(
+                R.dimen.conversation_header_vertical_item_padding_condensed);
     }
 
     @Override
@@ -99,25 +111,26 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        // reposition the folders if they don't fit horizontally next to the
-        // subject
-        // (taking into account child margins and parent padding)
-        final int childWidthSum = getTotalMeasuredChildWidth(mSubjectView)
-                + getTotalMeasuredChildWidth(mFoldersView) + getPaddingLeft() + getPaddingRight();
+        // If we currently have large text and we have greater than 2 lines,
+        // switch to smaller text size with smaller top padding and re-measure
+        if (mLargeText && mSubjectView.getLineCount() > 2) {
+            mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCondensedTextSize);
 
-        if (childWidthSum > getMeasuredWidth()) {
-            LayoutParams params = (LayoutParams) mFoldersView.getLayoutParams();
-            params.addRule(RelativeLayout.BELOW, R.id.subject);
-            params.addRule(RelativeLayout.ALIGN_BASELINE, 0);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                // start, top, end, bottom
+                mSubjectView.setPaddingRelative(mSubjectView.getPaddingStart(),
+                        mCondensedTopPadding, mSubjectView.getPaddingEnd(),
+                        mSubjectView.getPaddingBottom());
+            } else {
+                mSubjectView.setPadding(mSubjectView.getPaddingLeft(),
+                        mCondensedTopPadding, mSubjectView.getPaddingRight(),
+                        mSubjectView.getPaddingBottom());
+            }
+
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         }
     }
 
-    private static int getTotalMeasuredChildWidth(View child) {
-        final LayoutParams p = (LayoutParams) child.getLayoutParams();
-        return child.getMeasuredWidth() + p.leftMargin + p.rightMargin;
-    }
-
     public void setCallbacks(ConversationViewHeaderCallbacks callbacks,
             ConversationAccountController accountController) {
         mCallbacks = callbacks;
@@ -142,7 +155,8 @@
         if (settings.priorityArrowsEnabled && conv.isImportant()) {
             sb.append('.');
             sb.setSpan(new PriorityIndicatorSpan(getContext(),
-                    R.drawable.ic_email_caret_none_important_unread, mFoldersView.getPadding(), 0),
+                    R.drawable.ic_email_caret_none_important_unread, mFoldersView.getPadding(), 0,
+                    mFoldersView.getPaddingAbove()),
                     0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
         }
 
diff --git a/src/com/android/mail/browse/FolderSpan.java b/src/com/android/mail/browse/FolderSpan.java
index df77d22..70ac75e 100644
--- a/src/com/android/mail/browse/FolderSpan.java
+++ b/src/com/android/mail/browse/FolderSpan.java
@@ -36,8 +36,22 @@
 
     public interface FolderSpanDimensions {
         int getPadding();
+
+        /**
+         * Returns the padding value that corresponds to the horizontal padding
+         * surrounding the text inside the background color.
+         */
         int getPaddingExtraWidth();
+
+        /**
+         * Returns the padding value for the space between folders.
+         */
         int getPaddingBefore();
+
+        /**
+         * Returns the spacing above each line outside of the .
+         */
+        int getPaddingAbove();
         int getMaxWidth();
     }
 
@@ -70,10 +84,10 @@
 
     private int measureWidth(Paint paint, CharSequence text, int start, int end,
             boolean includePaddingBefore) {
-        final int paddingH = mDims.getPadding() + mDims.getPaddingExtraWidth();
+        final int paddingW = mDims.getPadding() + mDims.getPaddingExtraWidth();
         final int maxWidth = mDims.getMaxWidth();
 
-        int w = (int) paint.measureText(text, start, end) + 2 * paddingH;
+        int w = (int) paint.measureText(text, start, end) + 2 * paddingW;
         if (includePaddingBefore) {
             w += mDims.getPaddingBefore();
         }
@@ -88,8 +102,9 @@
     public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
             int y, int bottom, Paint paint) {
 
-        final int paddingH = mDims.getPadding() + mDims.getPaddingExtraWidth();
+        final int paddingW = mDims.getPadding() + mDims.getPaddingExtraWidth();
         final int paddingBefore = mDims.getPaddingBefore();
+        final int paddingAbove = mDims.getPaddingAbove();
         final int maxWidth = mDims.getMaxWidth();
 
         mWorkPaint.set(paint);
@@ -109,7 +124,7 @@
 
             mWorkPaint.setColor(mWorkPaint.bgColor);
             mWorkPaint.setStyle(Paint.Style.FILL);
-            canvas.drawRect(x + paddingBefore, top, x + bgWidth + paddingBefore, bottom,
+            canvas.drawRect(x + paddingBefore, top + paddingAbove, x + bgWidth + paddingBefore, bottom,
                     mWorkPaint);
 
             mWorkPaint.setColor(prevColor);
@@ -119,11 +134,11 @@
         // middle-ellipsize long strings
         if (bgWidth == maxWidth) {
             text = TextUtils.ellipsize(text.subSequence(start, end).toString(), mWorkPaint,
-                    bgWidth - 2 * paddingH, TextUtils.TruncateAt.MIDDLE);
+                    bgWidth - 2 * paddingW, TextUtils.TruncateAt.MIDDLE);
             start = 0;
             end = text.length();
         }
-        canvas.drawText(text, start, end, x + paddingH + paddingBefore, y, mWorkPaint);
+        canvas.drawText(text, start, end, x + paddingW + paddingBefore, y + paddingAbove, mWorkPaint);
     }
 
 }
diff --git a/src/com/android/mail/browse/FolderSpanTextView.java b/src/com/android/mail/browse/FolderSpanTextView.java
index 0f81d0c..83636fe 100644
--- a/src/com/android/mail/browse/FolderSpanTextView.java
+++ b/src/com/android/mail/browse/FolderSpanTextView.java
@@ -35,6 +35,8 @@
     private final int mFolderPadding;
     private final int mFolderPaddingExtraWidth;
     private final int mFolderPaddingBefore;
+    private final int mFolderPaddingAbove;
+
     private int mMaxSpanWidth;
 
     public FolderSpanTextView(Context context) {
@@ -50,6 +52,7 @@
                 R.dimen.conversation_folder_padding_extra_width);
         mFolderPaddingBefore = r.getDimensionPixelOffset(
                 R.dimen.conversation_folder_padding_before);
+        mFolderPaddingAbove = r.getDimensionPixelOffset(R.dimen.conversation_folder_padding_above);
     }
 
     @Override
@@ -76,8 +79,12 @@
     }
 
     @Override
+    public int getPaddingAbove() {
+        return mFolderPaddingAbove;
+    }
+
+    @Override
     public int getMaxWidth() {
         return mMaxSpanWidth;
     }
-
 }
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index e9daf82..bc90d54 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -212,7 +212,9 @@
 
     private boolean mIsViewOnlyMode = false;
 
-    private LetterTileProvider sLetterTileProvider;
+    private LetterTileProvider mLetterTileProvider;
+    private final int mContactPhotoWidth;
+    private final int mContactPhotoHeight;
 
     public interface MessageHeaderViewCallbacks {
         void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight);
@@ -245,6 +247,10 @@
         mEmailCopyMenu = new EmailCopyContextMenu(getContext());
         mInflater = LayoutInflater.from(context);
         mMyName = context.getString(R.string.me_object_pronun);
+
+        final Resources resources = getResources();
+        mContactPhotoWidth = resources.getDimensionPixelSize(R.dimen.contact_photo_width);
+        mContactPhotoHeight = resources.getDimensionPixelSize(R.dimen.contact_photo_height);
     }
 
     /**
@@ -891,20 +897,19 @@
         }
 
         if (!photoSet) {
-            mPhotoView.setImageBitmap(makeLetterTile(
-                    mSender.getName(), email, mPhotoView.getWidth(), mPhotoView.getHeight()));
+            mPhotoView.setImageBitmap(makeLetterTile(mSender.getName(), email));
         }
     }
 
     private Bitmap makeLetterTile(
-            String displayName, String senderAddress, int width, int height) {
-        final ImageCanvas.Dimensions dimensions = new ImageCanvas.Dimensions(
-                width, height, ImageCanvas.Dimensions.SCALE_ONE);
-
-        if (sLetterTileProvider == null) {
-            sLetterTileProvider = new LetterTileProvider(getContext());
+            String displayName, String senderAddress) {
+        if (mLetterTileProvider == null) {
+            mLetterTileProvider = new LetterTileProvider(getContext());
         }
-        return sLetterTileProvider.getLetterTile(dimensions, displayName, senderAddress);
+
+        final ImageCanvas.Dimensions dimensions = new ImageCanvas.Dimensions(
+                mContactPhotoWidth, mContactPhotoHeight, ImageCanvas.Dimensions.SCALE_ONE);
+        return mLetterTileProvider.getLetterTile(dimensions, displayName, senderAddress);
     }
 
 
diff --git a/src/com/android/mail/browse/PriorityIndicatorSpan.java b/src/com/android/mail/browse/PriorityIndicatorSpan.java
index be17207..44a96e2 100644
--- a/src/com/android/mail/browse/PriorityIndicatorSpan.java
+++ b/src/com/android/mail/browse/PriorityIndicatorSpan.java
@@ -49,14 +49,17 @@
     private final int mResId;
     private final int mPaddingV;
     private final int mPaddingH;
+    private final int mPaddingAbove;
 
     private WeakReference<Drawable> mDrawableRef;
 
-    public PriorityIndicatorSpan(Context context, int resId, int paddingV, int paddingH) {
+    public PriorityIndicatorSpan(Context context, int resId, int paddingV, int paddingH,
+            int paddingAbove) {
         mContext = context;
         mResId = resId;
         mPaddingV = paddingV;
         mPaddingH = paddingH;
+        mPaddingAbove = paddingAbove;
     }
 
     private Drawable getDrawable() {
@@ -102,7 +105,7 @@
         Drawable b = getCachedDrawable();
         canvas.save();
 
-        int transY = (top + bottom - b.getBounds().bottom) / 2;
+        final int transY = (top + bottom + mPaddingAbove - b.getBounds().bottom) / 2;
 
         canvas.translate(x + mPaddingH, transY);
         b.draw(canvas);
diff --git a/src/com/android/mail/browse/SuperCollapsedBlock.java b/src/com/android/mail/browse/SuperCollapsedBlock.java
index 7d4b6c4..1c58610 100644
--- a/src/com/android/mail/browse/SuperCollapsedBlock.java
+++ b/src/com/android/mail/browse/SuperCollapsedBlock.java
@@ -18,12 +18,9 @@
 package com.android.mail.browse;
 
 import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.BitmapDrawable;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.mail.R;
@@ -34,7 +31,7 @@
  * so the listener can hide the block and reveal the corresponding collapsed message headers.
  *
  */
-public class SuperCollapsedBlock extends FrameLayout implements View.OnClickListener {
+public class SuperCollapsedBlock extends LinearLayout implements View.OnClickListener {
 
     public interface OnClickListener {
         /**
@@ -46,9 +43,7 @@
 
     private SuperCollapsedBlockItem mModel;
     private OnClickListener mClick;
-    private View mIconView;
-    private TextView mCountView;
-    private View mBackgroundView;
+    private TextView mSuperCollapsedText;
 
     public SuperCollapsedBlock(Context context) {
         this(context, null);
@@ -67,16 +62,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-
-        mIconView = findViewById(R.id.super_collapsed_icon);
-        mCountView = (TextView) findViewById(R.id.super_collapsed_count);
-        mBackgroundView = findViewById(R.id.super_collapsed_background);
-
-        // Work around Honeycomb bug where BitmapDrawable's tileMode is unreliable in XML (5160739)
-        BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(
-                R.drawable.header_convo_view_thread_bg_holo);
-        bd.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
-        mBackgroundView.setBackgroundDrawable(bd);
+        mSuperCollapsedText = (TextView) findViewById(R.id.super_collapsed_text);
     }
 
     public void bind(SuperCollapsedBlockItem item) {
@@ -85,15 +71,14 @@
     }
 
     public void setCount(int count) {
-        mCountView.setText(Integer.toString(count));
-        mIconView.getBackground().setLevel(count);
+        mSuperCollapsedText.setText(
+                getResources().getQuantityString(R.plurals.show_messages_read, count, count));
     }
 
     @Override
     public void onClick(final View v) {
-        ((TextView) findViewById(R.id.super_collapsed_label)).setText(
+        ((TextView) findViewById(R.id.super_collapsed_text)).setText(
                 R.string.loading_conversation);
-        mCountView.setVisibility(GONE);
 
         if (mClick != null) {
             getHandler().post(new Runnable() {
@@ -104,13 +89,4 @@
             });
         }
     }
-
-    public static int getCannedHeight(Context context) {
-        Resources r = context.getResources();
-        // Rather than try to measure the height a super-collapsed block, just add up the known
-        // vertical dimension components.
-        return r.getDimensionPixelSize(R.dimen.super_collapsed_height)
-                + r.getDimensionPixelOffset(R.dimen.message_header_vertical_margin);
-    }
-
 }
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index 1f444fa..ed6ae53 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -22,6 +22,7 @@
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.DialogFragment;
 import android.app.Fragment;
 import android.app.FragmentTransaction;
 import android.app.LoaderManager;
@@ -116,7 +117,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 public class ComposeActivity extends Activity implements OnClickListener, OnNavigationListener,
-        RespondInlineListener, DialogInterface.OnClickListener, TextWatcher,
+        RespondInlineListener, TextWatcher,
         AttachmentAddedOrDeletedListener, OnAccountChangedListener,
         LoaderManager.LoaderCallbacks<Cursor>, TextView.OnEditorActionListener,
         FeedbackEnabledActivity {
@@ -246,8 +247,6 @@
     private boolean mReplyFromChanged;
     private MenuItem mSave;
     private MenuItem mSend;
-    private AlertDialog mRecipientErrorDialog;
-    private AlertDialog mSendConfirmDialog;
     @VisibleForTesting
     protected Message mRefMessage;
     private long mDraftId = UIProvider.INVALID_MESSAGE_ID;
@@ -676,12 +675,6 @@
     protected void onPause() {
         super.onPause();
 
-        if (mSendConfirmDialog != null) {
-            mSendConfirmDialog.dismiss();
-        }
-        if (mRecipientErrorDialog != null) {
-            mRecipientErrorDialog.dismiss();
-        }
         // When the user exits the compose view, see if this draft needs saving.
         // Don't save unnecessary drafts if we are only changing the orientation.
         if (!isChangingConfigurations()) {
@@ -2244,33 +2237,48 @@
         }
     }
 
+    public static class RecipientErrorDialogFragment extends DialogFragment {
+        public static RecipientErrorDialogFragment newInstance(final String message) {
+            final RecipientErrorDialogFragment frag = new RecipientErrorDialogFragment();
+            final Bundle args = new Bundle(1);
+            args.putString("message", message);
+            frag.setArguments(args);
+            return frag;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final String message = getArguments().getString("message");
+            return new AlertDialog.Builder(getActivity()).setMessage(message).setTitle(
+                    R.string.recipient_error_dialog_title)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setPositiveButton(
+                            R.string.ok, new Dialog.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            ((ComposeActivity)getActivity()).finishRecipientErrorDialog();
+                        }
+                    }).create();
+        }
+    }
+
+    private void finishRecipientErrorDialog() {
+        // after the user dismisses the recipient error
+        // dialog we want to make sure to refocus the
+        // recipient to field so they can fix the issue
+        // easily
+        if (mTo != null) {
+            mTo.requestFocus();
+        }
+    }
+
     /**
      * Show an error because the user has entered an invalid recipient.
      * @param message
      */
-    public void showRecipientErrorDialog(String message) {
-        // Only 1 invalid recipients error dialog should be allowed up at a
-        // time.
-        if (mRecipientErrorDialog != null) {
-            mRecipientErrorDialog.dismiss();
-        }
-        mRecipientErrorDialog = new AlertDialog.Builder(this).setMessage(message).setTitle(
-                R.string.recipient_error_dialog_title)
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setPositiveButton(
-                        R.string.ok, new Dialog.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int which) {
-                                // after the user dismisses the recipient error
-                                // dialog we want to make sure to refocus the
-                                // recipient to field so they can fix the issue
-                                // easily
-                                if (mTo != null) {
-                                    mTo.requestFocus();
-                                }
-                                mRecipientErrorDialog = null;
-                            }
-                        }).show();
+    private void showRecipientErrorDialog(final String message) {
+        final DialogFragment frag = RecipientErrorDialogFragment.newInstance(message);
+        frag.show(getFragmentManager(), "recipient error");
     }
 
     /**
@@ -2347,7 +2355,6 @@
     }
 
     /**
-     * @param body
      * @param save
      * @param showToast
      * @return Whether the send or save succeeded.
@@ -2363,7 +2370,6 @@
         }
 
         final String[] to, cc, bcc;
-        final Editable body = mBodyView.getEditableText();
         if (orientationChanged) {
             to = cc = bcc = new String[0];
         } else {
@@ -2394,18 +2400,11 @@
             return false;
         }
 
-        DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                sendOrSave(mBodyView.getEditableText(), save, showToast);
-            }
-        };
-
         // Show a warning before sending only if there are no attachments.
         if (!save) {
             if (mAttachmentsView.getAttachments().isEmpty() && showEmptyTextWarnings()) {
                 boolean warnAboutEmptySubject = isSubjectEmpty();
-                boolean emptyBody = TextUtils.getTrimmedLength(body) == 0;
+                boolean emptyBody = TextUtils.getTrimmedLength(mBodyView.getEditableText()) == 0;
 
                 // A warning about an empty body may not be warranted when
                 // forwarding mails, since a common use case is to forward
@@ -2416,23 +2415,25 @@
                 // assume that they accept sending the message. If they do not,
                 // the dialog listener is required to enable sending again.
                 if (warnAboutEmptySubject) {
-                    showSendConfirmDialog(R.string.confirm_send_message_with_no_subject, listener);
+                    showSendConfirmDialog(R.string.confirm_send_message_with_no_subject, save,
+                            showToast);
                     return true;
                 }
 
                 if (warnAboutEmptyBody) {
-                    showSendConfirmDialog(R.string.confirm_send_message_with_no_body, listener);
+                    showSendConfirmDialog(R.string.confirm_send_message_with_no_body, save,
+                            showToast);
                     return true;
                 }
             }
             // Ask for confirmation to send (if always required)
             if (showSendConfirmation()) {
-                showSendConfirmDialog(R.string.confirm_send_message, listener);
+                showSendConfirmDialog(R.string.confirm_send_message, save, showToast);
                 return true;
             }
         }
 
-        sendOrSave(body, save, showToast);
+        sendOrSave(save, showToast);
         return true;
     }
 
@@ -2455,17 +2456,48 @@
         return mCachedSettings != null ? mCachedSettings.confirmSend : false;
     }
 
-    private void showSendConfirmDialog(int messageId, DialogInterface.OnClickListener listener) {
-        if (mSendConfirmDialog != null) {
-            mSendConfirmDialog.dismiss();
-            mSendConfirmDialog = null;
+    public static class SendConfirmDialogFragment extends DialogFragment {
+        public static SendConfirmDialogFragment newInstance(final int messageId,
+                final boolean save, final boolean showToast) {
+            final SendConfirmDialogFragment frag = new SendConfirmDialogFragment();
+            final Bundle args = new Bundle(3);
+            args.putInt("messageId", messageId);
+            args.putBoolean("save", save);
+            args.putBoolean("showToast", showToast);
+            frag.setArguments(args);
+            return frag;
         }
-        mSendConfirmDialog = new AlertDialog.Builder(this).setMessage(messageId)
-                .setTitle(R.string.confirm_send_title)
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setPositiveButton(R.string.send, listener)
-                .setNegativeButton(R.string.cancel, this)
-                .show();
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final int messageId = getArguments().getInt("messageId");
+            final boolean save = getArguments().getBoolean("save");
+            final boolean showToast = getArguments().getBoolean("showToast");
+
+            return new AlertDialog.Builder(getActivity())
+                    .setMessage(messageId)
+                    .setTitle(R.string.confirm_send_title)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setPositiveButton(R.string.send,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    ((ComposeActivity)getActivity()).finishSendConfirmDialog(save,
+                                            showToast);
+                                }
+                            })
+                    .create();
+        }
+    }
+
+    private void finishSendConfirmDialog(final boolean save, final boolean showToast) {
+        sendOrSave(save, showToast);
+    }
+
+    private void showSendConfirmDialog(final int messageId, final boolean save,
+            final boolean showToast) {
+        final DialogFragment frag = SendConfirmDialogFragment.newInstance(messageId, save,
+                showToast);
+        frag.show(getFragmentManager(), "send confirm");
     }
 
     /**
@@ -2587,13 +2619,15 @@
         return draftType;
     }
 
-    private void sendOrSave(final Spanned body, final boolean save, final boolean showToast) {
+    private void sendOrSave(final boolean save, final boolean showToast) {
         // Check if user is a monkey. Monkeys can compose and hit send
         // button but are not allowed to send anything off the device.
         if (ActivityManager.isUserAMonkey()) {
             return;
         }
 
+        final Spanned body = mBodyView.getEditableText();
+
         SendOrSaveCallback callback = new SendOrSaveCallback() {
             // FIXME: unused
             private int mRestoredRequestId;
@@ -2932,46 +2966,33 @@
         }
     }
 
-    public void enableSend(boolean enabled) {
-        if (mSend != null) {
-            mSend.setEnabled(enabled);
+    public static class DiscardConfirmDialogFragment extends DialogFragment {
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            return new AlertDialog.Builder(getActivity())
+                    .setMessage(R.string.confirm_discard_text)
+                    .setPositiveButton(R.string.discard,
+                            new DialogInterface.OnClickListener() {
+                                @Override
+                                public void onClick(DialogInterface dialog, int which) {
+                                    ((ComposeActivity)getActivity()).doDiscardWithoutConfirmation();
+                                }
+                            })
+                    .create();
         }
     }
 
-    /**
-     * Handles button clicks from any error dialogs dealing with sending
-     * a message.
-     */
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        switch (which) {
-            case DialogInterface.BUTTON_POSITIVE: {
-                doDiscardWithoutConfirmation(true /* show toast */ );
-                break;
-            }
-            case DialogInterface.BUTTON_NEGATIVE: {
-                // If the user cancels the send, re-enable the send button.
-                enableSend(true);
-                break;
-            }
-        }
-
-    }
-
     private void doDiscard() {
-        new AlertDialog.Builder(this).setMessage(R.string.confirm_discard_text)
-                .setPositiveButton(R.string.ok, this)
-                .setNegativeButton(R.string.cancel, null)
-                .create().show();
+        final DialogFragment frag = new DiscardConfirmDialogFragment();
+        frag.show(getFragmentManager(), "discard confirm");
     }
     /**
      * Effectively discard the current message.
      *
      * This method is either invoked from the menu or from the dialog
      * once the user has confirmed that they want to discard the message.
-     * @param showToast show "Message discarded" toast if true
      */
-    private void doDiscardWithoutConfirmation(boolean showToast) {
+    private void doDiscardWithoutConfirmation() {
         synchronized (mDraftLock) {
             if (mDraftId != UIProvider.INVALID_MESSAGE_ID) {
                 ContentValues values = new ContentValues();
@@ -2989,10 +3010,8 @@
             }
         }
 
-        if (showToast) {
-            // Display a toast to let the user know
-            Toast.makeText(this, R.string.message_discarded, Toast.LENGTH_SHORT).show();
-        }
+        // Display a toast to let the user know
+        Toast.makeText(this, R.string.message_discarded, Toast.LENGTH_SHORT).show();
 
         // This prevents the draft from being saved in onPause().
         discardChanges();
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 7a03ee3..ea6bae0 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -831,7 +831,7 @@
         final int mode = mViewMode.getMode();
         mDrawerToggle.setDrawerIndicatorEnabled(
                 getShouldShowDrawerIndicator(mode, isTopLevel));
-        mDrawerContainer.setDrawerLockMode(getShouldAllowDrawerPull(mode, isTopLevel)
+        mDrawerContainer.setDrawerLockMode(getShouldAllowDrawerPull(mode)
                 ? DrawerLayout.LOCK_MODE_UNLOCKED : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
 
         mDrawerContainer.closeDrawers();
@@ -2103,7 +2103,7 @@
             final boolean isTopLevel = (mFolder == null) || (mFolder.parent == Uri.EMPTY);
             mDrawerToggle.setDrawerIndicatorEnabled(
                     getShouldShowDrawerIndicator(newMode, isTopLevel));
-            mDrawerContainer.setDrawerLockMode(getShouldAllowDrawerPull(newMode, isTopLevel)
+            mDrawerContainer.setDrawerLockMode(getShouldAllowDrawerPull(newMode)
                     ? DrawerLayout.LOCK_MODE_UNLOCKED : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
             closeDrawerIfOpen();
         }
@@ -2127,14 +2127,12 @@
     /**
      * Returns true if the left-screen swipe action (or Home icon tap) should pull a drawer out.
      * @param viewMode the current view mode.
-     * @param isTopLevel true if the current folder is not a child
      * @return whether the drawer can be opened using a swipe action or action bar tap.
      */
-    private static boolean getShouldAllowDrawerPull(final int viewMode, final boolean isTopLevel) {
+    private static boolean getShouldAllowDrawerPull(final int viewMode) {
         // if search list/conv mode, disable drawer pull
         // allow drawer pull everywhere except conversation mode where the list is hidden
-        return !ViewMode.isSearchMode(viewMode) && !(ViewMode.isConversationMode(viewMode))
-                && isTopLevel;
+        return !ViewMode.isSearchMode(viewMode) && !(ViewMode.isConversationMode(viewMode));
 
         // TODO(ath): get this to work to allow drawer pull in 2-pane conv mode.
     /* && !isConversationListVisible() */
@@ -4201,8 +4199,7 @@
 
     @Override
     public boolean isDrawerPullEnabled() {
-        final boolean notChild = (mFolder == null || mFolder.parent == Uri.EMPTY);
-        return getShouldAllowDrawerPull(mViewMode.getMode(), notChild);
+        return getShouldAllowDrawerPull(mViewMode.getMode());
     }
 
     @Override
diff --git a/src/com/android/mail/ui/ButteryProgressBar.java b/src/com/android/mail/ui/ButteryProgressBar.java
index e042141..86f5208 100644
--- a/src/com/android/mail/ui/ButteryProgressBar.java
+++ b/src/com/android/mail/ui/ButteryProgressBar.java
@@ -32,11 +32,32 @@
 
     private final Paint mPaint = new Paint();
 
-    final int mBarColor;
-    final int mSolidBarHeight;
-    final int mSolidBarDetentWidth;
+    private final int mBarColor;
+    private final int mSolidBarHeight;
+    private final int mSolidBarDetentWidth;
 
-    private static final int SEGMENT_COUNT = 3;
+    private final float mDensity;
+
+    private int mSegmentCount;
+
+    /**
+     * The baseline width that the other constants below are optimized for.
+     */
+    private static final int BASE_WIDTH_DP = 300;
+    /**
+     * A reasonable animation duration for the given width above. It will be weakly scaled up and
+     * down for wider and narrower widths, respectively-- the goal is to provide a relatively
+     * constant detent velocity.
+     */
+    private static final int BASE_DURATION_MS = 500;
+    /**
+     * A reasonable number of detents for the given width above. It will be weakly scaled up and
+     * down for wider and narrower widths, respectively.
+     */
+    private static final int BASE_SEGMENT_COUNT = 5;
+
+    private static final int DEFAULT_BAR_HEIGHT_DP = 4;
+    private static final int DEFAULT_DETENT_WIDTH_DP = 3;
 
     public ButteryProgressBar(Context c) {
         this(c, null);
@@ -45,20 +66,24 @@
     public ButteryProgressBar(Context c, AttributeSet attrs) {
         super(c, attrs);
 
+        mDensity = c.getResources().getDisplayMetrics().density;
+
         final TypedArray ta = c.obtainStyledAttributes(attrs, R.styleable.ButteryProgressBar);
         try {
-            mBarColor = ta.getColor(R.styleable.ButteryProgressBar_barColor, 0);
+            mBarColor = ta.getColor(R.styleable.ButteryProgressBar_barColor,
+                    c.getResources().getColor(android.R.color.holo_blue_light));
             mSolidBarHeight = ta.getDimensionPixelSize(
-                    R.styleable.ButteryProgressBar_barHeight, 0);
+                    R.styleable.ButteryProgressBar_barHeight,
+                    Math.round(DEFAULT_BAR_HEIGHT_DP * mDensity));
             mSolidBarDetentWidth = ta.getDimensionPixelSize(
-                    R.styleable.ButteryProgressBar_detentWidth, 0);
+                    R.styleable.ButteryProgressBar_detentWidth,
+                    Math.round(DEFAULT_DETENT_WIDTH_DP * mDensity));
         } finally {
             ta.recycle();
         }
 
         mAnimator = new ValueAnimator();
         mAnimator.setFloatValues(1.0f, 2.0f);
-        mAnimator.setDuration(300);
         mAnimator.setRepeatCount(ValueAnimator.INFINITE);
         mAnimator.setInterpolator(new ExponentialInterpolator());
         mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -79,7 +104,16 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         if (changed) {
-            mShadow.setBounds(0, mSolidBarHeight, getWidth(), getHeight() - mSolidBarHeight);
+            final int w = getWidth();
+
+            mShadow.setBounds(0, mSolidBarHeight, w, getHeight() - mSolidBarHeight);
+
+            final float widthMultiplier = w / mDensity / BASE_WIDTH_DP;
+            // simple scaling by width is too aggressive, so dampen it first
+            final float durationMult = 0.3f * (widthMultiplier - 1) + 1;
+            final float segmentMult = 0.1f * (widthMultiplier - 1) + 1;
+            mAnimator.setDuration((int) (BASE_DURATION_MS * durationMult));
+            mSegmentCount = (int) (BASE_SEGMENT_COUNT * segmentMult);
         }
     }
 
@@ -93,17 +127,20 @@
 
         final float val = (Float) mAnimator.getAnimatedValue();
 
-        final int totalW = getWidth();
-        int w = totalW;
-        float l = val * w;
+        final int w = getWidth();
+        // Because the left-most segment doesn't start all the way on the left, and because it moves
+        // towards the right as it animates, we need to offset all drawing towards the left. This
+        // ensures that the left-most detent starts at the left origin, and that the left portion
+        // is never blank as the animation progresses towards the right.
+        final int offset = w >> mSegmentCount - 1;
         // segments are spaced at half-width, quarter, eighth (powers-of-two). to maintain a smooth
         // transition between segments, we used a power-of-two interpolator.
-        for (int i = 0; i < SEGMENT_COUNT; i++) {
-            w = totalW >> (i + 1);
-            l = val * w;
-            canvas.drawRect(l + mSolidBarDetentWidth, 0, l * 2, mSolidBarHeight, mPaint);
+        for (int i = 0; i < mSegmentCount; i++) {
+            final float l = val * (w >> (i + 1));
+            final float r = (i == 0) ? w + offset : l * 2;
+            canvas.drawRect(l + mSolidBarDetentWidth - offset, 0, r - offset, mSolidBarHeight,
+                    mPaint);
         }
-        canvas.drawRect(0, 0, l, mSolidBarHeight, mPaint);
     }
 
     @Override