am eacd5793: am bf268f78: am 31c1e2c5: am ccd40b16: Merge "Display sync errors using snackbar and not as a TL footer" into ub-gmail-ur14-dev

* commit 'eacd57935fecb7184a0171704bfbe63d4d87b694':
  Display sync errors using snackbar and not as a TL footer
diff --git a/res/layout/conversation_list_footer_view.xml b/res/layout/conversation_list_footer_view.xml
index 2238e13..e5d0fbd 100644
--- a/res/layout/conversation_list_footer_view.xml
+++ b/res/layout/conversation_list_footer_view.xml
@@ -24,40 +24,6 @@
     android:layout_height="wrap_content"
     android:background="@drawable/conversation_item_background">
 
-    <LinearLayout android:id="@+id/network_error"
-        android:layout_width="match_parent"
-        android:layout_height="?android:attr/listPreferredItemHeight"
-        android:padding="5dip"
-        android:visibility="gone"
-        android:gravity="center_vertical">
-
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_alert_grey" />
-
-        <TextView android:id="@+id/error_text"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:textAppearance="?android:attr/textAppearanceLargeInverse"
-            android:layout_marginBottom="1dip"
-            android:paddingLeft="5dip"
-            android:textColor="@android:color/black"
-            android:text="@string/network_error"/>
-
-        <Button android:id="@+id/error_action_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            style="?android:attr/buttonStyleSmall"
-            android:textColor="@android:color/black"
-            android:paddingTop="15dip"
-            android:paddingBottom="15dip"
-            android:paddingLeft="20dip"
-            android:paddingRight="20dip"/>
-
-    </LinearLayout>
-
     <LinearLayout android:id="@+id/loading"
         android:layout_width="match_parent"
         android:layout_height="?android:attr/listPreferredItemHeight"
@@ -65,28 +31,29 @@
         android:visibility="gone">
 
         <ProgressBar
-            style="?android:attr/progressBarStyle"
             android:indeterminate="true"
             android:layout_width="32dp"
-            android:layout_height="32dp" />
+            android:layout_height="32dp"
+            style="?android:attr/progressBarStyle" />
 
     </LinearLayout>
-    <LinearLayout android:id="@+id/load_more"
+    <LinearLayout
+        android:id="@+id/load_more"
         android:layout_width="match_parent"
-        android:layout_height="?android:attr/listPreferredItemHeight"
-        android:gravity="center"
-        android:visibility="gone"
+        android:layout_height="wrap_content"
+        android:background="?android:attr/selectableItemBackground"
         android:clickable="true"
-        android:background="?android:attr/selectableItemBackground">
+        android:visibility="gone">
 
         <TextView
+            style="@style/ConversationListFooterLoadMoreStyle"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceLargeInverse"
-            android:layout_marginBottom="1dip"
-            android:paddingLeft="5dip"
-            android:textColor="@android:color/black"
-            android:text="@string/load_more"/>
+            android:layout_height="?android:attr/listPreferredItemHeight"
+            android:gravity="center"
+            android:text="@string/load_more"
+            android:textAllCaps="true"
+            android:textColor="@color/conversation_view_footer_load_more_text_color"
+            android:textSize="16sp" />
 
     </LinearLayout>
 </com.android.mail.browse.ConversationListFooterView>
diff --git a/res/values-ldrtl/styles-ldrtl.xml b/res/values-ldrtl/styles-ldrtl.xml
index f5088ae..1dfe03c 100644
--- a/res/values-ldrtl/styles-ldrtl.xml
+++ b/res/values-ldrtl/styles-ldrtl.xml
@@ -288,6 +288,10 @@
     <style name="ConversationListSpaciousStarStyle">
         <item name="android:layout_marginEnd">@dimen/conv_list_spacious_star_padding_end</item>
     </style>
+
+    <style name="ConversationListFooterLoadMoreStyle">
+        <item name="android:paddingStart">@dimen/conv_list_footer_load_more_padding</item>
+    </style>
     <!-- END Conversation list styles -->
 
     <style name="SpinnerAccountNameStyle" parent="ComposeFromTextViewStyle">
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a80cbf6..c7a66f5 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -74,6 +74,7 @@
     <color name="conversation_view_text_color_dark">@color/text_color_black</color>
     <color name="conversation_view_text_color_link_blue">@color/text_color_blue</color>
     <color name="conversation_view_footer_text_color">#a7a7a7</color>
+    <color name="conversation_view_footer_load_more_text_color">@color/accent_blue</color>
 
     <!-- Widget colors -->
     <color name="widget_header_bg_color">@color/primary_color</color>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index c6ad105..4a720c0 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -188,6 +188,7 @@
     <dimen name="conv_list_spacious_padding_end">16dip</dimen>
     <dimen name="conv_list_spacious_contact_image_padding_end">16dip</dimen>
     <dimen name="conv_list_spacious_star_padding_end">-8dip</dimen>
+    <dimen name="conv_list_footer_load_more_padding">72dp</dimen>
 
     <dimen name="badge_padding_extra_width">6dip</dimen>
     <dimen name="badge_rounded_corner_radius">2dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 76d3676..26413b9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -602,8 +602,6 @@
     <!-- Description of the clear icon (clears the current input text in the search bar) [CHAR LIMIT=100] -->
     <string name="search_clear_desc">Clear search text</string>
 
-    <!-- Shown in conversation list footer when application cannot make a connection [CHAR LIMIT=20]-->
-    <string name="network_error">No connection</string>
     <!-- Button at bottom of conversation list screen if last attempt to load conversations failed [CHAR LIMIT=20]-->
     <string name="retry">Retry</string>
     <!-- Button at bottom of conversation list screen if the folder for which contents are being shown supports loading more on demand [CHAR LIMIT=20]-->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 39da512..35ac5a5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -850,6 +850,10 @@
         <item name="android:layout_marginRight">@dimen/conv_list_spacious_star_padding_end</item>
     </style>
 
+    <style name="ConversationListFooterLoadMoreStyle">
+        <item name="android:paddingLeft">@dimen/conv_list_footer_load_more_padding</item>
+    </style>
+
     <style name="ConversationListDividerStyle">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">@dimen/divider_height</item>
diff --git a/src/com/android/mail/browse/ConversationListFooterView.java b/src/com/android/mail/browse/ConversationListFooterView.java
index c040640..a7e8fdd 100644
--- a/src/com/android/mail/browse/ConversationListFooterView.java
+++ b/src/com/android/mail/browse/ConversationListFooterView.java
@@ -22,30 +22,21 @@
 import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.Button;
 import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import com.android.mail.R;
 import com.android.mail.providers.Folder;
 import com.android.mail.providers.UIProvider;
-import com.android.mail.utils.Utils;
 
 public final class ConversationListFooterView extends LinearLayout implements View.OnClickListener {
 
     public interface FooterViewClickListener {
-        void onFooterViewErrorActionClick(Folder folder, int errorStatus);
         void onFooterViewLoadMoreClick(Folder folder);
     }
 
     private View mLoading;
-    private View mNetworkError;
     private View mLoadMore;
-    private Button mErrorActionButton;
-    private TextView mErrorText;
-    private Folder mFolder;
     private Uri mLoadMoreUri;
-    private int mErrorStatus;
     private FooterViewClickListener mClickListener;
 
     public ConversationListFooterView(Context context, AttributeSet attrs) {
@@ -57,12 +48,8 @@
         super.onFinishInflate();
 
         mLoading = findViewById(R.id.loading);
-        mNetworkError = findViewById(R.id.network_error);
         mLoadMore = findViewById(R.id.load_more);
         mLoadMore.setOnClickListener(this);
-        mErrorActionButton = (Button) findViewById(R.id.error_action_button);
-        mErrorActionButton.setOnClickListener(this);
-        mErrorText = (TextView)findViewById(R.id.error_text);
     }
 
     public void setClickListener(FooterViewClickListener listener) {
@@ -73,17 +60,13 @@
     public void onClick(View v) {
         final int id = v.getId();
         final Folder f = (Folder) v.getTag();
-        if (id == R.id.error_action_button) {
-            mClickListener.onFooterViewErrorActionClick(f, mErrorStatus);
-        } else if (id == R.id.load_more) {
+        if (id == R.id.load_more) {
             mClickListener.onFooterViewLoadMoreClick(f);
         }
     }
 
     public void setFolder(Folder folder) {
-        mFolder = folder;
-        mErrorActionButton.setTag(mFolder);
-        mLoadMore.setTag(mFolder);
+        mLoadMore.setTag(folder);
         mLoadMoreUri = folder.loadMoreUri;
     }
 
@@ -93,23 +76,18 @@
     public boolean updateStatus(final ConversationCursor cursor) {
         if (cursor == null) {
             mLoading.setVisibility(View.GONE);
-            mNetworkError.setVisibility(View.GONE);
             mLoadMore.setVisibility(View.GONE);
             return false;
         }
         boolean showFooter = true;
         final Bundle extras = cursor.getExtras();
         final int cursorStatus = extras.getInt(UIProvider.CursorExtraKeys.EXTRA_STATUS);
-        mErrorStatus = extras.containsKey(UIProvider.CursorExtraKeys.EXTRA_ERROR) ?
-                extras.getInt(UIProvider.CursorExtraKeys.EXTRA_ERROR)
-                : UIProvider.LastSyncResult.SUCCESS;
         final int totalCount = extras.getInt(UIProvider.CursorExtraKeys.EXTRA_TOTAL_COUNT);
 
         if (UIProvider.CursorStatus.isWaitingForResults(cursorStatus)) {
             if (cursor.getCount() != 0) {
                 // When loading more, show the spinner in the footer.
                 mLoading.setVisibility(View.VISIBLE);
-                mNetworkError.setVisibility(View.GONE);
                 mLoadMore.setVisibility(View.GONE);
             } else {
                 // We're currently loading, but we have no messages at all. We don't need to show
@@ -117,51 +95,11 @@
                 // conversation list itself.
                 showFooter = false;
             }
-        } else if (mErrorStatus != UIProvider.LastSyncResult.SUCCESS) {
-            // We are in some error state, show the footer with an error message.
-            mNetworkError.setVisibility(View.VISIBLE);
-            mErrorText.setText(Utils.getSyncStatusText(getContext(), mErrorStatus));
-            mLoading.setVisibility(View.GONE);
-            mLoadMore.setVisibility(View.GONE);
-            // Only show the "Retry" button for I/O errors; it won't help for
-            // internal errors.
-            mErrorActionButton.setVisibility(
-                    mErrorStatus != UIProvider.LastSyncResult.SECURITY_ERROR ?
-                    View.VISIBLE : View.GONE);
-
-            final int actionTextResourceId;
-            switch (mErrorStatus) {
-                case UIProvider.LastSyncResult.CONNECTION_ERROR:
-                    actionTextResourceId = R.string.retry;
-                    break;
-                case UIProvider.LastSyncResult.SERVER_ERROR:
-                    actionTextResourceId = R.string.retry;
-                    break;
-                case UIProvider.LastSyncResult.AUTH_ERROR:
-                    actionTextResourceId = R.string.signin;
-                    break;
-                case UIProvider.LastSyncResult.SECURITY_ERROR:
-                    actionTextResourceId = R.string.retry;
-                    mNetworkError.setVisibility(View.GONE);
-                    break; // Currently we do nothing for security errors.
-                case UIProvider.LastSyncResult.STORAGE_ERROR:
-                    actionTextResourceId = R.string.info;
-                    break;
-                case UIProvider.LastSyncResult.INTERNAL_ERROR:
-                    actionTextResourceId = R.string.report;
-                    break;
-                default:
-                    actionTextResourceId = R.string.retry;
-                    mNetworkError.setVisibility(View.GONE);
-                    break;
-            }
-            mErrorActionButton.setText(actionTextResourceId);
 
         } else if (mLoadMoreUri != null && cursor.getCount() < totalCount) {
             // We know that there are more messages on the server than we have locally, so we
             // need to show the footer with the "load more" button.
             mLoading.setVisibility(View.GONE);
-            mNetworkError.setVisibility(View.GONE);
             mLoadMore.setVisibility(View.VISIBLE);
         } else {
             showFooter = false;
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index ff021f8..783e4f3 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -27,6 +27,7 @@
 import android.provider.OpenableColumns;
 import android.text.TextUtils;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
@@ -119,6 +120,35 @@
         }
     }
 
+    /**
+     * Combines the reason for the sync request (user vs. background sync) with the status of the
+     * request (success vs failure reason) into a single integer value.
+     *
+     * @param syncStatus {@link SyncStatus} value describing the reason for the sync
+     * @param lastSyncResult {@link LastSyncResult} value describing the result of the sync
+     * @return a single integer packed with the status and result values
+     */
+    @VisibleForTesting
+    public static int createSyncValue(int syncStatus, int lastSyncResult) {
+        return lastSyncResult | (syncStatus << 4);
+    }
+
+    /**
+     * @param lastSyncValue value containing the {@link SyncStatus} and {@link LastSyncResult}
+     * @return the {@link LastSyncResult} within the <code>lastSyncValue</code>
+     */
+    public static int getResultFromLastSyncResult(int lastSyncValue) {
+        return lastSyncValue & 0x0f;
+    }
+
+    /**
+     * @param lastSyncValue value containing the {@link SyncStatus} and {@link LastSyncResult}
+     * @return the {@link SyncStatus} within the <code>lastSyncValue</code>
+     */
+    public static int getStatusFromLastSyncResult(int lastSyncValue) {
+        return lastSyncValue >> 4;
+    }
+
     // The actual content provider should define its own authority
     public static final String AUTHORITY = "com.android.mail.providers";
 
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 6ce65dd..5b355f3 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -3916,19 +3916,19 @@
         final ActionClickedListener listener;
         final int actionTextResourceId;
         final int lastSyncResult = folder.lastSyncResult;
-        switch (lastSyncResult & 0x0f) {
+        switch (UIProvider.getResultFromLastSyncResult(lastSyncResult)) {
             case UIProvider.LastSyncResult.CONNECTION_ERROR:
-                // The sync request that caused this failure.
-                final int syncRequest = lastSyncResult >> 4;
+                // The sync status that caused this failure.
+                final int syncStatus = UIProvider.getStatusFromLastSyncResult(lastSyncResult);
                 // Show: User explicitly pressed the refresh button and there is no connection
                 // Show: The first time the user enters the app and there is no connection
                 //       TODO(viki): Implement this.
                 // Reference: http://b/7202801
-                final boolean showToast = (syncRequest & UIProvider.SyncStatus.USER_REFRESH) != 0;
+                final boolean showToast = (syncStatus & UIProvider.SyncStatus.USER_REFRESH) != 0;
                 // Don't show: Already in the app; user switches to a synced label
                 // Don't show: In a live label and a background sync fails
                 final boolean avoidToast = !showToast && (folder.syncWindow > 0
-                        || (syncRequest & UIProvider.SyncStatus.BACKGROUND_SYNC) != 0);
+                        || (syncStatus & UIProvider.SyncStatus.BACKGROUND_SYNC) != 0);
                 if (avoidToast) {
                     return;
                 }
@@ -4010,35 +4010,6 @@
     }
 
     @Override
-    public void onFooterViewErrorActionClick(Folder folder, int errorStatus) {
-        Uri uri = null;
-        switch (errorStatus) {
-            case UIProvider.LastSyncResult.CONNECTION_ERROR:
-                if (folder != null && folder.refreshUri != null) {
-                    uri = folder.refreshUri;
-                }
-                break;
-            case UIProvider.LastSyncResult.AUTH_ERROR:
-                promptUserForAuthentication(mAccount);
-                return;
-            case UIProvider.LastSyncResult.SECURITY_ERROR:
-                return; // Currently we do nothing for security errors.
-            case UIProvider.LastSyncResult.STORAGE_ERROR:
-                showStorageErrorDialog();
-                return;
-            case UIProvider.LastSyncResult.INTERNAL_ERROR:
-                Utils.sendFeedback(mActivity, mAccount, true /* reportingProblem */);
-                return;
-            default:
-                return;
-        }
-
-        if (uri != null) {
-            startAsyncRefreshTask(uri);
-        }
-    }
-
-    @Override
     public void onFooterViewLoadMoreClick(Folder folder) {
         if (folder != null && folder.loadMoreUri != null) {
             startAsyncRefreshTask(folder.loadMoreUri);
diff --git a/src/com/android/mail/ui/FolderSelectionActivity.java b/src/com/android/mail/ui/FolderSelectionActivity.java
index bd19fc8..53e3539 100644
--- a/src/com/android/mail/ui/FolderSelectionActivity.java
+++ b/src/com/android/mail/ui/FolderSelectionActivity.java
@@ -388,11 +388,6 @@
     }
 
     @Override
-    public void onFooterViewErrorActionClick(Folder folder, int errorStatus) {
-        // Unsupported
-    }
-
-    @Override
     public void onFooterViewLoadMoreClick(Folder folder) {
         // Unsupported
     }
diff --git a/src/com/android/mail/ui/MailActivity.java b/src/com/android/mail/ui/MailActivity.java
index 235841c..f0ad7b3 100644
--- a/src/com/android/mail/ui/MailActivity.java
+++ b/src/com/android/mail/ui/MailActivity.java
@@ -425,11 +425,6 @@
     }
 
     @Override
-    public void onFooterViewErrorActionClick(Folder folder, int errorStatus) {
-        mController.onFooterViewErrorActionClick(folder, errorStatus);
-    }
-
-    @Override
     public void onFooterViewLoadMoreClick(Folder folder) {
         mController.onFooterViewLoadMoreClick(folder);
     }
diff --git a/tests/src/com/android/mail/providers/UIProviderTest.java b/tests/src/com/android/mail/providers/UIProviderTest.java
new file mode 100644
index 0000000..20f3854
--- /dev/null
+++ b/tests/src/com/android/mail/providers/UIProviderTest.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2014, Google Inc.
+ *
+ * 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.mail.providers;
+
+import android.test.AndroidTestCase;
+
+public class UIProviderTest extends AndroidTestCase {
+
+    public void testReadAndWriteOfLastSyncResult() {
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.NO_SYNC,
+                UIProvider.LastSyncResult.STORAGE_ERROR);
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.NO_SYNC,
+                UIProvider.LastSyncResult.SECURITY_ERROR);
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.USER_REFRESH,
+                UIProvider.LastSyncResult.SUCCESS);
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.USER_REFRESH,
+                UIProvider.LastSyncResult.AUTH_ERROR);
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.BACKGROUND_SYNC,
+                UIProvider.LastSyncResult.SUCCESS);
+        packAndUnpackLastSyncResult(UIProvider.SyncStatus.BACKGROUND_SYNC,
+                UIProvider.LastSyncResult.CONNECTION_ERROR);
+    }
+
+    private void packAndUnpackLastSyncResult(int syncStatus, int lastSyncResult) {
+        final int value = UIProvider.createSyncValue(syncStatus, lastSyncResult);
+
+        assertEquals(syncStatus, UIProvider.getStatusFromLastSyncResult(value));
+        assertEquals(lastSyncResult, UIProvider.getResultFromLastSyncResult(value));
+    }
+}