Commit 293b5ca2 authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

Fix crash in TabModelSelectorTabObserver#tabRemoved

Ran into this crash when changing the timing of Activity finishing in
tests.

TabModelSelectorTabObserver#tabRemoved posts a task, and then uses the
Tab after it's possibly been destroyed.

Changes to CriticalPersistedState were also necessary to avoid the
observer leak that would happen in this case.

Change-Id: I152a2d08cee86af51517f5708e57f8dc7fad4f9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2535559
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827176}
parent b6d1d101
...@@ -186,6 +186,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { ...@@ -186,6 +186,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
private final UserDataHost mUserDataHost = new UserDataHost(); private final UserDataHost mUserDataHost = new UserDataHost();
private boolean mIsDestroyed;
/** /**
* Creates an instance of a {@link TabImpl}. * Creates an instance of a {@link TabImpl}.
* *
...@@ -574,6 +576,11 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { ...@@ -574,6 +576,11 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
return mNativeTabAndroid != 0; return mNativeTabAndroid != 0;
} }
@Override
public boolean isDestroyed() {
return mIsDestroyed;
}
@Override @Override
public final void show(@TabSelectionType int type) { public final void show(@TabSelectionType int type) {
try { try {
...@@ -651,6 +658,10 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer { ...@@ -651,6 +658,10 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
@Override @Override
public void destroy() { public void destroy() {
// Set at the start since destroying the WebContents can lead to calling back into
// this class.
mIsDestroyed = true;
// Update the title before destroying the tab. http://b/5783092 // Update the title before destroying the tab. http://b/5783092
updateTitle(); updateTitle();
......
...@@ -16,6 +16,11 @@ public interface TabLifecycle { ...@@ -16,6 +16,11 @@ public interface TabLifecycle {
*/ */
boolean isInitialized(); boolean isInitialized();
/**
* @return Whether this Tab has been destroyed.
*/
boolean isDestroyed();
/** /**
* Prepares the tab to be shown. This method is supposed to be called before the tab is * Prepares the tab to be shown. This method is supposed to be called before the tab is
* displayed. It restores the ContentView if it is not available after the cold start and * displayed. It restores the ContentView if it is not available after the cold start and
......
...@@ -410,7 +410,9 @@ public class CriticalPersistedTabData extends PersistedTabData { ...@@ -410,7 +410,9 @@ public class CriticalPersistedTabData extends PersistedTabData {
} }
@Override @Override
public void destroy() {} public void destroy() {
mObservers.clear();
}
/** /**
* @return title of the {@link Tab} * @return title of the {@link Tab}
......
...@@ -75,6 +75,8 @@ public class TabModelSelectorTabObserver ...@@ -75,6 +75,8 @@ public class TabModelSelectorTabObserver
// Post the removal of the observer so that other tab events are notified // Post the removal of the observer so that other tab events are notified
// before removing the tab observer (e.g. detach tab from activity). // before removing the tab observer (e.g. detach tab from activity).
PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> {
// If the tab as been destroyed we cannot access PersistedTabData.
if (tab.isDestroyed()) return;
tab.removeObserver(TabModelSelectorTabObserver.this); tab.removeObserver(TabModelSelectorTabObserver.this);
CriticalPersistedTabData.from(tab).removeObserver( CriticalPersistedTabData.from(tab).removeObserver(
TabModelSelectorTabObserver.this); TabModelSelectorTabObserver.this);
......
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