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));
+ }
+}