ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / browser / web_contents / web_contents_android.cc
blob5e2b1284c7f186f55c9b27d8b0cffa4c0642622a
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_string.h"
9 #include "base/command_line.h"
10 #include "base/json/json_writer.h"
11 #include "base/logging.h"
12 #include "content/browser/android/interstitial_page_delegate_android.h"
13 #include "content/browser/frame_host/interstitial_page_impl.h"
14 #include "content/browser/media/android/browser_media_player_manager.h"
15 #include "content/browser/media/media_web_contents_observer.h"
16 #include "content/browser/renderer_host/render_view_host_impl.h"
17 #include "content/browser/web_contents/web_contents_impl.h"
18 #include "content/common/devtools_messages.h"
19 #include "content/common/frame_messages.h"
20 #include "content/common/input_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/common/content_switches.h"
26 #include "jni/WebContentsImpl_jni.h"
28 using base::android::AttachCurrentThread;
29 using base::android::ConvertJavaStringToUTF8;
30 using base::android::ConvertJavaStringToUTF16;
31 using base::android::ConvertUTF8ToJavaString;
32 using base::android::ScopedJavaGlobalRef;
34 namespace {
36 void JavaScriptResultCallback(const ScopedJavaGlobalRef<jobject>& callback,
37 const base::Value* result) {
38 JNIEnv* env = base::android::AttachCurrentThread();
39 std::string json;
40 base::JSONWriter::Write(result, &json);
41 ScopedJavaLocalRef<jstring> j_json = ConvertUTF8ToJavaString(env, json);
42 content::Java_WebContentsImpl_onEvaluateJavaScriptResult(
43 env, j_json.obj(), callback.obj());
46 void ReleaseAllMediaPlayers(content::WebContents* web_contents,
47 content::RenderFrameHost* render_frame_host) {
48 content::BrowserMediaPlayerManager* manager =
49 static_cast<content::WebContentsImpl*>(web_contents)->
50 media_web_contents_observer()->GetMediaPlayerManager(
51 render_frame_host);
52 if (manager)
53 manager->ReleaseAllMediaPlayers();
56 } // namespace
58 namespace content {
60 // static
61 WebContents* WebContents::FromJavaWebContents(
62 jobject jweb_contents_android) {
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
64 if (!jweb_contents_android)
65 return NULL;
67 WebContentsAndroid* web_contents_android =
68 reinterpret_cast<WebContentsAndroid*>(
69 Java_WebContentsImpl_getNativePointer(AttachCurrentThread(),
70 jweb_contents_android));
71 if (!web_contents_android)
72 return NULL;
73 return web_contents_android->web_contents();
76 // static
77 static void DestroyWebContents(JNIEnv* env,
78 jclass clazz,
79 jlong jweb_contents_android_ptr) {
80 WebContentsAndroid* web_contents_android =
81 reinterpret_cast<WebContentsAndroid*>(jweb_contents_android_ptr);
82 if (!web_contents_android)
83 return;
85 content::WebContents* web_contents = web_contents_android->web_contents();
86 if (!web_contents)
87 return;
89 delete web_contents;
92 // static
93 bool WebContentsAndroid::Register(JNIEnv* env) {
94 return RegisterNativesImpl(env);
97 WebContentsAndroid::WebContentsAndroid(WebContents* web_contents)
98 : web_contents_(web_contents),
99 navigation_controller_(&(web_contents->GetController())),
100 weak_factory_(this) {
101 JNIEnv* env = AttachCurrentThread();
102 obj_.Reset(env,
103 Java_WebContentsImpl_create(
104 env,
105 reinterpret_cast<intptr_t>(this),
106 navigation_controller_.GetJavaObject().obj()).obj());
109 WebContentsAndroid::~WebContentsAndroid() {
110 Java_WebContentsImpl_clearNativePtr(AttachCurrentThread(), obj_.obj());
113 base::android::ScopedJavaLocalRef<jobject>
114 WebContentsAndroid::GetJavaObject() {
115 return base::android::ScopedJavaLocalRef<jobject>(obj_);
118 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle(
119 JNIEnv* env, jobject obj) const {
120 return base::android::ConvertUTF16ToJavaString(env,
121 web_contents_->GetTitle());
124 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetVisibleURL(
125 JNIEnv* env, jobject obj) const {
126 return base::android::ConvertUTF8ToJavaString(
127 env, web_contents_->GetVisibleURL().spec());
130 bool WebContentsAndroid::IsLoading(JNIEnv* env, jobject obj) const {
131 return web_contents_->IsLoading();
134 bool WebContentsAndroid::IsLoadingToDifferentDocument(JNIEnv* env,
135 jobject obj) const {
136 return web_contents_->IsLoadingToDifferentDocument();
139 void WebContentsAndroid::Stop(JNIEnv* env, jobject obj) {
140 web_contents_->Stop();
143 void WebContentsAndroid::InsertCSS(
144 JNIEnv* env, jobject jobj, jstring jcss) {
145 web_contents_->InsertCSS(base::android::ConvertJavaStringToUTF8(env, jcss));
148 RenderWidgetHostViewAndroid*
149 WebContentsAndroid::GetRenderWidgetHostViewAndroid() {
150 RenderWidgetHostView* rwhv = NULL;
151 rwhv = web_contents_->GetRenderWidgetHostView();
152 if (web_contents_->ShowingInterstitialPage()) {
153 rwhv = web_contents_->GetInterstitialPage()
154 ->GetMainFrame()
155 ->GetRenderViewHost()
156 ->GetView();
158 return static_cast<RenderWidgetHostViewAndroid*>(rwhv);
161 jint WebContentsAndroid::GetBackgroundColor(JNIEnv* env, jobject obj) {
162 RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
163 if (!rwhva)
164 return SK_ColorWHITE;
165 return rwhva->GetCachedBackgroundColor();
168 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetURL(JNIEnv* env,
169 jobject obj) const {
170 return ConvertUTF8ToJavaString(env, web_contents_->GetURL().spec());
173 jboolean WebContentsAndroid::IsIncognito(JNIEnv* env, jobject obj) {
174 return web_contents_->GetBrowserContext()->IsOffTheRecord();
177 void WebContentsAndroid::ResumeResponseDeferredAtStart(JNIEnv* env,
178 jobject obj) {
179 static_cast<WebContentsImpl*>(web_contents_)->ResumeResponseDeferredAtStart();
182 void WebContentsAndroid::SetHasPendingNavigationTransitionForTesting(
183 JNIEnv* env,
184 jobject obj) {
185 base::CommandLine::ForCurrentProcess()->AppendSwitch(
186 switches::kEnableExperimentalWebPlatformFeatures);
187 RenderFrameHost* frame =
188 static_cast<WebContentsImpl*>(web_contents_)->GetMainFrame();
189 BrowserThread::PostTask(
190 BrowserThread::IO,
191 FROM_HERE,
192 base::Bind(
193 &TransitionRequestManager::AddPendingTransitionRequestDataForTesting,
194 base::Unretained(TransitionRequestManager::GetInstance()),
195 frame->GetProcess()->GetID(),
196 frame->GetRoutingID()));
199 void WebContentsAndroid::SetupTransitionView(JNIEnv* env,
200 jobject jobj,
201 jstring markup) {
202 web_contents_->GetMainFrame()->Send(new FrameMsg_SetupTransitionView(
203 web_contents_->GetMainFrame()->GetRoutingID(),
204 ConvertJavaStringToUTF8(env, markup)));
207 void WebContentsAndroid::BeginExitTransition(JNIEnv* env,
208 jobject jobj,
209 jstring css_selector,
210 jboolean exit_to_native_app) {
211 web_contents_->GetMainFrame()->Send(new FrameMsg_BeginExitTransition(
212 web_contents_->GetMainFrame()->GetRoutingID(),
213 ConvertJavaStringToUTF8(env, css_selector),
214 exit_to_native_app));
217 void WebContentsAndroid::RevertExitTransition(JNIEnv* env,
218 jobject jobj) {
219 web_contents_->GetMainFrame()->Send(new FrameMsg_RevertExitTransition(
220 web_contents_->GetMainFrame()->GetRoutingID()));
223 void WebContentsAndroid::HideTransitionElements(JNIEnv* env,
224 jobject jobj,
225 jstring css_selector) {
226 web_contents_->GetMainFrame()->Send(
227 new FrameMsg_HideTransitionElements(
228 web_contents_->GetMainFrame()->GetRoutingID(),
229 ConvertJavaStringToUTF8(env, css_selector)));
232 void WebContentsAndroid::ShowTransitionElements(JNIEnv* env,
233 jobject jobj,
234 jstring css_selector) {
235 web_contents_->GetMainFrame()->Send(
236 new FrameMsg_ShowTransitionElements(
237 web_contents_->GetMainFrame()->GetRoutingID(),
238 ConvertJavaStringToUTF8(env, css_selector)));
242 void WebContentsAndroid::ClearNavigationTransitionData(JNIEnv* env,
243 jobject jobj) {
244 static_cast<WebContentsImpl*>(web_contents_)->ClearNavigationTransitionData();
247 void WebContentsAndroid::FetchTransitionElements(JNIEnv* env,
248 jobject jobj,
249 jstring jurl) {
250 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
251 RenderFrameHost* frame = web_contents_->GetMainFrame();
253 scoped_ptr<TransitionLayerData> transition_data(new TransitionLayerData());
254 BrowserThread::PostTaskAndReplyWithResult(
255 BrowserThread::IO,
256 FROM_HERE,
257 base::Bind(&TransitionRequestManager::GetPendingTransitionRequest,
258 base::Unretained(TransitionRequestManager::GetInstance()),
259 frame->GetProcess()->GetID(),
260 frame->GetRoutingID(),
261 url,
262 transition_data.get()),
263 base::Bind(&WebContentsAndroid::OnTransitionElementsFetched,
264 weak_factory_.GetWeakPtr(),
265 base::Passed(&transition_data)));
268 void WebContentsAndroid::OnTransitionElementsFetched(
269 scoped_ptr<const TransitionLayerData> transition_data,
270 bool has_transition_data) {
271 // FetchTransitionElements is called after the navigation transition state
272 // machine starts, which means there must be transition data.
273 DCHECK(has_transition_data);
274 JNIEnv* env = AttachCurrentThread();
276 std::vector<TransitionElement>::const_iterator it =
277 transition_data->elements.begin();
278 for (; it != transition_data->elements.end(); ++it) {
279 ScopedJavaLocalRef<jstring> jstring_name(ConvertUTF8ToJavaString(env,
280 it->id));
281 Java_WebContentsImpl_addNavigationTransitionElements(
282 env, obj_.obj(), jstring_name.obj(),
283 it->rect.x(), it->rect.y(), it->rect.width(), it->rect.height());
286 ScopedJavaLocalRef<jstring> jstring_css_selector(
287 ConvertUTF8ToJavaString(env, transition_data->css_selector));
288 Java_WebContentsImpl_onTransitionElementsFetched(
289 env, obj_.obj(), jstring_css_selector.obj());
292 void WebContentsAndroid::OnHide(JNIEnv* env, jobject obj) {
293 web_contents_->WasHidden();
296 void WebContentsAndroid::OnShow(JNIEnv* env, jobject obj) {
297 web_contents_->WasShown();
300 void WebContentsAndroid::ReleaseMediaPlayers(JNIEnv* env, jobject jobj) {
301 #if defined(ENABLE_BROWSER_CDMS)
302 web_contents_->ForEachFrame(
303 base::Bind(&ReleaseAllMediaPlayers, base::Unretained(web_contents_)));
304 #endif // defined(ENABLE_BROWSER_CDMS)
307 void WebContentsAndroid::AddStyleSheetByURL(
308 JNIEnv* env,
309 jobject obj,
310 jstring url) {
311 web_contents_->GetMainFrame()->Send(new FrameMsg_AddStyleSheetByURL(
312 web_contents_->GetMainFrame()->GetRoutingID(),
313 ConvertJavaStringToUTF8(env, url)));
316 void WebContentsAndroid::ShowInterstitialPage(
317 JNIEnv* env,
318 jobject obj,
319 jstring jurl,
320 jlong delegate_ptr) {
321 GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
322 InterstitialPageDelegateAndroid* delegate =
323 reinterpret_cast<InterstitialPageDelegateAndroid*>(delegate_ptr);
324 InterstitialPage* interstitial = InterstitialPage::Create(
325 web_contents_, false, url, delegate);
326 delegate->set_interstitial_page(interstitial);
327 interstitial->Show();
330 jboolean WebContentsAndroid::IsShowingInterstitialPage(JNIEnv* env,
331 jobject obj) {
332 return web_contents_->ShowingInterstitialPage();
335 jboolean WebContentsAndroid::IsRenderWidgetHostViewReady(
336 JNIEnv* env,
337 jobject obj) {
338 RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
339 return view && view->HasValidFrame();
342 void WebContentsAndroid::ExitFullscreen(JNIEnv* env, jobject obj) {
343 web_contents_->ExitFullscreen();
346 void WebContentsAndroid::UpdateTopControlsState(
347 JNIEnv* env,
348 jobject obj,
349 bool enable_hiding,
350 bool enable_showing,
351 bool animate) {
352 RenderViewHost* host = web_contents_->GetRenderViewHost();
353 if (!host)
354 return;
355 host->Send(new ViewMsg_UpdateTopControlsState(host->GetRoutingID(),
356 enable_hiding,
357 enable_showing,
358 animate));
361 void WebContentsAndroid::ShowImeIfNeeded(JNIEnv* env, jobject obj) {
362 RenderViewHost* host = web_contents_->GetRenderViewHost();
363 if (!host)
364 return;
365 host->Send(new ViewMsg_ShowImeIfNeeded(host->GetRoutingID()));
368 void WebContentsAndroid::ScrollFocusedEditableNodeIntoView(
369 JNIEnv* env,
370 jobject obj) {
371 RenderViewHost* host = web_contents_->GetRenderViewHost();
372 if (!host)
373 return;
374 host->Send(new InputMsg_ScrollFocusedEditableNodeIntoRect(
375 host->GetRoutingID(), gfx::Rect()));
378 void WebContentsAndroid::SelectWordAroundCaret(JNIEnv* env, jobject obj) {
379 RenderViewHost* host = web_contents_->GetRenderViewHost();
380 if (!host)
381 return;
382 host->SelectWordAroundCaret();
385 bool WebContentsAndroid::WillHandleDeferAfterResponseStarted() {
386 JNIEnv* env = AttachCurrentThread();
387 return Java_WebContentsImpl_willHandleDeferAfterResponseStarted(env,
388 obj_.obj());
391 void WebContentsAndroid::DidDeferAfterResponseStarted(
392 const TransitionLayerData& transition_data) {
393 JNIEnv* env = AttachCurrentThread();
394 std::vector<GURL> entering_stylesheets;
395 std::string transition_color;
396 if (transition_data.response_headers.get()) {
397 TransitionRequestManager::ParseTransitionStylesheetsFromHeaders(
398 transition_data.response_headers,
399 entering_stylesheets,
400 transition_data.request_url);
402 transition_data.response_headers->EnumerateHeader(
403 NULL, "X-Transition-Entering-Color", &transition_color);
406 ScopedJavaLocalRef<jstring> jstring_markup(
407 ConvertUTF8ToJavaString(env, transition_data.markup));
409 ScopedJavaLocalRef<jstring> jstring_css_selector(
410 ConvertUTF8ToJavaString(env, transition_data.css_selector));
412 ScopedJavaLocalRef<jstring> jstring_transition_color(
413 ConvertUTF8ToJavaString(env, transition_color));
415 Java_WebContentsImpl_didDeferAfterResponseStarted(
416 env,
417 obj_.obj(),
418 jstring_markup.obj(),
419 jstring_css_selector.obj(),
420 jstring_transition_color.obj());
422 std::vector<GURL>::const_iterator iter = entering_stylesheets.begin();
423 for (; iter != entering_stylesheets.end(); ++iter) {
424 ScopedJavaLocalRef<jstring> jstring_url(
425 ConvertUTF8ToJavaString(env, iter->spec()));
426 Java_WebContentsImpl_addEnteringStylesheetToTransition(
427 env, obj_.obj(), jstring_url.obj());
431 void WebContentsAndroid::DidStartNavigationTransitionForFrame(int64 frame_id) {
432 JNIEnv* env = AttachCurrentThread();
433 Java_WebContentsImpl_didStartNavigationTransitionForFrame(
434 env, obj_.obj(), frame_id);
437 void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
438 jobject obj,
439 jstring script,
440 jobject callback) {
441 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
442 DCHECK(rvh);
444 if (!rvh->IsRenderViewLive()) {
445 if (!static_cast<WebContentsImpl*>(web_contents_)->
446 CreateRenderViewForInitialEmptyDocument()) {
447 LOG(ERROR) << "Failed to create RenderView in EvaluateJavaScript";
448 return;
452 if (!callback) {
453 // No callback requested.
454 web_contents_->GetMainFrame()->ExecuteJavaScript(
455 ConvertJavaStringToUTF16(env, script));
456 return;
459 // Secure the Java callback in a scoped object and give ownership of it to the
460 // base::Callback.
461 ScopedJavaGlobalRef<jobject> j_callback;
462 j_callback.Reset(env, callback);
463 content::RenderFrameHost::JavaScriptResultCallback js_callback =
464 base::Bind(&JavaScriptResultCallback, j_callback);
466 web_contents_->GetMainFrame()->ExecuteJavaScript(
467 ConvertJavaStringToUTF16(env, script), js_callback);
470 void WebContentsAndroid::AddMessageToDevToolsConsole(JNIEnv* env,
471 jobject jobj,
472 jint level,
473 jstring message) {
474 DCHECK_GE(level, 0);
475 DCHECK_LE(level, CONSOLE_MESSAGE_LEVEL_LAST);
477 web_contents_->GetMainFrame()->Send(new DevToolsAgentMsg_AddMessageToConsole(
478 web_contents_->GetMainFrame()->GetRoutingID(),
479 static_cast<ConsoleMessageLevel>(level),
480 ConvertJavaStringToUTF8(env, message)));
483 } // namespace content