Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / web_contents / web_contents_android.cc
blobb666d3de7fe9433b61e21ce42e5d899f4a61b42b
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/web_contents/web_contents_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "base/command_line.h"
11 #include "base/json/json_writer.h"
12 #include "base/logging.h"
13 #include "content/browser/accessibility/browser_accessibility_android.h"
14 #include "content/browser/accessibility/browser_accessibility_manager.h"
15 #include "content/browser/android/interstitial_page_delegate_android.h"
16 #include "content/browser/frame_host/interstitial_page_impl.h"
17 #include "content/browser/media/android/browser_media_player_manager.h"
18 #include "content/browser/media/media_web_contents_observer.h"
19 #include "content/browser/renderer_host/render_view_host_impl.h"
20 #include "content/browser/web_contents/web_contents_impl.h"
21 #include "content/common/devtools_messages.h"
22 #include "content/common/frame_messages.h"
23 #include "content/common/input_messages.h"
24 #include "content/common/view_messages.h"
25 #include "content/public/browser/browser_context.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/content_switches.h"
29 #include "jni/WebContentsImpl_jni.h"
30 #include "net/android/network_library.h"
31 #include "ui/accessibility/ax_node_data.h"
33 using base::android::AttachCurrentThread;
34 using base::android::ConvertJavaStringToUTF8;
35 using base::android::ConvertJavaStringToUTF16;
36 using base::android::ConvertUTF8ToJavaString;
37 using base::android::ConvertUTF16ToJavaString;
38 using base::android::ScopedJavaGlobalRef;
39 using base::android::ToJavaIntArray;
41 namespace content {
43 namespace {
45 void JavaScriptResultCallback(const ScopedJavaGlobalRef<jobject>& callback,
46 const base::Value* result) {
47 JNIEnv* env = base::android::AttachCurrentThread();
48 std::string json;
49 base::JSONWriter::Write(result, &json);
50 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, json);
51 Java_WebContentsImpl_onEvaluateJavaScriptResult(
52 env, j_json.obj(), callback.obj());
55 ScopedJavaLocalRef<jobject> WalkAXTreeDepthFirst(JNIEnv* env,
56 BrowserAccessibilityAndroid* node) {
58 ScopedJavaLocalRef<jstring> j_text =
59 ConvertUTF16ToJavaString(env, node->GetText());
60 ScopedJavaLocalRef<jstring> j_class =
61 ConvertUTF8ToJavaString(env, node->GetClassName());
62 const gfx::Rect& location = node->GetLocation();
63 ScopedJavaLocalRef<jobject> j_node =
64 Java_WebContentsImpl_createAccessibilitySnapshotNode(env,
65 location.x(), location.y(), node->GetScrollX(),
66 node->GetScrollY(), location.width(), location.height(),
67 j_text.obj(), j_class.obj());
69 for(uint32 i = 0; i < node->PlatformChildCount(); i++) {
70 BrowserAccessibilityAndroid* child =
71 static_cast<BrowserAccessibilityAndroid*>(
72 node->PlatformGetChild(i));
73 Java_WebContentsImpl_addAccessibilityNodeAsChild(env,
74 j_node.obj(), WalkAXTreeDepthFirst(env, child).obj());
76 return j_node;
79 // Walks over the AXTreeUpdate and creates a light weight snapshot.
80 void AXTreeSnapshotCallback(const ScopedJavaGlobalRef<jobject>& callback,
81 const ui::AXTreeUpdate& result) {
82 JNIEnv* env = base::android::AttachCurrentThread();
83 if (result.nodes.empty()) {
84 Java_WebContentsImpl_onAccessibilitySnapshot(env, nullptr, callback.obj());
85 return;
87 scoped_ptr<BrowserAccessibilityManager> manager(
88 BrowserAccessibilityManager::Create(result, nullptr));
89 BrowserAccessibilityAndroid* root =
90 static_cast<BrowserAccessibilityAndroid*>(manager->GetRoot());
91 ScopedJavaLocalRef<jobject> j_root = WalkAXTreeDepthFirst(env, root);
92 Java_WebContentsImpl_onAccessibilitySnapshot(
93 env, j_root.obj(), callback.obj());
96 void ReleaseAllMediaPlayers(WebContents* web_contents,
97 RenderFrameHost* render_frame_host) {
98 BrowserMediaPlayerManager* manager =
99 static_cast<WebContentsImpl*>(web_contents)->
100 media_web_contents_observer()->GetMediaPlayerManager(
101 render_frame_host);
102 if (manager)
103 manager->ReleaseAllMediaPlayers();
106 } // namespace
108 // static
109 WebContents* WebContents::FromJavaWebContents(
110 jobject jweb_contents_android) {
111 DCHECK_CURRENTLY_ON(BrowserThread::UI);
112 if (!jweb_contents_android)
113 return NULL;
115 WebContentsAndroid* web_contents_android =
116 reinterpret_cast<WebContentsAndroid*>(
117 Java_WebContentsImpl_getNativePointer(AttachCurrentThread(),
118 jweb_contents_android));
119 if (!web_contents_android)
120 return NULL;
121 return web_contents_android->web_contents();
124 // static
125 static void DestroyWebContents(JNIEnv* env,
126 jclass clazz,
127 jlong jweb_contents_android_ptr) {
128 WebContentsAndroid* web_contents_android =
129 reinterpret_cast<WebContentsAndroid*>(jweb_contents_android_ptr);
130 if (!web_contents_android)
131 return;
133 WebContents* web_contents = web_contents_android->web_contents();
134 if (!web_contents)
135 return;
137 delete web_contents;
140 // static
141 bool WebContentsAndroid::Register(JNIEnv* env) {
142 return RegisterNativesImpl(env);
145 WebContentsAndroid::WebContentsAndroid(WebContents* web_contents)
146 : web_contents_(web_contents),
147 navigation_controller_(&(web_contents->GetController())),
148 weak_factory_(this) {
149 JNIEnv* env = AttachCurrentThread();
150 obj_.Reset(env,
151 Java_WebContentsImpl_create(
152 env,
153 reinterpret_cast<intptr_t>(this),
154 navigation_controller_.GetJavaObject().obj()).obj());
155 RendererPreferences* prefs = web_contents_->GetMutableRendererPrefs();
156 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
157 prefs->network_contry_iso =
158 command_line->HasSwitch(switches::kNetworkCountryIso) ?
159 command_line->GetSwitchValueASCII(switches::kNetworkCountryIso)
160 : net::android::GetTelephonyNetworkCountryIso();
163 WebContentsAndroid::~WebContentsAndroid() {
164 Java_WebContentsImpl_clearNativePtr(AttachCurrentThread(), obj_.obj());
167 base::android::ScopedJavaLocalRef<jobject>
168 WebContentsAndroid::GetJavaObject() {
169 return base::android::ScopedJavaLocalRef<jobject>(obj_);
172 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle(
173 JNIEnv* env, jobject obj) const {
174 return base::android::ConvertUTF16ToJavaString(env,
175 web_contents_->GetTitle());
178 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetVisibleURL(
179 JNIEnv* env, jobject obj) const {
180 return base::android::ConvertUTF8ToJavaString(
181 env, web_contents_->GetVisibleURL().spec());
184 bool WebContentsAndroid::IsLoading(JNIEnv* env, jobject obj) const {
185 return web_contents_->IsLoading();
188 bool WebContentsAndroid::IsLoadingToDifferentDocument(JNIEnv* env,
189 jobject obj) const {
190 return web_contents_->IsLoadingToDifferentDocument();
193 void WebContentsAndroid::Stop(JNIEnv* env, jobject obj) {
194 web_contents_->Stop();
197 void WebContentsAndroid::InsertCSS(
198 JNIEnv* env, jobject jobj, jstring jcss) {
199 web_contents_->InsertCSS(base::android::ConvertJavaStringToUTF8(env, jcss));
202 RenderWidgetHostViewAndroid*
203 WebContentsAndroid::GetRenderWidgetHostViewAndroid() {
204 RenderWidgetHostView* rwhv = NULL;
205 rwhv = web_contents_->GetRenderWidgetHostView();
206 if (web_contents_->ShowingInterstitialPage()) {
207 rwhv = web_contents_->GetInterstitialPage()
208 ->GetMainFrame()
209 ->GetRenderViewHost()
210 ->GetView();
212 return static_cast<RenderWidgetHostViewAndroid*>(rwhv);
215 jint WebContentsAndroid::GetBackgroundColor(JNIEnv* env, jobject obj) {
216 RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
217 if (!rwhva)
218 return SK_ColorWHITE;
219 return rwhva->GetCachedBackgroundColor();
222 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetURL(JNIEnv* env,
223 jobject obj) const {
224 return ConvertUTF8ToJavaString(env, web_contents_->GetURL().spec());
227 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetLastCommittedURL(
228 JNIEnv* env,
229 jobject) const {
230 return ConvertUTF8ToJavaString(env,
231 web_contents_->GetLastCommittedURL().spec());
235 jboolean WebContentsAndroid::IsIncognito(JNIEnv* env, jobject obj) {
236 return web_contents_->GetBrowserContext()->IsOffTheRecord();
239 void WebContentsAndroid::ResumeResponseDeferredAtStart(JNIEnv* env,
240 jobject obj) {
241 static_cast<WebContentsImpl*>(web_contents_)->ResumeResponseDeferredAtStart();
244 void WebContentsAndroid::SetHasPendingNavigationTransitionForTesting(
245 JNIEnv* env,
246 jobject obj) {
247 base::CommandLine::ForCurrentProcess()->AppendSwitch(
248 switches::kEnableExperimentalWebPlatformFeatures);
249 RenderFrameHost* frame =
250 static_cast<WebContentsImpl*>(web_contents_)->GetMainFrame();
251 BrowserThread::PostTask(
252 BrowserThread::IO,
253 FROM_HERE,
254 base::Bind(
255 &TransitionRequestManager::AddPendingTransitionRequestDataForTesting,
256 base::Unretained(TransitionRequestManager::GetInstance()),
257 frame->GetProcess()->GetID(),
258 frame->GetRoutingID()));
261 void WebContentsAndroid::SetupTransitionView(JNIEnv* env,
262 jobject jobj,
263 jstring markup) {
264 web_contents_->GetMainFrame()->Send(new FrameMsg_SetupTransitionView(
265 web_contents_->GetMainFrame()->GetRoutingID(),
266 ConvertJavaStringToUTF8(env, markup)));
269 void WebContentsAndroid::BeginExitTransition(JNIEnv* env,
270 jobject jobj,
271 jstring css_selector,
272 jboolean exit_to_native_app) {
273 web_contents_->GetMainFrame()->Send(new FrameMsg_BeginExitTransition(
274 web_contents_->GetMainFrame()->GetRoutingID(),
275 ConvertJavaStringToUTF8(env, css_selector),
276 exit_to_native_app));
279 void WebContentsAndroid::RevertExitTransition(JNIEnv* env,
280 jobject jobj) {
281 web_contents_->GetMainFrame()->Send(new FrameMsg_RevertExitTransition(
282 web_contents_->GetMainFrame()->GetRoutingID()));
285 void WebContentsAndroid::HideTransitionElements(JNIEnv* env,
286 jobject jobj,
287 jstring css_selector) {
288 web_contents_->GetMainFrame()->Send(
289 new FrameMsg_HideTransitionElements(
290 web_contents_->GetMainFrame()->GetRoutingID(),
291 ConvertJavaStringToUTF8(env, css_selector)));
294 void WebContentsAndroid::ShowTransitionElements(JNIEnv* env,
295 jobject jobj,
296 jstring css_selector) {
297 web_contents_->GetMainFrame()->Send(
298 new FrameMsg_ShowTransitionElements(
299 web_contents_->GetMainFrame()->GetRoutingID(),
300 ConvertJavaStringToUTF8(env, css_selector)));
304 void WebContentsAndroid::ClearNavigationTransitionData(JNIEnv* env,
305 jobject jobj) {
306 static_cast<WebContentsImpl*>(web_contents_)->ClearNavigationTransitionData();
309 void WebContentsAndroid::FetchTransitionElements(JNIEnv* env,
310 jobject jobj,
311 jstring jurl) {
312 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
313 RenderFrameHost* frame = web_contents_->GetMainFrame();
315 scoped_ptr<TransitionLayerData> transition_data(new TransitionLayerData());
316 BrowserThread::PostTaskAndReplyWithResult(
317 BrowserThread::IO,
318 FROM_HERE,
319 base::Bind(&TransitionRequestManager::GetPendingTransitionRequest,
320 base::Unretained(TransitionRequestManager::GetInstance()),
321 frame->GetProcess()->GetID(),
322 frame->GetRoutingID(),
323 url,
324 transition_data.get()),
325 base::Bind(&WebContentsAndroid::OnTransitionElementsFetched,
326 weak_factory_.GetWeakPtr(),
327 base::Passed(&transition_data)));
330 void WebContentsAndroid::OnTransitionElementsFetched(
331 scoped_ptr<const TransitionLayerData> transition_data,
332 bool has_transition_data) {
333 // FetchTransitionElements is called after the navigation transition state
334 // machine starts, which means there must be transition data.
335 DCHECK(has_transition_data);
336 JNIEnv* env = AttachCurrentThread();
338 std::vector<TransitionElement>::const_iterator it =
339 transition_data->elements.begin();
340 for (; it != transition_data->elements.end(); ++it) {
341 ScopedJavaLocalRef<jstring> jstring_name(ConvertUTF8ToJavaString(env,
342 it->id));
343 Java_WebContentsImpl_addNavigationTransitionElements(
344 env, obj_.obj(), jstring_name.obj(),
345 it->rect.x(), it->rect.y(), it->rect.width(), it->rect.height());
348 ScopedJavaLocalRef<jstring> jstring_css_selector(
349 ConvertUTF8ToJavaString(env, transition_data->css_selector));
350 Java_WebContentsImpl_onTransitionElementsFetched(
351 env, obj_.obj(), jstring_css_selector.obj());
354 void WebContentsAndroid::OnHide(JNIEnv* env, jobject obj) {
355 web_contents_->WasHidden();
358 void WebContentsAndroid::OnShow(JNIEnv* env, jobject obj) {
359 web_contents_->WasShown();
362 void WebContentsAndroid::ReleaseMediaPlayers(JNIEnv* env, jobject jobj) {
363 #if defined(ENABLE_BROWSER_CDMS)
364 web_contents_->ForEachFrame(
365 base::Bind(&ReleaseAllMediaPlayers, base::Unretained(web_contents_)));
366 #endif // defined(ENABLE_BROWSER_CDMS)
369 void WebContentsAndroid::AddStyleSheetByURL(
370 JNIEnv* env,
371 jobject obj,
372 jstring url) {
373 web_contents_->GetMainFrame()->Send(new FrameMsg_AddStyleSheetByURL(
374 web_contents_->GetMainFrame()->GetRoutingID(),
375 ConvertJavaStringToUTF8(env, url)));
378 void WebContentsAndroid::ShowInterstitialPage(
379 JNIEnv* env,
380 jobject obj,
381 jstring jurl,
382 jlong delegate_ptr) {
383 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
384 InterstitialPageDelegateAndroid* delegate =
385 reinterpret_cast<InterstitialPageDelegateAndroid*>(delegate_ptr);
386 InterstitialPage* interstitial = InterstitialPage::Create(
387 web_contents_, false, url, delegate);
388 delegate->set_interstitial_page(interstitial);
389 interstitial->Show();
392 jboolean WebContentsAndroid::IsShowingInterstitialPage(JNIEnv* env,
393 jobject obj) {
394 return web_contents_->ShowingInterstitialPage();
397 jboolean WebContentsAndroid::IsRenderWidgetHostViewReady(
398 JNIEnv* env,
399 jobject obj) {
400 RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
401 return view && view->HasValidFrame();
404 void WebContentsAndroid::ExitFullscreen(JNIEnv* env, jobject obj) {
405 web_contents_->ExitFullscreen();
408 void WebContentsAndroid::UpdateTopControlsState(
409 JNIEnv* env,
410 jobject obj,
411 bool enable_hiding,
412 bool enable_showing,
413 bool animate) {
414 RenderViewHost* host = web_contents_->GetRenderViewHost();
415 if (!host)
416 return;
417 host->Send(new ViewMsg_UpdateTopControlsState(host->GetRoutingID(),
418 enable_hiding,
419 enable_showing,
420 animate));
423 void WebContentsAndroid::ShowImeIfNeeded(JNIEnv* env, jobject obj) {
424 RenderViewHost* host = web_contents_->GetRenderViewHost();
425 if (!host)
426 return;
427 host->Send(new ViewMsg_ShowImeIfNeeded(host->GetRoutingID()));
430 void WebContentsAndroid::ScrollFocusedEditableNodeIntoView(
431 JNIEnv* env,
432 jobject obj) {
433 RenderViewHost* host = web_contents_->GetRenderViewHost();
434 if (!host)
435 return;
436 host->Send(new InputMsg_ScrollFocusedEditableNodeIntoRect(
437 host->GetRoutingID(), gfx::Rect()));
440 void WebContentsAndroid::SelectWordAroundCaret(JNIEnv* env, jobject obj) {
441 RenderViewHost* host = web_contents_->GetRenderViewHost();
442 if (!host)
443 return;
444 host->SelectWordAroundCaret();
447 bool WebContentsAndroid::WillHandleDeferAfterResponseStarted() {
448 JNIEnv* env = AttachCurrentThread();
449 return Java_WebContentsImpl_willHandleDeferAfterResponseStarted(env,
450 obj_.obj());
453 void WebContentsAndroid::DidDeferAfterResponseStarted(
454 const TransitionLayerData& transition_data) {
455 JNIEnv* env = AttachCurrentThread();
456 std::vector<GURL> entering_stylesheets;
457 std::string transition_color;
458 if (transition_data.response_headers.get()) {
459 TransitionRequestManager::ParseTransitionStylesheetsFromHeaders(
460 transition_data.response_headers,
461 entering_stylesheets,
462 transition_data.request_url);
464 transition_data.response_headers->EnumerateHeader(
465 NULL, "X-Transition-Entering-Color", &transition_color);
468 ScopedJavaLocalRef<jstring> jstring_markup(
469 ConvertUTF8ToJavaString(env, transition_data.markup));
471 ScopedJavaLocalRef<jstring> jstring_css_selector(
472 ConvertUTF8ToJavaString(env, transition_data.css_selector));
474 ScopedJavaLocalRef<jstring> jstring_transition_color(
475 ConvertUTF8ToJavaString(env, transition_color));
477 Java_WebContentsImpl_didDeferAfterResponseStarted(
478 env,
479 obj_.obj(),
480 jstring_markup.obj(),
481 jstring_css_selector.obj(),
482 jstring_transition_color.obj());
484 std::vector<GURL>::const_iterator iter = entering_stylesheets.begin();
485 for (; iter != entering_stylesheets.end(); ++iter) {
486 ScopedJavaLocalRef<jstring> jstring_url(
487 ConvertUTF8ToJavaString(env, iter->spec()));
488 Java_WebContentsImpl_addEnteringStylesheetToTransition(
489 env, obj_.obj(), jstring_url.obj());
493 void WebContentsAndroid::DidStartNavigationTransitionForFrame(int64 frame_id) {
494 JNIEnv* env = AttachCurrentThread();
495 Java_WebContentsImpl_didStartNavigationTransitionForFrame(
496 env, obj_.obj(), frame_id);
499 void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
500 jobject obj,
501 jstring script,
502 jobject callback) {
503 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
504 DCHECK(rvh);
506 if (!rvh->IsRenderViewLive()) {
507 if (!static_cast<WebContentsImpl*>(web_contents_)->
508 CreateRenderViewForInitialEmptyDocument()) {
509 LOG(ERROR) << "Failed to create RenderView in EvaluateJavaScript";
510 return;
514 if (!callback) {
515 // No callback requested.
516 web_contents_->GetMainFrame()->ExecuteJavaScript(
517 ConvertJavaStringToUTF16(env, script));
518 return;
521 // Secure the Java callback in a scoped object and give ownership of it to the
522 // base::Callback.
523 ScopedJavaGlobalRef<jobject> j_callback;
524 j_callback.Reset(env, callback);
525 RenderFrameHost::JavaScriptResultCallback js_callback =
526 base::Bind(&JavaScriptResultCallback, j_callback);
528 web_contents_->GetMainFrame()->ExecuteJavaScript(
529 ConvertJavaStringToUTF16(env, script), js_callback);
532 void WebContentsAndroid::AddMessageToDevToolsConsole(JNIEnv* env,
533 jobject jobj,
534 jint level,
535 jstring message) {
536 DCHECK_GE(level, 0);
537 DCHECK_LE(level, CONSOLE_MESSAGE_LEVEL_LAST);
539 web_contents_->GetMainFrame()->Send(new DevToolsAgentMsg_AddMessageToConsole(
540 web_contents_->GetMainFrame()->GetRoutingID(),
541 static_cast<ConsoleMessageLevel>(level),
542 ConvertJavaStringToUTF8(env, message)));
545 jboolean WebContentsAndroid::HasAccessedInitialDocument(
546 JNIEnv* env,
547 jobject jobj) {
548 return static_cast<WebContentsImpl*>(web_contents_)->
549 HasAccessedInitialDocument();
552 jint WebContentsAndroid::GetThemeColor(JNIEnv* env, jobject obj) {
553 return web_contents_->GetThemeColor();
556 void WebContentsAndroid::RequestAccessibilitySnapshot(JNIEnv* env,
557 jobject obj,
558 jobject callback) {
559 // Secure the Java callback in a scoped object and give ownership of it to the
560 // base::Callback.
561 ScopedJavaGlobalRef<jobject> j_callback;
562 j_callback.Reset(env, callback);
563 WebContentsImpl::AXTreeSnapshotCallback snapshot_callback =
564 base::Bind(&AXTreeSnapshotCallback, j_callback);
566 static_cast<WebContentsImpl*>(web_contents_)->RequestAXTreeSnapshot(
567 snapshot_callback);
570 } // namespace content