| Index: chromecast/shell/browser/android/cast_window_android.cc
|
| diff --git a/chromecast/shell/browser/android/cast_window_android.cc b/chromecast/shell/browser/android/cast_window_android.cc
|
| index 1ecc1c9acba38175981d1afdf7c6ef7f390ad3e5..4b68cb95d3c469cef1259f248b448c805f510bea 100644
|
| --- a/chromecast/shell/browser/android/cast_window_android.cc
|
| +++ b/chromecast/shell/browser/android/cast_window_android.cc
|
| @@ -4,7 +4,7 @@
|
|
|
| #include "chromecast/shell/browser/android/cast_window_android.h"
|
|
|
| -#include "base/message_loop/message_loop.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| #include "base/path_service.h"
|
| #include "chromecast/shell/browser/android/cast_window_manager.h"
|
| #include "content/public/browser/devtools_agent_host.h"
|
| @@ -17,13 +17,22 @@
|
| namespace chromecast {
|
| namespace shell {
|
|
|
| +namespace {
|
| +
|
| +// The time (in milliseconds) we wait for after a page is closed (i.e.
|
| +// after an app is stopped) before we delete the corresponding WebContents.
|
| +const int kWebContentsDestructionDelayInMs = 50;
|
| +
|
| +} // namespace
|
| +
|
| // static
|
| bool CastWindowAndroid::RegisterJni(JNIEnv* env) {
|
| return RegisterNativesImpl(env);
|
| }
|
|
|
| CastWindowAndroid::CastWindowAndroid(content::WebContents* web_contents)
|
| - : content::WebContentsObserver(web_contents) {
|
| + : content::WebContentsObserver(web_contents),
|
| + weak_factory_(this) {
|
| }
|
|
|
| CastWindowAndroid::~CastWindowAndroid() {
|
| @@ -71,6 +80,13 @@ CastWindowAndroid* CastWindowAndroid::CreateCastWindowAndroid(
|
| }
|
|
|
| void CastWindowAndroid::Close() {
|
| + // Close page first, which fires the window.unload event. The WebContents
|
| + // itself will be destroyed after browser-process has received renderer
|
| + // notification that the page is closed.
|
| + web_contents_->GetRenderViewHost()->ClosePage();
|
| +}
|
| +
|
| +void CastWindowAndroid::Destroy() {
|
| // Note: if multiple windows becomes supported, this may close other devtools
|
| // sessions.
|
| content::DevToolsAgentHost::DetachAllClients();
|
| @@ -101,7 +117,29 @@ void CastWindowAndroid::AddNewContents(content::WebContents* source,
|
|
|
| void CastWindowAndroid::CloseContents(content::WebContents* source) {
|
| DCHECK_EQ(source, web_contents_.get());
|
| - Close();
|
| +
|
| + // We need to delay the deletion of web_contents_ (currently for 50ms) to
|
| + // give (and guarantee) the renderer enough time to finish 'onunload'
|
| + // handler (but we don't want to wait any longer than that to delay the
|
| + // starting of next app).
|
| +
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
|
| + // When shutting down in a test context, the last remaining WebContents
|
| + // is torn down at browser-thread shutdown time. Call Destroy directly to
|
| + // avoid losing the last posted task to delete this object.
|
| + // TODO(gunsch): This could probably be avoided by using a
|
| + // CompletionCallback in StopCurrentApp to wait until the app is completely
|
| + // stopped. This might require a separate message loop and might only be
|
| + // appropriate for test contexts or during shutdown, since it triggers a
|
| + // wait on the main thread.
|
| + Destroy();
|
| + return;
|
| + }
|
| +
|
| + base::MessageLoopProxy::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&CastWindowAndroid::Destroy, weak_factory_.GetWeakPtr()),
|
| + base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs));
|
| }
|
|
|
| bool CastWindowAndroid::CanOverscrollContent() const {
|
| @@ -128,7 +166,7 @@ void CastWindowAndroid::DeactivateContents(content::WebContents* contents) {
|
|
|
| void CastWindowAndroid::RenderProcessGone(base::TerminationStatus status) {
|
| LOG(ERROR) << "Render process gone: status=" << status;
|
| - Close();
|
| + Destroy();
|
| }
|
|
|
| } // namespace shell
|
|
|