Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / android / chrome_web_contents_delegate_android.cc
blob77a849b401c6ab0eae8eb0149165edff76b20ecd
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 void ChromeWebContentsDelegateAndroid::FindReply(
137 WebContents* web_contents,
138 int request_id,
139 int number_of_matches,
140 const gfx::Rect& selection_rect,
141 int active_match_ordinal,
142 bool final_update) {
143 if (!notification_registrar_.IsRegistered(this,
144 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
145 content::Source<WebContents>(web_contents))) {
146 notification_registrar_.Add(this,
147 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
148 content::Source<WebContents>(web_contents));
151 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
152 find_tab_helper->HandleFindReply(request_id,
153 number_of_matches,
154 selection_rect,
155 active_match_ordinal,
156 final_update);
159 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
160 WebContents* web_contents,
161 const FindNotificationDetails* find_result) {
162 JNIEnv* env = base::android::AttachCurrentThread();
163 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
164 if (obj.is_null())
165 return;
167 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
168 env, find_result->selection_rect());
170 // Create the details object.
171 ScopedJavaLocalRef<jobject> details_object =
172 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
173 env,
174 find_result->number_of_matches(),
175 selection_rect.obj(),
176 find_result->active_match_ordinal(),
177 find_result->final_update());
179 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
180 env,
181 obj.obj(),
182 details_object.obj());
185 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
186 WebContents* web_contents,
187 int version,
188 const std::vector<gfx::RectF>& rects,
189 const gfx::RectF& active_rect) {
190 JNIEnv* env = base::android::AttachCurrentThread();
191 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
192 if (obj.is_null())
193 return;
195 // Create the details object.
196 ScopedJavaLocalRef<jobject> details_object =
197 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
198 env,
199 version,
200 rects.size(),
201 CreateJavaRectF(env, active_rect).obj());
203 // Add the rects
204 for (size_t i = 0; i < rects.size(); ++i) {
205 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
206 env,
207 details_object.obj(),
209 CreateJavaRectF(env, rects[i]).obj());
212 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
213 env,
214 obj.obj(),
215 details_object.obj());
218 content::JavaScriptDialogManager*
219 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager(
220 WebContents* source) {
221 return app_modal::JavaScriptDialogManager::GetInstance();
224 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
225 content::WebContents* web_contents,
226 const content::MediaStreamRequest& request,
227 const content::MediaResponseCallback& callback) {
228 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
229 web_contents, request, callback, NULL);
232 bool ChromeWebContentsDelegateAndroid::CheckMediaAccessPermission(
233 content::WebContents* web_contents,
234 const GURL& security_origin,
235 content::MediaStreamType type) {
236 return MediaCaptureDevicesDispatcher::GetInstance()
237 ->CheckMediaAccessPermission(web_contents, security_origin, type);
240 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
241 WebContents* web_contents,
242 const GURL& url,
243 const base::FilePath& plugin_path,
244 const base::Callback<void(bool)>& callback) {
245 #if defined(ENABLE_PLUGINS)
246 PepperBrokerInfoBarDelegate::Create(
247 web_contents, url, plugin_path, callback);
248 return true;
249 #else
250 return false;
251 #endif
254 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
255 WebContents* source,
256 const content::OpenURLParams& params) {
257 WindowOpenDisposition disposition = params.disposition;
258 if (!source || (disposition != CURRENT_TAB &&
259 disposition != NEW_FOREGROUND_TAB &&
260 disposition != NEW_BACKGROUND_TAB &&
261 disposition != OFF_THE_RECORD &&
262 disposition != NEW_POPUP &&
263 disposition != NEW_WINDOW)) {
264 // We can't handle this here. Give the parent a chance.
265 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
268 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
269 chrome::NavigateParams nav_params(profile,
270 params.url,
271 params.transition);
272 FillNavigateParamsFromOpenURLParams(&nav_params, params);
273 nav_params.source_contents = source;
274 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
275 nav_params.user_gesture = params.user_gesture;
277 PopupBlockerTabHelper* popup_blocker_helper =
278 PopupBlockerTabHelper::FromWebContents(source);
279 DCHECK(popup_blocker_helper);
281 if ((params.disposition == NEW_POPUP ||
282 params.disposition == NEW_FOREGROUND_TAB ||
283 params.disposition == NEW_BACKGROUND_TAB ||
284 params.disposition == NEW_WINDOW) &&
285 !params.user_gesture &&
286 !base::CommandLine::ForCurrentProcess()->HasSwitch(
287 switches::kDisablePopupBlocking)) {
288 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
289 blink::WebWindowFeatures())) {
290 return NULL;
294 if (disposition == CURRENT_TAB) {
295 // Only prerender for a current-tab navigation to avoid session storage
296 // namespace issues.
297 nav_params.target_contents = source;
298 prerender::PrerenderManager* prerender_manager =
299 prerender::PrerenderManagerFactory::GetForProfile(profile);
300 if (prerender_manager &&
301 prerender_manager->MaybeUsePrerenderedPage(params.url, &nav_params)) {
302 return nav_params.target_contents;
306 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
309 bool ChromeWebContentsDelegateAndroid::ShouldResumeRequestsForCreatedWindow() {
310 JNIEnv* env = base::android::AttachCurrentThread();
311 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
312 if (obj.is_null())
313 return true;
315 return Java_ChromeWebContentsDelegateAndroid_shouldResumeRequestsForCreatedWindow(
316 env,
317 obj.obj());
320 void ChromeWebContentsDelegateAndroid::AddNewContents(
321 WebContents* source,
322 WebContents* new_contents,
323 WindowOpenDisposition disposition,
324 const gfx::Rect& initial_rect,
325 bool user_gesture,
326 bool* was_blocked) {
327 // No code for this yet.
328 DCHECK_NE(disposition, SAVE_TO_DISK);
329 // Can't create a new contents for the current tab - invalid case.
330 DCHECK_NE(disposition, CURRENT_TAB);
332 TabHelpers::AttachTabHelpers(new_contents);
334 JNIEnv* env = AttachCurrentThread();
335 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
336 bool handled = false;
337 if (!obj.is_null()) {
338 ScopedJavaLocalRef<jobject> jsource;
339 if (source)
340 jsource = source->GetJavaWebContents();
341 ScopedJavaLocalRef<jobject> jnew_contents;
342 if (new_contents)
343 jnew_contents = new_contents->GetJavaWebContents();
345 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
346 env,
347 obj.obj(),
348 jsource.obj(),
349 jnew_contents.obj(),
350 static_cast<jint>(disposition),
351 NULL,
352 user_gesture);
355 if (was_blocked)
356 *was_blocked = !handled;
357 if (!handled)
358 delete new_contents;
361 } // namespace android
362 } // namespace chrome
364 jboolean IsCapturingAudio(JNIEnv* env,
365 jclass clazz,
366 jobject java_web_contents) {
367 content::WebContents* web_contents =
368 content::WebContents::FromJavaWebContents(java_web_contents);
369 scoped_refptr<MediaStreamCaptureIndicator> indicator =
370 MediaCaptureDevicesDispatcher::GetInstance()->
371 GetMediaStreamCaptureIndicator();
372 return indicator->IsCapturingAudio(web_contents);
375 jboolean IsCapturingVideo(JNIEnv* env,
376 jclass clazz,
377 jobject java_web_contents) {
378 content::WebContents* web_contents =
379 content::WebContents::FromJavaWebContents(java_web_contents);
380 scoped_refptr<MediaStreamCaptureIndicator> indicator =
381 MediaCaptureDevicesDispatcher::GetInstance()->
382 GetMediaStreamCaptureIndicator();
383 return indicator->IsCapturingVideo(web_contents);
386 jboolean HasAudibleAudio(JNIEnv* env,
387 jclass clazz,
388 jobject java_web_contents) {
389 content::WebContents* web_contents =
390 content::WebContents::FromJavaWebContents(java_web_contents);
391 return web_contents->WasRecentlyAudible();