Rename CoalescedPermissionMessage to PermissionMessage
[chromium-blink-merge.git] / chrome / browser / android / chrome_web_contents_delegate_android.cc
blob7924f64c50a6f65b02c55da99a29f8ca52f19835
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/blocked_content/popup_blocker_tab_helper.h"
21 #include "chrome/browser/ui/browser_navigator.h"
22 #include "chrome/browser/ui/find_bar/find_notification_details.h"
23 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
24 #include "chrome/browser/ui/tab_helpers.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "components/app_modal/javascript_dialog_manager.h"
27 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/render_process_host.h"
31 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/web_contents.h"
33 #include "content/public/common/file_chooser_params.h"
34 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
35 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
36 #include "ui/gfx/geometry/rect.h"
37 #include "ui/gfx/geometry/rect_f.h"
39 #if defined(ENABLE_PLUGINS)
40 #include "chrome/browser/pepper_broker_infobar_delegate.h"
41 #endif
43 using base::android::AttachCurrentThread;
44 using base::android::ScopedJavaLocalRef;
45 using content::FileChooserParams;
46 using content::WebContents;
48 namespace {
50 ScopedJavaLocalRef<jobject> CreateJavaRectF(
51 JNIEnv* env,
52 const gfx::RectF& rect) {
53 return ScopedJavaLocalRef<jobject>(
54 Java_ChromeWebContentsDelegateAndroid_createRectF(env,
55 rect.x(),
56 rect.y(),
57 rect.right(),
58 rect.bottom()));
61 ScopedJavaLocalRef<jobject> CreateJavaRect(
62 JNIEnv* env,
63 const gfx::Rect& rect) {
64 return ScopedJavaLocalRef<jobject>(
65 Java_ChromeWebContentsDelegateAndroid_createRect(
66 env,
67 static_cast<int>(rect.x()),
68 static_cast<int>(rect.y()),
69 static_cast<int>(rect.right()),
70 static_cast<int>(rect.bottom())));
73 } // anonymous namespace
75 namespace chrome {
76 namespace android {
78 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
79 jobject obj)
80 : WebContentsDelegateAndroid(env, obj) {
83 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
84 notification_registrar_.RemoveAll();
87 // Register native methods.
88 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
89 return RegisterNativesImpl(env);
92 void ChromeWebContentsDelegateAndroid::LoadingStateChanged(
93 WebContents* source, bool to_different_document) {
94 bool has_stopped = source == NULL || !source->IsLoading();
95 WebContentsDelegateAndroid::LoadingStateChanged(
96 source, to_different_document);
97 LoadProgressChanged(source, has_stopped ? 1 : 0);
100 void ChromeWebContentsDelegateAndroid::RunFileChooser(
101 WebContents* web_contents,
102 const FileChooserParams& params) {
103 FileSelectHelper::RunFileChooser(web_contents, params);
106 void ChromeWebContentsDelegateAndroid::CloseContents(
107 WebContents* web_contents) {
108 // Prevent dangling registrations assigned to closed web contents.
109 if (notification_registrar_.IsRegistered(this,
110 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
111 content::Source<WebContents>(web_contents))) {
112 notification_registrar_.Remove(this,
113 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
114 content::Source<WebContents>(web_contents));
117 WebContentsDelegateAndroid::CloseContents(web_contents);
120 void ChromeWebContentsDelegateAndroid::Observe(
121 int type,
122 const content::NotificationSource& source,
123 const content::NotificationDetails& details) {
124 switch (type) {
125 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
126 OnFindResultAvailable(
127 content::Source<WebContents>(source).ptr(),
128 content::Details<FindNotificationDetails>(details).ptr());
129 break;
130 default:
131 NOTREACHED() << "Unexpected notification: " << type;
132 break;
136 blink::WebDisplayMode ChromeWebContentsDelegateAndroid::GetDisplayMode(
137 const WebContents* web_contents) const {
138 JNIEnv* env = base::android::AttachCurrentThread();
140 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
141 if (obj.is_null())
142 return blink::WebDisplayModeUndefined;
144 return static_cast<blink::WebDisplayMode>(
145 Java_ChromeWebContentsDelegateAndroid_getDisplayMode(
146 env, obj.obj())
150 void ChromeWebContentsDelegateAndroid::FindReply(
151 WebContents* web_contents,
152 int request_id,
153 int number_of_matches,
154 const gfx::Rect& selection_rect,
155 int active_match_ordinal,
156 bool final_update) {
157 if (!notification_registrar_.IsRegistered(this,
158 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
159 content::Source<WebContents>(web_contents))) {
160 notification_registrar_.Add(this,
161 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
162 content::Source<WebContents>(web_contents));
165 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
166 find_tab_helper->HandleFindReply(request_id,
167 number_of_matches,
168 selection_rect,
169 active_match_ordinal,
170 final_update);
173 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
174 WebContents* web_contents,
175 const FindNotificationDetails* find_result) {
176 JNIEnv* env = base::android::AttachCurrentThread();
177 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
178 if (obj.is_null())
179 return;
181 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
182 env, find_result->selection_rect());
184 // Create the details object.
185 ScopedJavaLocalRef<jobject> details_object =
186 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
187 env,
188 find_result->number_of_matches(),
189 selection_rect.obj(),
190 find_result->active_match_ordinal(),
191 find_result->final_update());
193 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
194 env,
195 obj.obj(),
196 details_object.obj());
199 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
200 WebContents* web_contents,
201 int version,
202 const std::vector<gfx::RectF>& rects,
203 const gfx::RectF& active_rect) {
204 JNIEnv* env = base::android::AttachCurrentThread();
205 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
206 if (obj.is_null())
207 return;
209 // Create the details object.
210 ScopedJavaLocalRef<jobject> details_object =
211 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
212 env,
213 version,
214 rects.size(),
215 CreateJavaRectF(env, active_rect).obj());
217 // Add the rects
218 for (size_t i = 0; i < rects.size(); ++i) {
219 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
220 env,
221 details_object.obj(),
223 CreateJavaRectF(env, rects[i]).obj());
226 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
227 env,
228 obj.obj(),
229 details_object.obj());
232 content::JavaScriptDialogManager*
233 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager(
234 WebContents* source) {
235 return app_modal::JavaScriptDialogManager::GetInstance();
238 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
239 content::WebContents* web_contents,
240 const content::MediaStreamRequest& request,
241 const content::MediaResponseCallback& callback) {
242 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
243 web_contents, request, callback, NULL);
246 bool ChromeWebContentsDelegateAndroid::CheckMediaAccessPermission(
247 content::WebContents* web_contents,
248 const GURL& security_origin,
249 content::MediaStreamType type) {
250 return MediaCaptureDevicesDispatcher::GetInstance()
251 ->CheckMediaAccessPermission(web_contents, security_origin, type);
254 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
255 WebContents* web_contents,
256 const GURL& url,
257 const base::FilePath& plugin_path,
258 const base::Callback<void(bool)>& callback) {
259 #if defined(ENABLE_PLUGINS)
260 PepperBrokerInfoBarDelegate::Create(
261 web_contents, url, plugin_path, callback);
262 return true;
263 #else
264 return false;
265 #endif
268 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
269 WebContents* source,
270 const content::OpenURLParams& params) {
271 WindowOpenDisposition disposition = params.disposition;
272 if (!source || (disposition != CURRENT_TAB &&
273 disposition != NEW_FOREGROUND_TAB &&
274 disposition != NEW_BACKGROUND_TAB &&
275 disposition != OFF_THE_RECORD &&
276 disposition != NEW_POPUP &&
277 disposition != NEW_WINDOW)) {
278 // We can't handle this here. Give the parent a chance.
279 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
282 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
283 chrome::NavigateParams nav_params(profile,
284 params.url,
285 params.transition);
286 FillNavigateParamsFromOpenURLParams(&nav_params, params);
287 nav_params.source_contents = source;
288 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
289 nav_params.user_gesture = params.user_gesture;
291 PopupBlockerTabHelper* popup_blocker_helper =
292 PopupBlockerTabHelper::FromWebContents(source);
293 DCHECK(popup_blocker_helper);
295 if ((params.disposition == NEW_POPUP ||
296 params.disposition == NEW_FOREGROUND_TAB ||
297 params.disposition == NEW_BACKGROUND_TAB ||
298 params.disposition == NEW_WINDOW) &&
299 !params.user_gesture &&
300 !base::CommandLine::ForCurrentProcess()->HasSwitch(
301 switches::kDisablePopupBlocking)) {
302 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
303 blink::WebWindowFeatures())) {
304 return NULL;
308 if (disposition == CURRENT_TAB) {
309 // Only prerender for a current-tab navigation to avoid session storage
310 // namespace issues.
311 nav_params.target_contents = source;
312 prerender::PrerenderManager* prerender_manager =
313 prerender::PrerenderManagerFactory::GetForProfile(profile);
314 if (prerender_manager &&
315 prerender_manager->MaybeUsePrerenderedPage(params.url, &nav_params)) {
316 return nav_params.target_contents;
320 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
323 bool ChromeWebContentsDelegateAndroid::ShouldResumeRequestsForCreatedWindow() {
324 JNIEnv* env = base::android::AttachCurrentThread();
325 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
326 if (obj.is_null())
327 return true;
329 return Java_ChromeWebContentsDelegateAndroid_shouldResumeRequestsForCreatedWindow(
330 env,
331 obj.obj());
334 void ChromeWebContentsDelegateAndroid::AddNewContents(
335 WebContents* source,
336 WebContents* new_contents,
337 WindowOpenDisposition disposition,
338 const gfx::Rect& initial_rect,
339 bool user_gesture,
340 bool* was_blocked) {
341 // No code for this yet.
342 DCHECK_NE(disposition, SAVE_TO_DISK);
343 // Can't create a new contents for the current tab - invalid case.
344 DCHECK_NE(disposition, CURRENT_TAB);
346 TabHelpers::AttachTabHelpers(new_contents);
348 JNIEnv* env = AttachCurrentThread();
349 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
350 bool handled = false;
351 if (!obj.is_null()) {
352 ScopedJavaLocalRef<jobject> jsource;
353 if (source)
354 jsource = source->GetJavaWebContents();
355 ScopedJavaLocalRef<jobject> jnew_contents;
356 if (new_contents)
357 jnew_contents = new_contents->GetJavaWebContents();
359 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
360 env,
361 obj.obj(),
362 jsource.obj(),
363 jnew_contents.obj(),
364 static_cast<jint>(disposition),
365 NULL,
366 user_gesture);
369 if (was_blocked)
370 *was_blocked = !handled;
371 if (!handled)
372 delete new_contents;
375 } // namespace android
376 } // namespace chrome
378 jboolean IsCapturingAudio(JNIEnv* env,
379 jclass clazz,
380 jobject java_web_contents) {
381 content::WebContents* web_contents =
382 content::WebContents::FromJavaWebContents(java_web_contents);
383 scoped_refptr<MediaStreamCaptureIndicator> indicator =
384 MediaCaptureDevicesDispatcher::GetInstance()->
385 GetMediaStreamCaptureIndicator();
386 return indicator->IsCapturingAudio(web_contents);
389 jboolean IsCapturingVideo(JNIEnv* env,
390 jclass clazz,
391 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->IsCapturingVideo(web_contents);
400 jboolean HasAudibleAudio(JNIEnv* env,
401 jclass clazz,
402 jobject java_web_contents) {
403 content::WebContents* web_contents =
404 content::WebContents::FromJavaWebContents(java_web_contents);
405 return web_contents->WasRecentlyAudible();