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