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 "chrome/browser/android/chrome_web_contents_delegate_android.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/command_line.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/file_select_helper.h"
12 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
13 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
14 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
15 #include "chrome/browser/prerender/prerender_manager.h"
16 #include "chrome/browser/prerender/prerender_manager_factory.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
19 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
20 #include "chrome/browser/ui/browser_navigator.h"
21 #include "chrome/browser/ui/find_bar/find_notification_details.h"
22 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
23 #include "chrome/browser/ui/tab_helpers.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_source.h"
28 #include "content/public/browser/render_process_host.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/file_chooser_params.h"
32 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
33 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
34 #include "ui/gfx/rect.h"
35 #include "ui/gfx/rect_f.h"
37 #if defined(ENABLE_PLUGINS)
38 #include "chrome/browser/pepper_broker_infobar_delegate.h"
41 using base::android::AttachCurrentThread
;
42 using base::android::ScopedJavaLocalRef
;
43 using content::FileChooserParams
;
44 using content::WebContents
;
48 ScopedJavaLocalRef
<jobject
> CreateJavaRectF(
50 const gfx::RectF
& rect
) {
51 return ScopedJavaLocalRef
<jobject
>(
52 Java_ChromeWebContentsDelegateAndroid_createRectF(env
,
59 ScopedJavaLocalRef
<jobject
> CreateJavaRect(
61 const gfx::Rect
& rect
) {
62 return ScopedJavaLocalRef
<jobject
>(
63 Java_ChromeWebContentsDelegateAndroid_createRect(
65 static_cast<int>(rect
.x()),
66 static_cast<int>(rect
.y()),
67 static_cast<int>(rect
.right()),
68 static_cast<int>(rect
.bottom())));
71 } // anonymous namespace
76 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv
* env
,
78 : WebContentsDelegateAndroid(env
, obj
) {
81 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
82 notification_registrar_
.RemoveAll();
85 // Register native methods.
86 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv
* env
) {
87 return RegisterNativesImpl(env
);
90 void ChromeWebContentsDelegateAndroid::LoadingStateChanged(
91 WebContents
* source
, bool to_different_document
) {
92 bool has_stopped
= source
== NULL
|| !source
->IsLoading();
93 WebContentsDelegateAndroid::LoadingStateChanged(
94 source
, to_different_document
);
95 LoadProgressChanged(source
, has_stopped
? 1 : 0);
98 void ChromeWebContentsDelegateAndroid::RunFileChooser(
99 WebContents
* web_contents
,
100 const FileChooserParams
& params
) {
101 FileSelectHelper::RunFileChooser(web_contents
, params
);
104 void ChromeWebContentsDelegateAndroid::CloseContents(
105 WebContents
* web_contents
) {
106 // Prevent dangling registrations assigned to closed web contents.
107 if (notification_registrar_
.IsRegistered(this,
108 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE
,
109 content::Source
<WebContents
>(web_contents
))) {
110 notification_registrar_
.Remove(this,
111 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE
,
112 content::Source
<WebContents
>(web_contents
));
115 WebContentsDelegateAndroid::CloseContents(web_contents
);
118 void ChromeWebContentsDelegateAndroid::Observe(
120 const content::NotificationSource
& source
,
121 const content::NotificationDetails
& details
) {
123 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE
:
124 OnFindResultAvailable(
125 content::Source
<WebContents
>(source
).ptr(),
126 content::Details
<FindNotificationDetails
>(details
).ptr());
129 NOTREACHED() << "Unexpected notification: " << type
;
134 void ChromeWebContentsDelegateAndroid::FindReply(
135 WebContents
* web_contents
,
137 int number_of_matches
,
138 const gfx::Rect
& selection_rect
,
139 int active_match_ordinal
,
141 if (!notification_registrar_
.IsRegistered(this,
142 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE
,
143 content::Source
<WebContents
>(web_contents
))) {
144 notification_registrar_
.Add(this,
145 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE
,
146 content::Source
<WebContents
>(web_contents
));
149 FindTabHelper
* find_tab_helper
= FindTabHelper::FromWebContents(web_contents
);
150 find_tab_helper
->HandleFindReply(request_id
,
153 active_match_ordinal
,
157 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
158 WebContents
* web_contents
,
159 const FindNotificationDetails
* find_result
) {
160 JNIEnv
* env
= base::android::AttachCurrentThread();
161 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
165 ScopedJavaLocalRef
<jobject
> selection_rect
= CreateJavaRect(
166 env
, find_result
->selection_rect());
168 // Create the details object.
169 ScopedJavaLocalRef
<jobject
> details_object
=
170 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
172 find_result
->number_of_matches(),
173 selection_rect
.obj(),
174 find_result
->active_match_ordinal(),
175 find_result
->final_update());
177 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
180 details_object
.obj());
183 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
184 WebContents
* web_contents
,
186 const std::vector
<gfx::RectF
>& rects
,
187 const gfx::RectF
& active_rect
) {
188 JNIEnv
* env
= base::android::AttachCurrentThread();
189 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
193 // Create the details object.
194 ScopedJavaLocalRef
<jobject
> details_object
=
195 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
199 CreateJavaRectF(env
, active_rect
).obj());
202 for (size_t i
= 0; i
< rects
.size(); ++i
) {
203 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
205 details_object
.obj(),
207 CreateJavaRectF(env
, rects
[i
]).obj());
210 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
213 details_object
.obj());
216 content::JavaScriptDialogManager
*
217 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager() {
218 return GetJavaScriptDialogManagerInstance();
221 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
222 content::WebContents
* web_contents
,
223 const content::MediaStreamRequest
& request
,
224 const content::MediaResponseCallback
& callback
) {
225 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
226 web_contents
, request
, callback
, NULL
);
229 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
230 WebContents
* web_contents
,
232 const base::FilePath
& plugin_path
,
233 const base::Callback
<void(bool)>& callback
) {
234 #if defined(ENABLE_PLUGINS)
235 PepperBrokerInfoBarDelegate::Create(
236 web_contents
, url
, plugin_path
, callback
);
243 WebContents
* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
245 const content::OpenURLParams
& params
) {
246 WindowOpenDisposition disposition
= params
.disposition
;
247 if (!source
|| (disposition
!= CURRENT_TAB
&&
248 disposition
!= NEW_FOREGROUND_TAB
&&
249 disposition
!= NEW_BACKGROUND_TAB
&&
250 disposition
!= OFF_THE_RECORD
&&
251 disposition
!= NEW_POPUP
&&
252 disposition
!= NEW_WINDOW
)) {
253 // We can't handle this here. Give the parent a chance.
254 return WebContentsDelegateAndroid::OpenURLFromTab(source
, params
);
257 Profile
* profile
= Profile::FromBrowserContext(source
->GetBrowserContext());
258 chrome::NavigateParams
nav_params(profile
,
261 FillNavigateParamsFromOpenURLParams(&nav_params
, params
);
262 nav_params
.source_contents
= source
;
263 nav_params
.window_action
= chrome::NavigateParams::SHOW_WINDOW
;
264 nav_params
.user_gesture
= params
.user_gesture
;
266 PopupBlockerTabHelper
* popup_blocker_helper
=
267 PopupBlockerTabHelper::FromWebContents(source
);
268 DCHECK(popup_blocker_helper
);
270 if ((params
.disposition
== NEW_POPUP
||
271 params
.disposition
== NEW_FOREGROUND_TAB
||
272 params
.disposition
== NEW_BACKGROUND_TAB
||
273 params
.disposition
== NEW_WINDOW
) &&
274 !params
.user_gesture
&&
275 !CommandLine::ForCurrentProcess()->HasSwitch(
276 switches::kDisablePopupBlocking
)) {
277 if (popup_blocker_helper
->MaybeBlockPopup(nav_params
,
278 blink::WebWindowFeatures())) {
283 if (disposition
== CURRENT_TAB
) {
284 // Only prerender for a current-tab navigation to avoid session storage
286 nav_params
.target_contents
= source
;
287 prerender::PrerenderManager
* prerender_manager
=
288 prerender::PrerenderManagerFactory::GetForProfile(profile
);
289 if (prerender_manager
&&
290 prerender_manager
->MaybeUsePrerenderedPage(params
.url
, &nav_params
)) {
291 return nav_params
.target_contents
;
295 return WebContentsDelegateAndroid::OpenURLFromTab(source
, params
);
298 void ChromeWebContentsDelegateAndroid::AddNewContents(
300 WebContents
* new_contents
,
301 WindowOpenDisposition disposition
,
302 const gfx::Rect
& initial_pos
,
305 // No code for this yet.
306 DCHECK_NE(disposition
, SAVE_TO_DISK
);
307 // Can't create a new contents for the current tab - invalid case.
308 DCHECK_NE(disposition
, CURRENT_TAB
);
310 TabHelpers::AttachTabHelpers(new_contents
);
312 JNIEnv
* env
= AttachCurrentThread();
313 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
314 bool handled
= false;
315 if (!obj
.is_null()) {
316 handled
= Java_ChromeWebContentsDelegateAndroid_addNewContents(
319 reinterpret_cast<intptr_t>(source
),
320 reinterpret_cast<intptr_t>(new_contents
),
321 static_cast<jint
>(disposition
),
330 void ChromeWebContentsDelegateAndroid::WebContentsCreated(
331 content::WebContents
* source_contents
, int opener_render_frame_id
,
332 const base::string16
& frame_name
, const GURL
& target_url
,
333 content::WebContents
* new_contents
) {
334 JNIEnv
* env
= AttachCurrentThread();
335 ScopedJavaLocalRef
<jobject
> obj
= GetJavaDelegate(env
);
338 Java_ChromeWebContentsDelegateAndroid_webContentsCreated(env
, obj
.obj(),
339 reinterpret_cast<intptr_t>(source_contents
), opener_render_frame_id
,
340 base::android::ConvertUTF16ToJavaString(env
, frame_name
).Release(),
341 base::android::ConvertUTF8ToJavaString(env
, target_url
.spec()).Release(),
342 reinterpret_cast<intptr_t>(new_contents
));
345 } // namespace android
346 } // namespace chrome