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