[Tizen] Add web-engine-chromium plugin 37/189737/5
authorYongGeol Jung <yg48.jung@samsung.com>
Wed, 5 Sep 2018 06:39:56 +0000 (23:39 -0700)
committerYongGeol Jung <yg48.jung@samsung.com>
Fri, 21 Sep 2018 00:29:47 +0000 (17:29 -0700)
Change-Id: Ic29bbdbcbe73ec835af702be79ef7694af882ba6
Signed-off-by: YongGeol Jung <yg48.jung@samsung.com>
build/tizen/configure.ac
build/tizen/web-engine-chromium/Makefile.am [new file with mode: 0644]
build/tizen/web-engine-chromium/configure.ac [new file with mode: 0644]
dali-extension/web-engine-chromium/file.list [new file with mode: 0644]
dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp [new file with mode: 0644]
dali-extension/web-engine-chromium/tizen-web-engine-chromium.h [new file with mode: 0644]
packaging/dali-extension.spec

index 7d24fe1..d23afeb 100644 (file)
@@ -19,6 +19,7 @@ PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
 AC_CONFIG_SUBDIRS(key)
 AC_CONFIG_SUBDIRS(video-player)
 AC_CONFIG_SUBDIRS(web-engine-lite)
+AC_CONFIG_SUBDIRS(web-engine-chromium)
 
 AC_CONFIG_FILES([
 Makefile
diff --git a/build/tizen/web-engine-chromium/Makefile.am b/build/tizen/web-engine-chromium/Makefile.am
new file mode 100644 (file)
index 0000000..31555bf
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2018 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build the Dali web engine chromium plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/web-engine-chromium/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-web-engine-chromium-plugin.la
+
+libdali_web_engine_chromium_plugin_la_SOURCES = \
+                     $(web_engine_chromium_plugin_src_files)
+
+libdali_web_engine_chromium_plugin_la_DEPENDENCIES =
+
+libdali_web_engine_chromium_plugin_la_CXXFLAGS = \
+                      $(DALI_CFLAGS) \
+                      $(WEB_ENGINE_CHROMIUM_CFLAGS) \
+                      $(ELEMENTARY_CFLAGS) \
+                      -I../../../dali-extension/web-engine-chromium \
+                      -Werror -Wall
+
+libdali_web_engine_chromium_plugin_la_LIBADD = \
+                      $(DALI_LIBS) \
+                      $(WEB_ENGINE_CHROMIUM_LIBS)
+
+libdali_web_engine_chromium_plugin_la_LDFLAGS = \
+                      -rdynamic
+
diff --git a/build/tizen/web-engine-chromium/configure.ac b/build/tizen/web-engine-chromium/configure.ac
new file mode 100644 (file)
index 0000000..92069f5
--- /dev/null
@@ -0,0 +1,29 @@
+4_define([dali_version],[0.1.0])
+AC_INIT([dali], [dali_version])
+AM_INIT_AUTOMAKE([-Wall foreign])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+LT_INIT
+
+DALI_EXTENSION_VERSION=dali_version
+AC_SUBST(DALI_EXTENSION_VERSION)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+PKG_CHECK_MODULES(WAYLAND, libtbm)
+PKG_CHECK_MODULES(WEB_ENGINE_CHROMIUM, chromium-efl)
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/dali-extension/web-engine-chromium/file.list b/dali-extension/web-engine-chromium/file.list
new file mode 100644 (file)
index 0000000..fa00bc1
--- /dev/null
@@ -0,0 +1,2 @@
+web_engine_chromium_plugin_src_files = \
+   $(extension_src_dir)/web-engine-chromium/tizen-web-engine-chromium.cpp
diff --git a/dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp b/dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp
new file mode 100644 (file)
index 0000000..aa65481
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <tizen-web-engine-chromium.h>
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Elementary.h>
+
+#include <EWebKit_internal.h>
+#include <EWebKit_product.h>
+
+using namespace Dali;
+
+namespace Dali {
+namespace Plugin {
+class WebViewContainerForDali {
+ public:
+  static void InitGalobalIfNeeded() {
+    if (!window_) {
+      elm_init(0, 0);
+      ewk_init();
+      window_ = ecore_evas_new("wayland_egl", 0, 0, 1, 1, 0);
+    }
+  }
+
+  static void ClearGlobalIfNeeded() {
+    // What we should clear?
+  }
+
+  WebViewContainerForDali(WebViewContainerClient& client, int width, int height)
+      : client_(client),
+        width_(width),
+        height_(height) {
+    InitGalobalIfNeeded();
+    InitWebView();
+    instance_count_++;
+  }
+
+  ~WebViewContainerForDali() {
+    evas_object_del(webview_);
+    ClearGlobalIfNeeded();
+    instance_count_--;
+  }
+
+  void InitWebView() {
+    Ewk_Context* context = ewk_context_default_get();
+    ewk_context_max_refresh_rate_set(context, 60);
+    webview_ = ewk_view_add(ecore_evas_get(window_));
+    ewk_view_offscreen_rendering_enabled_set(webview_, true);
+
+    evas_object_smart_callback_add(webview_, "offscreen,frame,rendered",
+                                   &WebViewContainerForDali::OnFrameRendered,
+                                   &client_);
+    evas_object_smart_callback_add(webview_, "load,started",
+                                   &WebViewContainerForDali::OnLoadStarted,
+                                   &client_);
+    evas_object_smart_callback_add(webview_, "load,finished",
+                                   &WebViewContainerForDali::OnLoadFinished,
+                                   &client_);
+    evas_object_smart_callback_add(webview_, "console,message",
+                                   &WebViewContainerForDali::OnConsoleMessage,
+                                   this);
+
+    evas_object_resize(webview_, width_, height_);
+    evas_object_show(webview_);
+  }
+
+  void LoadUrl(const std::string& url) {
+    ewk_view_url_set(webview_, url.c_str());
+  }
+
+  void LoadHtml(const std::string& html) {
+    ewk_view_html_string_load(webview_, html.c_str(), 0, 0);
+  }
+
+  std::string GetUrl() {
+    return std::string(ewk_view_url_get(webview_));
+  }
+
+  void Reload() {
+    ewk_view_reload(webview_);
+  }
+
+  void StopLoading() {
+    ewk_view_stop(webview_);
+  }
+
+  void GoBack() {
+    ewk_view_back(webview_);
+  }
+
+  void GoForward() {
+    ewk_view_forward(webview_);
+  }
+
+  bool CanGoBack() {
+    return ewk_view_back_possible(webview_);
+  }
+
+  bool CanGoForward() {
+    return ewk_view_forward_possible(webview_);
+  }
+
+  void EvaluateJavaScript(const std::string& script) {
+    ewk_view_script_execute(webview_, script.c_str(), 0, 0);
+  }
+
+  void ClearHistory() {
+    ewk_view_back_forward_list_clear(webview_);
+  }
+
+  void ClearCache() {
+    ewk_context_cache_clear(ewk_view_context_get(webview_));
+  }
+
+  void SetSize(int width, int height) {
+    width_ = width;
+    height_ = height;
+    evas_object_resize(webview_, width_, height_);
+  }
+
+  bool SendTouchEvent(const TouchData& touch) {
+    Ewk_Touch_Event_Type type = EWK_TOUCH_START;
+    Evas_Touch_Point_State state = EVAS_TOUCH_POINT_DOWN;
+    switch (touch.GetState(0)) {
+    case PointState::DOWN:
+      type = EWK_TOUCH_START;
+      state = EVAS_TOUCH_POINT_DOWN;
+      break;
+    case PointState::UP:
+      type = EWK_TOUCH_END;
+      state = EVAS_TOUCH_POINT_UP;
+      break;
+    case PointState::MOTION:
+      type = EWK_TOUCH_MOVE;
+      state = EVAS_TOUCH_POINT_MOVE;
+      break;
+    case PointState::INTERRUPTED:
+      type = EWK_TOUCH_CANCEL;
+      state = EVAS_TOUCH_POINT_CANCEL;
+      break;
+    default:
+      break;
+    }
+
+    Eina_List* point_list = 0;
+    Ewk_Touch_Point* point = new Ewk_Touch_Point;
+    point->id = 0;
+    point->x = touch.GetLocalPosition(0).x;
+    point->y = touch.GetLocalPosition(0).y;
+    point->state = state;
+    point_list = eina_list_append(point_list, point);
+
+    ewk_view_feed_touch_event(webview_, type, point_list, 0);
+    eina_list_free(point_list);
+    return true;
+  }
+
+  bool SendKeyEvent(const KeyEvent& keyEvent) {
+    void* key_event = 0;
+    if (keyEvent.state == KeyEvent::Down) {
+      Evas_Event_Key_Down down_event;
+      memset(&down_event, 0, sizeof(Evas_Event_Key_Down));
+      down_event.key = keyEvent.keyPressedName.c_str();
+      down_event.string = keyEvent.keyPressed.c_str();
+      key_event = static_cast<void*>(&down_event);
+      ewk_view_send_key_event(webview_, key_event, true);
+    } else {
+      Evas_Event_Key_Up up_event;
+      memset(&up_event, 0, sizeof(Evas_Event_Key_Up));
+      up_event.key = keyEvent.keyPressedName.c_str();
+      up_event.string = keyEvent.keyPressed.c_str();
+      key_event = static_cast<void*>(&up_event);
+      ewk_view_send_key_event(webview_, key_event, false);
+     }
+     return true;
+  }
+
+ private:
+  static void OnFrameRendered(void* data, Evas_Object*, void* buffer) {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->UpdateImage(static_cast<tbm_surface_h>(buffer));
+  }
+
+  static void OnLoadStarted(void* data, Evas_Object*, void*) {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->LoadStarted();
+  }
+
+  static void OnLoadFinished(void* data, Evas_Object*, void*) {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->LoadFinished();
+  }
+
+  static void OnConsoleMessage(void*, Evas_Object*, void* event_info) {
+    Ewk_Console_Message* console_message = (Ewk_Console_Message*)event_info;
+    printf("console message:%s:", ewk_console_message_source_get(console_message));
+    printf("%d:", ewk_console_message_line_get(console_message));
+    printf("%d:", ewk_console_message_level_get(console_message));
+    printf("%s\n", ewk_console_message_text_get(console_message));
+  }
+
+  static void OnJavaScriptMessage(Evas_Object* o, Ewk_Script_Message message) {
+  }
+
+ private:
+  static Ecore_Evas* window_;
+  static int instance_count_;
+
+  Evas_Object* webview_;
+  WebViewContainerClient& client_;
+
+  int width_;
+  int height_;
+};
+
+Ecore_Evas* WebViewContainerForDali::window_ = 0;
+int WebViewContainerForDali::instance_count_ = 0;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+class TBMSurfaceSourceInitializer {
+ public:
+  explicit TBMSurfaceSourceInitializer(NativeImageSourcePtr& image_src,
+                                       int width, int height) {
+    surface_ = tbm_surface_create(width, height, TBM_FORMAT_ARGB8888);
+    if (!surface_)
+      printf("Failed to create tbm surface.");
+
+    Any tbm_source(surface_);
+    image_src = NativeImageSource::New(tbm_source);
+    Any empty_source(0);
+    image_src->SetSource(empty_source);
+  }
+
+  ~TBMSurfaceSourceInitializer() {
+    if (surface_) {
+      if (tbm_surface_destroy(surface_) != TBM_SURFACE_ERROR_NONE)
+        printf("Failed to destroy tbm surface.");
+    }
+  }
+ private:
+  tbm_surface_h surface_;
+};
+
+TizenWebEngine::TizenWebEngine()
+    : webview_container_(0) {
+}
+
+TizenWebEngine::~TizenWebEngine() {
+  Destroy();
+}
+
+void TizenWebEngine::Create(int width, int height,
+                            const std::string& locale,
+                            const std::string& timezoneID) {
+  webview_container_ =
+      new WebViewContainerForDali(*this, width, height);
+  TBMSurfaceSourceInitializer initializer(dali_image_src_, width, height);
+}
+
+void TizenWebEngine::Destroy() {
+  if (webview_container_) {
+    delete webview_container_;
+    webview_container_ = 0;
+  }
+}
+
+void TizenWebEngine::LoadUrl(const std::string& path) {
+  if (webview_container_)
+    webview_container_->LoadUrl(path);
+}
+
+NativeImageInterfacePtr TizenWebEngine::GetNativeImageSource() {
+  return dali_image_src_;
+}
+
+const std::string& TizenWebEngine::GetUrl() {
+  if (webview_container_)
+    url_ =  webview_container_->GetUrl();
+  return url_;
+}
+
+void TizenWebEngine::LoadHTMLString(const std::string& string) {
+  if (webview_container_)
+    return webview_container_->LoadHtml(string);
+}
+
+void TizenWebEngine::Reload() {
+  if (webview_container_)
+    webview_container_->Reload();
+}
+
+void TizenWebEngine::StopLoading() {
+  if (webview_container_)
+    webview_container_->StopLoading();
+}
+
+bool TizenWebEngine::CanGoForward() {
+  if (webview_container_)
+    return webview_container_->CanGoForward();
+  return false;
+}
+
+void TizenWebEngine::GoForward() {
+  if (webview_container_)
+    webview_container_->GoForward();
+}
+
+bool TizenWebEngine::CanGoBack() {
+  if (webview_container_)
+    return webview_container_->CanGoBack();
+  return false;
+}
+
+void TizenWebEngine::GoBack() {
+  if (webview_container_)
+    webview_container_->GoBack();
+}
+
+void TizenWebEngine::EvaluateJavaScript(const std::string& script) {
+  if (webview_container_)
+    webview_container_->EvaluateJavaScript(script);
+}
+
+void TizenWebEngine::AddJavaScriptInterface(
+    const std::string& exposedObjectName,
+    const std::string& jsFunctionName,
+    std::function<std::string(const std::string&)> cb ) {
+  // Not implemented yet.
+}
+
+void TizenWebEngine::RemoveJavascriptInterface(
+    const std::string& exposedObjectName,
+    const std::string& jsFunctionName ) {
+  // Not implemented yet.
+}
+
+void TizenWebEngine::ClearHistory() {
+  if (webview_container_)
+    webview_container_->ClearHistory();
+}
+
+void TizenWebEngine::ClearCache() {
+  if (webview_container_)
+    webview_container_->ClearCache();
+}
+
+void TizenWebEngine::SetSize(int width, int height) {
+  if (webview_container_)
+    webview_container_->SetSize(width, height);
+}
+
+bool TizenWebEngine::SendTouchEvent(const Dali::TouchData& touch) {
+  if (webview_container_)
+    return webview_container_->SendTouchEvent(touch);
+  return false;
+}
+
+bool TizenWebEngine::SendKeyEvent(const Dali::KeyEvent& event) {
+  if (webview_container_)
+    return webview_container_->SendKeyEvent(event);
+  return false;
+}
+
+Dali::WebEnginePlugin::WebEngineSignalType& TizenWebEngine::PageLoadStartedSignal() {
+  return load_started_signal_;
+}
+
+Dali::WebEnginePlugin::WebEngineSignalType& TizenWebEngine::PageLoadFinishedSignal() {
+  return load_finished_signal_;
+}
+
+// WebViewContainerClient Interface
+void TizenWebEngine::UpdateImage(tbm_surface_h buffer) {
+  if (!buffer)
+    return;
+
+  Any source(buffer);
+  dali_image_src_->SetSource(source);
+  Dali::Stage::GetCurrent().KeepRendering(0.0f);
+}
+
+void TizenWebEngine::LoadStarted() {
+  printf("# TizenWebEngine LoadStarted : %s\n", GetUrl().c_str());
+  load_started_signal_.Emit(GetUrl());
+}
+
+void TizenWebEngine::LoadFinished() {
+  printf("# TizenWebEngine LoadFinished : %s\n", GetUrl().c_str());
+  load_finished_signal_.Emit(GetUrl());
+}
+}
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+#define EXPORT_API __attribute__((__visibility__("default")))
+///////////////////////////////////////////////////////////////////////////////////////////////////////
+extern "C" EXPORT_API Dali::WebEnginePlugin* CreateWebEnginePlugin() {
+  return new Dali::Plugin::TizenWebEngine();
+}
+
+extern "C" EXPORT_API void DestroyWebEnginePlugin(Dali::WebEnginePlugin* plugin) {
+  if (plugin)
+    delete plugin;
+}
diff --git a/dali-extension/web-engine-chromium/tizen-web-engine-chromium.h b/dali-extension/web-engine-chromium/tizen-web-engine-chromium.h
new file mode 100644 (file)
index 0000000..c59d650
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef DALI_TIZEN_WEB_ENGINE_CHROMIUM_H
+#define DALI_TIZEN_WEB_ENGINE_CHROMIUM_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <functional>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali/devel-api/adaptor-framework/web-engine-plugin.h>
+#include <dali/public-api/images/native-image-interface.h>
+
+#include <tbm_surface.h>
+
+namespace Dali {
+namespace Plugin {
+
+class WebViewContainerForDali;
+
+class WebViewContainerClient {
+public:
+  virtual void UpdateImage(tbm_surface_h buffer) = 0;
+  virtual void LoadStarted() = 0;
+  virtual void LoadFinished() = 0;
+};
+
+class TizenWebEngine
+    : public Dali::WebEnginePlugin,
+      public WebViewContainerClient {
+ public:
+  TizenWebEngine();
+  ~TizenWebEngine() override;
+
+  // WebEnginePlugin Interface
+  void Create(int width, int height,
+              const std::string& locale,
+              const std::string& timezoneID) override;
+  void Destroy() override;
+
+  void LoadUrl(const std::string& url) override;
+  NativeImageInterfacePtr GetNativeImageSource() override;
+  const std::string& GetUrl() override;
+
+  void LoadHTMLString(const std::string& string) override;
+  void Reload() override;
+  void StopLoading() override;
+
+  bool CanGoForward() override;
+  void GoForward() override;
+  bool CanGoBack() override;
+  void GoBack() override;
+
+  void EvaluateJavaScript(const std::string& script) override;
+  void AddJavaScriptInterface(
+      const std::string& exposedObjectName,
+      const std::string& jsFunctionName,
+      std::function<std::string(const std::string&)> cb ) override;
+  void RemoveJavascriptInterface(const std::string& exposedObjectName,
+                                 const std::string& jsFunctionName) override;
+
+  void ClearHistory() override;
+  void ClearCache() override;
+
+  void SetSize(int width, int height) override;
+
+  bool SendTouchEvent(const Dali::TouchData& touch) override;
+  bool SendKeyEvent(const Dali::KeyEvent& event) override;
+
+  Dali::WebEnginePlugin::WebEngineSignalType& PageLoadStartedSignal() override;
+  Dali::WebEnginePlugin::WebEngineSignalType& PageLoadFinishedSignal() override;
+
+  // WebViewContainerClient Interface
+  void UpdateImage(tbm_surface_h buffer) override;
+  void LoadStarted() override;
+  void LoadFinished() override;
+
+ private:
+  WebViewContainerForDali* webview_container_;
+  Dali::NativeImageSourcePtr dali_image_src_;
+
+  Dali::WebEnginePlugin::WebEngineSignalType load_started_signal_;
+  Dali::WebEnginePlugin::WebEngineSignalType load_finished_signal_;
+
+  std::string url_;
+};
+}
+}
+
+#endif
index a38fbc9..df77fb7 100644 (file)
@@ -82,6 +82,20 @@ BuildRequires: pkgconfig(lightweight-web-engine)
 Web Engine Lite plugin to support WebView for Dali
 
 ##############################
+# Dali Web Engine chromium Plugin
+##############################
+
+%package web-engine-chromium-plugin
+Summary:    Plugin to support WebView for Dali
+Group:      System/Libraries
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(chromium-efl)
+BuildRequires: pkgconfig(elementary)
+
+%description web-engine-chromium-plugin
+Web Engine chromium plugin to support WebView for Dali
+
+##############################
 # Preparation
 ##############################
 %prep
@@ -147,6 +161,10 @@ exit 0
 /sbin/ldconfig
 exit 0
 
+%post web-engine-chromium-plugin
+/sbin/ldconfig
+exit 0
+
 ##############################
 #   Pre Uninstall old package
 ##############################
@@ -172,6 +190,10 @@ exit 0
 /sbin/ldconfig
 exit 0
 
+%postun web-engine-chromium-plugin
+/sbin/ldconfig
+exit 0
+
 ##############################
 # Files in Binary Packages
 ##############################
@@ -203,3 +225,9 @@ exit 0
 %defattr(-,root,root,-)
 %{_libdir}/libdali-web-engine-lite-plugin.so*
 %license LICENSE
+
+%files web-engine-chromium-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-web-engine-chromium-plugin.so*
+%license LICENSE