Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / android / chrome_web_contents_delegate_android.cc
blobbc00951611de3b79be79309112dde80469d200d8
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/ssl/security_state_model.h"
21 #include "chrome/browser/ui/android/bluetooth_chooser_android.h"
22 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
23 #include "chrome/browser/ui/browser_navigator.h"
24 #include "chrome/browser/ui/find_bar/find_notification_details.h"
25 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
26 #include "chrome/browser/ui/tab_helpers.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "components/app_modal/javascript_dialog_manager.h"
29 #include "content/public/browser/notification_details.h"
30 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/notification_source.h"
32 #include "content/public/browser/render_process_host.h"
33 #include "content/public/browser/render_view_host.h"
34 #include "content/public/browser/web_contents.h"
35 #include "content/public/common/file_chooser_params.h"
36 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
37 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
38 #include "ui/gfx/geometry/rect.h"
39 #include "ui/gfx/geometry/rect_f.h"
41 #if defined(ENABLE_PLUGINS)
42 #include "chrome/browser/pepper_broker_infobar_delegate.h"
43 #endif
45 using base::android::AttachCurrentThread;
46 using base::android::ScopedJavaLocalRef;
47 using content::BluetoothChooser;
48 using content::FileChooserParams;
49 using content::WebContents;
51 namespace {
53 ScopedJavaLocalRef<jobject> CreateJavaRectF(
54 JNIEnv* env,
55 const gfx::RectF& rect) {
56 return ScopedJavaLocalRef<jobject>(
57 Java_ChromeWebContentsDelegateAndroid_createRectF(env,
58 rect.x(),
59 rect.y(),
60 rect.right(),
61 rect.bottom()));
64 ScopedJavaLocalRef<jobject> CreateJavaRect(
65 JNIEnv* env,
66 const gfx::Rect& rect) {
67 return ScopedJavaLocalRef<jobject>(
68 Java_ChromeWebContentsDelegateAndroid_createRect(
69 env,
70 static_cast<int>(rect.x()),
71 static_cast<int>(rect.y()),
72 static_cast<int>(rect.right()),
73 static_cast<int>(rect.bottom())));
76 } // anonymous namespace
78 namespace chrome {
79 namespace android {
81 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
82 jobject obj)
83 : WebContentsDelegateAndroid(env, obj) {
86 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
87 notification_registrar_.RemoveAll();
90 // Register native methods.
91 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
92 return RegisterNativesImpl(env);
95 void ChromeWebContentsDelegateAndroid::LoadingStateChanged(
96 WebContents* source, bool to_different_document) {
97 bool has_stopped = source == NULL || !source->IsLoading();
98 WebContentsDelegateAndroid::LoadingStateChanged(
99 source, to_different_document);
100 LoadProgressChanged(source, has_stopped ? 1 : 0);
103 void ChromeWebContentsDelegateAndroid::RunFileChooser(
104 WebContents* web_contents,
105 const FileChooserParams& params) {
106 FileSelectHelper::RunFileChooser(web_contents, params);
109 scoped_ptr<BluetoothChooser>
110 ChromeWebContentsDelegateAndroid::RunBluetoothChooser(
111 content::WebContents* web_contents,
112 const BluetoothChooser::EventHandler& event_handler,
113 const GURL& origin) {
114 return make_scoped_ptr(
115 new BluetoothChooserAndroid(web_contents, event_handler, origin));
118 void ChromeWebContentsDelegateAndroid::VisibleSSLStateChanged(
119 content::WebContents* web_contents) {
120 DCHECK(web_contents);
121 // Notify the model that the security state has changed, so that the
122 // URL bar updates with up-to-date data computed by the model.
123 SecurityStateModel* model = SecurityStateModel::FromWebContents(web_contents);
124 DCHECK(model);
125 model->SecurityStateChanged();
126 WebContentsDelegateAndroid::VisibleSSLStateChanged(web_contents);
129 void ChromeWebContentsDelegateAndroid::CloseContents(
130 WebContents* web_contents) {
131 // Prevent dangling registrations assigned to closed web contents.
132 if (notification_registrar_.IsRegistered(this,
133 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
134 content::Source<WebContents>(web_contents))) {
135 notification_registrar_.Remove(this,
136 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
137 content::Source<WebContents>(web_contents));
140 WebContentsDelegateAndroid::CloseContents(web_contents);
143 void ChromeWebContentsDelegateAndroid::Observe(
144 int type,
145 const content::NotificationSource& source,
146 const content::NotificationDetails& details) {
147 switch (type) {
148 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
149 OnFindResultAvailable(
150 content::Source<WebContents>(source).ptr(),
151 content::Details<FindNotificationDetails>(details).ptr());
152 break;
153 default:
154 NOTREACHED() << "Unexpected notification: " << type;
155 break;
159 blink::WebDisplayMode ChromeWebContentsDelegateAndroid::GetDisplayMode(
160 const WebContents* web_contents) const {
161 JNIEnv* env = base::android::AttachCurrentThread();
163 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
164 if (obj.is_null())
165 return blink::WebDisplayModeUndefined;
167 return static_cast<blink::WebDisplayMode>(
168 Java_ChromeWebContentsDelegateAndroid_getDisplayMode(
169 env, obj.obj())
173 void ChromeWebContentsDelegateAndroid::FindReply(
174 WebContents* web_contents,
175 int request_id,
176 int number_of_matches,
177 const gfx::Rect& selection_rect,
178 int active_match_ordinal,
179 bool final_update) {
180 if (!notification_registrar_.IsRegistered(this,
181 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
182 content::Source<WebContents>(web_contents))) {
183 notification_registrar_.Add(this,
184 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
185 content::Source<WebContents>(web_contents));
188 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
189 find_tab_helper->HandleFindReply(request_id,
190 number_of_matches,
191 selection_rect,
192 active_match_ordinal,
193 final_update);
196 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
197 WebContents* web_contents,
198 const FindNotificationDetails* find_result) {
199 JNIEnv* env = base::android::AttachCurrentThread();
200 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
201 if (obj.is_null())
202 return;
204 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
205 env, find_result->selection_rect());
207 // Create the details object.
208 ScopedJavaLocalRef<jobject> details_object =
209 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
210 env,
211 find_result->number_of_matches(),
212 selection_rect.obj(),
213 find_result->active_match_ordinal(),
214 find_result->final_update());
216 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
217 env,
218 obj.obj(),
219 details_object.obj());
222 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
223 WebContents* web_contents,
224 int version,
225 const std::vector<gfx::RectF>& rects,
226 const gfx::RectF& active_rect) {
227 JNIEnv* env = base::android::AttachCurrentThread();
228 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
229 if (obj.is_null())
230 return;
232 // Create the details object.
233 ScopedJavaLocalRef<jobject> details_object =
234 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
235 env,
236 version,
237 rects.size(),
238 CreateJavaRectF(env, active_rect).obj());
240 // Add the rects
241 for (size_t i = 0; i < rects.size(); ++i) {
242 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
243 env,
244 details_object.obj(),
246 CreateJavaRectF(env, rects[i]).obj());
249 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
250 env,
251 obj.obj(),
252 details_object.obj());
255 content::JavaScriptDialogManager*
256 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager(
257 WebContents* source) {
258 return app_modal::JavaScriptDialogManager::GetInstance();
261 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
262 content::WebContents* web_contents,
263 const content::MediaStreamRequest& request,
264 const content::MediaResponseCallback& callback) {
265 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
266 web_contents, request, callback, NULL);
269 bool ChromeWebContentsDelegateAndroid::CheckMediaAccessPermission(
270 content::WebContents* web_contents,
271 const GURL& security_origin,
272 content::MediaStreamType type) {
273 return MediaCaptureDevicesDispatcher::GetInstance()
274 ->CheckMediaAccessPermission(web_contents, security_origin, type);
277 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
278 WebContents* web_contents,
279 const GURL& url,
280 const base::FilePath& plugin_path,
281 const base::Callback<void(bool)>& callback) {
282 #if defined(ENABLE_PLUGINS)
283 PepperBrokerInfoBarDelegate::Create(
284 web_contents, url, plugin_path, callback);
285 return true;
286 #else
287 return false;
288 #endif
291 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
292 WebContents* source,
293 const content::OpenURLParams& params) {
294 WindowOpenDisposition disposition = params.disposition;
295 if (!source || (disposition != CURRENT_TAB &&
296 disposition != NEW_FOREGROUND_TAB &&
297 disposition != NEW_BACKGROUND_TAB &&
298 disposition != OFF_THE_RECORD &&
299 disposition != NEW_POPUP &&
300 disposition != NEW_WINDOW)) {
301 // We can't handle this here. Give the parent a chance.
302 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
305 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
306 chrome::NavigateParams nav_params(profile,
307 params.url,
308 params.transition);
309 FillNavigateParamsFromOpenURLParams(&nav_params, params);
310 nav_params.source_contents = source;
311 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
312 nav_params.user_gesture = params.user_gesture;
314 PopupBlockerTabHelper* popup_blocker_helper =
315 PopupBlockerTabHelper::FromWebContents(source);
316 DCHECK(popup_blocker_helper);
318 if ((params.disposition == NEW_POPUP ||
319 params.disposition == NEW_FOREGROUND_TAB ||
320 params.disposition == NEW_BACKGROUND_TAB ||
321 params.disposition == NEW_WINDOW) &&
322 !params.user_gesture &&
323 !base::CommandLine::ForCurrentProcess()->HasSwitch(
324 switches::kDisablePopupBlocking)) {
325 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
326 blink::WebWindowFeatures())) {
327 return NULL;
331 if (disposition == CURRENT_TAB) {
332 // Only prerender for a current-tab navigation to avoid session storage
333 // namespace issues.
334 nav_params.target_contents = source;
335 prerender::PrerenderManager* prerender_manager =
336 prerender::PrerenderManagerFactory::GetForProfile(profile);
337 if (prerender_manager &&
338 prerender_manager->MaybeUsePrerenderedPage(params.url, &nav_params)) {
339 return nav_params.target_contents;
343 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
346 bool ChromeWebContentsDelegateAndroid::ShouldResumeRequestsForCreatedWindow() {
347 JNIEnv* env = base::android::AttachCurrentThread();
348 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
349 if (obj.is_null())
350 return true;
352 return Java_ChromeWebContentsDelegateAndroid_shouldResumeRequestsForCreatedWindow(
353 env,
354 obj.obj());
357 void ChromeWebContentsDelegateAndroid::AddNewContents(
358 WebContents* source,
359 WebContents* new_contents,
360 WindowOpenDisposition disposition,
361 const gfx::Rect& initial_rect,
362 bool user_gesture,
363 bool* was_blocked) {
364 // No code for this yet.
365 DCHECK_NE(disposition, SAVE_TO_DISK);
366 // Can't create a new contents for the current tab - invalid case.
367 DCHECK_NE(disposition, CURRENT_TAB);
369 TabHelpers::AttachTabHelpers(new_contents);
371 JNIEnv* env = AttachCurrentThread();
372 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
373 bool handled = false;
374 if (!obj.is_null()) {
375 ScopedJavaLocalRef<jobject> jsource;
376 if (source)
377 jsource = source->GetJavaWebContents();
378 ScopedJavaLocalRef<jobject> jnew_contents;
379 if (new_contents)
380 jnew_contents = new_contents->GetJavaWebContents();
382 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
383 env,
384 obj.obj(),
385 jsource.obj(),
386 jnew_contents.obj(),
387 static_cast<jint>(disposition),
388 NULL,
389 user_gesture);
392 if (was_blocked)
393 *was_blocked = !handled;
394 if (!handled)
395 delete new_contents;
398 } // namespace android
399 } // namespace chrome
401 jboolean IsCapturingAudio(JNIEnv* env,
402 const JavaParamRef<jclass>& clazz,
403 const JavaParamRef<jobject>& java_web_contents) {
404 content::WebContents* web_contents =
405 content::WebContents::FromJavaWebContents(java_web_contents);
406 scoped_refptr<MediaStreamCaptureIndicator> indicator =
407 MediaCaptureDevicesDispatcher::GetInstance()->
408 GetMediaStreamCaptureIndicator();
409 return indicator->IsCapturingAudio(web_contents);
412 jboolean IsCapturingVideo(JNIEnv* env,
413 const JavaParamRef<jclass>& clazz,
414 const JavaParamRef<jobject>& java_web_contents) {
415 content::WebContents* web_contents =
416 content::WebContents::FromJavaWebContents(java_web_contents);
417 scoped_refptr<MediaStreamCaptureIndicator> indicator =
418 MediaCaptureDevicesDispatcher::GetInstance()->
419 GetMediaStreamCaptureIndicator();
420 return indicator->IsCapturingVideo(web_contents);