b5b9cf238d31dd1c61fc6ad396a5ef7c953e1d95
[platform/framework/web/chromium-efl.git] / tizen_src / impl / web_contents_delegate_efl.cc
1 #include "web_contents_delegate_efl.h"
2
3 #include "API/ewk_console_message_private.h"
4 #include "API/ewk_error_private.h"
5 #include "API/ewk_certificate_private.h"
6 #include "API/ewk_policy_decision_private.h"
7 #include "API/ewk_user_media_private.h"
8 #include "browser/policy_response_delegate_efl.h"
9 #include "browser/renderer_host/render_widget_host_view_efl.h"
10 #include "browser/inputpicker/color_chooser_efl.h"
11 #include "common/render_messages_efl.h"
12 #include "eweb_view.h"
13 #include "eweb_view_callbacks.h"
14 #include "public/ewk_view.h"
15
16 #include "base/strings/utf_string_conversions.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/browser/invalidate_type.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/favicon_status.h"
22 #include "content/public/common/favicon_url.h"
23 #include "content/common/date_time_suggestion.h"
24 #include "net/base/load_states.h"
25 #include "net/http/http_response_headers.h"
26 #include "printing/pdf_metafile_skia.h"
27 #include "url/gurl.h"
28 #include "browser/favicon/favicon_service.h"
29
30 #include "tizen_webview/public/tw_web_context.h"
31 #include "tizen_webview/public/tw_input_type.h"
32
33 #ifdef TIZEN_AUTOFILL_SUPPORT
34 #include "browser/autofill/autofill_manager_delegate_efl.h"
35 #include "browser/password_manager/password_manager_client_efl.h"
36 #include "components/autofill/content/browser/autofill_driver_impl.h"
37 #include "components/autofill/core/browser/autofill_manager.h"
38 #include "components/web_modal/web_contents_modal_dialog_manager.h"
39
40 using autofill::AutofillDriverImpl;
41 using autofill::AutofillManager;
42 using autofill::AutofillManagerDelegateEfl;
43 #endif
44
45 using base::string16;
46 using namespace tizen_webview;
47
48 namespace content {
49
50 void WritePdfDataToFile(printing::PdfMetafileSkia* metafile, const base::FilePath& filename) {
51   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
52   DCHECK(metafile);
53   metafile->SaveTo(filename);
54   delete metafile;
55 }
56
57 WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
58     : web_view_(view)
59     , is_fullscreen_(false)
60     , web_contents_(NULL)
61     , document_created_(false)
62     , should_open_new_window_(true)
63     , dialog_manager_(NULL)
64     , forward_backward_list_count_(0)
65     , weak_ptr_factory_(this) {
66   BrowserContext* browser_context = web_view_->context()->browser_context();
67   web_contents_ = WebContents::Create(WebContents::CreateParams(browser_context));
68   web_contents_->SetDelegate(this);
69   Observe(web_contents_);
70
71 #ifdef TIZEN_AUTOFILL_SUPPORT
72   AutofillManagerDelegateEfl::CreateForWebContents(web_contents_);
73   AutofillManagerDelegateEfl * autofill_manager =
74     AutofillManagerDelegateEfl::FromWebContents(web_contents_);
75   autofill_manager->SetEWebView(view);
76   AutofillDriverImpl::CreateForWebContentsAndDelegate(web_contents_,
77     autofill_manager, EWebView::GetPlatformLocale(), AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
78   PasswordManagerClientEfl::CreateForWebContents(web_contents_);
79 #endif
80 }
81
82 WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view, WebContents* contents)
83   : WebContentsObserver(contents)
84   , web_view_(view)
85   , is_fullscreen_(false)
86   , web_contents_(contents)
87   , document_created_(false)
88   , should_open_new_window_(true)
89   , dialog_manager_(NULL)
90   , forward_backward_list_count_(0)
91   , weak_ptr_factory_(this) {
92   web_contents_->SetDelegate(this);
93 }
94
95 WebContentsDelegateEfl::~WebContentsDelegateEfl() {
96   // It's important to delete web_contents_ before dialog_manager_
97   // destructor of web contents uses dialog_manager_
98
99   delete web_contents_;
100   delete dialog_manager_;
101 }
102
103 void WebContentsDelegateEfl::NavigationStateChanged(const WebContents* source, unsigned changed_flags) {
104   if (changed_flags & content::INVALIDATE_TYPE_URL) {
105     const char* url = source->GetVisibleURL().spec().c_str();
106     web_view_->SmartCallback<EWebViewCallbacks::URLChanged>().call(url);
107     web_view_->SmartCallback<EWebViewCallbacks::URIChanged>().call(url);
108   }
109 }
110
111 void WebContentsDelegateEfl::LoadingStateChanged(WebContents* source,
112                                                  bool to_different_document) {
113   if (source->IsLoading())
114     web_view_->SmartCallback<EWebViewCallbacks::LoadProgressStarted>().call();
115   else
116     web_view_->SmartCallback<EWebViewCallbacks::LoadProgressFinished>().call();
117 }
118
119 void WebContentsDelegateEfl::LoadProgressChanged(WebContents* source, double progress) {
120   web_view_->SetProgressValue(progress);
121   web_view_->SmartCallback<EWebViewCallbacks::LoadProgress>().call(&progress);
122 }
123
124 bool WebContentsDelegateEfl::ShouldCreateWebContents(
125     WebContents* web_contents,
126     int route_id,
127     WindowContainerType window_container_type,
128     const string16& /*frame_name*/,
129     const GURL& target_url,
130     const std::string& partition_id,
131     SessionStorageNamespace* session_storage_namespace) {
132   // this method is called ONLY when creating new window - no matter what type
133   web_view_->set_policy_decision(new tizen_webview::PolicyDecision(this, target_url));
134   web_view_->SmartCallback<EWebViewCallbacks::NewWindowPolicyDecision>().call(web_view_->get_policy_decision());
135   // Chromium has sync API. We cannot block this calls on UI thread.
136   CHECK(!web_view_->get_policy_decision()->isSuspended());
137   if (web_view_->get_policy_decision()->isDecided())
138     return should_open_new_window_;
139
140   // By default we return false. If embedder is not prepared to handle new window creation then we prevent this behaviour.
141   return false;
142 }
143
144 void WebContentsDelegateEfl::WebContentsCreated(
145     WebContents* source_contents,
146     int opener_render_frame_id,
147     const string16& frame_name,
148     const GURL& target_url,
149     WebContents* new_contents) {
150   // FIXME: we should have the specifications for the new window (size, position, etc.) to set it up correctly.
151
152   RenderWidgetHostViewEfl* source_rwhv = reinterpret_cast<RenderWidgetHostViewEfl*>(source_contents->GetRenderWidgetHostView());
153   DCHECK(source_rwhv);
154   EWebView* source_view = source_rwhv->eweb_view();
155   DCHECK(source_view);
156   source_view->CreateNewWindow(new_contents);
157 }
158
159 void WebContentsDelegateEfl::CloseContents(WebContents* source) {
160   web_view_->SmartCallback<EWebViewCallbacks::WindowClosed>().call();
161 }
162
163 void WebContentsDelegateEfl::ToggleFullscreenModeForTab(WebContents* web_contents,
164       bool enter_fullscreen) {
165   is_fullscreen_ = enter_fullscreen;
166   if(enter_fullscreen)
167     web_view_->SmartCallback<EWebViewCallbacks::EnterFullscreen>().call();
168   else
169     web_view_->SmartCallback<EWebViewCallbacks::ExitFullscreen>().call();
170 }
171
172 bool WebContentsDelegateEfl::IsFullscreenForTabOrPending(
173       const WebContents* web_contents) const {
174   return is_fullscreen_;
175 }
176
177 void WebContentsDelegateEfl::RegisterProtocolHandler(WebContents* web_contents,
178         const std::string& protocol, const GURL& url, bool user_gesture) {
179   scoped_ptr<tizen_webview::Custom_Handlers_Data> protocol_data(
180       new tizen_webview::Custom_Handlers_Data(protocol.c_str(),
181           url.host().c_str(), url.spec().c_str()));
182   web_view_->SmartCallback<EWebViewCallbacks::RegisterProtocolHandler>().call(protocol_data.get());
183 }
184
185 WebContentsDelegateEfl::PendingAccessRequest::PendingAccessRequest(
186   const content::MediaStreamRequest& request,
187   const content::MediaResponseCallback& callback)
188   : request(request)
189   , callback(callback) {
190 }
191
192 WebContentsDelegateEfl::PendingAccessRequest::~PendingAccessRequest() {
193 }
194
195 void WebContentsDelegateEfl::OnAccessRequestResponse(Eina_Bool allowed) {
196 #warning "[M37] Fix media permissions"
197 #if 0
198   MediaStreamDevices devices;
199   DVLOG(1) << __FUNCTION__ << " Queue Size: " << requests_Queue_.size();
200   if (requests_Queue_.empty()) {
201     DVLOG(1) << __FUNCTION__ << " Empty Queue ";
202     return;
203   }
204   PendingAccessRequest pending_request = requests_Queue_.front();
205   if (pending_request.callback.is_null()) {
206     requests_Queue_.pop_front();
207     DVLOG(1) << __FUNCTION__ << " Invalid Callback ";
208     return;
209   }
210   if (allowed) {
211     if (pending_request.request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
212       DVLOG(1) << __FUNCTION__ << "Added Audio Device";
213       devices.push_back(MediaStreamDevice(pending_request.request.audio_type,
214                                           "default", "Default"));
215     }
216     if (pending_request.request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
217       DVLOG(1) << __FUNCTION__ << " Added Video Device";
218       devices.push_back(MediaStreamDevice(pending_request.request.video_type,
219                                           "1", "1"));
220     }
221     pending_request.callback.Run(devices, scoped_ptr<MediaStreamUI>());
222   } else {
223     DVLOG(1) << __FUNCTION__ << " Decline request with empty list";
224     pending_request.callback.Run(MediaStreamDevices(),
225                                  scoped_ptr<MediaStreamUI>());
226   }
227   requests_Queue_.pop_front();
228 #endif
229 }
230
231 void WebContentsDelegateEfl::RequestMediaAccessPermission(
232         WebContents* web_contents,
233         const MediaStreamRequest& request,
234         const MediaResponseCallback& callback) {
235   //send callback to application to request for user permission.
236   _Ewk_User_Media_Permission_Request* media_permission_request =
237     new _Ewk_User_Media_Permission_Request(web_view_, request,this);
238   requests_Queue_.push_back(PendingAccessRequest(request, callback));
239   web_view_->SmartCallback<EWebViewCallbacks::UserMediaPermission>().call(
240     media_permission_request);
241 }
242
243 void WebContentsDelegateEfl::OnAuthRequired(net::URLRequest* request,
244                                             const std::string& realm,
245                                             LoginDelegateEfl* login_delegate) {
246   web_view_->InvokeAuthCallback(login_delegate, request->url(), realm);
247 }
248
249 void WebContentsDelegateEfl::DidStartProvisionalLoadForFrame(RenderFrameHost* render_frame_host,
250                                                              const GURL& validated_url,
251                                                              bool is_error_page,
252                                                              bool is_iframe_srcdoc) {
253   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadStarted>().call();
254 }
255
256 void WebContentsDelegateEfl::DidCommitProvisionalLoadForFrame(RenderFrameHost* render_frame_host,
257                                                               const GURL& url,
258                                                               PageTransition transition_type) {
259   web_view_->SmartCallback<EWebViewCallbacks::LoadCommitted>().call();
260 }
261
262 void WebContentsDelegateEfl::DidNavigateAnyFrame(const LoadCommittedDetails& details, const FrameNavigateParams& params) {
263   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadRedirect>().call();
264   static_cast<BrowserContextEfl*>(web_contents_->GetBrowserContext())->AddVisitedURLs(params.redirects);
265 }
266
267 void WebContentsDelegateEfl::DidFailProvisionalLoad(RenderFrameHost* render_frame_host,
268                                                     const GURL& validated_url,
269                                                     int error_code,
270                                                     const string16& error_description) {
271   DidFailLoad(render_frame_host, validated_url, error_code, error_description);
272 }
273 void WebContentsDelegateEfl::DidFailLoad(RenderFrameHost* render_frame_host,
274                                          const GURL& validated_url,
275                                          int error_code,
276                                          const string16& error_description) {
277   if (render_frame_host->GetParent())
278     return;
279
280   scoped_ptr<_Ewk_Error> error(new _Ewk_Error(error_code,
281                                             validated_url.possibly_invalid_spec().c_str(),
282                                             error_description.empty() ?
283                                                 net::ErrorToString(error_code) :
284                                                 UTF16ToUTF8(error_description).c_str()));
285
286   web_view_->SmartCallback<EWebViewCallbacks::LoadError>().call(error.get());
287 }
288
289 void WebContentsDelegateEfl::DidFinishLoad(RenderFrameHost* render_frame_host,
290                                            const GURL& validated_url) {
291   if (!render_frame_host->GetParent())
292     return;
293
294   NavigationEntry *entry = web_contents()->GetController().GetActiveEntry();
295   FaviconStatus &favicon = entry->GetFavicon();
296
297   // check/update the url and favicon url in favicon database
298   FaviconService fs;
299   fs.SetFaviconURLForPageURL(favicon.url, validated_url);
300
301   // download favicon if there is no such in database
302   if (!fs.ExistsForFaviconURL(favicon.url)) {
303     fprintf(stderr, "[DidFinishLoad] :: no favicon in database for URL: %s\n", favicon.url.spec().c_str());
304     favicon_downloader_.reset(new FaviconDownloader(web_contents(),
305                                                    favicon.url,
306                                                    base::Bind(&WebContentsDelegateEfl::DidDownloadFavicon,
307                                                               weak_ptr_factory_.GetWeakPtr())));
308     favicon_downloader_->Start();
309   } else {
310     web_view_->SmartCallback<EWebViewCallbacks::IconReceived>().call();
311   }
312
313   web_view_->SmartCallback<EWebViewCallbacks::LoadFinished>().call();
314 }
315
316 void WebContentsDelegateEfl::DidStartLoading(RenderViewHost* render_view_host) {
317   web_view_->SmartCallback<EWebViewCallbacks::LoadStarted>().call();
318 }
319
320 void WebContentsDelegateEfl::DidUpdateFaviconURL(const std::vector<FaviconURL>& candidates) {
321   // select and set proper favicon
322   for (unsigned int i = 0; i < candidates.size(); ++i) {
323     FaviconURL favicon = candidates[i];
324     if (favicon.icon_type == FaviconURL::FAVICON && !favicon.icon_url.is_empty()) {
325       NavigationEntry *entry = web_contents_->GetController().GetActiveEntry();
326       if (!entry)
327         return;
328       entry->GetFavicon().url = favicon.icon_url;
329       entry->GetFavicon().valid = true;
330       return;
331     }
332   }
333   return;
334 }
335
336 void WebContentsDelegateEfl::DidDownloadFavicon(bool success, const GURL& icon_url, const SkBitmap& bitmap) {
337   favicon_downloader_.reset();
338   if (success) {
339     FaviconService fs;
340     fs.SetBitmapForFaviconURL(bitmap, icon_url);
341     // emit "icon,received"
342     web_view_->SmartCallback<EWebViewCallbacks::IconReceived>().call();
343   }
344 }
345
346 void WebContentsDelegateEfl::RequestCertificateConfirm(WebContents* /*web_contents*/,
347                                                       int cert_error,
348                                                       const net::SSLInfo& ssl_info,
349                                                       const GURL& url,
350                                                       ResourceType::Type /*resource_type*/,
351                                                       bool /*overridable*/,
352                                                       bool /*strict_enforcement*/,
353                                                       const base::Callback<void(bool)>& callback,
354                                                       CertificateRequestResultType* result) {
355   DCHECK(result);
356   std::string pem_certificate;
357   if (!net::X509Certificate::GetPEMEncoded(ssl_info.cert->os_cert_handle(), &pem_certificate)) {
358     *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
359     return;
360   }
361   // |result| can be used to deny/cancel request synchronously.
362   // ewk api does not need it. We don't use it.
363   scoped_ptr<_Ewk_Certificate_Policy_Decision> policy(new _Ewk_Certificate_Policy_Decision(url,
364                                                                                          pem_certificate,
365                                                                                          cert_error,
366                                                                                          callback));
367   web_view_->SmartCallback<EWebViewCallbacks::RequestCertificateConfirm>().call(policy.get());
368   if (!policy->isSuspended && !policy->isDecided)
369     callback.Run(true);
370 }
371
372 void WebContentsDelegateEfl::SetContentSecurityPolicy(const std::string& policy, tizen_webview::ContentSecurityPolicyType header_type) {
373   // Might makes sense as it only uses existing functionality already exposed for javascript. Needs extra api at blink side.
374   // Not necessary for eflwebview bringup.
375 #if !defined(EWK_BRINGUP)
376   if (document_created_) {
377     RenderViewHost* rvh = web_contents_->GetRenderViewHost();
378     rvh->Send(new EwkViewMsg_SetCSP(rvh->GetRoutingID(), policy, header_type));
379   } else {
380     DCHECK(!pending_content_security_policy_.get());
381     pending_content_security_policy_.reset(new ContentSecurityPolicy(policy, header_type));
382   }
383 #endif
384 }
385
386 void WebContentsDelegateEfl::ShowPopupMenu(const gfx::Rect& rect, blink::TextDirection textDirection, double pageScaleFactor, const std::vector<MenuItem>& items, int data, int selectedIndex, bool multiple) {
387   web_view_->ShowPopupMenu(rect, textDirection, pageScaleFactor, items, data, selectedIndex, multiple);
388 }
389
390 void WebContentsDelegateEfl::HidePopupMenu() {
391   web_view_->HidePopupMenu();
392 }
393
394 void WebContentsDelegateEfl::FindReply(WebContents* web_contents,
395                                        int request_id,
396                                        int number_of_matches,
397                                        const gfx::Rect& selection_rect,
398                                        int active_match_ordinal,
399                                        bool final_update) {
400   if (final_update && request_id == web_view_->current_find_request_id()) {
401     unsigned int uint_number_of_matches = static_cast<unsigned int>(number_of_matches);
402     web_view_->SmartCallback<EWebViewCallbacks::TextFound>().call(&uint_number_of_matches);
403   }
404 }
405
406 JavaScriptDialogManager* WebContentsDelegateEfl::GetJavaScriptDialogManager() {
407   if (!dialog_manager_)
408     dialog_manager_ = new JavaScriptDialogManagerEfl();
409   return dialog_manager_;
410 }
411
412 bool WebContentsDelegateEfl::OnMessageReceived(const IPC::Message& message) {
413   bool handled = true;
414   IPC_BEGIN_MESSAGE_MAP(WebContentsDelegateEfl, message)
415     IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_GetContentSecurityPolicy, OnGetContentSecurityPolicy)
416     IPC_MESSAGE_HANDLER(EwkHostMsg_DidPrintPagesToPdf, OnPrintedMetafileReceived)
417     IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage)
418     IPC_MESSAGE_HANDLER(EwkHostMsg_FormSubmit, OnFormSubmit)
419     IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage, OnWrtPluginSyncMessage)
420     IPC_MESSAGE_UNHANDLED(handled = false)
421   IPC_END_MESSAGE_MAP()
422
423   return handled;
424 }
425
426 void WebContentsDelegateEfl::OnFormSubmit(const GURL&url) {
427   web_view_->SmartCallback<EWebViewCallbacks::FormSubmit>().call(url.GetContent().c_str());
428 }
429
430 void WebContentsDelegateEfl::OnWrtPluginMessage(const tizen_webview::WrtIpcMessageData& data) {
431   scoped_ptr<tizen_webview::WrtIpcMessageData> p(new tizen_webview::WrtIpcMessageData);
432   p->type = data.type;
433   p->value = data.value;
434   p->id = data.id;
435   p->reference_id = data.reference_id;
436
437   web_view_->SmartCallback<EWebViewCallbacks::WrtPluginsMessage>().call(p.get());
438 }
439
440 void WebContentsDelegateEfl::OnWrtPluginSyncMessage(const tizen_webview::WrtIpcMessageData& data,
441                                                     IPC::Message* reply) {
442   scoped_ptr<tizen_webview::WrtIpcMessageData> tmp(new tizen_webview::WrtIpcMessageData);
443   tmp->type = data.type;
444   web_view_->SmartCallback<EWebViewCallbacks::WrtPluginsMessage>().call(tmp.get());
445   EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp->value);
446   Send(reply);
447 }
448
449 void WebContentsDelegateEfl::DidFirstVisuallyNonEmptyPaint() {
450   web_view_->SmartCallback<EWebViewCallbacks::FrameRendered>().call(0);
451 }
452
453 void WebContentsDelegateEfl::OnGetContentSecurityPolicy(IPC::Message* reply_msg) {
454   document_created_ = true;
455   if (!pending_content_security_policy_.get()) {
456     EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams(reply_msg, std::string(), TW_CSP_DEFAULT_POLICY);
457   } else {
458     EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams(reply_msg,
459         pending_content_security_policy_->policy, pending_content_security_policy_->header_type);
460     pending_content_security_policy_.reset();
461   }
462   Send(reply_msg);
463 }
464
465 void WebContentsDelegateEfl::OnPrintedMetafileReceived(const DidPrintPagesParams& params) {
466   base::SharedMemory shared_buf(params.metafile_data_handle, true);
467   if (!shared_buf.Map(params.data_size)) {
468      NOTREACHED() << "couldn't map";
469      return;
470   }
471   scoped_ptr<printing::PdfMetafileSkia> metafile(new printing::PdfMetafileSkia);
472   if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
473     NOTREACHED() << "Invalid metafile header";
474     return;
475   }
476   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
477         base::Bind(&WritePdfDataToFile, metafile.release(), params.filename));
478 }
479
480 void WebContentsDelegateEfl::NavigationEntryCommitted(const LoadCommittedDetails& load_details) {
481   int forward_backward_list_count = web_contents()->GetController().GetEntryCount();
482   if (forward_backward_list_count != forward_backward_list_count_) {
483     web_view_->InvokeBackForwardListChangedCallback();
484     forward_backward_list_count_ = forward_backward_list_count;
485   }
486 }
487
488 void WebContentsDelegateEfl::RenderProcessGone(base::TerminationStatus status) {
489   // See RenderWidgetHostViewEfl::RenderProcessGone.
490   if (status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION
491       || status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED
492       || status == base::TERMINATION_STATUS_PROCESS_CRASHED) {
493     bool unused = false;
494     web_view_->SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&unused);
495     // A sane app would handle the callback and delete the view immediately.
496     // Otherwise, we will most probably crash when a method is called on |web_view_|.
497   }
498 }
499
500 bool WebContentsDelegateEfl::AddMessageToConsole(WebContents* source,
501                                               int32 level,
502                                               const string16& message,
503                                               int32 line_no,
504                                               const string16& source_id) {
505   scoped_ptr<_Ewk_Console_Message> console_message(new _Ewk_Console_Message(level,
506                                                                           UTF16ToUTF8(message).c_str(),
507                                                                           line_no,
508                                                                           source->GetVisibleURL().spec().c_str()));
509   web_view_->SmartCallback<EWebViewCallbacks::ConsoleMessage>().call(console_message.get());
510   return true;
511 }
512
513 void WebContentsDelegateEfl::RunFileChooser(WebContents* web_contents, const FileChooserParams& params) {
514   web_view_->ShowFileChooser(params);
515 }
516
517 content::ColorChooser* WebContentsDelegateEfl::OpenColorChooser(
518     WebContents* web_contents,
519     SkColor color,
520     const std::vector<ColorSuggestion>& suggestions) {
521   ColorChooserEfl* color_chooser_efl = new ColorChooserEfl(web_contents);
522   web_view_->RequestColorPicker(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), SkColorGetA(color));
523
524   return color_chooser_efl;
525 }
526
527 void WebContentsDelegateEfl::OpenDateTimeDialog(
528     ui::TextInputType dialog_type,
529     double dialog_value,
530     double min,
531     double max,
532     double step,
533     const std::vector<DateTimeSuggestion>& suggestions) {
534   int inputPickerType;
535   std::string inputMethodHints;
536
537   switch (dialog_type) {
538     case ui::TEXT_INPUT_TYPE_DATE:
539       inputPickerType = TW_INPUT_TYPE_DATE;
540       inputMethodHints = "date";
541       break;
542     case ui::TEXT_INPUT_TYPE_DATE_TIME:
543       inputPickerType = TW_INPUT_TYPE_DATETIME;
544       inputMethodHints = "datetime";
545       break;
546     case ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL:
547       inputPickerType = TW_INPUT_TYPE_DATETIMELOCAL;
548       inputMethodHints = "datetime-local";
549       break;
550     case ui::TEXT_INPUT_TYPE_TIME:
551       inputPickerType = TW_INPUT_TYPE_TIME;
552       inputMethodHints = "time";
553       break;
554     case ui::TEXT_INPUT_TYPE_WEEK:
555       inputPickerType = TW_INPUT_TYPE_WEEK;
556       inputMethodHints = "week";
557       break;
558     case ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE:
559       inputPickerType = TW_INPUT_TYPE_TEXT;
560       inputMethodHints = "date";
561       break;
562     case ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD:
563       inputPickerType = TW_INPUT_TYPE_DATETIME;
564       inputMethodHints = "datetime";
565       break;
566     case ui::TEXT_INPUT_TYPE_MONTH:
567       inputPickerType = TW_INPUT_TYPE_MONTH;
568       inputMethodHints = "month";
569       break;
570     default:
571       inputPickerType = TW_INPUT_TYPE_TEXT;
572       inputMethodHints = "";
573       break;
574   }
575   web_view_->InputPickerShow(static_cast<tizen_webview::Input_Type>(inputPickerType), inputMethodHints.c_str());
576 }
577 } //namespace content