[M67 Dev][EWK] Classify EWK APIs by public, internal, or product
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / eweb_view.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 "eweb_view.h"
6
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/pickle.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "browser/navigation_policy_handler_efl.h"
13 #include "browser/quota_permission_context_efl.h"
14 #include "browser/web_view_browser_message_filter.h"
15 #include "common/content_client_efl.h"
16 #include "common/render_messages_ewk.h"
17 #include "common/version_info.h"
18 #include "common/web_contents_utils.h"
19 #include "components/sessions/content/content_serialized_navigation_builder.h"
20 #include "components/sessions/core/serialized_navigation_entry.h"
21 #include "content/browser/renderer_host/render_view_host_impl.h"
22 #include "content/browser/renderer_host/render_widget_host_view_efl.h"
23 #include "content/browser/renderer_host/ui_events_helper.h"
24 #include "content/browser/renderer_host/web_event_factory_efl.h"
25 #include "content/browser/web_contents/web_contents_impl_efl.h"
26 #include "content/browser/web_contents/web_contents_view.h"
27 #include "content/browser/web_contents/web_contents_view_efl.h"
28 #include "content/common/content_client_export.h"
29 #include "content/common/frame_messages.h"
30 #include "content/common/view_messages.h"
31 #include "content/public/browser/browser_message_filter.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/host_zoom_map.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/resource_dispatcher_host.h"
37 #include "content/public/common/content_client.h"
38 #include "content/public/common/user_agent.h"
39 #include "permission_popup_manager.cc"
40 #include "private/ewk_back_forward_list_private.h"
41 #include "private/ewk_context_private.h"
42 #include "private/ewk_frame_private.h"
43 #include "private/ewk_policy_decision_private.h"
44 #include "private/ewk_quota_permission_request_private.h"
45 #include "private/ewk_settings_private.h"
46 #include "private/ewk_text_style_private.h"
47 #include "private/webview_delegate_ewk.h"
48 #include "public/ewk_hit_test_internal.h"
49 #include "services/network/public/cpp/resource_request_body.h"
50 #include "skia/ext/platform_canvas.h"
51 #include "third_party/blink/public/platform/web_string.h"
52 #include "third_party/blink/public/web/web_find_options.h"
53 #include "tizen/system_info.h"
54 #include "ui/base/l10n/l10n_util.h"
55 #include "ui/display/screen.h"
56 #include "ui/events/event_switches.h"
57 #include "web_contents_delegate_efl.h"
58 #include "web_contents_efl_delegate_ewk.h"
59 #include "web_contents_view_efl_delegate_ewk.h"
60
61 #include "browser/web_view_evas_handler.h"
62
63 #include "browser/selectpicker/popup_menu_item.h"
64 #include "browser/selectpicker/popup_menu_item_private.h"
65 #include <Ecore_Evas.h>
66 #include <Elementary.h>
67 #include <Eina.h>
68
69 #include <iostream>
70
71 using namespace content;
72 using web_contents_utils::WebViewFromWebContents;
73
74 namespace {
75
76 int screen_orientation_ = 0;
77
78 static const char* kRendererCrashedHTMLMessage =
79     "<html><body><h1>Renderer process has crashed!</h1></body></html>";
80
81 inline void SetDefaultStringIfNull(const char*& variable,
82                                    const char* default_string) {
83   if (!variable) {
84     variable = default_string;
85   }
86 }
87
88 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
89                             Eina_Rectangle* eina_rect) {
90   eina_rect->x = gfx_rect.x();
91   eina_rect->y = gfx_rect.y();
92   eina_rect->w = gfx_rect.width();
93   eina_rect->h = gfx_rect.height();
94 }
95
96 static content::WebContents* NullCreateWebContents(void*) {
97   return NULL;
98 }
99
100 }  // namespace
101
102 class WebViewAsyncRequestHitTestDataCallback {
103  public:
104   WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
105       : x_(x), y_(y), mode_(mode) {}
106   virtual ~WebViewAsyncRequestHitTestDataCallback(){};
107
108   virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
109
110  protected:
111   int GetX() const { return x_; }
112   int GetY() const { return y_; }
113   Ewk_Hit_Test_Mode GetMode() const { return mode_; }
114
115  private:
116   int x_;
117   int y_;
118   Ewk_Hit_Test_Mode mode_;
119 };
120
121 class WebViewAsyncRequestHitTestDataUserCallback
122     : public WebViewAsyncRequestHitTestDataCallback {
123  public:
124   WebViewAsyncRequestHitTestDataUserCallback(
125       int x,
126       int y,
127       Ewk_Hit_Test_Mode mode,
128       Ewk_View_Hit_Test_Request_Callback callback,
129       void* user_data)
130       : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
131         callback_(callback),
132         user_data_(user_data) {}
133
134   void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
135     DCHECK(callback_);
136     callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
137               user_data_);
138   }
139
140  private:
141   Ewk_View_Hit_Test_Request_Callback callback_;
142   void* user_data_;
143 };
144
145 int EWebView::find_request_id_counter_ = 0;
146 content::WebContentsEflDelegate::WebContentsCreateCallback
147     EWebView::create_new_window_web_contents_cb_ =
148         base::Bind(&NullCreateWebContents);
149
150 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
151   return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
152 }
153
154 RenderWidgetHostViewEfl* EWebView::rwhv() const {
155   return static_cast<RenderWidgetHostViewEfl*>(
156       web_contents_->GetRenderWidgetHostView());
157 }
158
159 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
160     : context_(context),
161       evas_object_(object),
162       native_view_(object),
163       touch_events_enabled_(false),
164       mouse_events_enabled_(false),
165       text_zoom_factor_(1.0),
166       formIsNavigating_(false),
167       current_find_request_id_(find_request_id_counter_++),
168       progress_(0.0),
169       hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
170                            base::WaitableEvent::InitialState::NOT_SIGNALED),
171       page_scale_factor_(1.0),
172       is_initialized_(false) {}
173
174 void EWebView::Initialize() {
175   if (is_initialized_) {
176     return;
177   }
178
179   InitializeContent();
180
181   evas_event_handler_ = new WebViewEvasEventHandler(this);
182
183   scroll_detector_.reset(new ScrollDetector(this));
184
185   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
186   web_contents_->SetDelegate(web_contents_delegate_.get());
187   back_forward_list_.reset(
188       new _Ewk_Back_Forward_List(web_contents_->GetController()));
189
190   DCHECK(web_contents_->GetRenderViewHost());
191   // Settings (content::WebPreferences) will be initalized by
192   // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
193   settings_.reset(new Ewk_Settings(
194       evas_object_,
195       web_contents_->GetRenderViewHost()->GetWebkitPreferences()));
196 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
197   base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
198   if (cmdline->HasSwitch(switches::kTouchEvents))
199     SetTouchEventsEnabled(true);
200   else
201 #endif
202     SetMouseEventsEnabled(true);
203
204   popupMenuItems_ = 0;
205   popupPicker_ = 0;
206
207   formNavigation_.count = 1;
208   formNavigation_.position = 0;
209   formNavigation_.prevState = false;
210   formNavigation_.nextState = false;
211
212   // allow this object and its children to get a focus
213   elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
214   is_initialized_ = true;
215 }
216
217 EWebView::~EWebView() {
218   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
219       hit_test_callback_iterator;
220   for (hit_test_callback_iterator = hit_test_callback_.begin();
221        hit_test_callback_iterator != hit_test_callback_.end();
222        hit_test_callback_iterator++)
223     delete hit_test_callback_iterator->second;
224   hit_test_callback_.clear();
225
226   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
227        ++iter)
228     delete *iter;
229
230   delayed_messages_.clear();
231
232   if (!is_initialized_) {
233     return;
234   }
235
236   context_menu_.reset();
237   mhtml_callback_map_.Clear();
238
239   ReleasePopupMenuList();
240
241   if (popupPicker_)
242     popup_picker_del(popupPicker_);
243
244   formNavigation_.count = 1;
245   formNavigation_.position = 0;
246   formNavigation_.prevState = false;
247   formNavigation_.nextState = false;
248
249   //  evas_object_del(evas_object());
250
251   // Release manually those scoped pointers to
252   // make sure they are released in correct order
253   web_contents_.reset();
254   web_contents_delegate_.reset();
255
256   // This code must be executed after WebContents deletion
257   // because WebContents depends on BrowserContext which
258   // is deleted along with EwkContext.
259   CHECK(!web_contents_);
260   if (old_context_.get()) {
261     Ewk_Context::Delete(context_.get());
262     context_ = old_context_;
263     old_context_ = NULL;
264   }
265
266   GetPermissionPopupManager()->DeleteAllPermissionRequest();
267   permission_popup_manager_.reset();
268
269   if (context_->GetImpl()->browser_context()->IsOffTheRecord())
270     Ewk_Context::Delete(context_.get());
271 }
272
273 void EWebView::ReleasePopupMenuList() {
274   if (!popupMenuItems_)
275     return;
276
277   void* dummyItem;
278   EINA_LIST_FREE(popupMenuItems_, dummyItem) {
279     delete static_cast<Popup_Menu_Item*>(dummyItem);
280   }
281
282   popupMenuItems_ = 0;
283 }
284
285 void EWebView::ResetContextMenuController() {
286   return context_menu_.reset();
287 }
288
289 void EWebView::SetFocus(Eina_Bool focus) {
290   if (HasFocus() != focus)
291     elm_object_focus_set(native_view_, focus);
292 }
293
294 void EWebView::CreateNewWindow(
295     content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
296   create_new_window_web_contents_cb_ = cb;
297   Evas_Object* new_object = NULL;
298   SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
299   create_new_window_web_contents_cb_ = base::Bind(&NullCreateWebContents);
300   DCHECK(new_object);
301 }
302
303 // static
304 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
305   EWebView* thiz = WebViewFromWebContents(wc);
306   DCHECK(thiz->evas_object_);
307   Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
308   if (!parent) {
309     LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
310     return thiz->evas_object_;
311   }
312
313   if (elm_object_widget_check(parent)) {
314     Evas_Object* elm_parent = elm_object_top_widget_get(parent);
315     if (elm_parent)
316       return elm_parent;
317     return parent;
318   }
319
320   LOG(WARNING) << "Could not find elementary parent for WebView object!";
321   return thiz->evas_object_;
322 }
323
324 void EWebView::SetURL(const GURL& url) {
325   NavigationController::LoadURLParams params(url);
326   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
327   web_contents_->GetController().LoadURLWithParams(params);
328 }
329
330 const GURL& EWebView::GetURL() const {
331   return web_contents_->GetVisibleURL();
332 }
333
334 void EWebView::Reload() {
335   web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
336 }
337
338 void EWebView::ReloadBypassingCache() {
339   web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
340                                         true);
341 }
342
343 Eina_Bool EWebView::CanGoBack() {
344   return web_contents_->GetController().CanGoBack();
345 }
346
347 Eina_Bool EWebView::CanGoForward() {
348   return web_contents_->GetController().CanGoForward();
349 }
350
351 Eina_Bool EWebView::HasFocus() const {
352   return elm_object_focus_get(native_view_);
353 }
354
355 Eina_Bool EWebView::GoBack() {
356   if (!web_contents_->GetController().CanGoBack())
357     return EINA_FALSE;
358
359   web_contents_->GetController().GoBack();
360   return EINA_TRUE;
361 }
362
363 Eina_Bool EWebView::GoForward() {
364   if (!web_contents_->GetController().CanGoForward())
365     return EINA_FALSE;
366
367   web_contents_->GetController().GoForward();
368   return EINA_TRUE;
369 }
370
371 void EWebView::Stop() {
372   if (web_contents_->IsLoading())
373     web_contents_->Stop();
374 }
375
376 void EWebView::Suspend() {
377   CHECK(web_contents_);
378   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
379   RenderFrameHost* rfh = web_contents_->GetMainFrame();
380   CHECK(rvh);
381   CHECK(rfh);
382
383   rfh->BlockRequestsForFrame();
384 #if 0
385   content::BrowserThread::PostTask(
386       content::BrowserThread::IO, FROM_HERE,
387       base::Bind(&content::ResourceDispatcherHost::BlockRequestsForFrameFromUI,
388                  rfh));
389
390   if (rvh)
391     rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
392 #endif
393 }
394
395 void EWebView::Resume() {
396   CHECK(web_contents_);
397   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
398   RenderFrameHost* rfh = web_contents_->GetMainFrame();
399   CHECK(rvh);
400   CHECK(rfh);
401
402   rfh->ResumeBlockedRequestsForFrame();
403 #if 0
404   content::BrowserThread::PostTask(
405       content::BrowserThread::IO, FROM_HERE,
406       base::Bind(
407           &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
408           rfh));
409
410   if (rvh)
411     rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
412 #endif
413 }
414
415 double EWebView::GetTextZoomFactor() const {
416   if (text_zoom_factor_ < 0.0)
417     return -1.0;
418
419   return text_zoom_factor_;
420 }
421
422 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
423   if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
424     return;
425
426   text_zoom_factor_ = text_zoom_factor;
427   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
428   if (!render_view_host)
429     return;
430
431   render_view_host->Send(new ViewMsg_SetTextZoomFactor(
432       render_view_host->GetRoutingID(), text_zoom_factor));
433 }
434
435 double EWebView::GetPageZoomFactor() const {
436   return content::ZoomLevelToZoomFactor(
437       content::HostZoomMap::GetZoomLevel(web_contents_.get()));
438 }
439
440 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
441   content::HostZoomMap::SetZoomLevel(
442       web_contents_.get(), content::ZoomFactorToZoomLevel(page_zoom_factor));
443 }
444
445 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
446   EINA_SAFETY_ON_NULL_RETURN(command);
447
448   value = (value == NULL) ? "" : value;
449
450   RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
451       web_contents_->GetRenderViewHost()->GetWidget());
452
453 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
454   // This is moved to mojo in upstream. Change it.
455   // https://chromium-review.googlesource.com/c/chromium/src/+/541036
456   rwhi->ExecuteEditCommand(command, value);
457 #endif
458
459   // This is workaround for rich text toolbar buttons in email application
460   if (!strcmp(command, "InsertOrderedList") ||
461       !strcmp(command, "InsertUnorderedList") ||
462       !strcmp(command, "AlignCenter") || !strcmp(command, "AlignJustified") ||
463       !strcmp(command, "AlignLeft") || !strcmp(command, "AlignRight")) {
464     QuerySelectionStyle();
465   }
466 }
467
468 void EWebView::SetOrientation(int orientation) {
469   // For backward compatibility, a value in range of [0, 360] is used
470   // instead of [-90, 180] because the class gfx::Display, containing
471   // orientaion value, supports the former range.
472   if (orientation == -90)
473     orientation = 270;
474   screen_orientation_ = orientation;
475
476   if (screen_orientation_ == 0 || screen_orientation_ == 90 ||
477       screen_orientation_ == 180 || screen_orientation_ == 270) {
478     GetWebContentsViewEfl()->SetOrientation(screen_orientation_);
479
480     // workaround for platform issue not resizing popup after rotation
481     // this should be removed when when proper fix will be applied for platorm.
482
483     int width = 0;
484     int height = 0;
485     const Ecore_Evas* ee =
486         ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
487     ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
488     if (orientation == 90 || orientation == 270)
489       std::swap(width, height);
490
491     if (context_menu_)
492       context_menu_->SetPopupSize(width, height);
493     if (inputPicker_)
494       inputPicker_->SetPopupSize(width, height);
495     if (popup_controller_)
496       popup_controller_->SetPopupSize(width, height);
497     if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
498       dialogMG->SetPopupSize(width, height);
499     if (popupPicker_)
500       popup_picker_resize(popupPicker_, width, height);
501   }
502 }
503
504 int EWebView::GetOrientation() {
505   return screen_orientation_;
506 }
507
508 void EWebView::Show() {
509   evas_object_show(native_view_);
510   web_contents_->WasShown();
511 }
512
513 void EWebView::Hide() {
514   evas_object_hide(native_view_);
515   web_contents_->WasHidden();
516 }
517
518 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
519                                   const GURL& url,
520                                   const std::string& realm) {
521   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
522
523   auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
524   SmartCallback<EWebViewCallbacks::AuthChallenge>().call(auth_challenge_.get());
525
526   if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
527     auth_challenge_->is_decided = true;
528     auth_challenge_->login_delegate->Cancel();
529   }
530 }
531
532 void EWebView::InvokePolicyResponseCallback(
533     _Ewk_Policy_Decision* policy_decision) {
534   SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
535       policy_decision);
536
537   if (policy_decision->isSuspended())
538     return;
539
540   if (!policy_decision->isDecided())
541     policy_decision->Use();
542
543   delete policy_decision;
544 }
545
546 void EWebView::InvokePolicyNavigationCallback(
547     RenderViewHost* rvh,
548     const NavigationPolicyParams params,
549     bool* handled) {
550   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
551
552   SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
553
554   std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
555       new _Ewk_Policy_Decision(params, rvh));
556
557   SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
558       policy_decision.get());
559
560   CHECK(!policy_decision->isSuspended());
561
562   // TODO: Navigation can't be suspended
563   // this aproach is synchronous and requires immediate response
564   // Maybe there is different approach (like resource throttle response
565   // mechanism) that allows us to
566   // suspend navigation
567   if (!policy_decision->isDecided())
568     policy_decision->Use();
569
570   *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
571              NavigationPolicyHandlerEfl::Handled;
572 }
573
574 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
575                                  const Eina_List* points,
576                                  const Evas_Modifier* modifiers) {
577   const Eina_List* l;
578   void* data;
579   EINA_LIST_FOREACH(points, l, data) {
580     const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
581     if (point->state == EVAS_TOUCH_POINT_STILL) {
582       // Chromium doesn't expect (and doesn't like) these events.
583       continue;
584     }
585     if (rwhv()) {
586       Evas_Coord_Point pt;
587       pt.x = point->x;
588       pt.y = point->y;
589       ui::TouchEvent touch_event =
590           MakeTouchEvent(pt, point->state, point->id, evas_object());
591       rwhv()->HandleTouchEvent(&touch_event);
592     }
593   }
594 }
595
596 content::WebContentsViewEfl* EWebView::GetWebContentsViewEfl() const {
597   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
598   return static_cast<WebContentsViewEfl*>(wc->GetView());
599 }
600
601 bool EWebView::TouchEventsEnabled() const {
602   return touch_events_enabled_;
603 }
604
605 // TODO: Touch events use the same mouse events in EFL API.
606 // Figure out how to distinguish touch and mouse events on touch&mice devices.
607 // Currently mouse and touch support is mutually exclusive.
608 void EWebView::SetTouchEventsEnabled(bool enabled) {
609   if (touch_events_enabled_ == enabled)
610     return;
611
612   touch_events_enabled_ = enabled;
613   GetWebContentsViewEfl()->SetTouchEventsEnabled(enabled);
614
615 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
616   // there is no flag touch_enabled in web preferences
617   GetSettings()->getPreferences().touch_enabled = enabled;
618   GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
619 #endif
620   GetSettings()->getPreferences().editing_behavior =
621       enabled ? content::EDITING_BEHAVIOR_ANDROID
622               : content::EDITING_BEHAVIOR_UNIX;
623   UpdateWebKitPreferences();
624 }
625
626 bool EWebView::MouseEventsEnabled() const {
627   return mouse_events_enabled_;
628 }
629
630 void EWebView::SetMouseEventsEnabled(bool enabled) {
631   if (mouse_events_enabled_ == enabled)
632     return;
633
634   mouse_events_enabled_ = enabled;
635   GetWebContentsViewEfl()->SetTouchEventsEnabled(!enabled);
636 }
637
638 namespace {
639
640 class JavaScriptCallbackDetails {
641  public:
642   JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
643                             void* user_data,
644                             Evas_Object* view)
645       : callback_func_(callback_func), user_data_(user_data), view_(view) {}
646
647   Ewk_View_Script_Execute_Callback callback_func_;
648   void* user_data_;
649   Evas_Object* view_;
650 };
651
652 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
653                         const base::Value* result) {
654   if (!script_callback_data->callback_func_)
655     return;
656
657   std::string return_string;
658   result->GetAsString(&return_string);
659   script_callback_data->callback_func_(script_callback_data->view_,
660                                        return_string.c_str(),
661                                        script_callback_data->user_data_);
662 }
663
664 }  // namespace
665
666 bool EWebView::ExecuteJavaScript(const char* script,
667                                  Ewk_View_Script_Execute_Callback callback,
668                                  void* userdata) {
669   if (!script)
670     return false;
671
672   if (!web_contents_delegate_)  // question, can I remove this check?
673     return false;
674
675   if (!web_contents_)
676     return false;
677
678   RenderFrameHost* render_frame_host = web_contents_->GetMainFrame();
679   if (!render_frame_host)
680     return false;
681
682   // Note: M37. Execute JavaScript, |script| with
683   // |RenderFrameHost::ExecuteJavaScript|.
684   // @see also https://codereview.chromium.org/188893005 for more details.
685   base::string16 js_script;
686   base::UTF8ToUTF16(script, strlen(script), &js_script);
687   if (callback) {
688 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
689     JavaScriptCallbackDetails* script_callback_data =
690         new JavaScriptCallbackDetails(callback, userdata, evas_object_);
691     // In M47, it isn't possible anymore to execute javascript in the generic
692     // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
693     // unchanged @see https://codereview.chromium.org/1123783002
694     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
695         js_script,
696         base::Bind(&JavaScriptComplete, base::Owned(script_callback_data)));
697 #endif
698   } else {
699     // We use ExecuteJavaScriptWithUserGestureForTests instead of
700     // ExecuteJavaScript because
701     // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
702     // was the
703     // behaviour is m34, and we want to keep it that way.
704     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(js_script);
705   }
706
707   return true;
708 }
709
710 bool EWebView::SetUserAgent(const char* userAgent) {
711   const content::NavigationController& controller =
712       web_contents_->GetController();
713   bool override = userAgent && strlen(userAgent);
714   for (int i = 0; i < controller.GetEntryCount(); ++i)
715     controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
716   // TODO: Check if override_in_new_tabs has to be true.
717   web_contents_->SetUserAgentOverride(override ? userAgent : std::string(),
718                                       false /* override_in_new_tabs */);
719   return true;
720 }
721
722 bool EWebView::SetUserAgentAppName(const char* application_name) {
723   EflWebView::VersionInfo::GetInstance()->SetProductName(
724       application_name ? application_name : "");
725
726   return true;
727 }
728
729 bool EWebView::SetPrivateBrowsing(bool incognito) {
730   if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
731     return false;
732
733   GURL url = web_contents_->GetVisibleURL();
734   if (old_context_.get()) {
735     DCHECK(!incognito);
736     web_contents_.reset();
737     web_contents_delegate_.reset();
738     Ewk_Context::Delete(context_.get());
739     context_ = old_context_;
740     old_context_ = NULL;
741   } else {
742     if (incognito) {
743       old_context_ = context_;
744     }
745     context_ = Ewk_Context::Create(incognito);
746   }
747
748   InitializeContent();
749   SetURL(url);
750   return true;
751 }
752
753 bool EWebView::GetPrivateBrowsing() const {
754   return context_->GetImpl()->browser_context()->IsOffTheRecord();
755 }
756
757 void EWebView::set_magnifier(bool status) {
758   rwhv()->set_magnifier(status);
759 }
760
761 const char* EWebView::GetUserAgent() const {
762   if (!web_contents_->GetUserAgentOverride().empty())
763     user_agent_ = web_contents_->GetUserAgentOverride();
764   else
765     user_agent_ = content::GetContentClientExport()->GetUserAgent();
766   return user_agent_.c_str();
767 }
768
769 const char* EWebView::GetUserAgentAppName() const {
770   user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->Name();
771   return user_agent_app_name_.c_str();
772 }
773
774 const char* EWebView::GetSelectedText() const {
775   if (!rwhv())
776     return "";
777
778   return base::UTF16ToUTF8(rwhv()->GetSelectedText()).c_str();
779 }
780
781 _Ewk_Frame* EWebView::GetMainFrame() {
782   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
783
784   if (!frame_.get()) {
785     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
786
787     if (render_view_host)
788       frame_.reset(new _Ewk_Frame(render_view_host->GetMainFrame()));
789   }
790
791   return frame_.get();
792 }
793
794 void EWebView::UpdateWebKitPreferences() {
795   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
796
797   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
798   if (!render_view_host)
799     return;
800
801   web_contents_delegate_->OnUpdateSettings(settings_.get());
802   render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
803
804   UpdateWebkitPreferencesEfl(render_view_host);
805 }
806
807 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
808   DCHECK(render_view_host);
809
810   IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
811       render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
812
813   if (render_view_host->IsRenderViewLive()) {
814     render_view_host->Send(message);
815   } else {
816     delayed_messages_.push_back(message);
817   }
818 }
819
820 void EWebView::SetContentSecurityPolicy(const char* policy,
821                                         Ewk_CSP_Header_Type type) {
822   web_contents_delegate_->SetContentSecurityPolicy(
823       (policy ? policy : std::string()), type);
824 }
825
826 void EWebView::LoadHTMLString(const char* html,
827                               const char* base_uri,
828                               const char* unreachable_uri) {
829   LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
830 }
831
832 void EWebView::LoadPlainTextString(const char* plain_text) {
833   LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
834 }
835
836 void EWebView::LoadData(const char* data,
837                         size_t size,
838                         const char* mime_type,
839                         const char* encoding,
840                         const char* base_uri,
841                         const char* unreachable_uri) {
842   SetDefaultStringIfNull(mime_type, "text/html");
843   SetDefaultStringIfNull(encoding, "utf-8");
844   SetDefaultStringIfNull(base_uri, "about:blank");  // Webkit2 compatible
845   SetDefaultStringIfNull(unreachable_uri, "");
846
847   std::string str_data = data;
848
849   if (size < str_data.length())
850     str_data = str_data.substr(0, size);
851
852   std::string url_str("data:");
853   url_str.append(mime_type);
854   url_str.append(";charset=");
855   url_str.append(encoding);
856   url_str.append(",");
857   url_str.append(str_data);
858
859   NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
860
861   data_params.base_url_for_data_url = GURL(base_uri);
862   data_params.virtual_url_for_data_url = GURL(unreachable_uri);
863
864   data_params.load_type = NavigationController::LOAD_TYPE_DATA;
865   data_params.should_replace_current_entry = false;
866   data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
867   web_contents_->GetController().LoadURLWithParams(data_params);
868 }
869
870 void EWebView::InvokeLoadError(const GURL& url,
871                                int error_code,
872                                const std::string& error_description,
873                                bool is_main_frame) {
874   if (!is_main_frame)
875     return;
876
877   std::unique_ptr<_Ewk_Error> err(
878       new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
879                      error_description.c_str()));
880
881   SmartCallback<EWebViewCallbacks::LoadError>().call(err.get());
882 }
883
884 void EWebView::ShowPopupMenu(const std::vector<content::MenuItem>& items,
885                              int selectedIndex,
886                              bool multiple) {
887   // Request form navigation information as early as possible,
888   // given that is renderer will ping-back with actual requested data.
889   RenderFrameHostImpl* render_frame_host =
890       static_cast<RenderFrameHostImpl*>(web_contents_->GetMainFrame());
891   if (render_frame_host)
892     render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
893         render_frame_host->GetRoutingID()));
894
895   Eina_List* popupItems = 0;
896   const size_t size = items.size();
897   for (size_t i = 0; i < size; ++i) {
898     popupItems = eina_list_append(popupItems, new Popup_Menu_Item(items[i]));
899   }
900
901   ReleasePopupMenuList();
902   popupMenuItems_ = popupItems;
903
904   if (popupPicker_ && FormIsNavigating()) {
905     popupPicker_->multiSelect = multiple;
906     PopupMenuUpdate(popupMenuItems_, selectedIndex);
907     SetFormIsNavigating(false);
908     return;
909   }
910
911   if (popupPicker_)
912     popup_picker_del(popupPicker_);
913   popupPicker_ = 0;
914
915   if (multiple)
916     popupPicker_ =
917         popup_picker_new(this, evas_object(), popupMenuItems_, 0, multiple);
918   else
919     popupPicker_ = popup_picker_new(this, evas_object(), popupMenuItems_,
920                                     selectedIndex, multiple);
921
922   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
923                               formNavigation_.count, false);
924 }
925
926 Eina_Bool EWebView::HidePopupMenu() {
927   if (!popupPicker_)
928     return false;
929
930   if (FormIsNavigating())
931     return true;
932
933   popup_picker_del(popupPicker_);
934   popupPicker_ = 0;
935   return true;
936 }
937
938 void EWebView::UpdateFormNavigation(int formElementCount,
939                                     int currentNodeIndex,
940                                     bool prevState,
941                                     bool nextState) {
942   formNavigation_.count = formElementCount;
943   formNavigation_.position = currentNodeIndex;
944   formNavigation_.prevState = prevState;
945   formNavigation_.nextState = nextState;
946 }
947
948 bool EWebView::IsSelectPickerShown() const {
949   return (popupPicker_ != NULL);
950 }
951
952 void EWebView::CloseSelectPicker() {
953   listClosed(popupPicker_, 0, 0, 0);
954 }
955
956 void EWebView::SetFormIsNavigating(bool formIsNavigating) {
957   formIsNavigating_ = formIsNavigating;
958 }
959
960 Eina_Bool EWebView::PopupMenuUpdate(Eina_List* items, int selectedIndex) {
961   if (!popupPicker_)
962     return false;
963
964   popup_picker_update(evas_object(), popupPicker_, items, selectedIndex);
965   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
966                               formNavigation_.count, false);
967   return true;
968 }
969
970 void EWebView::FormNavigate(bool direction) {
971   RenderFrameHostImpl* render_frame_host =
972       static_cast<RenderFrameHostImpl*>(web_contents_->GetMainFrame());
973   if (!render_frame_host)
974     return;
975
976   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
977                               formNavigation_.count, true);
978
979   if ((direction && formNavigation_.nextState) ||
980       (!direction && formNavigation_.prevState))
981     SetFormIsNavigating(true);
982
983   listClosed(popupPicker_, 0, 0, 0);
984   render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
985       render_frame_host->GetRoutingID(), direction));
986 }
987
988 Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
989   RenderFrameHostImpl* render_frame_host =
990       static_cast<RenderFrameHostImpl*>(web_contents_->GetMainFrame());
991   if (!render_frame_host)
992     return false;
993
994   if (!popupMenuItems_)
995     return false;
996
997   // When user select empty space then no index is selected, so selectedIndex
998   // value is -1
999   // In that case we should call valueChanged() with -1 index.That in turn call
1000   // popupDidHide()
1001   // in didChangeSelectedIndex() for reseting the value of m_popupIsVisible in
1002   // RenderMenuList.
1003   if (selectedIndex != -1 &&
1004       selectedIndex >= (int)eina_list_count(popupMenuItems_))
1005     return false;
1006
1007   // In order to reuse RenderFrameHostImpl::DidSelectPopupMenuItems() method in
1008   // Android,
1009   // put selectedIndex into std::vector<int>.
1010   std::vector<int> selectedIndices;
1011   selectedIndices.push_back(selectedIndex);
1012 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1013   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1014 #endif
1015   return true;
1016 }
1017
1018 Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
1019     std::vector<int>& selectedIndices) {
1020   RenderFrameHostImpl* render_frame_host =
1021       static_cast<RenderFrameHostImpl*>(web_contents_->GetMainFrame());
1022   if (!render_frame_host)
1023     return false;
1024
1025   if (!popupMenuItems_)
1026     return false;
1027 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1028   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1029 #endif
1030   return true;
1031 }
1032
1033 Eina_Bool EWebView::PopupMenuClose() {
1034 // DJKim : FIXME
1035 #if 0
1036   if (!impl->popupMenuProxy)
1037     return false;
1038
1039   impl->popupMenuProxy = 0;
1040 #endif
1041   HidePopupMenu();
1042
1043   if (!popupMenuItems_)
1044     return false;
1045
1046   void* item;
1047   EINA_LIST_FREE(popupMenuItems_, item)
1048   delete static_cast<Popup_Menu_Item*>(item);
1049   popupMenuItems_ = 0;
1050
1051   RenderFrameHostImpl* render_frame_host =
1052       static_cast<RenderFrameHostImpl*>(web_contents_->GetMainFrame());
1053   if (!render_frame_host)
1054     return false;
1055 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1056   render_frame_host->DidCancelPopupMenu();
1057 #endif
1058   return true;
1059 }
1060
1061 void EWebView::HandleLongPressGesture(
1062     const content::ContextMenuParams& params) {
1063   // This menu is created in renderer process and it does not now anything about
1064   // view scaling factor and it has another calling sequence, so coordinates is
1065   // not updated.
1066   content::ContextMenuParams convertedParams = params;
1067   gfx::Point convertedPoint =
1068       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1069   convertedParams.x = convertedPoint.x();
1070   convertedParams.y = convertedPoint.y();
1071
1072   Evas_Coord x, y;
1073   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1074   convertedParams.x += x;
1075   convertedParams.y += y;
1076
1077   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1078     bool show_context_menu_now =
1079         !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1080                                                         convertedParams);
1081     if (show_context_menu_now)
1082       ShowContextMenuInternal(convertedParams);
1083   }
1084 }
1085
1086 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1087   // This menu is created in renderer process and it does not now anything about
1088   // view scaling factor and it has another calling sequence, so coordinates is
1089   // not updated.
1090   content::ContextMenuParams convertedParams = params;
1091   gfx::Point convertedPoint =
1092       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1093   convertedParams.x = convertedPoint.x();
1094   convertedParams.y = convertedPoint.y();
1095
1096   Evas_Coord x, y;
1097   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1098   convertedParams.x += x;
1099   convertedParams.y += y;
1100
1101   context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1102
1103   ShowContextMenuInternal(convertedParams);
1104 }
1105
1106 void EWebView::ShowContextMenuInternal(
1107     const content::ContextMenuParams& params) {
1108   context_menu_.reset(
1109       new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1110   if (!context_menu_->PopulateAndShowContextMenu(params)) {
1111     context_menu_.reset();
1112     if (GetSelectionController())
1113       GetSelectionController()->HideHandles();
1114   }
1115 }
1116
1117 void EWebView::CancelContextMenu(int request_id) {
1118   if (context_menu_)
1119     context_menu_->HideContextMenu();
1120 }
1121
1122 void EWebView::Find(const char* text, Ewk_Find_Options find_options) {
1123   base::string16 find_text = base::UTF8ToUTF16(text);
1124   bool find_next = (previous_text_ == find_text);
1125
1126   if (!find_next) {
1127     current_find_request_id_ = find_request_id_counter_++;
1128     previous_text_ = find_text;
1129   }
1130
1131   blink::WebFindOptions web_find_options;
1132   web_find_options.forward = !(find_options & EWK_FIND_OPTIONS_BACKWARDS);
1133   web_find_options.match_case =
1134       !(find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1135   web_find_options.find_next = find_next;
1136
1137   web_contents_->Find(current_find_request_id_, find_text, web_find_options);
1138 }
1139
1140 void EWebView::SetScale(double scale_factor, int x, int y) {
1141   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1142   // Do not cache |scale_factor| here as it may be discarded by Blink's
1143   // minimumPageScaleFactor and maximumPageScaleFactor.
1144   // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1145   render_view_host->Send(new EwkViewMsg_Scale(render_view_host->GetRoutingID(),
1146                                               scale_factor, x, y));
1147 }
1148
1149 bool EWebView::GetScrollPosition(int* x, int* y) const {
1150   DCHECK(x);
1151   DCHECK(y);
1152
1153   if (scroll_detector_->IsScrollOffsetChanged()) {
1154     *x = previous_scroll_position_.x();
1155     *y = previous_scroll_position_.y();
1156   } else {
1157     const gfx::Vector2d scroll_position =
1158         scroll_detector_->GetLastScrollPosition();
1159     *x = scroll_position.x();
1160     *y = scroll_position.y();
1161   }
1162   return true;
1163 }
1164
1165 void EWebView::SetScroll(int x, int y) {
1166   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1167   if (!render_view_host)
1168     return;
1169
1170   int maxX, maxY;
1171   GetScrollSize(&maxX, &maxY);
1172   previous_scroll_position_.set_x(std::min(std::max(x, 0), maxX));
1173   previous_scroll_position_.set_y(std::min(std::max(y, 0), maxY));
1174
1175   scroll_detector_->SetScrollOffsetChanged();
1176
1177   render_view_host->Send(
1178       new EwkViewMsg_SetScroll(render_view_host->GetRoutingID(), x, y));
1179 }
1180
1181 void EWebView::UseSettingsFont() {
1182   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1183   if (render_view_host)
1184     render_view_host->Send(
1185         new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1186 }
1187
1188 void EWebView::DidChangeContentsSize(int width, int height) {
1189   contents_size_ = gfx::Size(width, height);
1190   SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1191 }
1192
1193 const Eina_Rectangle EWebView::GetContentsSize() const {
1194   Eina_Rectangle rect;
1195   EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1196                      contents_size_.height());
1197   return rect;
1198 }
1199
1200 void EWebView::GetScrollSize(int* width, int* height) {
1201   if (width)
1202     *width = 0;
1203   if (height)
1204     *height = 0;
1205
1206   Eina_Rectangle last_view_port =
1207       WebViewDelegateEwk::GetInstance().GetLastUsedViewPortArea(evas_object());
1208   int scaled_content_width =
1209       static_cast<int>(contents_size_.width() * page_scale_factor_);
1210   int scaled_content_height =
1211       static_cast<int>(contents_size_.height() * page_scale_factor_);
1212
1213   if (width && scaled_content_width > last_view_port.w)
1214     *width = scaled_content_width - last_view_port.w;
1215   if (height && scaled_content_height > last_view_port.h)
1216     *height = scaled_content_height - last_view_port.h;
1217 }
1218
1219 void EWebView::MoveCaret(const gfx::Point& point) {
1220   if (rwhv())
1221     rwhv()->MoveCaret(point);
1222 }
1223
1224 void EWebView::QuerySelectionStyle() {
1225   if (GetSettings()->textStyleStateState()) {
1226     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1227     render_view_host->Send(
1228         new EwkViewMsg_GetSelectionStyle(render_view_host->GetRoutingID()));
1229   }
1230 }
1231
1232 void EWebView::OnQuerySelectionStyleReply(const SelectionStylePrams& params) {
1233   gfx::Rect left_rect, right_rect;
1234   if (GetSelectionController()) {
1235     GetSelectionController()->GetSelectionBounds(&left_rect, &right_rect);
1236     _Ewk_Text_Style style_data(params, left_rect.origin(),
1237                                right_rect.bottom_right());
1238     SmartCallback<EWebViewCallbacks::TextStyleState>().call(&style_data);
1239   }
1240 }
1241
1242 SelectionControllerEfl* EWebView::GetSelectionController() const {
1243   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1244   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1245       render_view_host->GetWidget()->GetView());
1246   return view ? view->GetSelectionController() : 0;
1247 }
1248
1249 void EWebView::SelectLinkText(const gfx::Point& touch_point) {
1250 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1251   float device_scale_factor =
1252       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1253   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1254   render_view_host->Send(new ViewMsg_SelectLinkText(
1255       render_view_host->GetRoutingID(),
1256       gfx::Point(touch_point.x() / device_scale_factor,
1257                  touch_point.y() / device_scale_factor)));
1258 #endif
1259 }
1260
1261 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1262                                  Eina_Rectangle* right_rect) {
1263   if (left_rect && right_rect) {
1264     gfx::Rect left, right;
1265     if (GetSelectionController()) {
1266       GetSelectionController()->GetSelectionBounds(&left, &right);
1267       GetEinaRectFromGfxRect(left, left_rect);
1268       GetEinaRectFromGfxRect(right, right_rect);
1269       return true;
1270     }
1271   }
1272   return false;
1273 }
1274
1275 Eina_Bool EWebView::ClearSelection() {
1276   if (!rwhv())
1277     return EINA_FALSE;
1278
1279   ResetContextMenuController();
1280   rwhv()->SelectionChanged(base::string16(), 0, gfx::Range());
1281
1282   if (GetSelectionController())
1283     return GetSelectionController()->ClearSelectionViaEWebView();
1284
1285   return EINA_FALSE;
1286 }
1287
1288 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1289                                               int y,
1290                                               Ewk_Hit_Test_Mode mode) {
1291   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1292
1293   int view_x, view_y;
1294   EvasToBlinkCords(x, y, &view_x, &view_y);
1295
1296   return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1297 }
1298
1299 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1300     int x,
1301     int y,
1302     Ewk_Hit_Test_Mode mode,
1303     Ewk_View_Hit_Test_Request_Callback callback,
1304     void* user_data) {
1305   int view_x, view_y;
1306   EvasToBlinkCords(x, y, &view_x, &view_y);
1307   return AsyncRequestHitTestDataAtBlinkCords(
1308       view_x, view_y, mode,
1309       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1310                                                      user_data));
1311 }
1312
1313 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1314     int x,
1315     int y,
1316     Ewk_Hit_Test_Mode mode,
1317     Ewk_View_Hit_Test_Request_Callback callback,
1318     void* user_data) {
1319   return AsyncRequestHitTestDataAtBlinkCords(
1320       x, y, mode,
1321       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1322                                                      user_data));
1323 }
1324
1325 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1326     int x,
1327     int y,
1328     Ewk_Hit_Test_Mode mode,
1329     WebViewAsyncRequestHitTestDataCallback* cb) {
1330   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1331   DCHECK(cb);
1332
1333   static int64_t request_id = 1;
1334
1335   if (cb) {
1336     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1337     DCHECK(render_view_host);
1338
1339     if (render_view_host) {
1340       render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1341           render_view_host->GetRoutingID(), x, y, mode, request_id));
1342       hit_test_callback_[request_id] = cb;
1343       ++request_id;
1344       return EINA_TRUE;
1345     }
1346   }
1347
1348   // if failed we delete callback as it is not needed anymore
1349   delete cb;
1350   return EINA_FALSE;
1351 }
1352
1353 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1354                                         int64_t request_id) {
1355   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1356
1357   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1358       hit_test_callback_.find(request_id);
1359
1360   if (it == hit_test_callback_.end())
1361     return;
1362   std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1363
1364   it->second->Run(hit_test.get(), this);
1365   delete it->second;
1366   hit_test_callback_.erase(it);
1367 }
1368
1369 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1370     int x,
1371     int y,
1372     Ewk_Hit_Test_Mode mode) {
1373   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1374
1375   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1376   DCHECK(render_view_host);
1377
1378   if (render_view_host) {
1379     // We wait on UI thread till hit test data is updated.
1380     render_view_host->Send(
1381         new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1382     hit_test_completion_.Wait();
1383     return new _Ewk_Hit_Test(hit_test_params_);
1384   }
1385
1386   return NULL;
1387 }
1388
1389 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1390   DCHECK(display::Screen::GetScreen());
1391   Evas_Coord tmpX, tmpY;
1392   evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
1393
1394   if (view_x) {
1395     *view_x = x - tmpX;
1396     *view_x /=
1397         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1398   }
1399
1400   if (view_y) {
1401     *view_y = y - tmpY;
1402     *view_y /=
1403         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1404   }
1405 }
1406
1407 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1408   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1409   hit_test_params_ = params;
1410   hit_test_completion_.Signal();
1411 }
1412
1413 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1414
1415 void EWebView::RenderViewCreated(RenderViewHost* render_view_host) {
1416   SendDelayedMessages(render_view_host);
1417   UpdateWebkitPreferencesEfl(render_view_host);
1418   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1419       render_view_host->GetWidget()->GetView());
1420   if (view)
1421     view->SetEvasHandler(evas_event_handler_);
1422
1423   if (render_view_host) {
1424     WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1425     if (content) {
1426       RenderProcessHost* host = render_view_host->GetProcess();
1427       if (host)
1428         host->AddFilter(new WebViewBrowserMessageFilter(content));
1429     }
1430   }
1431 }
1432
1433 void EWebView::SetOverrideEncoding(const std::string& encoding) {
1434 // EWK_BRINGUP definition should be removed.
1435 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1436   web_contents_->SetOverrideEncoding(encoding);
1437 #endif  // !defined(EWK_BRINGUP)
1438 }
1439
1440 void EWebView::SetQuotaPermissionRequestCallback(
1441     Ewk_Quota_Permission_Request_Callback callback,
1442     void* user_data) {
1443   quota_request_callback_.Set(callback, user_data);
1444 }
1445
1446 void EWebView::InvokeQuotaPermissionRequest(
1447     _Ewk_Quota_Permission_Request* request,
1448     const content::QuotaPermissionContext::PermissionCallback& cb) {
1449   quota_permission_request_map_[request] = cb;
1450   request->setView(evas_object());
1451   if (quota_request_callback_.IsCallbackSet())
1452     quota_request_callback_.Run(evas_object(), request);
1453   else
1454     QuotaRequestCancel(request);
1455 }
1456
1457 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1458                                  bool allow) {
1459   DCHECK(quota_permission_request_map_.find(request) !=
1460          quota_permission_request_map_.end());
1461
1462   QuotaPermissionContext::PermissionCallback cb =
1463       quota_permission_request_map_[request];
1464
1465   if (allow)
1466     QuotaPermissionContextEfl::DispatchCallback(
1467         cb, QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
1468   else
1469     QuotaPermissionContextEfl::DispatchCallback(
1470         cb, QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
1471
1472   quota_permission_request_map_.erase(request);
1473   delete request;
1474 }
1475
1476 void EWebView::QuotaRequestCancel(
1477     const _Ewk_Quota_Permission_Request* request) {
1478   DCHECK(quota_permission_request_map_.find(request) !=
1479          quota_permission_request_map_.end());
1480
1481   QuotaPermissionContext::PermissionCallback cb =
1482       quota_permission_request_map_[request];
1483   QuotaPermissionContextEfl::DispatchCallback(
1484       cb, QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1485   quota_permission_request_map_.erase(request);
1486   delete request;
1487 }
1488
1489 bool EWebView::GetLinkMagnifierEnabled() const {
1490   return web_contents_->GetMutableRendererPrefs()
1491              ->tap_multiple_targets_strategy ==
1492          TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1493 }
1494
1495 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1496   web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1497       enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1498               : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1499   web_contents_->GetRenderViewHost()->SyncRendererPrefs();
1500 }
1501
1502 bool EWebView::GetSnapshotAsync(
1503     Eina_Rectangle rect,
1504     Ewk_Web_App_Screenshot_Captured_Callback callback,
1505     void* user_data) {
1506   if (!rwhv())
1507     return false;
1508
1509   return rwhv()->RequestSnapshotAsync(rect, callback, user_data);
1510 }
1511
1512 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect) {
1513   Evas_Object* image = NULL;
1514 #ifdef OS_TIZEN
1515   if (!rwhv() || !rwhv()->MakeCurrent())
1516     return NULL;
1517
1518   int width = rect.w;
1519   int height = rect.h;
1520
1521   if (width > rwhv()->GetViewBoundsInPix().width() - rect.x)
1522     width = rwhv()->GetViewBoundsInPix().width() - rect.x;
1523   if (height > rwhv()->GetViewBoundsInPix().height() - rect.y)
1524     height = rwhv()->GetViewBoundsInPix().height() - rect.y;
1525
1526   int x = rect.x;
1527   int y = rwhv()->GetViewBoundsInPix().height() - height + rect.y;
1528
1529   Evas_GL_API* gl_api = rwhv()->evasGlApi();
1530   DCHECK(gl_api);
1531   int size = width * height * sizeof(GLuint);
1532
1533   GLuint* tmp = (GLuint*)malloc(size);
1534   if (!tmp)
1535     return NULL;
1536
1537   GLuint* bits = (GLuint*)malloc(size);
1538   if (!bits) {
1539     free(tmp);
1540     return NULL;
1541   }
1542
1543   gl_api->glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1544                        (GLubyte*)bits);
1545
1546   // flip the Y axis and change color format from RGBA to BGRA
1547   int i, j, idx1, idx2;
1548   GLuint d;
1549   for (j = 0; j < height; j++) {
1550     for (i = 0; i < width; i++) {
1551       idx1 = (j * width) + i;
1552       idx2 = ((height - 1) - j) * width + i;
1553       d = bits[idx1];
1554       tmp[idx2] = ((d & 0x000000ff) << 16) + ((d & 0x00ff0000) >> 16) +
1555                   ((d & 0xff00ff00));
1556     }
1557   }
1558
1559   image = evas_object_image_filled_add(rwhv()->evas());
1560   if (image) {
1561     evas_object_image_size_set(image, width, height);
1562     evas_object_image_alpha_set(image, EINA_TRUE);
1563     evas_object_image_data_copy_set(image, tmp);
1564     evas_object_resize(image, width, height);
1565   }
1566 #endif
1567   return image;
1568 }
1569
1570 void EWebView::BackForwardListClear() {
1571   content::NavigationController& controller = web_contents_->GetController();
1572
1573   int entry_count = controller.GetEntryCount();
1574   bool entry_removed = false;
1575
1576   for (int i = 0; i < entry_count; i++) {
1577     if (controller.RemoveEntryAtIndex(i)) {
1578       entry_removed = true;
1579       entry_count = controller.GetEntryCount();
1580       i--;
1581     }
1582   }
1583
1584   if (entry_removed) {
1585     back_forward_list_->ClearCache();
1586     InvokeBackForwardListChangedCallback();
1587   }
1588 }
1589
1590 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1591   return back_forward_list_.get();
1592 }
1593
1594 void EWebView::InvokeBackForwardListChangedCallback() {
1595   SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1596 }
1597
1598 _Ewk_History* EWebView::GetBackForwardHistory() const {
1599   return new _Ewk_History(web_contents_->GetController());
1600 }
1601
1602 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1603                                 void* userData) {
1604   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1605   if (!renderViewHost) {
1606     return false;
1607   }
1608   WebApplicationCapableGetCallback* cb =
1609       new WebApplicationCapableGetCallback(callback, userData);
1610   int callbackId = web_app_capable_get_callback_map_.Add(cb);
1611   return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1612       renderViewHost->GetRoutingID(), callbackId));
1613 }
1614
1615 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1616                                 void* userData) {
1617   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1618   if (!renderViewHost) {
1619     return false;
1620   }
1621   WebApplicationIconUrlGetCallback* cb =
1622       new WebApplicationIconUrlGetCallback(callback, userData);
1623   int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1624   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1625       renderViewHost->GetRoutingID(), callbackId));
1626 }
1627
1628 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1629                                  void* userData) {
1630   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1631   if (!renderViewHost) {
1632     return false;
1633   }
1634   WebApplicationIconUrlsGetCallback* cb =
1635       new WebApplicationIconUrlsGetCallback(callback, userData);
1636   int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1637   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1638       renderViewHost->GetRoutingID(), callbackId));
1639 }
1640
1641 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1642   WebApplicationCapableGetCallback* callback =
1643       web_app_capable_get_callback_map_.Lookup(callbackId);
1644   if (!callback)
1645     return;
1646   callback->Run(capable);
1647 }
1648
1649 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1650                                               int callbackId) {
1651   WebApplicationIconUrlGetCallback* callback =
1652       web_app_icon_url_get_callback_map_.Lookup(callbackId);
1653   if (!callback)
1654     return;
1655   callback->Run(iconUrl);
1656 }
1657
1658 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1659                                                int callbackId) {
1660   WebApplicationIconUrlsGetCallback* callback =
1661       web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1662   if (!callback) {
1663     return;
1664   }
1665   callback->Run(iconUrls);
1666 }
1667
1668 void EWebView::SetNotificationPermissionCallback(
1669     Ewk_View_Notification_Permission_Callback callback,
1670     void* user_data) {
1671   notification_permission_callback_.Set(callback, user_data);
1672 }
1673
1674 bool EWebView::IsNotificationPermissionCallbackSet() const {
1675   return notification_permission_callback_.IsCallbackSet();
1676 }
1677
1678 bool EWebView::InvokeNotificationPermissionCallback(
1679     Ewk_Notification_Permission_Request* request) {
1680   Eina_Bool ret = EINA_FALSE;
1681   notification_permission_callback_.Run(evas_object_, request, &ret);
1682   return ret;
1683 }
1684
1685 int EWebView::SetEwkViewPlainTextGetCallback(
1686     Ewk_View_Plain_Text_Get_Callback callback,
1687     void* user_data) {
1688   EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
1689       new EwkViewPlainTextGetCallback;
1690   view_plain_text_callback_ptr->Set(callback, user_data);
1691   return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
1692 }
1693
1694 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
1695                             void* user_data) {
1696   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1697   if (!render_view_host)
1698     return false;
1699   int plain_text_get_callback_id =
1700       SetEwkViewPlainTextGetCallback(callback, user_data);
1701   return render_view_host->Send(new EwkViewMsg_PlainTextGet(
1702       render_view_host->GetRoutingID(), plain_text_get_callback_id));
1703 }
1704
1705 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
1706                                           int plain_text_get_callback_id) {
1707   EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
1708       plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
1709   view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
1710   plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
1711 }
1712
1713 void EWebView::SetViewGeolocationPermissionCallback(
1714     Ewk_View_Geolocation_Permission_Callback callback,
1715     void* user_data) {
1716   geolocation_permission_cb_.Set(callback, user_data);
1717 }
1718
1719 bool EWebView::InvokeViewGeolocationPermissionCallback(
1720     _Ewk_Geolocation_Permission_Request* permission_context,
1721     Eina_Bool* callback_result) {
1722   return geolocation_permission_cb_.Run(evas_object_, permission_context,
1723                                         callback_result);
1724 }
1725
1726 void EWebView::SetViewUserMediaPermissionCallback(
1727     Ewk_View_User_Media_Permission_Callback callback,
1728     void* user_data) {
1729   user_media_permission_cb_.Set(callback, user_data);
1730 }
1731
1732 bool EWebView::InvokeViewUserMediaPermissionCallback(
1733     _Ewk_User_Media_Permission_Request* permission_context,
1734     Eina_Bool* callback_result) {
1735   return user_media_permission_cb_.Run(evas_object_, permission_context,
1736                                        callback_result);
1737 }
1738
1739 void EWebView::SetViewUnfocusAllowCallback(
1740     Ewk_View_Unfocus_Allow_Callback callback,
1741     void* user_data) {
1742   unfocus_allow_cb_.Set(callback, user_data);
1743 }
1744
1745 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
1746                                               Eina_Bool* callback_result) {
1747   return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
1748 }
1749
1750 void EWebView::StopFinding() {
1751   web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
1752 }
1753
1754 void EWebView::SetProgressValue(double progress) {
1755   progress_ = progress;
1756 }
1757
1758 double EWebView::GetProgressValue() {
1759   return progress_;
1760 }
1761
1762 const char* EWebView::GetTitle() {
1763   title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
1764   return title_.c_str();
1765 }
1766
1767 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
1768   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1769   if (!render_view_host)
1770     return false;
1771
1772   return render_view_host->Send(
1773       new EwkViewMsg_PrintToPdf(render_view_host->GetRoutingID(), width, height,
1774                                 base::FilePath(filename)));
1775 }
1776
1777 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
1778                             void* user_data) {
1779   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1780   if (!render_view_host)
1781     return false;
1782
1783   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
1784   callback_details->Set(callback, user_data);
1785   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
1786   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
1787       render_view_host->GetRoutingID(), mhtml_callback_id));
1788 }
1789
1790 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
1791                                  int callback_id) {
1792   MHTMLCallbackDetails* callback_details =
1793       mhtml_callback_map_.Lookup(callback_id);
1794   callback_details->Run(evas_object(), mhtml_content.c_str());
1795   mhtml_callback_map_.Remove(callback_id);
1796 }
1797
1798 bool EWebView::IsFullscreen() {
1799   return web_contents_delegate_->IsFullscreenForTabOrPending(
1800       web_contents_.get());
1801 }
1802
1803 void EWebView::ExitFullscreen() {
1804   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1805   wci->ExitFullscreen(false);
1806 }
1807
1808 double EWebView::GetScale() {
1809   return page_scale_factor_;
1810 }
1811
1812 void EWebView::DidChangePageScaleFactor(double scale_factor) {
1813   page_scale_factor_ = scale_factor;
1814   GetWebContentsViewEfl()->SetPageScaleFactor(scale_factor);
1815 }
1816
1817 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
1818   return static_cast<JavaScriptDialogManagerEfl*>(
1819       web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
1820 }
1821
1822 void EWebView::SetJavaScriptAlertCallback(
1823     Ewk_View_JavaScript_Alert_Callback callback,
1824     void* user_data) {
1825   GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
1826 }
1827
1828 void EWebView::JavaScriptAlertReply() {
1829   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
1830                                                                std::string());
1831   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1832 }
1833
1834 void EWebView::SetJavaScriptConfirmCallback(
1835     Ewk_View_JavaScript_Confirm_Callback callback,
1836     void* user_data) {
1837   GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
1838 }
1839
1840 void EWebView::JavaScriptConfirmReply(bool result) {
1841   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
1842                                                                std::string());
1843   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1844 }
1845
1846 void EWebView::SetJavaScriptPromptCallback(
1847     Ewk_View_JavaScript_Prompt_Callback callback,
1848     void* user_data) {
1849   GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
1850 }
1851
1852 void EWebView::JavaScriptPromptReply(const char* result) {
1853   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
1854       true, (std::string(result)));
1855   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1856 }
1857
1858 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
1859   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1860   if (!render_view_host) {
1861     if (min_scale)
1862       *min_scale = -1.f;
1863     if (max_scale)
1864       *max_scale = -1.f;
1865     return;
1866   }
1867
1868   WebPreferences prefs = render_view_host->GetWebkitPreferences();
1869   if (min_scale)
1870     *min_scale = prefs.default_minimum_page_scale_factor;
1871   if (max_scale)
1872     *max_scale = prefs.default_maximum_page_scale_factor;
1873 }
1874
1875 void EWebView::SetDrawsTransparentBackground(bool enabled) {
1876   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1877   if (!render_view_host)
1878     return;
1879
1880   render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
1881       render_view_host->GetRoutingID(), enabled));
1882 }
1883
1884 void EWebView::GetSessionData(const char** data, unsigned* length) const {
1885   static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
1886
1887   NavigationController& navigationController = web_contents_->GetController();
1888   base::Pickle sessionPickle;
1889   const int itemCount = navigationController.GetEntryCount();
1890
1891   sessionPickle.WriteInt(itemCount);
1892   sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
1893
1894   for (int i = 0; i < itemCount; i++) {
1895     NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
1896     sessions::SerializedNavigationEntry serializedEntry =
1897         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
1898             i, *navigationEntry);
1899     serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
1900   }
1901
1902   *data = static_cast<char*>(malloc(sizeof(char) * sessionPickle.size()));
1903   memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
1904   *length = sessionPickle.size();
1905 }
1906
1907 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
1908   base::Pickle sessionPickle(data, length);
1909   base::PickleIterator pickleIterator(sessionPickle);
1910   int entryCount;
1911   int currentEntry;
1912
1913   if (!pickleIterator.ReadInt(&entryCount))
1914     return false;
1915   if (!pickleIterator.ReadInt(&currentEntry))
1916     return false;
1917
1918   std::vector<sessions::SerializedNavigationEntry> serializedEntries;
1919   serializedEntries.resize(entryCount);
1920   for (int i = 0; i < entryCount; ++i) {
1921     if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
1922       return false;
1923   }
1924
1925   if (!entryCount)
1926     return true;
1927
1928   std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
1929       sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
1930           serializedEntries, context()->browser_context());
1931
1932   NavigationController& navigationController = web_contents_->GetController();
1933
1934   if (currentEntry < 0)
1935     currentEntry = 0;
1936
1937   if (currentEntry >= static_cast<int>(scopedEntries.size()))
1938     currentEntry = scopedEntries.size() - 1;
1939
1940 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1941   // FIXME: EWK_BRINGUP definition should be removed.
1942   navigationController.Restore(
1943       currentEntry, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
1944       &scopedEntries);
1945 #endif  // !defined(EWK_BRINGUP)
1946   return true;
1947 }
1948
1949 void EWebView::SetBrowserFont() {
1950   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1951   if (render_view_host)
1952     render_view_host->Send(
1953         new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID()));
1954 }
1955
1956 void EWebView::SetCertificatePem(const std::string& certificate) {
1957   pem_certificate_ = certificate;
1958   SmartCallback<EWebViewCallbacks::SetCertificatePem>().call(
1959       pem_certificate_.c_str());
1960 }
1961
1962 bool EWebView::IsDragging() const {
1963   return GetWebContentsViewEfl()->IsDragging();
1964 }
1965
1966 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
1967                                const content::FileChooserParams& params) {
1968   if (!IsMobileProfile() && !IsWearableProfile())
1969     return;
1970
1971 #if !defined(EWK_BRINGUP)
1972   if (params.capture) {
1973     const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
1974     unsigned int capture_types_num =
1975         sizeof(capture_types) / sizeof(*capture_types);
1976     for (unsigned int i = 0; i < capture_types_num; ++i) {
1977       for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
1978         if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
1979           filechooser_mode_ = params.mode;
1980           LaunchCamera(params.accept_types[j]);
1981           return;
1982         }
1983       }
1984     }
1985   }
1986 #endif
1987   file_chooser_.reset(
1988       new content::FileChooserControllerEfl(render_frame_host, &params));
1989   file_chooser_->Open();
1990 }
1991
1992 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1993 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
1994   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1995   if (!render_view_host)
1996     return;
1997
1998   IPC::Message* message =
1999       new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2000   if (render_view_host->IsRenderViewLive()) {
2001     render_view_host->Send(message);
2002   } else {
2003     delayed_messages_.push_back(message);
2004   }
2005 }
2006 #endif
2007
2008 gfx::Point EWebView::GetContextMenuPosition() const {
2009   return context_menu_position_;
2010 }
2011
2012 void EWebView::ShowContentsDetectedPopup(const char* message) {
2013   popup_controller_.reset(new PopupControllerEfl(this));
2014   popup_controller_->openPopup(message);
2015 }
2016
2017 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2018   inputPicker_.reset(new InputPicker(*this));
2019   inputPicker_->ShowColorPicker(r, g, b, a);
2020 }
2021
2022 void EWebView::DismissColorPicker() {
2023   inputPicker_->HideColorPicker();
2024 }
2025
2026 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2027   web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2028   return true;
2029 }
2030
2031 void EWebView::InputPickerShow(ui::TextInputType input_type,
2032                                double input_value) {
2033   inputPicker_.reset(new InputPicker(*this));
2034   inputPicker_->showDatePicker(input_type, input_value);
2035 }
2036
2037 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2038   RenderFrameHost* render_frame_host = web_contents_->GetMainFrame();
2039   if (render_frame_host)
2040     render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2041         render_frame_host->GetRoutingID(), invalidUrl));
2042 }
2043
2044 std::string EWebView::GetPlatformLocale() {
2045   char* local_default = setlocale(LC_CTYPE, 0);
2046   if (!local_default)
2047     return std::string("en-US");
2048   std::string locale = std::string(local_default);
2049   size_t position = locale.find('_');
2050   if (position != std::string::npos)
2051     locale.replace(position, 1, "-");
2052   position = locale.find('.');
2053   if (position != std::string::npos)
2054     locale = locale.substr(0, position);
2055   return locale;
2056 }
2057
2058 int EWebView::StartInspectorServer(int port) {
2059   return context_->InspectorServerStart(port);
2060 }
2061
2062 bool EWebView::StopInspectorServer() {
2063   return context_->InspectorServerStop();
2064 }
2065
2066 void EWebView::InvokeWebProcessCrashedCallback() {
2067   DCHECK_CURRENTLY_ON(BrowserThread::UI);
2068   const GURL last_url = GetURL();
2069   bool callback_handled = false;
2070   SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2071   if (!callback_handled)
2072     LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2073                    last_url.possibly_invalid_spec().c_str());
2074 }
2075
2076 void EWebView::HandleRendererProcessCrash() {
2077   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
2078                           base::Bind(&EWebView::InvokeWebProcessCrashedCallback,
2079                                      base::Unretained(this)));
2080 }
2081
2082 void EWebView::InitializeContent() {
2083   int width, height;
2084   evas_object_geometry_get(evas_object_, 0, 0, &width, &height);
2085
2086   WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2087   if (!new_contents) {
2088     WebContents::CreateParams params(context_->browser_context());
2089     params.initial_size = gfx::Size(width, height);
2090     web_contents_.reset(
2091         new WebContentsImplEfl(context_->browser_context(), this));
2092     static_cast<WebContentsImpl*>(web_contents_.get())->Init(params);
2093     VLOG(1) << "Initial WebContents size: " << params.initial_size.ToString();
2094   } else {
2095     web_contents_.reset(new_contents);
2096
2097     // When a new webview is created in response to a request from the
2098     // engine, the BrowserContext instance of the originator WebContents
2099     // is used by the newly created WebContents object.
2100     // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2101     //
2102     // Hence, if as part of the WebView creation, the embedding APP
2103     // passes in a Ewk_Context instance that wraps a different instance of
2104     // BrowserContext than the one the originator WebContents holds,
2105     // undefined behavior can be seen.
2106     //
2107     // This is a snippet code that illustrate the scenario:
2108     //
2109     // (..)
2110     // evas_object_smart_callback_add(web_view_, "create,window",
2111     //                                &OnNewWindowRequest, this);
2112     // (..)
2113     //
2114     // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2115     //   (..)
2116     //   EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2117     //   ewk_context_new());
2118     //   *static_cast<Evas_Object**>(out_view) = new_web_view;
2119     //   (..)
2120     // }
2121     //
2122     // The new Ewk_Context object created and passed in as parameter to
2123     // ewk_view_add_with_context wraps a different instance of BrowserContext
2124     // than the one the new WebContents object will hold.
2125     //
2126     // CHECK below aims at catching misuse of this API.
2127     bool should_crash = context_->GetImpl()->browser_context() !=
2128                         web_contents_->GetBrowserContext();
2129     if (should_crash) {
2130       CHECK(false)
2131           << "BrowserContext of new WebContents does not match EWebView's. "
2132           << "Please see 'ewk_view_add*' documentation. "
2133           << "Aborting execution ...";
2134     }
2135   }
2136   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2137   web_contents_->SetDelegate(web_contents_delegate_.get());
2138   GetWebContentsViewEfl()->SetEflDelegate(
2139       new WebContentsViewEflDelegateEwk(this));
2140   WebContentsImplEfl* wc_efl =
2141       static_cast<WebContentsImplEfl*>(web_contents_.get());
2142   wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2143   back_forward_list_.reset(
2144       new _Ewk_Back_Forward_List(web_contents_->GetController()));
2145   back_forward_list_.reset(
2146       new _Ewk_Back_Forward_List(web_contents_->GetController()));
2147
2148   permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2149
2150   native_view_ = static_cast<Evas_Object*>(web_contents_->GetNativeView());
2151   evas_object_smart_member_add(native_view_, evas_object_);
2152 }
2153
2154 #if defined(OS_TIZEN) && !defined(EWK_BRINGUP)
2155 void EWebView::cameraResultCb(service_h request,
2156                               service_h reply,
2157                               service_result_e result,
2158                               void* data) {
2159   if (!IsMobileProfile() && !IsWearableProfile())
2160     return;
2161
2162   EWebView* webview = static_cast<EWebView*>(data);
2163   RenderViewHost* render_view_host =
2164       webview->web_contents_->GetRenderViewHost();
2165   if (result == SERVICE_RESULT_SUCCEEDED) {
2166     int ret = -1;
2167     char** filesarray;
2168     int number;
2169     ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2170                                        &filesarray, &number);
2171     if (filesarray) {
2172       for (int i = 0; i < number; i++) {
2173         std::vector<ui::SelectedFileInfo> files;
2174         if (!render_view_host) {
2175           return;
2176         }
2177         if (filesarray[i]) {
2178           GURL url(filesarray[i]);
2179           if (!url.is_valid()) {
2180             base::FilePath path(url.SchemeIsFile() ? url.path()
2181                                                    : filesarray[i]);
2182             files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2183           }
2184         }
2185         render_view_host->FilesSelectedInChooser(files,
2186                                                  webview->filechooser_mode_);
2187       }
2188     }
2189   } else {
2190     std::vector<ui::SelectedFileInfo> files;
2191     if (render_view_host) {
2192       render_view_host->FilesSelectedInChooser(files,
2193                                                webview->filechooser_mode_);
2194     }
2195   }
2196 }
2197
2198 bool EWebView::LaunchCamera(base::string16 mimetype) {
2199   service_h svcHandle = 0;
2200   if (service_create(&svcHandle) < 0 || !svcHandle) {
2201     LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2202     return false;
2203   }
2204   service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2205   service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2206   service_add_extra_data(svcHandle, "CALLER", "Browser");
2207
2208   int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2209   if (ret != SERVICE_ERROR_NONE) {
2210     LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2211     service_destroy(svcHandle);
2212     return false;
2213   }
2214   service_destroy(svcHandle);
2215   return true;
2216 }
2217 #endif
2218
2219 void EWebView::UrlRequestSet(
2220     const char* url,
2221     content::NavigationController::LoadURLType loadtype,
2222     Eina_Hash* headers,
2223     const char* body) {
2224   GURL gurl(url);
2225   content::NavigationController::LoadURLParams params(gurl);
2226   params.load_type = loadtype;
2227   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2228
2229   if (body) {
2230     std::string s(body);
2231     params.post_data =
2232         network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2233   }
2234
2235   net::HttpRequestHeaders header;
2236   if (headers) {
2237     Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2238     Eina_Hash_Tuple* t;
2239     while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2240       if (t->key) {
2241         const char* value_str =
2242             t->data ? static_cast<const char*>(t->data) : "";
2243         base::StringPiece name = static_cast<const char*>(t->key);
2244         base::StringPiece value = value_str;
2245         header.SetHeader(name, value);
2246         // net::HttpRequestHeaders.ToString() returns string with newline
2247         params.extra_headers += header.ToString();
2248       }
2249     }
2250     eina_iterator_free(it);
2251   }
2252
2253   web_contents_->GetController().LoadURLWithParams(params);
2254 }
2255
2256 bool EWebView::HandleShow() {
2257   if (!native_view_)
2258     return false;
2259
2260   Show();
2261   return true;
2262 }
2263
2264 bool EWebView::HandleHide() {
2265   if (!native_view_)
2266     return false;
2267
2268   Hide();
2269   return true;
2270 }
2271
2272 bool EWebView::HandleMove(int x, int y) {
2273   if (!native_view_)
2274     return false;
2275   evas_object_move(native_view_, x, y);
2276   return true;
2277 }
2278
2279 bool EWebView::HandleResize(int width, int height) {
2280   if (!native_view_)
2281     return false;
2282   evas_object_resize(native_view_, width, height);
2283   return true;
2284 }
2285
2286 bool EWebView::HandleTextSelectionDown(int x, int y) {
2287   if (!GetSelectionController())
2288     return false;
2289   return GetSelectionController()->TextSelectionDown(x, y);
2290 }
2291
2292 bool EWebView::HandleTextSelectionUp(int x, int y) {
2293   if (!GetSelectionController())
2294     return false;
2295   return GetSelectionController()->TextSelectionUp(x, y);
2296 }
2297
2298 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2299   if (!GetSelectionController())
2300     return;
2301
2302   GetSelectionController()->PostHandleTapGesture(is_content_editable);
2303 }
2304
2305 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2306   blink::WebInputEvent::Type event_type = event.GetType();
2307   if (event_type == blink::WebInputEvent::kGestureDoubleTap ||
2308       event_type == blink::WebInputEvent::kGesturePinchBegin) {
2309     SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2310   }
2311   if (event_type == blink::WebInputEvent::kGestureDoubleTap ||
2312       event_type == blink::WebInputEvent::kGesturePinchEnd) {
2313     SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2314   }
2315 }
2316
2317 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2318   DCHECK(render_view_host);
2319
2320   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2321     BrowserThread::PostTask(
2322         BrowserThread::UI, FROM_HERE,
2323         base::Bind(&EWebView::SendDelayedMessages, base::Unretained(this),
2324                    render_view_host));
2325     return;
2326   }
2327
2328   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2329        ++iter) {
2330     IPC::Message* message = *iter;
2331     message->set_routing_id(render_view_host->GetRoutingID());
2332     render_view_host->Send(message);
2333   }
2334
2335   delayed_messages_.clear();
2336 }