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