1 // Copyright (c) 2012 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/components/web_contents_delegate_android/web_contents_delegate_android.h"
7 #include <android/keycodes.h>
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "content/components/web_contents_delegate_android/color_chooser_android.h"
12 #include "content/public/browser/android/content_view_core.h"
13 #include "content/public/browser/render_widget_host_view.h"
14 #include "content/public/browser/invalidate_type.h"
15 #include "content/public/browser/page_navigator.h"
16 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/web_contents.h"
19 #include "content/public/common/page_transition_types.h"
20 #include "content/public/common/referrer.h"
21 #include "jni/WebContentsDelegateAndroid_jni.h"
22 #include "ui/gfx/rect.h"
23 #include "webkit/glue/window_open_disposition.h"
25 using base::android::AttachCurrentThread
;
26 using base::android::ConvertUTF8ToJavaString
;
27 using base::android::ConvertUTF16ToJavaString
;
28 using base::android::HasClass
;
29 using base::android::ScopedJavaLocalRef
;
33 WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv
* env
, jobject obj
)
34 : weak_java_delegate_(env
, obj
) {
37 WebContentsDelegateAndroid::~WebContentsDelegateAndroid() {
40 ScopedJavaLocalRef
<jobject
>
41 WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv
* env
) const {
42 return weak_java_delegate_
.get(env
);
45 // ----------------------------------------------------------------------------
46 // WebContentsDelegate methods
47 // ----------------------------------------------------------------------------
49 ColorChooser
* WebContentsDelegateAndroid::OpenColorChooser(
53 return ColorChooser::Create(color_chooser_id
, source
, color
);
56 // OpenURLFromTab() will be called when we're performing a browser-intiated
57 // navigation. The most common scenario for this is opening new tabs (see
58 // RenderViewImpl::decidePolicyForNavigation for more details).
59 WebContents
* WebContentsDelegateAndroid::OpenURLFromTab(
61 const OpenURLParams
& params
) {
62 const GURL
& url
= params
.url
;
63 WindowOpenDisposition disposition
= params
.disposition
;
64 PageTransition
transition(
65 PageTransitionFromInt(params
.transition
));
67 if (!source
|| (disposition
!= CURRENT_TAB
&&
68 disposition
!= NEW_FOREGROUND_TAB
&&
69 disposition
!= NEW_BACKGROUND_TAB
&&
70 disposition
!= OFF_THE_RECORD
)) {
75 JNIEnv
* env
= AttachCurrentThread();
76 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
78 return WebContentsDelegate::OpenURLFromTab(source
, params
);
80 if (disposition
== NEW_FOREGROUND_TAB
||
81 disposition
== NEW_BACKGROUND_TAB
||
82 disposition
== OFF_THE_RECORD
) {
83 JNIEnv
* env
= AttachCurrentThread();
84 ScopedJavaLocalRef
<jstring
> java_url
=
85 ConvertUTF8ToJavaString(env
, url
.spec());
86 Java_WebContentsDelegateAndroid_openNewTab(env
,
89 disposition
== OFF_THE_RECORD
);
93 source
->GetController().LoadURL(url
, params
.referrer
, transition
,
98 void WebContentsDelegateAndroid::NavigationStateChanged(
99 const WebContents
* source
, unsigned changed_flags
) {
100 if (changed_flags
& INVALIDATE_TYPE_TITLE
) {
101 JNIEnv
* env
= AttachCurrentThread();
102 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
105 Java_WebContentsDelegateAndroid_onTitleUpdated(
110 void WebContentsDelegateAndroid::AddNewContents(
112 WebContents
* new_contents
,
113 WindowOpenDisposition disposition
,
114 const gfx::Rect
& initial_pos
,
117 JNIEnv
* env
= AttachCurrentThread();
118 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
119 bool handled
= false;
120 if (!obj
.is_null()) {
121 handled
= Java_WebContentsDelegateAndroid_addNewContents(
124 reinterpret_cast<jint
>(source
),
125 reinterpret_cast<jint
>(new_contents
),
126 static_cast<jint
>(disposition
),
134 void WebContentsDelegateAndroid::ActivateContents(WebContents
* contents
) {
135 // TODO(dtrainor) When doing the merge I came across this. Should we be
136 // activating this tab here?
139 void WebContentsDelegateAndroid::DeactivateContents(WebContents
* contents
) {
143 void WebContentsDelegateAndroid::LoadingStateChanged(WebContents
* source
) {
144 JNIEnv
* env
= AttachCurrentThread();
145 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
148 bool has_stopped
= source
== NULL
|| !source
->IsLoading();
151 Java_WebContentsDelegateAndroid_onLoadStopped(env
, obj
.obj());
153 Java_WebContentsDelegateAndroid_onLoadStarted(env
, obj
.obj());
156 void WebContentsDelegateAndroid::LoadProgressChanged(WebContents
* source
,
158 JNIEnv
* env
= AttachCurrentThread();
159 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
162 Java_WebContentsDelegateAndroid_notifyLoadProgressChanged(
168 void WebContentsDelegateAndroid::CloseContents(WebContents
* source
) {
169 JNIEnv
* env
= AttachCurrentThread();
170 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
173 Java_WebContentsDelegateAndroid_closeContents(env
, obj
.obj());
176 void WebContentsDelegateAndroid::MoveContents(WebContents
* source
,
177 const gfx::Rect
& pos
) {
181 bool WebContentsDelegateAndroid::AddMessageToConsole(
184 const string16
& message
,
186 const string16
& source_id
) {
187 JNIEnv
* env
= AttachCurrentThread();
188 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
190 return WebContentsDelegate::AddMessageToConsole(source
, level
, message
,
192 ScopedJavaLocalRef
<jstring
> jmessage(ConvertUTF16ToJavaString(env
, message
));
193 ScopedJavaLocalRef
<jstring
> jsource_id(
194 ConvertUTF16ToJavaString(env
, source_id
));
195 int jlevel
= WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP
;
197 case logging::LOG_VERBOSE
:
198 jlevel
= WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP
;
200 case logging::LOG_INFO
:
201 jlevel
= WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG
;
203 case logging::LOG_WARNING
:
204 jlevel
= WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING
;
206 case logging::LOG_ERROR
:
207 jlevel
= WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR
;
212 return Java_WebContentsDelegateAndroid_addMessageToConsole(
214 GetJavaDelegate(env
).obj(),
221 // This is either called from TabContents::DidNavigateMainFramePostCommit() with
222 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In
223 // Chrome, the latter is not always called, especially not during history
224 // navigation. So we only handle the first case and pass the source TabContents'
225 // url to Java to update the UI.
226 void WebContentsDelegateAndroid::UpdateTargetURL(WebContents
* source
,
231 JNIEnv
* env
= AttachCurrentThread();
232 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
235 ScopedJavaLocalRef
<jstring
> java_url
=
236 ConvertUTF8ToJavaString(env
, source
->GetURL().spec());
237 Java_WebContentsDelegateAndroid_onUpdateUrl(env
,
242 void WebContentsDelegateAndroid::HandleKeyboardEvent(
244 const NativeWebKeyboardEvent
& event
) {
245 jobject key_event
= event
.os_event
;
247 JNIEnv
* env
= AttachCurrentThread();
248 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
251 Java_WebContentsDelegateAndroid_handleKeyboardEvent(
252 env
, obj
.obj(), key_event
);
256 bool WebContentsDelegateAndroid::TakeFocus(WebContents
* source
, bool reverse
) {
257 JNIEnv
* env
= AttachCurrentThread();
258 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
260 return WebContentsDelegate::TakeFocus(source
, reverse
);
261 return Java_WebContentsDelegateAndroid_takeFocus(
262 env
, obj
.obj(), reverse
);
265 void WebContentsDelegateAndroid::ShowRepostFormWarningDialog(
266 WebContents
* source
) {
267 JNIEnv
* env
= AttachCurrentThread();
268 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
271 ScopedJavaLocalRef
<jobject
> content_view_core
=
272 ContentViewCore::FromWebContents(source
)->GetJavaObject();
273 if (content_view_core
.is_null())
275 Java_WebContentsDelegateAndroid_showRepostFormWarningDialog(env
, obj
.obj(),
276 content_view_core
.obj());
279 void WebContentsDelegateAndroid::ToggleFullscreenModeForTab(
280 WebContents
* web_contents
,
281 bool enter_fullscreen
) {
282 JNIEnv
* env
= AttachCurrentThread();
283 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
286 Java_WebContentsDelegateAndroid_toggleFullscreenModeForTab(
287 env
, obj
.obj(), enter_fullscreen
);
290 bool WebContentsDelegateAndroid::IsFullscreenForTabOrPending(
291 const WebContents
* web_contents
) const {
292 JNIEnv
* env
= AttachCurrentThread();
293 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
296 return Java_WebContentsDelegateAndroid_isFullscreenForTabOrPending(
300 // ----------------------------------------------------------------------------
301 // Native JNI methods
302 // ----------------------------------------------------------------------------
304 // Register native methods
306 bool RegisterWebContentsDelegateAndroid(JNIEnv
* env
) {
307 if (!HasClass(env
, kWebContentsDelegateAndroidClassPath
)) {
308 DLOG(ERROR
) << "Unable to find class WebContentsDelegateAndroid!";
311 return RegisterNativesImpl(env
);
314 } // namespace content