Chromium Code Reviews| 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..b9d844e56c4f10ae98b2e81621b3138813e69ca9 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) { |
| + throw sWindowDetachTrace; |
|
newt (away)
2015/11/18 01:46:54
If you throw sWindowDetachTrace then Chrome will c
Ian Wen
2015/11/18 01:56:26
Done.
|
| + } |
| + throw ex; |
| + } |
| + |
| mPopup = null; |
| } |