Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / android / chrome_web_contents_delegate_android.cc
blob1fb8fcf3d78f72254703226bbd8016c48bcbaaca
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/android/feature_utilities.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/file_select_helper.h"
13 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
14 #include "chrome/browser/media/media_stream_capture_indicator.h"
15 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
16 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
17 #include "chrome/browser/prerender/prerender_manager.h"
18 #include "chrome/browser/prerender/prerender_manager_factory.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/android/bluetooth_chooser_android.h"
21 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
22 #include "chrome/browser/ui/browser_navigator.h"
23 #include "chrome/browser/ui/find_bar/find_notification_details.h"
24 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
25 #include "chrome/browser/ui/tab_helpers.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "components/app_modal/javascript_dialog_manager.h"
28 #include "content/public/browser/notification_details.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/notification_source.h"
31 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/render_view_host.h"
33 #include "content/public/browser/web_contents.h"
34 #include "content/public/common/file_chooser_params.h"
35 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
36 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
37 #include "ui/gfx/geometry/rect.h"
38 #include "ui/gfx/geometry/rect_f.h"
40 #if defined(ENABLE_PLUGINS)
41 #include "chrome/browser/pepper_broker_infobar_delegate.h"
42 #endif
44 using base::android::AttachCurrentThread;
45 using base::android::ScopedJavaLocalRef;
46 using content::BluetoothChooser;
47 using content::FileChooserParams;
48 using content::WebContents;
50 namespace {
52 ScopedJavaLocalRef<jobject> CreateJavaRectF(
53 JNIEnv* env,
54 const gfx::RectF& rect) {
55 return ScopedJavaLocalRef<jobject>(
56 Java_ChromeWebContentsDelegateAndroid_createRectF(env,
57 rect.x(),
58 rect.y(),
59 rect.right(),
60 rect.bottom()));
63 ScopedJavaLocalRef<jobject> CreateJavaRect(
64 JNIEnv* env,
65 const gfx::Rect& rect) {
66 return ScopedJavaLocalRef<jobject>(
67 Java_ChromeWebContentsDelegateAndroid_createRect(
68 env,
69 static_cast<int>(rect.x()),
70 static_cast<int>(rect.y()),
71 static_cast<int>(rect.right()),
72 static_cast<int>(rect.bottom())));
75 } // anonymous namespace
77 namespace chrome {
78 namespace android {
80 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
81 jobject obj)
82 : WebContentsDelegateAndroid(env, obj) {
85 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
86 notification_registrar_.RemoveAll();
89 // Register native methods.
90 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
91 return RegisterNativesImpl(env);
94 void ChromeWebContentsDelegateAndroid::LoadingStateChanged(
95 WebContents* source, bool to_different_document) {
96 bool has_stopped = source == NULL || !source->IsLoading();
97 WebContentsDelegateAndroid::LoadingStateChanged(
98 source, to_different_document);
99 LoadProgressChanged(source, has_stopped ? 1 : 0);
102 void ChromeWebContentsDelegateAndroid::RunFileChooser(
103 WebContents* web_contents,
104 const FileChooserParams& params) {
105 FileSelectHelper::RunFileChooser(web_contents, params);
108 scoped_ptr<BluetoothChooser>
109 ChromeWebContentsDelegateAndroid::RunBluetoothChooser(
110 content::WebContents* web_contents,
111 const BluetoothChooser::EventHandler& event_handler,
112 const GURL& origin) {
113 return make_scoped_ptr(
114 new BluetoothChooserAndroid(web_contents, event_handler, origin));
117 void ChromeWebContentsDelegateAndroid::CloseContents(
118 WebContents* web_contents) {
119 // Prevent dangling registrations assigned to closed web contents.
120 if (notification_registrar_.IsRegistered(this,
121 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
122 content::Source<WebContents>(web_contents))) {
123 notification_registrar_.Remove(this,
124 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
125 content::Source<WebContents>(web_contents));
128 WebContentsDelegateAndroid::CloseContents(web_contents);
131 void ChromeWebContentsDelegateAndroid::Observe(
132 int type,
133 const content::NotificationSource& source,
134 const content::NotificationDetails& details) {
135 switch (type) {
136 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
137 OnFindResultAvailable(
138 content::Source<WebContents>(source).ptr(),
139 content::Details<FindNotificationDetails>(details).ptr());
140 break;
141 default:
142 NOTREACHED() << "Unexpected notification: " << type;
143 break;
147 blink::WebDisplayMode ChromeWebContentsDelegateAndroid::GetDisplayMode(
148 const WebContents* web_contents) const {
149 JNIEnv* env = base::android::AttachCurrentThread();
151 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
152 if (obj.is_null())
153 return blink::WebDisplayModeUndefined;
155 return static_cast<blink::WebDisplayMode>(
156 Java_ChromeWebContentsDelegateAndroid_getDisplayMode(
157 env, obj.obj())
161 void ChromeWebContentsDelegateAndroid::FindReply(
162 WebContents* web_contents,
163 int request_id,
164 int number_of_matches,
165 const gfx::Rect& selection_rect,
166 int active_match_ordinal,
167 bool final_update) {
168 if (!notification_registrar_.IsRegistered(this,
169 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
170 content::Source<WebContents>(web_contents))) {
171 notification_registrar_.Add(this,
172 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
173 content::Source<WebContents>(web_contents));
176 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
177 find_tab_helper->HandleFindReply(request_id,
178 number_of_matches,
179 selection_rect,
180 active_match_ordinal,
181 final_update);
184 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
185 WebContents* web_contents,
186 const FindNotificationDetails* find_result) {
187 JNIEnv* env = base::android::AttachCurrentThread();
188 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
189 if (obj.is_null())
190 return;
192 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
193 env, find_result->selection_rect());
195 // Create the details object.
196 ScopedJavaLocalRef<jobject> details_object =
197 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
198 env,
199 find_result->number_of_matches(),
200 selection_rect.obj(),
201 find_result->active_match_ordinal(),
202 find_result->final_update());
204 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
205 env,
206 obj.obj(),
207 details_object.obj());
210 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
211 WebContents* web_contents,
212 int version,
213 const std::vector<gfx::RectF>& rects,
214 const gfx::RectF& active_rect) {
215 JNIEnv* env = base::android::AttachCurrentThread();
216 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
217 if (obj.is_null())
218 return;
220 // Create the details object.
221 ScopedJavaLocalRef<jobject> details_object =
222 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
223 env,
224 version,
225 rects.size(),
226 CreateJavaRectF(env, active_rect).obj());
228 // Add the rects
229 for (size_t i = 0; i < rects.size(); ++i) {
230 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
231 env,
232 details_object.obj(),
234 CreateJavaRectF(env, rects[i]).obj());
237 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
238 env,
239 obj.obj(),
240 details_object.obj());
243 content::JavaScriptDialogManager*
244 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager(
245 WebContents* source) {
246 return app_modal::JavaScriptDialogManager::GetInstance();
249 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
250 content::WebContents* web_contents,
251 const content::MediaStreamRequest& request,
252 const content::MediaResponseCallback& callback) {
253 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
254 web_contents, request, callback, NULL);
257 bool ChromeWebContentsDelegateAndroid::CheckMediaAccessPermission(
258 content::WebContents* web_contents,
259 const GURL& security_origin,
260 content::MediaStreamType type) {
261 return MediaCaptureDevicesDispatcher::GetInstance()
262 ->CheckMediaAccessPermission(web_contents, security_origin, type);
265 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
266 WebContents* web_contents,
267 const GURL& url,
268 const base::FilePath& plugin_path,
269 const base::Callback<void(bool)>& callback) {
270 #if defined(ENABLE_PLUGINS)
271 PepperBrokerInfoBarDelegate::Create(
272 web_contents, url, plugin_path, callback);
273 return true;
274 #else
275 return false;
276 #endif
279 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
280 WebContents* source,
281 const content::OpenURLParams& params) {
282 WindowOpenDisposition disposition = params.disposition;
283 if (!source || (disposition != CURRENT_TAB &&
284 disposition != NEW_FOREGROUND_TAB &&
285 disposition != NEW_BACKGROUND_TAB &&
286 disposition != OFF_THE_RECORD &&
287 disposition != NEW_POPUP &&
288 disposition != NEW_WINDOW)) {
289 // We can't handle this here. Give the parent a chance.
290 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
293 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
294 chrome::NavigateParams nav_params(profile,
295 params.url,
296 params.transition);
297 FillNavigateParamsFromOpenURLParams(&nav_params, params);
298 nav_params.source_contents = source;
299 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
300 nav_params.user_gesture = params.user_gesture;
302 PopupBlockerTabHelper* popup_blocker_helper =
303 PopupBlockerTabHelper::FromWebContents(source);
304 DCHECK(popup_blocker_helper);
306 if ((params.disposition == NEW_POPUP ||
307 params.disposition == NEW_FOREGROUND_TAB ||
308 params.disposition == NEW_BACKGROUND_TAB ||
309 params.disposition == NEW_WINDOW) &&
310 !params.user_gesture &&
311 !base::CommandLine::ForCurrentProcess()->HasSwitch(
312 switches::kDisablePopupBlocking)) {
313 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
314 blink::WebWindowFeatures())) {
315 return NULL;
319 if (disposition == CURRENT_TAB) {
320 // Only prerender for a current-tab navigation to avoid session storage
321 // namespace issues.
322 nav_params.target_contents = source;
323 prerender::PrerenderManager* prerender_manager =
324 prerender::PrerenderManagerFactory::GetForProfile(profile);
325 if (prerender_manager &&
326 prerender_manager->MaybeUsePrerenderedPage(params.url, &nav_params)) {
327 return nav_params.target_contents;
331 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
334 bool ChromeWebContentsDelegateAndroid::ShouldResumeRequestsForCreatedWindow() {
335 JNIEnv* env = base::android::AttachCurrentThread();
336 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
337 if (obj.is_null())
338 return true;
340 return Java_ChromeWebContentsDelegateAndroid_shouldResumeRequestsForCreatedWindow(
341 env,
342 obj.obj());
345 void ChromeWebContentsDelegateAndroid::AddNewContents(
346 WebContents* source,
347 WebContents* new_contents,
348 WindowOpenDisposition disposition,
349 const gfx::Rect& initial_rect,
350 bool user_gesture,
351 bool* was_blocked) {
352 // No code for this yet.
353 DCHECK_NE(disposition, SAVE_TO_DISK);
354 // Can't create a new contents for the current tab - invalid case.
355 DCHECK_NE(disposition, CURRENT_TAB);
357 TabHelpers::AttachTabHelpers(new_contents);
359 JNIEnv* env = AttachCurrentThread();
360 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
361 bool handled = false;
362 if (!obj.is_null()) {
363 ScopedJavaLocalRef<jobject> jsource;
364 if (source)
365 jsource = source->GetJavaWebContents();
366 ScopedJavaLocalRef<jobject> jnew_contents;
367 if (new_contents)
368 jnew_contents = new_contents->GetJavaWebContents();
370 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
371 env,
372 obj.obj(),
373 jsource.obj(),
374 jnew_contents.obj(),
375 static_cast<jint>(disposition),
376 NULL,
377 user_gesture);
380 if (was_blocked)
381 *was_blocked = !handled;
382 if (!handled)
383 delete new_contents;
386 } // namespace android
387 } // namespace chrome
389 jboolean IsCapturingAudio(JNIEnv* env,
390 const JavaParamRef<jclass>& clazz,
391 const JavaParamRef<jobject>& java_web_contents) {
392 content::WebContents* web_contents =
393 content::WebContents::FromJavaWebContents(java_web_contents);
394 scoped_refptr<MediaStreamCaptureIndicator> indicator =
395 MediaCaptureDevicesDispatcher::GetInstance()->
396 GetMediaStreamCaptureIndicator();
397 return indicator->IsCapturingAudio(web_contents);
400 jboolean IsCapturingVideo(JNIEnv* env,
401 const JavaParamRef<jclass>& clazz,
402 const JavaParamRef<jobject>& java_web_contents) {
403 content::WebContents* web_contents =
404 content::WebContents::FromJavaWebContents(java_web_contents);
405 scoped_refptr<MediaStreamCaptureIndicator> indicator =
406 MediaCaptureDevicesDispatcher::GetInstance()->
407 GetMediaStreamCaptureIndicator();
408 return indicator->IsCapturingVideo(web_contents);