Commit d117eb1c authored by ianwen's avatar ianwen Committed by Commit bot

Introduce Queue-Based Notification Snackbars

Notification snackbars are low-priority snackbars that are stored in a
queue, contrary to tranditional "action" snackbars that ought to be
shown immediately and are stored in a stack.

When a queue snackbar is showing, a stack snackbar can always kick in
and override the snackbar; however when a stack snackbar is showing, a
queue snackbar will wait till the stack is cleared.

Queue snackbars are not dismissed in batch; instead, they will be shown
one by one, in FIFO order.

BUG=579347

Review URL: https://codereview.chromium.org/1635753002

Cr-Commit-Position: refs/heads/master@{#371899}
parent 1f3c2431
...@@ -52,8 +52,9 @@ public class DownloadSnackbarController implements SnackbarManager.SnackbarContr ...@@ -52,8 +52,9 @@ public class DownloadSnackbarController implements SnackbarManager.SnackbarContr
public void onDownloadSucceeded( public void onDownloadSucceeded(
DownloadInfo downloadInfo, final long downloadId, boolean canBeResolved) { DownloadInfo downloadInfo, final long downloadId, boolean canBeResolved) {
if (getSnackbarManager() == null) return; if (getSnackbarManager() == null) return;
Snackbar snackbar = Snackbar.make(mContext.getString( Snackbar snackbar = Snackbar.make(
R.string.download_succeeded_message, downloadInfo.getFileName()), this); mContext.getString(R.string.download_succeeded_message, downloadInfo.getFileName()),
this, Snackbar.TYPE_NOTIFICATION);
// TODO(qinmin): Coalesce snackbars if multiple downloads finish at the same time. // TODO(qinmin): Coalesce snackbars if multiple downloads finish at the same time.
snackbar.setDuration(SNACKBAR_DURATION_IN_MILLISECONDS).setSingleLine(false); snackbar.setDuration(SNACKBAR_DURATION_IN_MILLISECONDS).setSingleLine(false);
Pair<DownloadInfo, Long> actionData = null; Pair<DownloadInfo, Long> actionData = null;
...@@ -75,7 +76,7 @@ public class DownloadSnackbarController implements SnackbarManager.SnackbarContr ...@@ -75,7 +76,7 @@ public class DownloadSnackbarController implements SnackbarManager.SnackbarContr
public void onDownloadFailed(String errorMessage, boolean showAllDownloads) { public void onDownloadFailed(String errorMessage, boolean showAllDownloads) {
if (getSnackbarManager() == null) return; if (getSnackbarManager() == null) return;
// TODO(qinmin): Coalesce snackbars if multiple downloads finish at the same time. // TODO(qinmin): Coalesce snackbars if multiple downloads finish at the same time.
Snackbar snackbar = Snackbar.make(errorMessage, this) Snackbar snackbar = Snackbar.make(errorMessage, this, Snackbar.TYPE_NOTIFICATION)
.setSingleLine(false) .setSingleLine(false)
.setDuration(SNACKBAR_DURATION_IN_MILLISECONDS); .setDuration(SNACKBAR_DURATION_IN_MILLISECONDS);
if (showAllDownloads) { if (showAllDownloads) {
......
...@@ -83,12 +83,13 @@ public class EnhancedBookmarkUndoController extends BookmarkModelObserver implem ...@@ -83,12 +83,13 @@ public class EnhancedBookmarkUndoController extends BookmarkModelObserver implem
if (!isUndoable) return; if (!isUndoable) return;
if (titles.length == 1) { if (titles.length == 1) {
mSnackbarManager.showSnackbar(Snackbar.make(titles[0], this) mSnackbarManager.showSnackbar(Snackbar.make(titles[0], this, Snackbar.TYPE_ACTION)
.setTemplateText(mContext.getString(R.string.undo_bar_delete_message)) .setTemplateText(mContext.getString(R.string.undo_bar_delete_message))
.setAction(mContext.getString(R.string.undo_bar_button_text), null)); .setAction(mContext.getString(R.string.undo_bar_button_text), null));
} else { } else {
mSnackbarManager.showSnackbar( mSnackbarManager.showSnackbar(
Snackbar.make(String.format(Locale.getDefault(), "%d", titles.length), this) Snackbar.make(String.format(Locale.getDefault(), "%d", titles.length), this,
Snackbar.TYPE_ACTION)
.setTemplateText(mContext.getString(R.string.undo_bar_multiple_delete_message)) .setTemplateText(mContext.getString(R.string.undo_bar_multiple_delete_message))
.setAction(mContext.getString(R.string.undo_bar_button_text), null)); .setAction(mContext.getString(R.string.undo_bar_button_text), null));
} }
......
...@@ -119,9 +119,9 @@ public class EnhancedBookmarkUtils { ...@@ -119,9 +119,9 @@ public class EnhancedBookmarkUtils {
bookmarkModel, activity, bookmarkId); bookmarkModel, activity, bookmarkId);
if (getLastUsedParent(activity) == null) { if (getLastUsedParent(activity) == null) {
snackbar = Snackbar.make(activity.getString(R.string.enhanced_bookmark_page_saved), snackbar = Snackbar.make(activity.getString(R.string.enhanced_bookmark_page_saved),
snackbarController); snackbarController, Snackbar.TYPE_ACTION);
} else { } else {
snackbar = Snackbar.make(folderName, snackbarController) snackbar = Snackbar.make(folderName, snackbarController, Snackbar.TYPE_ACTION)
.setTemplateText(activity.getString( .setTemplateText(activity.getString(
R.string.enhanced_bookmark_page_saved_folder)); R.string.enhanced_bookmark_page_saved_folder));
} }
...@@ -164,7 +164,9 @@ public class EnhancedBookmarkUtils { ...@@ -164,7 +164,9 @@ public class EnhancedBookmarkUtils {
snackbarController = createSnackbarControllerForEditButton( snackbarController = createSnackbarControllerForEditButton(
bookmarkModel, activity, bookmarkId); bookmarkModel, activity, bookmarkId);
} }
snackbar = Snackbar.make(activity.getString(messageId, suffix), snackbarController) snackbar = Snackbar
.make(activity.getString(messageId, suffix), snackbarController,
Snackbar.TYPE_ACTION)
.setAction(activity.getString(buttonId), null).setSingleLine(false); .setAction(activity.getString(buttonId), null).setSingleLine(false);
} }
......
...@@ -608,7 +608,7 @@ public class NewTabPage ...@@ -608,7 +608,7 @@ public class NewTabPage
} }
Context context = mNewTabPageView.getContext(); Context context = mNewTabPageView.getContext();
Snackbar snackbar = Snackbar.make(context.getString(R.string.most_visited_item_removed), Snackbar snackbar = Snackbar.make(context.getString(R.string.most_visited_item_removed),
mMostVisitedItemRemovedController) mMostVisitedItemRemovedController, Snackbar.TYPE_ACTION)
.setAction(context.getString(R.string.undo_bar_button_text), url); .setAction(context.getString(R.string.undo_bar_button_text), url);
mTab.getSnackbarManager().showSnackbar(snackbar); mTab.getSnackbarManager().showSnackbar(snackbar);
} }
......
...@@ -59,7 +59,7 @@ public class OfflinePageFreeUpSpaceDialog ...@@ -59,7 +59,7 @@ public class OfflinePageFreeUpSpaceDialog
public void onDismissNoAction(Object actionData) {} public void onDismissNoAction(Object actionData) {}
@Override @Override
public void onAction(Object actionData) {} public void onAction(Object actionData) {}
}); }, Snackbar.TYPE_ACTION);
} }
@Override @Override
......
...@@ -308,7 +308,8 @@ public class OfflinePageUtils { ...@@ -308,7 +308,8 @@ public class OfflinePageUtils {
} }
} }
}; };
Snackbar snackbar = Snackbar.make(context.getString(snackbarTextId), snackbarController) Snackbar snackbar = Snackbar
.make(context.getString(snackbarTextId), snackbarController, Snackbar.TYPE_ACTION)
.setAction(context.getString(actionTextId), buttonType); .setAction(context.getString(actionTextId), buttonType);
activity.getSnackbarManager().showSnackbar(snackbar); activity.getSnackbarManager().showSnackbar(snackbar);
} }
......
...@@ -83,7 +83,7 @@ public class GeolocationSnackbarController implements SnackbarController { ...@@ -83,7 +83,7 @@ public class GeolocationSnackbarController implements SnackbarController {
int durationMs = DeviceClassManager.isAccessibilityModeEnabled(view.getContext()) int durationMs = DeviceClassManager.isAccessibilityModeEnabled(view.getContext())
? ACCESSIBILITY_SNACKBAR_DURATION_MS : SNACKBAR_DURATION_MS; ? ACCESSIBILITY_SNACKBAR_DURATION_MS : SNACKBAR_DURATION_MS;
final GeolocationSnackbarController controller = new GeolocationSnackbarController(); final GeolocationSnackbarController controller = new GeolocationSnackbarController();
final Snackbar snackbar = Snackbar.make(message, controller) final Snackbar snackbar = Snackbar.make(message, controller, Snackbar.TYPE_ACTION)
.setAction(settings, view) .setAction(settings, view)
.setSingleLine(false) .setSingleLine(false)
.setDuration(durationMs); .setDuration(durationMs);
......
...@@ -39,20 +39,20 @@ public class DataUseSnackbarController implements SnackbarManager.SnackbarContro ...@@ -39,20 +39,20 @@ public class DataUseSnackbarController implements SnackbarManager.SnackbarContro
} }
public void showDataUseTrackingStartedBar() { public void showDataUseTrackingStartedBar() {
mSnackbarManager.showSnackbar(Snackbar.make( mSnackbarManager.showSnackbar(Snackbar
mContext.getString(R.string.data_use_tracking_started_snackbar_message), this) .make(mContext.getString(R.string.data_use_tracking_started_snackbar_message), this,
Snackbar.TYPE_NOTIFICATION)
.setAction(mContext.getString(R.string.data_use_tracking_snackbar_action), .setAction(mContext.getString(R.string.data_use_tracking_snackbar_action),
STARTED_SNACKBAR) STARTED_SNACKBAR));
.setForceDisplay());
DataUseTabUIManager.recordDataUseUIAction(DataUsageUIAction.STARTED_SNACKBAR_SHOWN); DataUseTabUIManager.recordDataUseUIAction(DataUsageUIAction.STARTED_SNACKBAR_SHOWN);
} }
public void showDataUseTrackingEndedBar() { public void showDataUseTrackingEndedBar() {
mSnackbarManager.showSnackbar(Snackbar.make( mSnackbarManager.showSnackbar(Snackbar
mContext.getString(R.string.data_use_tracking_ended_snackbar_message), this) .make(mContext.getString(R.string.data_use_tracking_ended_snackbar_message), this,
Snackbar.TYPE_NOTIFICATION)
.setAction(mContext.getString(R.string.data_use_tracking_snackbar_action), .setAction(mContext.getString(R.string.data_use_tracking_snackbar_action),
ENDED_SNACKBAR) ENDED_SNACKBAR));
.setForceDisplay());
DataUseTabUIManager.recordDataUseUIAction(DataUsageUIAction.ENDED_SNACKBAR_SHOWN); DataUseTabUIManager.recordDataUseUIAction(DataUsageUIAction.ENDED_SNACKBAR_SHOWN);
} }
......
...@@ -95,10 +95,9 @@ public class LoFiBarPopupController implements SnackbarManager.SnackbarControlle ...@@ -95,10 +95,9 @@ public class LoFiBarPopupController implements SnackbarManager.SnackbarControlle
String buttonText = mContext String buttonText = mContext
.getString(isPreview ? R.string.data_reduction_lo_fi_preview_snackbar_action .getString(isPreview ? R.string.data_reduction_lo_fi_preview_snackbar_action
: R.string.data_reduction_lo_fi_snackbar_action); : R.string.data_reduction_lo_fi_snackbar_action);
mSnackbarManager.showSnackbar(Snackbar.make(message, this) mSnackbarManager.showSnackbar(Snackbar.make(message, this, Snackbar.TYPE_NOTIFICATION)
.setAction(buttonText, tab.getId()) .setAction(buttonText, tab.getId())
.setDuration(DEFAULT_LO_FI_SNACKBAR_SHOW_DURATION_MS) .setDuration(DEFAULT_LO_FI_SNACKBAR_SHOW_DURATION_MS));
.setForceDisplay());
DataReductionProxySettings.getInstance().incrementLoFiSnackbarShown(); DataReductionProxySettings.getInstance().incrementLoFiSnackbarShown();
DataReductionProxyUma.dataReductionProxyLoFiUIAction( DataReductionProxyUma.dataReductionProxyLoFiUIAction(
DataReductionProxyUma.ACTION_LOAD_IMAGES_SNACKBAR_SHOWN); DataReductionProxyUma.ACTION_LOAD_IMAGES_SNACKBAR_SHOWN);
......
...@@ -18,6 +18,18 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; ...@@ -18,6 +18,18 @@ import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
* .setAction("undo", actionData)); * .setAction("undo", actionData));
*/ */
public class Snackbar { public class Snackbar {
/**
* Snackbars that are created as an immediate response to user's action. These snackbars are
* managed in a stack and will be swiped away altogether after timeout.
*/
public static final int TYPE_ACTION = 0;
/**
* Snackbars that are for notification purposes. These snackbars are stored in a queue and thus
* are of lower priority, compared to {@link #TYPE_ACTION}. Notification snackbars are dismissed
* one by one.
*/
public static final int TYPE_NOTIFICATION = 1;
private SnackbarController mController; private SnackbarController mController;
private CharSequence mText; private CharSequence mText;
...@@ -28,20 +40,23 @@ public class Snackbar { ...@@ -28,20 +40,23 @@ public class Snackbar {
private boolean mSingleLine = true; private boolean mSingleLine = true;
private int mDurationMs; private int mDurationMs;
private Bitmap mProfileImage; private Bitmap mProfileImage;
private boolean mForceDisplay = false; private int mType;
// Prevent instantiation. // Prevent instantiation.
private Snackbar() {} private Snackbar() {}
/** /**
* Creates and returns a snackbar to display the given text. * Creates and returns a snackbar to display the given text.
*
* @param text The text to show on the snackbar. * @param text The text to show on the snackbar.
* @param controller The SnackbarController to receive callbacks about the snackbar's state. * @param controller The SnackbarController to receive callbacks about the snackbar's state.
* @param type Type of the snackbar. Either {@link #TYPE_ACTION} or {@link #TYPE_NOTIFICATION}.
*/ */
public static Snackbar make(CharSequence text, SnackbarController controller) { public static Snackbar make(CharSequence text, SnackbarController controller, int type) {
Snackbar s = new Snackbar(); Snackbar s = new Snackbar();
s.mText = text; s.mText = text;
s.mController = controller; s.mController = controller;
s.mType = type;
return s; return s;
} }
...@@ -102,27 +117,6 @@ public class Snackbar { ...@@ -102,27 +117,6 @@ public class Snackbar {
return this; return this;
} }
/**
* Forces this snackbar to be shown when {@link #dismissAllSnackbars(SnackbarManager)} is called
* from a timeout. If {@link #showSnackbar(SnackbarManager)} is called while this snackbar is
* showing, the new snackbar will be added to the stack and this snackbar will not be
* overwritten.
*/
public Snackbar setForceDisplay() {
mForceDisplay = true;
return this;
}
/**
* Returns true if this snackbar should still be shown when @link
* #dismissAllSnackbars(SnackbarManager)} is called from a timeout. If
* {@link #showSnackbar(SnackbarManager)} is called while this snackbar is showing, the new
* snackbar will be added to the stack and this snackbar will not be overwritten.
*/
public boolean getForceDisplay() {
return mForceDisplay;
}
SnackbarController getController() { SnackbarController getController() {
return mController; return mController;
} }
...@@ -164,4 +158,11 @@ public class Snackbar { ...@@ -164,4 +158,11 @@ public class Snackbar {
Bitmap getProfileImage() { Bitmap getProfileImage() {
return mProfileImage; return mProfileImage;
} }
/**
* @return Whether the snackbar is of {@link #TYPE_ACTION}.
*/
boolean isTypeAction() {
return mType == TYPE_ACTION;
}
} }
...@@ -27,6 +27,7 @@ class SnackbarPopupWindow extends PopupWindow { ...@@ -27,6 +27,7 @@ class SnackbarPopupWindow extends PopupWindow {
private final TextView mActionButtonView; private final TextView mActionButtonView;
private final ImageView mProfileImageView; private final ImageView mProfileImageView;
private final int mAnimationDuration; private final int mAnimationDuration;
private Snackbar mSnackbar;
/** /**
* Creates an instance of the {@link SnackbarPopupWindow}. * Creates an instance of the {@link SnackbarPopupWindow}.
...@@ -63,12 +64,18 @@ class SnackbarPopupWindow extends PopupWindow { ...@@ -63,12 +64,18 @@ class SnackbarPopupWindow extends PopupWindow {
} }
/** /**
* Updates the view to display data from the given snackbar. * Updates the view to display data from the given snackbar. No-op if the popup is already
* * showing the given snackbar.
* @param snackbar The snackbar to display * @param snackbar The snackbar to display
* @param animate Whether or not to animate the text in or set it immediately * @return Whether update has actually been executed.
*/ */
void update(Snackbar snackbar, boolean animate) { boolean update(Snackbar snackbar) {
return update(snackbar, true);
}
private boolean update(Snackbar snackbar, boolean animate) {
if (mSnackbar == snackbar) return false;
mSnackbar = snackbar;
mMessageView.setMaxLines(snackbar.getSingleLine() ? 1 : Integer.MAX_VALUE); mMessageView.setMaxLines(snackbar.getSingleLine() ? 1 : Integer.MAX_VALUE);
mMessageView.setTemplate(snackbar.getTemplateText()); mMessageView.setTemplate(snackbar.getTemplateText());
setViewText(mMessageView, snackbar.getText(), animate); setViewText(mMessageView, snackbar.getText(), animate);
...@@ -104,6 +111,7 @@ class SnackbarPopupWindow extends PopupWindow { ...@@ -104,6 +111,7 @@ class SnackbarPopupWindow extends PopupWindow {
} else { } else {
((ViewGroup) view).removeView(mProfileImageView); ((ViewGroup) view).removeView(mProfileImageView);
} }
return true;
} }
private void setViewText(TextView view, CharSequence text, boolean animate) { private void setViewText(TextView view, CharSequence text, boolean animate) {
......
...@@ -38,7 +38,7 @@ public class AutoSigninSnackbarController ...@@ -38,7 +38,7 @@ public class AutoSigninSnackbarController
if (snackbarManager == null) return; if (snackbarManager == null) return;
AutoSigninSnackbarController snackbarController = AutoSigninSnackbarController snackbarController =
new AutoSigninSnackbarController(snackbarManager, tab); new AutoSigninSnackbarController(snackbarManager, tab);
Snackbar snackbar = Snackbar.make(text, snackbarController); Snackbar snackbar = Snackbar.make(text, snackbarController, Snackbar.TYPE_NOTIFICATION);
Resources resources = tab.getWindowAndroid().getActivity().get().getResources(); Resources resources = tab.getWindowAndroid().getActivity().get().getResources();
int backgroundColor = ApiCompatibilityUtils.getColor(resources, int backgroundColor = ApiCompatibilityUtils.getColor(resources,
R.color.smart_lock_auto_signin_snackbar_background_color); R.color.smart_lock_auto_signin_snackbar_background_color);
......
...@@ -127,7 +127,7 @@ public class UndoBarPopupController implements SnackbarManager.SnackbarControlle ...@@ -127,7 +127,7 @@ public class UndoBarPopupController implements SnackbarManager.SnackbarControlle
mSnackbarManager.isShowing() ? TAB_CLOSE_UNDO_TOAST_SHOWN_WARM mSnackbarManager.isShowing() ? TAB_CLOSE_UNDO_TOAST_SHOWN_WARM
: TAB_CLOSE_UNDO_TOAST_SHOWN_COLD, : TAB_CLOSE_UNDO_TOAST_SHOWN_COLD,
TAB_CLOSE_UNDO_TOAST_COUNT); TAB_CLOSE_UNDO_TOAST_COUNT);
mSnackbarManager.showSnackbar(Snackbar.make(content, this) mSnackbarManager.showSnackbar(Snackbar.make(content, this, Snackbar.TYPE_ACTION)
.setTemplateText(mContext.getString(R.string.undo_bar_close_message)) .setTemplateText(mContext.getString(R.string.undo_bar_close_message))
.setAction(mContext.getString(R.string.undo_bar_button_text), tabId)); .setAction(mContext.getString(R.string.undo_bar_button_text), tabId));
} }
...@@ -142,7 +142,7 @@ public class UndoBarPopupController implements SnackbarManager.SnackbarControlle ...@@ -142,7 +142,7 @@ public class UndoBarPopupController implements SnackbarManager.SnackbarControlle
*/ */
private void showUndoCloseAllBar(List<Integer> closedTabIds) { private void showUndoCloseAllBar(List<Integer> closedTabIds) {
String content = String.format(Locale.getDefault(), "%d", closedTabIds.size()); String content = String.format(Locale.getDefault(), "%d", closedTabIds.size());
mSnackbarManager.showSnackbar(Snackbar.make(content, this) mSnackbarManager.showSnackbar(Snackbar.make(content, this, Snackbar.TYPE_ACTION)
.setTemplateText(mContext.getString(R.string.undo_bar_close_all_message)) .setTemplateText(mContext.getString(R.string.undo_bar_close_all_message))
.setAction(mContext.getString(R.string.undo_bar_button_text), closedTabIds)); .setAction(mContext.getString(R.string.undo_bar_button_text), closedTabIds));
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.snackbar;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
/**
* Tests for {@link SnackbarManager}.
*/
public class SnackbarTest extends ChromeTabbedActivityTestBase {
SnackbarManager mManager;
SnackbarController mDefaultController = new SnackbarController() {
@Override
public void onDismissNoAction(Object actionData) {
}
@Override
public void onAction(Object actionData) {
}
};
@Override
public void startMainActivity() throws InterruptedException {
SnackbarManager.setDurationForTesting(1000);
startMainActivityOnBlankPage();
mManager = getActivity().getSnackbarManager();
}
@MediumTest
public void testStackQueueOrder() throws InterruptedException {
final Snackbar stackbar = Snackbar.make("stack", mDefaultController,
Snackbar.TYPE_ACTION);
final Snackbar queuebar = Snackbar.make("queue", mDefaultController,
Snackbar.TYPE_NOTIFICATION);
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mManager.showSnackbar(stackbar);
}
});
CriteriaHelper.pollForUIThreadCriteria(new Criteria("First snackbar not shown") {
@Override
public boolean isSatisfied() {
return mManager.isShowing() && mManager.getCurrentSnackbarForTesting() == stackbar;
}
});
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mManager.showSnackbar(queuebar);
assertTrue("Snackbar not showing", mManager.isShowing());
assertEquals("Snackbars on stack should not be cancled by snackbars on queue",
stackbar, mManager.getCurrentSnackbarForTesting());
}
});
CriteriaHelper.pollForUIThreadCriteria(new Criteria("Snackbar on queue not shown") {
@Override
public boolean isSatisfied() {
return mManager.isShowing() && mManager.getCurrentSnackbarForTesting() == queuebar;
}
});
CriteriaHelper.pollForUIThreadCriteria(new Criteria("Snackbar did not time out") {
@Override
public boolean isSatisfied() {
return !mManager.isShowing();
}
});
}
@SmallTest
public void testQueueStackOrder() throws InterruptedException {
final Snackbar stackbar = Snackbar.make("stack", mDefaultController,
Snackbar.TYPE_ACTION);
final Snackbar queuebar = Snackbar.make("queue", mDefaultController,
Snackbar.TYPE_NOTIFICATION);
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mManager.showSnackbar(queuebar);
}
});
CriteriaHelper.pollForUIThreadCriteria(new Criteria("First snackbar not shown") {
@Override
public boolean isSatisfied() {
return mManager.isShowing() && mManager.getCurrentSnackbarForTesting() == queuebar;
}
});
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
mManager.showSnackbar(stackbar);
}
});
CriteriaHelper.pollForUIThreadCriteria(
new Criteria("Snackbar on queue was not cleared by snackbar stack.") {
@Override
public boolean isSatisfied() {
return mManager.isShowing()
&& mManager.getCurrentSnackbarForTesting() == stackbar;
}
});
CriteriaHelper.pollForUIThreadCriteria(new Criteria("Snackbar did not time out") {
@Override
public boolean isSatisfied() {
return !mManager.isShowing();
}
});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment