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/command_line.h"
9 #include "chrome/browser/android/tab_android.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/protected_media_identifier_permission_context.h"
14 #include "chrome/browser/media/protected_media_identifier_permission_context_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
17 #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
18 #include "chrome/browser/ui/browser_navigator.h"
19 #include "chrome/browser/ui/find_bar/find_notification_details.h"
20 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "content/public/browser/notification_details.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/notification_source.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/file_chooser_params.h"
29 #include "jni/ChromeWebContentsDelegateAndroid_jni.h"
30 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
31 #include "ui/gfx/rect.h"
32 #include "ui/gfx/rect_f.h"
34 #if defined(ENABLE_PLUGINS)
35 #include "chrome/browser/pepper_broker_infobar_delegate.h"
38 using base::android::AttachCurrentThread;
39 using base::android::ScopedJavaLocalRef;
40 using content::FileChooserParams;
41 using content::WebContents;
45 ScopedJavaLocalRef<jobject> CreateJavaRectF(
47 const gfx::RectF& rect) {
48 return ScopedJavaLocalRef<jobject>(
49 Java_ChromeWebContentsDelegateAndroid_createRectF(env,
56 ScopedJavaLocalRef<jobject> CreateJavaRect(
58 const gfx::Rect& rect) {
59 return ScopedJavaLocalRef<jobject>(
60 Java_ChromeWebContentsDelegateAndroid_createRect(
62 static_cast<int>(rect.x()),
63 static_cast<int>(rect.y()),
64 static_cast<int>(rect.right()),
65 static_cast<int>(rect.bottom())));
68 } // anonymous namespace
73 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
75 : WebContentsDelegateAndroid(env, obj) {
78 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
79 notification_registrar_.RemoveAll();
82 // Register native methods.
83 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
84 return RegisterNativesImpl(env);
87 void ChromeWebContentsDelegateAndroid::RunFileChooser(
88 WebContents* web_contents,
89 const FileChooserParams& params) {
90 FileSelectHelper::RunFileChooser(web_contents, params);
93 void ChromeWebContentsDelegateAndroid::CloseContents(
94 WebContents* web_contents) {
95 // Prevent dangling registrations assigned to closed web contents.
96 if (notification_registrar_.IsRegistered(this,
97 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
98 content::Source<WebContents>(web_contents))) {
99 notification_registrar_.Remove(this,
100 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
101 content::Source<WebContents>(web_contents));
104 WebContentsDelegateAndroid::CloseContents(web_contents);
107 void ChromeWebContentsDelegateAndroid::Observe(
109 const content::NotificationSource& source,
110 const content::NotificationDetails& details) {
112 case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
113 OnFindResultAvailable(
114 content::Source<WebContents>(source).ptr(),
115 content::Details<FindNotificationDetails>(details).ptr());
118 NOTREACHED() << "Unexpected notification: " << type;
123 void ChromeWebContentsDelegateAndroid::FindReply(
124 WebContents* web_contents,
126 int number_of_matches,
127 const gfx::Rect& selection_rect,
128 int active_match_ordinal,
130 if (!notification_registrar_.IsRegistered(this,
131 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
132 content::Source<WebContents>(web_contents))) {
133 notification_registrar_.Add(this,
134 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
135 content::Source<WebContents>(web_contents));
138 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
139 find_tab_helper->HandleFindReply(request_id,
142 active_match_ordinal,
146 void ChromeWebContentsDelegateAndroid::OnFindResultAvailable(
147 WebContents* web_contents,
148 const FindNotificationDetails* find_result) {
149 JNIEnv* env = base::android::AttachCurrentThread();
150 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
154 ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
155 env, find_result->selection_rect());
157 // Create the details object.
158 ScopedJavaLocalRef<jobject> details_object =
159 Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
161 find_result->number_of_matches(),
162 selection_rect.obj(),
163 find_result->active_match_ordinal(),
164 find_result->final_update());
166 Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
169 details_object.obj());
172 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
173 WebContents* web_contents,
175 const std::vector<gfx::RectF>& rects,
176 const gfx::RectF& active_rect) {
177 JNIEnv* env = base::android::AttachCurrentThread();
178 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
182 // Create the details object.
183 ScopedJavaLocalRef<jobject> details_object =
184 Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
188 CreateJavaRectF(env, active_rect).obj());
191 for (size_t i = 0; i < rects.size(); ++i) {
192 Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
194 details_object.obj(),
196 CreateJavaRectF(env, rects[i]).obj());
199 Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
202 details_object.obj());
205 content::JavaScriptDialogManager*
206 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager() {
207 return GetJavaScriptDialogManagerInstance();
210 void ChromeWebContentsDelegateAndroid::RequestMediaAccessPermission(
211 content::WebContents* web_contents,
212 const content::MediaStreamRequest& request,
213 const content::MediaResponseCallback& callback) {
214 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
215 web_contents, request, callback, NULL);
218 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
219 WebContents* web_contents,
221 const base::FilePath& plugin_path,
222 const base::Callback<void(bool)>& callback) {
223 #if defined(ENABLE_PLUGINS)
224 PepperBrokerInfoBarDelegate::Create(
225 web_contents, url, plugin_path, callback);
232 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
234 const content::OpenURLParams& params) {
235 WindowOpenDisposition disposition = params.disposition;
236 if (!source || (disposition != CURRENT_TAB &&
237 disposition != NEW_FOREGROUND_TAB &&
238 disposition != NEW_BACKGROUND_TAB &&
239 disposition != OFF_THE_RECORD &&
240 disposition != NEW_POPUP &&
241 disposition != NEW_WINDOW)) {
242 // We can't handle this here. Give the parent a chance.
243 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
246 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
247 chrome::NavigateParams nav_params(profile,
250 FillNavigateParamsFromOpenURLParams(&nav_params, params);
251 nav_params.source_contents = source;
252 nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
253 nav_params.user_gesture = params.user_gesture;
255 PopupBlockerTabHelper* popup_blocker_helper =
256 PopupBlockerTabHelper::FromWebContents(source);
257 DCHECK(popup_blocker_helper);
259 if ((params.disposition == NEW_POPUP ||
260 params.disposition == NEW_FOREGROUND_TAB ||
261 params.disposition == NEW_BACKGROUND_TAB ||
262 params.disposition == NEW_WINDOW) &&
263 !params.user_gesture &&
264 !CommandLine::ForCurrentProcess()->HasSwitch(
265 switches::kDisablePopupBlocking)) {
266 if (popup_blocker_helper->MaybeBlockPopup(nav_params,
267 WebKit::WebWindowFeatures())) {
272 return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
275 void ChromeWebContentsDelegateAndroid::AddNewContents(
277 WebContents* new_contents,
278 WindowOpenDisposition disposition,
279 const gfx::Rect& initial_pos,
282 // No code for this yet.
283 DCHECK_NE(disposition, SAVE_TO_DISK);
284 // Can't create a new contents for the current tab - invalid case.
285 DCHECK_NE(disposition, CURRENT_TAB);
287 TabAndroid::InitTabHelpers(new_contents);
289 JNIEnv* env = AttachCurrentThread();
290 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
291 bool handled = false;
292 if (!obj.is_null()) {
293 handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
296 reinterpret_cast<jint>(source),
297 reinterpret_cast<jint>(new_contents),
298 static_cast<jint>(disposition),
308 ChromeWebContentsDelegateAndroid::RequestProtectedMediaIdentifierPermission(
309 const WebContents* web_contents,
310 const GURL& frame_url,
311 const base::Callback<void(bool)>& callback) {
313 Profile::FromBrowserContext(web_contents->GetBrowserContext());
314 ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile)->
315 RequestProtectedMediaIdentifierPermission(
316 web_contents->GetRenderProcessHost()->GetID(),
317 web_contents->GetRenderViewHost()->GetRoutingID(),
322 } // namespace android
323 } // namespace chrome