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