diff options
Diffstat (limited to 'content/browser')
6 files changed, 86 insertions, 2 deletions
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index e5ee763..163ee4c 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc @@ -108,7 +108,7 @@ IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() { } void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) { - shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script); + shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(script); } // Loads a page with an input text field and places sample text in it. Also, diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 80ff6a1..304fc07 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc @@ -89,7 +89,7 @@ std::vector<std::string> DumpAccessibilityEventsTest::Dump() { shell(), AccessibilityModeComplete, ui::AX_EVENT_NONE)); - web_contents->GetMainFrame()->ExecuteJavaScript( + web_contents->GetMainFrame()->ExecuteJavaScriptForTests( base::ASCIIToUTF16("go()")); // Wait for at least one accessibility event generated in response to diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 81aa7c3..c7314b4 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -92,6 +92,10 @@ int g_next_accessibility_reset_token = 1; // The next value to use for the javascript callback id. int g_next_javascript_callback_id = 1; +// Whether to allow injecting javascript into any kind of frame (for Android +// WebView). +bool g_allow_injecting_javascript = false; + // The (process id, routing id) pair that identifies one RenderFrame. typedef std::pair<int32, int32> RenderFrameHostID; typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> @@ -127,6 +131,11 @@ RenderFrameHost* RenderFrameHost::FromID(int render_process_id, } // static +void RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView() { + g_allow_injecting_javascript = true; +} + +// static RenderFrameHostImpl* RenderFrameHostImpl::FromID(int process_id, int routing_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -272,6 +281,7 @@ void RenderFrameHostImpl::AddMessageToConsole(ConsoleMessageLevel level, void RenderFrameHostImpl::ExecuteJavaScript( const base::string16& javascript) { + CHECK(CanExecuteJavaScript()); Send(new FrameMsg_JavaScriptExecuteRequest(routing_id_, javascript, 0, false)); @@ -280,6 +290,7 @@ void RenderFrameHostImpl::ExecuteJavaScript( void RenderFrameHostImpl::ExecuteJavaScript( const base::string16& javascript, const JavaScriptResultCallback& callback) { + CHECK(CanExecuteJavaScript()); int key = g_next_javascript_callback_id++; Send(new FrameMsg_JavaScriptExecuteRequest(routing_id_, javascript, @@ -287,6 +298,23 @@ void RenderFrameHostImpl::ExecuteJavaScript( javascript_callbacks_.insert(std::make_pair(key, callback)); } +void RenderFrameHostImpl::ExecuteJavaScriptForTests( + const base::string16& javascript) { + Send(new FrameMsg_JavaScriptExecuteRequestForTests(routing_id_, + javascript, + 0, false, false)); +} + +void RenderFrameHostImpl::ExecuteJavaScriptForTests( + const base::string16& javascript, + const JavaScriptResultCallback& callback) { + int key = g_next_javascript_callback_id++; + Send(new FrameMsg_JavaScriptExecuteRequestForTests(routing_id_, javascript, + key, true, false)); + javascript_callbacks_.insert(std::make_pair(key, callback)); +} + + void RenderFrameHostImpl::ExecuteJavaScriptWithUserGestureForTests( const base::string16& javascript) { Send(new FrameMsg_JavaScriptExecuteRequestForTests(routing_id_, @@ -2132,4 +2160,16 @@ void RenderFrameHostImpl::UpdatePermissionsForNavigation( } } +bool RenderFrameHostImpl::CanExecuteJavaScript() { + return g_allow_injecting_javascript || + frame_tree_node_->current_url().SchemeIs(kChromeDevToolsScheme) || + ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( + GetProcess()->GetID()) || + // It's possible to load about:blank in a Web UI renderer. + // See http://crbug.com/42547 + (frame_tree_node_->current_url().spec() == url::kAboutBlankURL) || + // InterstitialPageImpl should be the only case matching this. + (delegate_->GetAsWebContents() == nullptr); +} + } // namespace content diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 8035992..b4e9442 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h @@ -139,6 +139,10 @@ class CONTENT_EXPORT RenderFrameHostImpl void ExecuteJavaScript(const base::string16& javascript) override; void ExecuteJavaScript(const base::string16& javascript, const JavaScriptResultCallback& callback) override; + void ExecuteJavaScriptForTests(const base::string16& javascript) override; + void ExecuteJavaScriptForTests( + const base::string16& javascript, + const JavaScriptResultCallback& callback) override; void ExecuteJavaScriptWithUserGestureForTests( const base::string16& javascript) override; void ExecuteJavaScriptInIsolatedWorld( @@ -584,6 +588,9 @@ class CONTENT_EXPORT RenderFrameHostImpl const CommonNavigationParams& common_params, const RequestNavigationParams& request_params); + // Returns true if the ExecuteJavaScript() API can be used on this host. + bool CanExecuteJavaScript(); + // For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a // refcount that calls Shutdown when it reaches zero. This allows each // RenderFrameHostManager to just care about RenderFrameHosts, while ensuring diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index 33296c1..8fd5c50 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc @@ -440,6 +440,39 @@ void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env, ConvertJavaStringToUTF16(env, script), js_callback); } +void WebContentsAndroid::EvaluateJavaScriptForTests(JNIEnv* env, + jobject obj, + jstring script, + jobject callback) { + RenderViewHost* rvh = web_contents_->GetRenderViewHost(); + DCHECK(rvh); + + if (!rvh->IsRenderViewLive()) { + if (!static_cast<WebContentsImpl*>(web_contents_)-> + CreateRenderViewForInitialEmptyDocument()) { + LOG(ERROR) << "Failed to create RenderView in EvaluateJavaScriptForTests"; + return; + } + } + + if (!callback) { + // No callback requested. + web_contents_->GetMainFrame()->ExecuteJavaScriptForTests( + ConvertJavaStringToUTF16(env, script)); + return; + } + + // Secure the Java callback in a scoped object and give ownership of it to the + // base::Callback. + ScopedJavaGlobalRef<jobject> j_callback; + j_callback.Reset(env, callback); + RenderFrameHost::JavaScriptResultCallback js_callback = + base::Bind(&JavaScriptResultCallback, j_callback); + + web_contents_->GetMainFrame()->ExecuteJavaScriptForTests( + ConvertJavaStringToUTF16(env, script), js_callback); +} + void WebContentsAndroid::AddMessageToDevToolsConsole(JNIEnv* env, jobject jobj, jint level, diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index 9eb9238..56e71b8 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h @@ -86,6 +86,10 @@ class CONTENT_EXPORT WebContentsAndroid jobject obj, jstring script, jobject callback); + void EvaluateJavaScriptForTests(JNIEnv* env, + jobject obj, + jstring script, + jobject callback); void AddMessageToDevToolsConsole(JNIEnv* env, jobject jobj, |