Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / android / chrome_web_contents_delegate_android.cc
blobecc988db5ce157217c62eee5d0aeee3fe6cf0344
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/media_stream_capture_indicator.h"
14 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
15 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
16 #include "chrome/browser/prerender/prerender_manager.h"
17 #include "chrome/browser/prerender/prerender_manager_factory.h"
18 #include "chrome/browser/profiles/profile.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 "components/app_modal/javascript_dialog_manager.h"
26 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/render_process_host.h"
30 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/common/file_chooser_params.h"
33 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
34 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
35 #include "ui/gfx/geometry/rect.h"
36 #include "ui/gfx/geometry/rect_f.h"
38 #if defined(ENABLE_PLUGINS)
39 #include "chrome/browser/pepper_broker_infobar_delegate.h"
40 #endif
42 using base::android::AttachCurrentThread;
43 using base::android::ScopedJavaLocalRef;
44 using content::FileChooserParams;
45 using content::WebContents;
47 namespace {
49 ScopedJavaLocalRef<jobject> CreateJavaRectF(
50 JNIEnv* env,
51 const gfx::RectF& rect) {
52 return ScopedJavaLocalRef<jobject>(
53 Java_ChromeWebContentsDelegateAndroid_createRectF(env,
54 rect.x(),
55 rect.y(),
56 rect.right(),
57 rect.bottom()));
60 ScopedJavaLocalRef<jobject> CreateJavaRect(
61 JNIEnv* env,
62 const gfx::Rect& rect) {
63 return ScopedJavaLocalRef<jobject>(
64 Java_ChromeWebContentsDelegateAndroid_createRect(
65 env,
66 static_cast<int>(rect.x()),
67 static_cast<int>(rect.y()),
68 static_cast<int>(rect.right()),
69 static_cast<int>(rect.bottom())));
72 } // anonymous namespace
74 namespace chrome {
75 namespace android {
77 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
78 jobject obj)
79 : WebContentsDelegateAndroid(env, obj) {
82 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
83 notification_registrar_.RemoveAll();
86 // Register native methods.
87 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
88 return RegisterNativesImpl(env);
91 void ChromeWebContentsDelegateAndroid::LoadingStateChanged(
92 WebContents* source, bool to_different_document) {
93 bool has_stopped = source == NULL || !source->IsLoading();
94 WebContentsDelegateAndroid::LoadingStateChanged(
95 source, to_different_document);
96 LoadProgressChanged(source, has_stopped ? 1 : 0);
99 void ChromeWebContentsDelegateAndroid::RunFileChooser(
100 WebContents* web_contents,
101 const FileChooserParams& params) {
102 FileSelectHelper::RunFileChooser(web_contents, params);
105 void ChromeWebContentsDelegateAndroid::CloseContents(
106 WebContents* web_contents) {
107 // Prevent dangling registrations assigned to closed web contents.
108 if (notification_registrar_.IsRegistered(this,
109 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
110 content::Source<WebContents>(web_contents))) {
111 notification_registrar_.Remove(this,
112 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
113 content::Source<WebContents>(web_contents));
116 WebContentsDelegateAndroid::CloseContents(web_contents);
119 void ChromeWebContentsDelegateAndroid::Observe(
120 int type,
121 const content::NotificationSource& source,
122 const content::NotificationDetails& details) {
123 switch (type) {
124 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
125 OnFindResultAvailable(
126 content::Source<WebContents>(source).ptr(),
127 content::Details<FindNotificationDetails>(details).ptr());
128 break;
129 default:
130 NOTREACHED() << "Unexpected notification: " << type;
131 break;
135 void ChromeWebContentsDelegateAndroid::FindReply(
136 WebContents* web_contents,
137 int request_id,
138 int number_of_matches,
139 const gfx::Rect& selection_rect,
140 int active_match_ordinal,
141 bool final_update) {
142 if (!notification_registrar_.IsRegistered(this,
143 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
144 content::Source<WebContents>(web_contents))) {
145 notification_registrar_.Add(this,
146 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
147 content::Source<WebContents>(web_contents));
150 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
151 find_tab_helper->HandleFindReply(request_id,
152 number_of_matches,
153 selection_rect,
154 active_match_ordinal,
155 final_update);
158 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
159 WebContents* web_contents,
160 const FindNotificationDetails* find_result) {
161 JNIEnv* env = base::android::AttachCurrentThread();
162 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
163 if (obj.is_null())
164 return;
166 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
167 env, find_result->selection_rect());
169 // Create the details object.
170 ScopedJavaLocalRef<jobject> details_object =
171 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
172 env,
173 find_result->number_of_matches(),
174 selection_rect.obj(),
175 find_result->active_match_ordinal(),
176 find_result->final_update());
178 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
179 env,
180 obj.obj(),
181 details_object.obj());
184 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
185 WebContents* web_contents,
186 int version,
187 const std::vector<gfx::RectF>& rects,
188 const gfx::RectF& active_rect) {
189 JNIEnv* env = base::android::AttachCurrentThread();
190 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
191 if (obj.is_null())
192 return;
194 // Create the details object.
195 ScopedJavaLocalRef<jobject> details_object =
196 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
197 env,
198 version,
199 rects.size(),
200 CreateJavaRectF(env, active_rect).obj());
202 // Add the rects
203 for (size_t i = 0; i < rects.size(); ++i) {
204 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
205 env,
206 details_object.obj(),
208 CreateJavaRectF(env, rects[i]).obj());
211 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
212 env,
213 obj.obj(),
214 details_object.obj());
217 content::JavaScriptDialogManager*
218 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager(
219 WebContents* source) {
220 return app_modal::JavaScriptDialogManager::GetInstance();
223 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
224 content::WebContents* web_contents,
225 const content::MediaStreamRequest& request,
226 const content::MediaResponseCallback& callback) {
227 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
228 web_contents, request, callback, NULL);
231 bool ChromeWebContentsDelegateAndroid::CheckMediaAccessPermission(
232 content::WebContents* web_contents,
233 const GURL& security_origin,
234 content::MediaStreamType type) {
235 return MediaCaptureDevicesDispatcher::GetInstance()
236 ->CheckMediaAccessPermission(web_contents, security_origin, type);
239 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
240 WebContents* web_contents,
241 const GURL& url,
242 const base::FilePath& plugin_path,
243 const base::Callback<void(bool)>& callback) {
244 #if defined(ENABLE_PLUGINS)
245 PepperBrokerInfoBarDelegate::Create(
246 web_contents, url, plugin_path, callback);
247 return true;
248 #else
249 return false;
250 #endif
253 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
254 WebContents* source,
255 const content::OpenURLParams& params) {
256 WindowOpenDisposition disposition = params.disposition;
257 if (!source || (disposition != CURRENT_TAB &&
258 disposition != NEW_FOREGROUND_TAB &&
259 disposition != NEW_BACKGROUND_TAB &&
260 disposition != OFF_THE_RECORD &&
261 disposition != NEW_POPUP &&
262 disposition != NEW_WINDOW)) {
263 // We can't handle this here. Give the parent a chance.
264 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
267 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
268 chrome::NavigateParams nav_params(profile,
269 params.url,
270 params.transition);
271 FillNavigateParamsFromOpenURLParams(&nav_params, params);
272 nav_params.source_contents = source;
273 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
274 nav_params.user_gesture = params.user_gesture;
276 PopupBlockerTabHelper* popup_blocker_helper =
277 PopupBlockerTabHelper::FromWebContents(source);
278 DCHECK(popup_blocker_helper);
280 if ((params.disposition == NEW_POPUP ||
281 params.disposition == NEW_FOREGROUND_TAB ||
282 params.disposition == NEW_BACKGROUND_TAB ||
283 params.disposition == NEW_WINDOW) &&
284 !params.user_gesture &&
285 !base::CommandLine::ForCurrentProcess()->HasSwitch(
286 switches::kDisablePopupBlocking)) {
287 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
288 blink::WebWindowFeatures())) {
289 return NULL;
293 if (disposition == CURRENT_TAB) {
294 // Only prerender for a current-tab navigation to avoid session storage
295 // namespace issues.
296 nav_params.target_contents = source;
297 prerender::PrerenderManager* prerender_manager =
298 prerender::PrerenderManagerFactory::GetForProfile(profile);
299 if (prerender_manager &&
300 prerender_manager->MaybeUsePrerenderedPage(params.url, &nav_params)) {
301 return nav_params.target_contents;
305 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
308 void ChromeWebContentsDelegateAndroid::AddNewContents(
309 WebContents* source,
310 WebContents* new_contents,
311 WindowOpenDisposition disposition,
312 const gfx::Rect& initial_rect,
313 bool user_gesture,
314 bool* was_blocked) {
315 // No code for this yet.
316 DCHECK_NE(disposition, SAVE_TO_DISK);
317 // Can't create a new contents for the current tab - invalid case.
318 DCHECK_NE(disposition, CURRENT_TAB);
320 TabHelpers::AttachTabHelpers(new_contents);
322 JNIEnv* env = AttachCurrentThread();
323 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
324 bool handled = false;
325 if (!obj.is_null()) {
326 ScopedJavaLocalRef<jobject> jsource;
327 if (source)
328 jsource = source->GetJavaWebContents();
329 ScopedJavaLocalRef<jobject> jnew_contents;
330 if (new_contents)
331 jnew_contents = new_contents->GetJavaWebContents();
333 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
334 env,
335 obj.obj(),
336 jsource.obj(),
337 jnew_contents.obj(),
338 static_cast<jint>(disposition),
339 NULL,
340 user_gesture);
343 if (was_blocked)
344 *was_blocked = !handled;
345 if (!handled)
346 delete new_contents;
349 } // namespace android
350 } // namespace chrome
352 jboolean IsCapturingAudio(JNIEnv* env,
353 jclass clazz,
354 jobject java_web_contents) {
355 content::WebContents* web_contents =
356 content::WebContents::FromJavaWebContents(java_web_contents);
357 scoped_refptr<MediaStreamCaptureIndicator> indicator =
358 MediaCaptureDevicesDispatcher::GetInstance()->
359 GetMediaStreamCaptureIndicator();
360 return indicator->IsCapturingAudio(web_contents);
363 jboolean IsCapturingVideo(JNIEnv* env,
364 jclass clazz,
365 jobject java_web_contents) {
366 content::WebContents* web_contents =
367 content::WebContents::FromJavaWebContents(java_web_contents);
368 scoped_refptr<MediaStreamCaptureIndicator> indicator =
369 MediaCaptureDevicesDispatcher::GetInstance()->
370 GetMediaStreamCaptureIndicator();
371 return indicator->IsCapturingVideo(web_contents);
374 jboolean HasAudibleAudio(JNIEnv* env,
375 jclass clazz,
376 jobject java_web_contents) {
377 content::WebContents* web_contents =
378 content::WebContents::FromJavaWebContents(java_web_contents);
379 return web_contents->WasRecentlyAudible();