- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / android / chrome_web_contents_delegate_android.cc
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.
4
5 #include "chrome/browser/android/chrome_web_contents_delegate_android.h"
6
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"
33
34 #if defined(ENABLE_PLUGINS)
35 #include "chrome/browser/pepper_broker_infobar_delegate.h"
36 #endif
37
38 using base::android::AttachCurrentThread;
39 using base::android::ScopedJavaLocalRef;
40 using content::FileChooserParams;
41 using content::WebContents;
42
43 namespace {
44
45 ScopedJavaLocalRef<jobject> CreateJavaRectF(
46     JNIEnv* env,
47     const gfx::RectF& rect) {
48   return ScopedJavaLocalRef<jobject>(
49       Java_ChromeWebContentsDelegateAndroid_createRectF(env,
50                                                         rect.x(),
51                                                         rect.y(),
52                                                         rect.right(),
53                                                         rect.bottom()));
54 }
55
56 ScopedJavaLocalRef<jobject> CreateJavaRect(
57     JNIEnv* env,
58     const gfx::Rect& rect) {
59   return ScopedJavaLocalRef<jobject>(
60       Java_ChromeWebContentsDelegateAndroid_createRect(
61           env,
62           static_cast<int>(rect.x()),
63           static_cast<int>(rect.y()),
64           static_cast<int>(rect.right()),
65           static_cast<int>(rect.bottom())));
66 }
67
68 }  // anonymous namespace
69
70 namespace chrome {
71 namespace android {
72
73 ChromeWebContentsDelegateAndroid::ChromeWebContentsDelegateAndroid(JNIEnv* env,
74                                                                    jobject obj)
75     : WebContentsDelegateAndroid(env, obj) {
76 }
77
78 ChromeWebContentsDelegateAndroid::~ChromeWebContentsDelegateAndroid() {
79   notification_registrar_.RemoveAll();
80 }
81
82 // Register native methods.
83 bool RegisterChromeWebContentsDelegateAndroid(JNIEnv* env) {
84   return RegisterNativesImpl(env);
85 }
86
87 void ChromeWebContentsDelegateAndroid::RunFileChooser(
88     WebContents* web_contents,
89     const FileChooserParams& params) {
90   FileSelectHelper::RunFileChooser(web_contents, params);
91 }
92
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));
102   }
103
104   WebContentsDelegateAndroid::CloseContents(web_contents);
105 }
106
107 void ChromeWebContentsDelegateAndroid::Observe(
108     int type,
109     const content::NotificationSource& source,
110     const content::NotificationDetails& details) {
111   switch (type) {
112     case chrome::NOTIFICATION_FIND_RESULT_AVAILABLE:
113       OnFindResultAvailable(
114           content::Source<WebContents>(source).ptr(),
115           content::Details<FindNotificationDetails>(details).ptr());
116       break;
117     default:
118       NOTREACHED() << "Unexpected notification: " << type;
119       break;
120   }
121 }
122
123 void ChromeWebContentsDelegateAndroid::FindReply(
124     WebContents* web_contents,
125     int request_id,
126     int number_of_matches,
127     const gfx::Rect& selection_rect,
128     int active_match_ordinal,
129     bool final_update) {
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));
136   }
137
138   FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents);
139   find_tab_helper->HandleFindReply(request_id,
140                                    number_of_matches,
141                                    selection_rect,
142                                    active_match_ordinal,
143                                    final_update);
144 }
145
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);
151   if (obj.is_null())
152     return;
153
154   ScopedJavaLocalRef<jobject> selection_rect = CreateJavaRect(
155       env, find_result->selection_rect());
156
157   // Create the details object.
158   ScopedJavaLocalRef<jobject> details_object =
159       Java_ChromeWebContentsDelegateAndroid_createFindNotificationDetails(
160           env,
161           find_result->number_of_matches(),
162           selection_rect.obj(),
163           find_result->active_match_ordinal(),
164           find_result->final_update());
165
166   Java_ChromeWebContentsDelegateAndroid_onFindResultAvailable(
167       env,
168       obj.obj(),
169       details_object.obj());
170 }
171
172 void ChromeWebContentsDelegateAndroid::FindMatchRectsReply(
173     WebContents* web_contents,
174     int version,
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);
179   if (obj.is_null())
180     return;
181
182   // Create the details object.
183   ScopedJavaLocalRef<jobject> details_object =
184       Java_ChromeWebContentsDelegateAndroid_createFindMatchRectsDetails(
185           env,
186           version,
187           rects.size(),
188           CreateJavaRectF(env, active_rect).obj());
189
190   // Add the rects
191   for (size_t i = 0; i < rects.size(); ++i) {
192       Java_ChromeWebContentsDelegateAndroid_setMatchRectByIndex(
193           env,
194           details_object.obj(),
195           i,
196           CreateJavaRectF(env, rects[i]).obj());
197   }
198
199   Java_ChromeWebContentsDelegateAndroid_onFindMatchRectsAvailable(
200       env,
201       obj.obj(),
202       details_object.obj());
203 }
204
205 content::JavaScriptDialogManager*
206 ChromeWebContentsDelegateAndroid::GetJavaScriptDialogManager() {
207   return GetJavaScriptDialogManagerInstance();
208 }
209
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);
216 }
217
218 bool ChromeWebContentsDelegateAndroid::RequestPpapiBrokerPermission(
219     WebContents* web_contents,
220     const GURL& url,
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);
226     return true;
227 #else
228     return false;
229 #endif
230 }
231
232 WebContents* ChromeWebContentsDelegateAndroid::OpenURLFromTab(
233     WebContents* source,
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);
244   }
245
246   Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
247   chrome::NavigateParams nav_params(profile,
248                                     params.url,
249                                     params.transition);
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;
254
255   PopupBlockerTabHelper* popup_blocker_helper =
256       PopupBlockerTabHelper::FromWebContents(source);
257   DCHECK(popup_blocker_helper);
258
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())) {
268       return NULL;
269     }
270   }
271
272   return WebContentsDelegateAndroid::OpenURLFromTab(source, params);
273 }
274
275 void ChromeWebContentsDelegateAndroid::AddNewContents(
276     WebContents* source,
277     WebContents* new_contents,
278     WindowOpenDisposition disposition,
279     const gfx::Rect& initial_pos,
280     bool user_gesture,
281     bool* was_blocked) {
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);
286
287   TabAndroid::InitTabHelpers(new_contents);
288
289   JNIEnv* env = AttachCurrentThread();
290   ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
291   bool handled = false;
292   if (!obj.is_null()) {
293     handled = Java_ChromeWebContentsDelegateAndroid_addNewContents(
294         env,
295         obj.obj(),
296         reinterpret_cast<jint>(source),
297         reinterpret_cast<jint>(new_contents),
298         static_cast<jint>(disposition),
299         NULL,
300         user_gesture);
301   }
302
303   if (!handled)
304     delete new_contents;
305 }
306
307 void
308 ChromeWebContentsDelegateAndroid::RequestProtectedMediaIdentifierPermission(
309     const WebContents* web_contents,
310     const GURL& frame_url,
311     const base::Callback<void(bool)>& callback) {
312   Profile* profile =
313       Profile::FromBrowserContext(web_contents->GetBrowserContext());
314   ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile)->
315       RequestProtectedMediaIdentifierPermission(
316             web_contents->GetRenderProcessHost()->GetID(),
317             web_contents->GetRenderViewHost()->GetRoutingID(),
318             frame_url,
319             callback);
320 }
321
322 }  // namespace android
323 }  // namespace chrome