Index: chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java |
index 79bd12005d49d19fd88549ef96b7efbd3c2f8208..885c8d8e8ccbba8fc01b68f9d185c3a13bfcfef7 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java |
@@ -4,13 +4,18 @@ |
package org.chromium.chrome.browser.snackbar; |
+import android.annotation.TargetApi; |
+import android.app.Activity; |
+import android.content.Context; |
import android.graphics.Rect; |
+import android.os.Build; |
import android.os.Handler; |
+import android.util.AttributeSet; |
import android.view.Gravity; |
import android.view.View; |
import android.view.View.OnClickListener; |
import android.view.ViewTreeObserver.OnGlobalLayoutListener; |
-import android.view.Window; |
+import android.widget.LinearLayout; |
import org.chromium.base.ApiCompatibilityUtils; |
import org.chromium.base.VisibleForTesting; |
@@ -38,6 +43,29 @@ import java.util.Stack; |
*/ |
public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener { |
+ private static RuntimeException sWindowDetachTrace; |
+ |
+ /** |
+ * A {@link LinearLayout} that logs the stack trace when {@link #onDetachedFromWindow()} is |
+ * called. |
+ */ |
+ public static class WindowDismissalAwareLayout extends LinearLayout { |
+ // TODO(ianwen): remove this class after crbug.com/553569 is fixed. |
+ /** |
+ * Constructor for XML inflation. |
+ */ |
+ public WindowDismissalAwareLayout(Context context, AttributeSet attrs) { |
+ super(context, attrs); |
+ } |
+ |
+ @Override |
+ protected void onDetachedFromWindow() { |
+ super.onDetachedFromWindow(); |
+ sWindowDetachTrace = new RuntimeException( |
+ "Stacktrace for Snackbar view to be detached from window"); |
+ } |
+ } |
+ |
/** |
* Interface that shows the ability to provide a unified snackbar manager. |
*/ |
@@ -82,6 +110,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener |
private static final int DEFAULT_SNACKBAR_DURATION_MS = 3000; |
private static final int ACCESSIBILITY_MODE_SNACKBAR_DURATION_MS = 6000; |
+ private static final String TAG = "cr_snackbar"; |
// Used instead of the constant so tests can override the value. |
private static int sSnackbarDurationMs = DEFAULT_SNACKBAR_DURATION_MS; |
@@ -89,6 +118,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener |
private final boolean mIsTablet; |
+ private Activity mActivity; |
private View mDecor; |
private final Handler mUIThreadHandler; |
private Stack<Snackbar> mStack = new Stack<Snackbar>(); |
@@ -107,8 +137,9 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener |
/** |
* Constructs a SnackbarManager to show snackbars in the given window. |
*/ |
- public SnackbarManager(Window window) { |
- mDecor = window.getDecorView(); |
+ public SnackbarManager(Activity activity) { |
+ mActivity = activity; |
+ mDecor = activity.getWindow().getDecorView(); |
mUIThreadHandler = new Handler(); |
mIsTablet = DeviceFormFactor.isTablet(mDecor.getContext()); |
} |
@@ -150,11 +181,28 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener |
* |
* @param isTimeout Whether dismissal was triggered by timeout. |
*/ |
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) |
public void dismissAllSnackbars(boolean isTimeout) { |
mUIThreadHandler.removeCallbacks(mHideRunnable); |
if (mPopup != null) { |
- mPopup.dismiss(); |
+ // TODO(ianwen): remove the try catch after crbug.com/553569 is fixed. |
+ try { |
+ mPopup.dismiss(); |
+ } catch (IllegalArgumentException ex) { |
+ if (mActivity != null) { |
+ android.util.Log.d(TAG, "Activity.toString()? " + mActivity); |
+ android.util.Log.d(TAG, "Activity is finishing? " + mActivity.isFinishing()); |
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { |
+ android.util.Log.d(TAG, "Activity is destroyed?" + mActivity.isDestroyed()); |
+ } |
+ } |
+ if (sWindowDetachTrace != null) { |
+ android.util.Log.d(TAG, "Window detach stack trace", sWindowDetachTrace); |
+ } |
+ throw ex; |
+ } |
+ |
mPopup = null; |
} |