Enable content shell with aura for desktop
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / web_contents_delegate_efl.cc
1 // Copyright 2014 Samsung Electronics. 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 "web_contents_delegate_efl.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "browser/favicon/favicon_database.h"
9 #include "browser/inputpicker/color_chooser_efl.h"
10 #include "browser/javascript_dialog_manager_efl.h"
11 #include "browser/policy_response_delegate_efl.h"
12 #include "common/render_messages_ewk.h"
13 #include "components/favicon/core/favicon_url.h"
14 #include "components/favicon_base/favicon_types.h"
15 #include "components/password_manager/core/common/password_manager_pref_names.h"
16 #include "components/prefs/pref_service.h"
17 #include "content/common/content_switches_internal.h"
18 #include "content/common/render_messages_efl.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/favicon_status.h"
21 #include "content/public/browser/invalidate_type.h"
22 #include "content/public/browser/navigation_entry.h"
23 #include "content/public/browser/navigation_handle.h"
24 #include "eweb_view.h"
25 #include "eweb_view_callbacks.h"
26 #include "net/base/load_states.h"
27 #include "net/http/http_response_headers.h"
28 #include "printing/metafile_skia.h"
29 #include "private/ewk_certificate_private.h"
30 #include "private/ewk_console_message_private.h"
31 #include "private/ewk_custom_handlers_private.h"
32 #include "private/ewk_error_private.h"
33 #include "private/ewk_policy_decision_private.h"
34 #include "private/ewk_user_media_private.h"
35 #include "private/webview_delegate_ewk.h"
36 #include "third_party/blink/public/common/input/web_input_event.h"
37 #include "url/gurl.h"
38
39 #if defined(OS_TIZEN)
40 #include <app_control.h>
41 #include <app_manager.h>
42 #endif
43
44 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
45 #include "content/public/browser/media_capture_devices.h"
46 #include "media/capture/video/tizen/video_capture_device_tizen.h"
47 #endif
48
49 #if defined(TIZEN_AUTOFILL_SUPPORT)
50 #include "browser/autofill/autofill_client_efl.h"
51 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
52 #include "browser/password_manager/password_manager_client_efl.h"
53 #include "components/autofill/core/browser/autofill_client.h"
54 #include "components/autofill/core/browser/autofill_manager.h"
55 #include "components/web_modal/web_contents_modal_dialog_manager.h"
56
57 using autofill::AutofillManager;
58 using autofill::AutofillClientEfl;
59 using autofill::ContentAutofillDriverFactory;
60 using password_manager::PasswordManagerClientEfl;
61 #endif
62
63 using std::u16string;
64 using namespace ui;
65
66 namespace content {
67
68 void WritePdfDataToFile(printing::MetafileSkia* metafile,
69                         const base::FilePath& filename) {
70 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
72 #endif
73   DCHECK(metafile);
74   base::File file(filename,
75                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
76   metafile->SaveTo(&file);
77   file.Close();
78   delete metafile;
79 }
80
81 #if defined(OS_TIZEN) && defined(TIZEN_MULTIMEDIA_SUPPORT)
82 static const MediaStreamDevice* GetRequestedVideoDevice(
83     const std::string& device_id) {
84   const MediaStreamDevices& video_devices =
85       MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices();
86   if (video_devices.empty())
87     return NULL;
88   if (device_id.length() == 0)
89     return &(*video_devices.begin());
90   return video_devices.FindById(device_id);
91 }
92 #endif
93
94 WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
95     : WebContentsObserver(&view->web_contents()),
96       web_view_(view),
97       is_fullscreen_(false),
98       web_contents_(view->web_contents()),
99       did_render_frame_(false),
100       did_first_visually_non_empty_paint_(false),
101       document_created_(false),
102       dialog_manager_(NULL),
103       weak_ptr_factory_(this) {
104 #if defined(TIZEN_AUTOFILL_SUPPORT)
105   AutofillClientEfl::CreateForWebContents(&web_contents_);
106   AutofillClientEfl* autofill_client =
107       AutofillClientEfl::FromWebContents(&web_contents_);
108   autofill_client->SetEWebView(view);
109   PasswordManagerClientEfl::CreateForWebContentsWithAutofillClient(
110       &web_contents_, autofill_client);
111   ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
112       &web_contents_, autofill_client, EWebView::GetPlatformLocale(),
113       AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
114 #endif
115 }
116
117 WebContentsDelegateEfl::~WebContentsDelegateEfl() {
118   // It's important to delete web_contents_ before dialog_manager_
119   // destructor of web contents uses dialog_manager_
120
121   delete dialog_manager_;
122 }
123
124 WebContents* WebContentsDelegateEfl::OpenURLFromTab(
125     WebContents* source,
126     const OpenURLParams& params) {
127   const GURL& url = params.url;
128   WindowOpenDisposition disposition = params.disposition;
129
130   if (!source || (disposition != WindowOpenDisposition::CURRENT_TAB &&
131                   disposition != WindowOpenDisposition::NEW_FOREGROUND_TAB &&
132                   disposition != WindowOpenDisposition::NEW_BACKGROUND_TAB &&
133                   disposition != WindowOpenDisposition::OFF_THE_RECORD)) {
134     NOTIMPLEMENTED();
135     return NULL;
136   }
137
138   if (disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB ||
139       disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB ||
140       disposition == WindowOpenDisposition::OFF_THE_RECORD) {
141     Evas_Object* new_object = NULL;
142     web_view_->SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(
143         &new_object);
144
145     if (!new_object)
146       return NULL;
147
148     if (disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB)
149       ActivateContents(source);
150
151     EWebView* wv =
152         WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(new_object);
153     DCHECK(wv);
154     wv->SetURL(url);
155     return NULL;
156   }
157
158   ui::PageTransition transition(ui::PageTransitionFromInt(params.transition));
159   source->GetController().LoadURL(url, params.referrer, transition,
160                                   std::string());
161   return source;
162 }
163
164 void WebContentsDelegateEfl::NavigationStateChanged(
165     WebContents* source, InvalidateTypes changed_flags) {
166   // We only notify clients if visible url actually changed, because on some
167   // pages we would get notifications with flag INVALIDATE_TYPE_URL even when
168   // visible url did not change.
169   if ((changed_flags & INVALIDATE_TYPE_URL) &&
170        last_visible_url_ != source->GetVisibleURL()) {
171     last_visible_url_ = source->GetVisibleURL();
172     const char* url = last_visible_url_.spec().c_str();
173
174     web_view_->SmartCallback<EWebViewCallbacks::URLChanged>().call(url);
175     web_view_->SmartCallback<EWebViewCallbacks::URIChanged>().call(url);
176   }
177 }
178
179 void WebContentsDelegateEfl::LoadingStateChanged(WebContents* source,
180                                                  bool to_different_document) {
181   if (source->IsLoading())
182     web_view_->SmartCallback<EWebViewCallbacks::LoadProgressStarted>().call();
183   else
184     web_view_->SmartCallback<EWebViewCallbacks::LoadProgressFinished>().call();
185 }
186
187 void WebContentsDelegateEfl::LoadProgressChanged(double progress) {
188   web_view_->SetProgressValue(progress);
189   web_view_->SmartCallback<EWebViewCallbacks::LoadProgress>().call(&progress);
190 }
191
192 void WebContentsDelegateEfl::DidStartNavigation(
193     NavigationHandle* navigation_handle) {
194   if (!navigation_handle->IsInMainFrame())
195     return;
196   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadStarted>().call();
197 }
198
199 bool WebContentsDelegateEfl::ShouldCreateWebContents(
200     WebContents* web_contents,
201     RenderFrameHost* opener,
202     SiteInstance* source_site_instance,
203     int32_t route_id,
204     int32_t main_frame_route_id,
205     int32_t main_frame_widget_route_id,
206     mojom::WindowContainerType window_container_type,
207     const GURL& opener_url,
208     const std::string& frame_name,
209     const GURL& target_url,
210     const std::string& partition_id,
211     SessionStorageNamespace* session_storage_namespace) {
212   // We implement the asynchronous version of the function, this
213   // one should never be invoked.
214   NOTREACHED();
215   return false;
216 }
217
218 void WebContentsDelegateEfl::CloseContents(WebContents* source) {
219   web_view_->SmartCallback<EWebViewCallbacks::WindowClosed>().call();
220 }
221
222 void WebContentsDelegateEfl::EnterFullscreenModeForTab(
223     RenderFrameHost* requesting_frame,
224     const blink::mojom::FullscreenOptions& options) {
225   is_fullscreen_ = true;
226   web_view_->SmartCallback<EWebViewCallbacks::EnterFullscreen>().call();
227 }
228
229 void WebContentsDelegateEfl::ExitFullscreenModeForTab(
230     WebContents* web_contents) {
231   is_fullscreen_ = false;
232   web_view_->SmartCallback<EWebViewCallbacks::ExitFullscreen>().call();
233 }
234
235 bool WebContentsDelegateEfl::IsFullscreenForTabOrPending(
236     const WebContents* web_contents) {
237   return is_fullscreen_;
238 }
239
240 void WebContentsDelegateEfl::RegisterProtocolHandler(
241     RenderFrameHost* host,
242     const std::string& protocol,
243     const GURL& url,
244     bool user_gesture) {
245   Ewk_Custom_Handlers_Data protocol_data(protocol.c_str(), url.host().c_str(),
246                                          url.spec().c_str());
247   web_view_->SmartCallback<EWebViewCallbacks::RegisterProtocolHandler>().call(
248       &protocol_data);
249 }
250
251 void WebContentsDelegateEfl::UnregisterProtocolHandler(
252     RenderFrameHost* host,
253     const std::string& protocol,
254     const GURL& url,
255     bool user_gesture) {
256   Ewk_Custom_Handlers_Data protocol_data(protocol.c_str(), url.host().c_str(),
257                                          url.spec().c_str());
258   web_view_->SmartCallback<EWebViewCallbacks::UnregisterProtocolHandler>().call(
259       &protocol_data);
260 }
261
262 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
263 void WebContentsDelegateEfl::RequestMediaAccessAllow(
264     const MediaStreamRequest& request,
265     MediaResponseCallback callback) {
266   MediaStreamDevices devices;
267
268   if (request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
269     devices.push_back(
270         MediaStreamDevice(request.audio_type, "default", "Default"));
271   }
272
273   if (request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
274 #if defined(OS_TIZEN)
275     const MediaStreamDevice* video_device =
276         GetRequestedVideoDevice(request.requested_video_device_id);
277     if (video_device) {
278       devices.push_back(*video_device);
279     } else {
280       std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
281                               std::unique_ptr<MediaStreamUI>());
282     }
283 #else
284     devices.push_back(
285         MediaStreamDevice(request.video_type, "/dev/video0", "1"));
286 #endif
287   }
288
289   std::move(callback).Run(devices, MEDIA_DEVICE_OK,
290                           std::unique_ptr<MediaStreamUI>());
291 }
292
293 void WebContentsDelegateEfl::RequestMediaAccessDeny(
294     const MediaStreamRequest& request,
295     MediaResponseCallback callback) {
296   LOG(ERROR) << __FUNCTION__ << " Decline request with empty list";
297   std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
298                           std::unique_ptr<MediaStreamUI>());
299 }
300
301 bool WebContentsDelegateEfl::CheckMediaAccessPermission(
302     WebContents* web_contents,
303     const GURL& security_origin,
304     MediaStreamType type) {
305   return true;
306 }
307
308 void WebContentsDelegateEfl::RequestMediaAccessPermission(
309     WebContents* web_contents,
310     const MediaStreamRequest& request,
311     MediaResponseCallback callback) {
312   std::unique_ptr<_Ewk_User_Media_Permission_Request> media_permission_request(
313       new _Ewk_User_Media_Permission_Request(this, request,
314                                              std::move(callback)));
315
316   Eina_Bool callback_result = EINA_FALSE;
317   if (!web_view_->InvokeViewUserMediaPermissionCallback(
318           media_permission_request.get(), &callback_result)) {
319     web_view_->SmartCallback<EWebViewCallbacks::UserMediaPermission>().call(
320         media_permission_request.get());
321   }
322
323   // if policy is suspended, the API takes over the policy object lifetime
324   // and policy will be deleted after decision is made
325   if (media_permission_request->IsSuspended())
326     ignore_result(media_permission_request.release());
327   else if (!media_permission_request->IsDecided()) {
328     callback.Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
329                  std::unique_ptr<MediaStreamUI>());
330   }
331 }
332 #endif
333
334 void WebContentsDelegateEfl::OnAuthRequired(const std::string& realm,
335                                             const GURL& url,
336                                             LoginDelegateEfl* login_delegate) {
337   web_view_->InvokeAuthCallback(login_delegate, url, realm);
338 }
339
340 void WebContentsDelegateEfl::DidStartProvisionalLoadForFrame(
341     RenderFrameHost* render_frame_host,
342     const GURL& validated_url,
343     bool is_error_page,
344     bool is_iframe_srcdoc) {
345   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadStarted>().call();
346 }
347
348 void WebContentsDelegateEfl::DidCommitProvisionalLoadForFrame(
349     RenderFrameHost* render_frame_host,
350     const GURL& url,
351     ui::PageTransition transition_type) {
352   web_view_->SmartCallback<EWebViewCallbacks::LoadCommitted>().call();
353 }
354
355 void WebContentsDelegateEfl::DidNavigateMainFrame(
356     const LoadCommittedDetails& details) {
357   // The condition checks whether the main frame navigated to a different page,
358   // not scrolled to a fragment inside the current page.
359   if (details.is_navigation_to_different_page())
360     web_view_->SmartCallback<EWebViewCallbacks::LoadStarted>().call();
361 }
362
363 void WebContentsDelegateEfl::DocumentOnLoadCompletedInMainFrame() {
364   web_view_->SmartCallback<EWebViewCallbacks::LoadFinished>().call();
365 }
366
367 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
368 void WebContentsDelegateEfl::DidNavigateAnyFrame(
369     RenderFrameHost* render_frame_host,
370     const LoadCommittedDetails& details,
371     const FrameNavigateParams& params) {
372   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadRedirect>().call();
373   static_cast<BrowserContextEfl*>(web_contents_.GetBrowserContext())
374       ->AddVisitedURLs(params.redirects);
375 }
376 #endif
377
378 void WebContentsDelegateEfl::DidFinishLoad(RenderFrameHost* render_frame_host,
379                                            const GURL& validated_url) {
380   if (render_frame_host->GetParent())
381     return;
382
383   NavigationEntry* entry = web_contents().GetController().GetVisibleEntry();
384   if (!entry)
385     return;
386
387   FaviconStatus& favicon = entry->GetFavicon();
388
389   if (favicon.valid) {
390     // check/update the url and favicon url in favicon database
391     FaviconDatabase::Instance()->SetFaviconURLForPageURL(favicon.url,
392                                                          validated_url);
393
394     // download favicon if there is no such in database
395     if (!FaviconDatabase::Instance()->ExistsForFaviconURL(favicon.url)) {
396       LOG(ERROR) << "[DidFinishLoad] :: no favicon in database for URL: "
397                  << favicon.url.spec();
398       favicon_downloader_.reset(new FaviconDownloader(
399           &web_contents_, favicon.url,
400           base::BindOnce(&WebContentsDelegateEfl::DidDownloadFavicon,
401                          weak_ptr_factory_.GetWeakPtr())));
402       favicon_downloader_->Start();
403     } else {
404       web_view_->SmartCallback<EWebViewCallbacks::IconReceived>().call();
405     }
406   }
407
408   web_contents_.Focus();
409 }
410
411 void WebContentsDelegateEfl::DidUpdateFaviconURL(
412     RenderFrameHost* render_frame_host,
413     const std::vector<blink::mojom::FaviconURLPtr>& candidates) {
414   // select and set proper favicon
415   for (const auto& favicon : candidates) {
416     if (favicon->icon_type == blink::mojom::FaviconIconType::kFavicon &&
417         !favicon->icon_url.is_valid()) {
418       NavigationEntry* entry = web_contents_.GetController().GetVisibleEntry();
419       if (!entry)
420         return;
421       entry->GetFavicon().url = favicon->icon_url;
422       entry->GetFavicon().valid = true;
423       return;
424     }
425   }
426 }
427
428 void WebContentsDelegateEfl::DidDownloadFavicon(bool success,
429                                                 const GURL& icon_url,
430                                                 const SkBitmap& bitmap) {
431   favicon_downloader_.reset();
432   if (success) {
433     FaviconDatabase::Instance()->SetBitmapForFaviconURL(bitmap, icon_url);
434     // emit "icon,received"
435     web_view_->SmartCallback<EWebViewCallbacks::IconReceived>().call();
436   }
437 }
438
439 void WebContentsDelegateEfl::RequestCertificateConfirm(
440     WebContents* /*web_contents*/,
441     int cert_error,
442     const net::SSLInfo& ssl_info,
443     const GURL& url,
444     bool /*overridable*/,
445     bool /*strict_enforcement*/,
446     base::OnceCallback<void(CertificateRequestResultType)> callback) {
447 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
448   // FIXME: EWK_BRINGUP definition should be removed.
449   DCHECK(result);
450   std::string pem_certificate;
451   if (!net::X509Certificate::GetPEMEncoded(ssl_info.cert->os_cert_handle(),
452                                            &pem_certificate)) {
453     *result = CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
454     return;
455   }
456   certificate_policy_decision_.reset(new _Ewk_Certificate_Policy_Decision(
457       url, pem_certificate, cert_error, std::move(callback)));
458 #endif  // !defined(EWK_BRINGUP)
459   web_view_->SmartCallback<EWebViewCallbacks::RequestCertificateConfirm>().call(
460       certificate_policy_decision_.get());
461
462   // if policy is suspended, the API takes over the policy object lifetime
463   // and policy will be deleted after decision is made
464 #if !defined(EWK_BRINGUP)  // FIXME: m108 bringup
465   if (certificate_policy_decision_->isSuspended()) {
466     ignore_result(certificate_policy_decision_.release());
467   } else {
468     certificate_policy_decision_->setDecision(true);
469   }
470 #endif
471 }
472
473 void WebContentsDelegateEfl::ActivateContents(WebContents* contents) {
474 #if defined(OS_TIZEN)
475   app_control_h app_control = nullptr;
476   int ret = app_control_create(&app_control);
477   if (ret != APP_CONTROL_ERROR_NONE) {
478     LOG(ERROR) << "app_control_create is failed with err " << ret;
479     return;
480   }
481
482   std::unique_ptr<std::remove_pointer<app_control_h>::type,
483                   decltype(app_control_destroy)*>
484       auto_release{app_control, app_control_destroy};
485
486   char* app_id = nullptr;
487   ret = app_manager_get_app_id(getpid(), &app_id);
488   if (ret != APP_MANAGER_ERROR_NONE) {
489     LOG(ERROR) << "app_manager_get_app_id is failed with err " << ret;
490     return;
491   }
492
493   ret = app_control_set_app_id(app_control, app_id);
494   if (app_id)
495     free(app_id);
496   if (ret != APP_CONTROL_ERROR_NONE) {
497     LOG(ERROR) << "app_control_set_app_id is failed with err " << ret;
498     return;
499   }
500
501   ret = app_control_send_launch_request(app_control, nullptr, nullptr);
502   if (ret != APP_CONTROL_ERROR_NONE) {
503     LOG(ERROR) << "app_control_send_launch_request is failed with err " << ret;
504     return;
505   }
506 #endif
507 }
508
509 void WebContentsDelegateEfl::SetContentSecurityPolicy(
510     const std::string& policy,
511     Ewk_CSP_Header_Type header_type) {
512   if (document_created_) {
513 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
514     RenderViewHost* rvh = web_contents_.GetRenderViewHost();
515     rvh->Send(new EwkViewMsg_SetCSP(rvh->GetRoutingID(), policy, header_type));
516 #endif
517   } else {
518     DCHECK(!pending_content_security_policy_.get());
519     pending_content_security_policy_.reset(
520         new ContentSecurityPolicy(policy, header_type));
521   }
522 }
523
524 void WebContentsDelegateEfl::FindReply(WebContents* web_contents,
525                                        int request_id,
526                                        int number_of_matches,
527                                        const gfx::Rect& selection_rect,
528                                        int active_match_ordinal,
529                                        bool final_update) {
530   if (final_update && request_id == web_view_->current_find_request_id()) {
531     unsigned int uint_number_of_matches =
532         static_cast<unsigned int>(number_of_matches);
533     web_view_->SmartCallback<EWebViewCallbacks::TextFound>().call(
534         &uint_number_of_matches);
535   }
536 }
537
538 void WebContentsDelegateEfl::DidRenderFrame() {
539   // Call FrameRendered callback when loading and first layout is finished.
540   if (!did_render_frame_ && did_first_visually_non_empty_paint_ &&
541       (web_view_->GetProgressValue() > 0.1)) {
542     did_first_visually_non_empty_paint_ = false;
543     did_render_frame_ = true;
544 #if defined(USE_TTRACE)
545     TTRACE_WEB("WebContentsDelegateEfl::DidRenderFrame");
546 #endif
547     LOG(INFO) << "WebContentsDelegateEfl::DidRenderFrame";
548
549     // "frame,rendered" message is triggered as soon as rendering of a frame
550     // is completed.
551     web_view_->SmartCallback<EWebViewCallbacks::FrameRendered>().call(0);
552   }
553 }
554
555 JavaScriptDialogManager* WebContentsDelegateEfl::GetJavaScriptDialogManager(
556     WebContents* source) {
557   if (!dialog_manager_)
558     dialog_manager_ = new JavaScriptDialogManagerEfl();
559   return dialog_manager_;
560 }
561
562 void WebContentsDelegateEfl::OnUpdateSettings(const Ewk_Settings* settings) {
563 #if defined(TIZEN_AUTOFILL_SUPPORT)
564   PasswordManagerClientEfl* client =
565       PasswordManagerClientEfl::FromWebContents(&web_contents_);
566   if (client) {
567     PrefService* prefs = client->GetPrefs();
568     prefs->SetBoolean(password_manager::prefs::kPasswordManagerSavingEnabled,
569                       settings->autofillPasswordForm());
570   }
571 #endif
572 }
573
574 bool WebContentsDelegateEfl::OnMessageReceived(
575     const IPC::Message& message,
576     RenderFrameHost* render_frame_host) {
577   bool handled = true;
578   IPC_BEGIN_MESSAGE_MAP(WebContentsDelegateEfl, message)
579     IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_GetContentSecurityPolicy,
580                                     OnGetContentSecurityPolicy)
581     IPC_MESSAGE_HANDLER(EwkHostMsg_DidPrintPagesToPdf,
582                         OnPrintedMetafileReceived)
583     IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage)
584     IPC_MESSAGE_HANDLER_DELAY_REPLY(EwkHostMsg_WrtSyncMessage,
585                                     OnWrtPluginSyncMessage)
586     IPC_MESSAGE_UNHANDLED(handled = false)
587   IPC_END_MESSAGE_MAP()
588
589   return handled;
590 }
591
592 void WebContentsDelegateEfl::DidFailProvisionalLoad(
593     RenderFrameHost* render_frame_host,
594     const GURL& validated_url,
595     int error_code,
596     const std::u16string& error_description,
597     bool /*was_ignored_by_handler*/) {
598   DidFailLoad(render_frame_host, validated_url, error_code);
599 }
600
601 void WebContentsDelegateEfl::DidFailLoad(RenderFrameHost* render_frame_host,
602                                          const GURL& validated_url,
603                                          int error_code) {
604   bool is_main_frame = !render_frame_host->GetParent();
605   web_view_->InvokeLoadError(validated_url, error_code, std::string(),
606                              is_main_frame);
607 }
608
609 bool WebContentsDelegateEfl::Send(IPC::Message* message) {
610   if (!web_contents_.GetRenderViewHost()) {
611     delete message;
612     return false;
613   }
614 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
615   return web_contents_.GetRenderViewHost()->Send(message);
616 #else
617   return false;
618 #endif
619 }
620
621 void WebContentsDelegateEfl::OnWrtPluginMessage(
622     const Ewk_Wrt_Message_Data& data) {
623   std::unique_ptr<Ewk_Wrt_Message_Data> p(new Ewk_Wrt_Message_Data);
624   p->type = data.type;
625   p->value = data.value;
626   p->id = data.id;
627   p->reference_id = data.reference_id;
628
629   web_view_->SmartCallback<EWebViewCallbacks::WrtPluginsMessage>().call(
630       p.get());
631 }
632
633 void WebContentsDelegateEfl::OnWrtPluginSyncMessage(
634     const Ewk_Wrt_Message_Data& data,
635     IPC::Message* reply) {
636   Ewk_Wrt_Message_Data tmp = data;
637   web_view_->SmartCallback<EWebViewCallbacks::WrtPluginsMessage>().call(&tmp);
638   EwkHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value);
639   Send(reply);
640 }
641
642 void WebContentsDelegateEfl::DidFirstVisuallyNonEmptyPaint() {
643   did_first_visually_non_empty_paint_ = true;
644   web_view_->SmartCallback<EWebViewCallbacks::LoadNonEmptyLayoutFinished>()
645       .call();
646 }
647
648 void WebContentsDelegateEfl::DidStartLoading() {
649   did_render_frame_ = false;
650 }
651
652 void WebContentsDelegateEfl::OnGetContentSecurityPolicy(
653     IPC::Message* reply_msg) {
654   document_created_ = true;
655   if (!pending_content_security_policy_.get()) {
656     EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams(
657         reply_msg, std::string(), EWK_DEFAULT_POLICY);
658   } else {
659     EwkHostMsg_GetContentSecurityPolicy::WriteReplyParams(
660         reply_msg, pending_content_security_policy_->policy,
661         pending_content_security_policy_->header_type);
662     pending_content_security_policy_.reset();
663   }
664   Send(reply_msg);
665 }
666
667 void WebContentsDelegateEfl::OnPrintedMetafileReceived(
668     const DidPrintPagesParams& params) {
669 #if !defined(EWK_BRINGUP)  // FIXME: m85 bringup
670   base::SharedMemory shared_buf(params.metafile_data_handle, true);
671   if (!shared_buf.Map(params.data_size)) {
672     NOTREACHED() << "couldn't map";
673     return;
674   }
675
676   std::unique_ptr<printing::MetafileSkia> metafile(
677       new printing::MetafileSkia());
678   if (!metafile->InitFromData(shared_buf.memory(), params.data_size)) {
679     NOTREACHED() << "Invalid metafile header";
680     return;
681   }
682
683   BrowserThread::PostTask(
684       BrowserThread::FILE, FROM_HERE,
685       base::BindOnce(&WritePdfDataToFile, metafile.release(), params.filename));
686 #endif
687 }
688
689 void WebContentsDelegateEfl::NavigationEntryCommitted(
690     const LoadCommittedDetails& load_details) {
691   web_view_->InvokeBackForwardListChangedCallback();
692 }
693
694 void WebContentsDelegateEfl::RenderViewCreated(
695     RenderViewHost* render_view_host) {
696   web_view_->RenderViewCreated(render_view_host);
697 }
698
699 void WebContentsDelegateEfl::RenderProcessGone(base::TerminationStatus status) {
700   // See RenderWidgetHostViewEfl::RenderProcessGone.
701   if (status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
702       status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ||
703       status == base::TERMINATION_STATUS_PROCESS_CRASHED) {
704     web_view_->HandleRendererProcessCrash();
705   }
706 }
707
708 bool WebContentsDelegateEfl::DidAddMessageToConsole(
709     WebContents* source,
710     blink::mojom::ConsoleMessageLevel level,
711     const std::u16string& message,
712     int32_t line_no,
713     const std::u16string& source_id) {
714   std::unique_ptr<_Ewk_Console_Message> console_message(
715       new _Ewk_Console_Message(static_cast<unsigned>(level),
716                                base::UTF16ToUTF8(message).c_str(), line_no,
717                                base::UTF16ToUTF8(source_id).c_str()));
718   web_view_->SmartCallback<EWebViewCallbacks::ConsoleMessage>().call(
719       console_message.get());
720   return true;
721 }
722
723 void WebContentsDelegateEfl::RunFileChooser(
724     RenderFrameHost* render_frame_host,
725     scoped_refptr<FileSelectListener> listener,
726     const blink::mojom::FileChooserParams& params) {
727   web_view_->ShowFileChooser(render_frame_host, params);
728 }
729
730 std::unique_ptr<ColorChooser> WebContentsDelegateEfl::OpenColorChooser(
731     WebContents* web_contents,
732     SkColor color,
733     const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) {
734   web_view_->RequestColorPicker(SkColorGetR(color), SkColorGetG(color),
735                                 SkColorGetB(color), SkColorGetA(color));
736   return std::make_unique<ColorChooserEfl>(*web_contents);
737 }
738
739 #if !defined(EWK_BRINGUP)  // FIXME: m76 bringup
740 void WebContentsDelegateEfl::OpenDateTimeDialog(
741     ui::TextInputType dialog_type,
742     double dialog_value,
743     double min,
744     double max,
745     double step,
746     const std::vector<DateTimeSuggestion>& suggestions) {
747   web_view_->InputPickerShow(dialog_type, dialog_value);
748 }
749 #endif
750
751 bool WebContentsDelegateEfl::PreHandleGestureEvent(
752     WebContents* source,
753     const blink::WebGestureEvent& event) {
754   blink::WebInputEvent::Type event_type = event.GetType();
755   switch (event_type) {
756     case blink::WebInputEvent::Type::kGestureDoubleTap:
757       if (is_fullscreen_)
758         return true;
759       break;
760     case blink::WebInputEvent::Type::kGesturePinchBegin:
761     case blink::WebInputEvent::Type::kGesturePinchUpdate:
762     case blink::WebInputEvent::Type::kGesturePinchEnd:
763       if (!IsPinchToZoomEnabled() ||
764           IsFullscreenForTabOrPending(&web_contents()))
765         return true;
766       break;
767     default:
768       break;
769   }
770   return false;
771 }
772
773 void WebContentsDelegateEfl::TitleWasSet(NavigationEntry* entry,
774                                          bool /*explicit_set*/) {
775   if (entry)
776     web_view_->GetBackForwardList()->UpdateItemWithEntry(entry);
777 }
778
779 }  // namespace content