This repository has been archived by the owner on Apr 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 211
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Android WebView] Terminate execution of stuck JS code on navigation …
…requests Allow WebView.loadUrl-family functions to terminate execution of JS code that seems to be stuck in a loop. BUG=390906 Review URL: https://codereview.chromium.org/366913006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281715 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
mnaganov@chromium.org
committed
Jul 8, 2014
1 parent
1f0a2e4
commit 69538c3
Showing
12 changed files
with
256 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
android_webview/renderer/aw_execution_termination_filter.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copyright 2014 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. | ||
|
||
#include "android_webview/renderer/aw_execution_termination_filter.h" | ||
|
||
#include <v8.h> | ||
|
||
#include "android_webview/common/render_view_messages.h" | ||
#include "base/message_loop/message_loop_proxy.h" | ||
|
||
namespace { | ||
const int kTerminationTimeoutInSeconds = 3; | ||
} // namespace | ||
|
||
namespace android_webview { | ||
|
||
AwExecutionTerminationFilter::AwExecutionTerminationFilter( | ||
const scoped_refptr<base::MessageLoopProxy>& io_message_loop, | ||
const scoped_refptr<base::MessageLoopProxy>& main_message_loop) | ||
: io_message_loop_(io_message_loop), | ||
main_message_loop_(main_message_loop), | ||
render_thread_isolate_(NULL) { | ||
} | ||
|
||
AwExecutionTerminationFilter::~AwExecutionTerminationFilter() { | ||
} | ||
|
||
void AwExecutionTerminationFilter::SetRenderThreadIsolate( | ||
v8::Isolate* isolate) { | ||
render_thread_isolate_ = isolate; | ||
} | ||
|
||
bool AwExecutionTerminationFilter::OnMessageReceived( | ||
const IPC::Message& message) { | ||
bool handled = true; | ||
IPC_BEGIN_MESSAGE_MAP(AwExecutionTerminationFilter, message) | ||
IPC_MESSAGE_HANDLER(AwViewMsg_CheckRenderThreadResponsiveness, | ||
OnCheckRenderThreadResponsiveness) | ||
IPC_MESSAGE_UNHANDLED(handled = false) | ||
IPC_END_MESSAGE_MAP() | ||
return handled; | ||
} | ||
|
||
void AwExecutionTerminationFilter::OnCheckRenderThreadResponsiveness() { | ||
termination_timer_.Start( | ||
FROM_HERE, | ||
base::TimeDelta::FromSeconds(kTerminationTimeoutInSeconds), | ||
base::Bind(&AwExecutionTerminationFilter::TerminateExecution, this)); | ||
// Post a request to stop the timer via render thread's message loop | ||
// to ensure that render thread is responsive. | ||
main_message_loop_->PostTask( | ||
FROM_HERE, | ||
base::Bind(&AwExecutionTerminationFilter::StopTimerOnMainThread, | ||
this)); | ||
} | ||
|
||
void AwExecutionTerminationFilter::StopTimerOnMainThread() { | ||
io_message_loop_->PostTask( | ||
FROM_HERE, | ||
base::Bind(&AwExecutionTerminationFilter::StopTimer, this)); | ||
} | ||
|
||
void AwExecutionTerminationFilter::StopTimer() { | ||
termination_timer_.Stop(); | ||
} | ||
|
||
void AwExecutionTerminationFilter::TerminateExecution() { | ||
if (render_thread_isolate_) { | ||
LOG(WARNING) << "Trying to terminate JavaScript execution because " | ||
"renderer is unresponsive"; | ||
v8::V8::TerminateExecution(render_thread_isolate_); | ||
} | ||
} | ||
|
||
} // namespace android_webview |
64 changes: 64 additions & 0 deletions
64
android_webview/renderer/aw_execution_termination_filter.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Copyright 2014 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. | ||
|
||
#ifndef ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_ | ||
#define ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_ | ||
|
||
#include "base/memory/scoped_ptr.h" | ||
#include "base/timer/timer.h" | ||
#include "ipc/message_filter.h" | ||
|
||
namespace base { | ||
class MessageLoopProxy; | ||
} | ||
|
||
namespace v8 { | ||
class Isolate; | ||
} | ||
|
||
namespace android_webview { | ||
|
||
// The purpose of AwExecutionTerminationFilter is to attempt to terminate | ||
// any JavaScript code that is stuck in a loop before doing a navigation | ||
// originating from a Andoird WebView URL loading functions. | ||
// | ||
// This is how it works. AwExecutionTerminationFilter is created on render | ||
// thread. It listens on IO thread for navigation requests coming from | ||
// AwContents.loadUrl calls. On each such a request, it posts a delayed | ||
// cancellable task on the IO thread's message loop and, at the same time, posts | ||
// a cancellation task on the render thread's message loop. If render thread | ||
// is not stuck, the cancellation task runs and cancels the delayed task. | ||
// Otherwise, the delayed task runs and terminates execution of JS code | ||
// from the IO thread. | ||
class AwExecutionTerminationFilter : public IPC::MessageFilter { | ||
public: | ||
AwExecutionTerminationFilter( | ||
const scoped_refptr<base::MessageLoopProxy>& io_message_loop, | ||
const scoped_refptr<base::MessageLoopProxy>& main_message_loop); | ||
|
||
void SetRenderThreadIsolate(v8::Isolate* isolate); | ||
|
||
private: | ||
virtual ~AwExecutionTerminationFilter(); | ||
|
||
// IPC::MessageFilter methods. | ||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | ||
|
||
void OnCheckRenderThreadResponsiveness(); | ||
void StopTimerOnMainThread(); | ||
void StopTimer(); | ||
void TerminateExecution(); | ||
|
||
const scoped_refptr<base::MessageLoopProxy> io_message_loop_; | ||
const scoped_refptr<base::MessageLoopProxy> main_message_loop_; | ||
|
||
v8::Isolate* render_thread_isolate_; | ||
base::OneShotTimer<AwExecutionTerminationFilter> termination_timer_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(AwExecutionTerminationFilter); | ||
}; | ||
|
||
} // namespace android_webview | ||
|
||
#endif // ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_ |