[M67 Dev][WRT][Arch] Enable single process mode for web runtime 51/187851/3
authoryh106.jung <yh106.jung@samsung.com>
Tue, 6 Dec 2016 09:37:15 +0000 (18:37 +0900)
committerSungsik Han <ss440.han@samsung.com>
Wed, 10 Oct 2018 11:14:26 +0000 (11:14 +0000)
Enables single process mode for web runtime.

Reference:
https://review.tizen.org/gerrit/#/c/173876/

Change-Id: I527d5b051f98e25c70f42fa14e25054ed513d047
Signed-off-by: yh106.jung <yh106.jung@samsung.com>
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
content/browser/renderer_host/render_process_host_impl.cc
tizen_src/ewk/efl_integration/content_browser_client_efl.cc
tizen_src/ewk/efl_integration/content_browser_client_efl.h
tizen_src/ewk/efl_integration/eweb_context.cc
tizen_src/ewk/efl_integration/eweb_context.h

index e2f33e5..f77db77 100644 (file)
@@ -3370,6 +3370,14 @@ void RenderProcessHostImpl::UnregisterHost(int host_id) {
 
   g_all_hosts.Get().Remove(host_id);
 
+#if defined(OS_TIZEN)
+  // On single process mode, crash is occurred once termination of web app
+  // because GetSiteProcessMapForBrowserContext is called
+  // after BrowserContext is deleted. Hence we early return here.
+  if (run_renderer_in_process())
+    return;
+#endif
+
   // Look up the map of site to process for the given browser_context,
   // in case we need to remove this process from it.  It will be registered
   // under any sites it rendered that use process-per-site mode.
index 9359d52..2c0f81c 100644 (file)
@@ -50,12 +50,16 @@ using content::BrowserThread;
 namespace content {
 
 ContentBrowserClientEfl::ContentBrowserClientEfl()
-    : browser_main_parts_efl_(nullptr)
+    : browser_main_parts_efl_(nullptr),
 #if defined(ENABLE_NOTIFICATIONS)
-      ,
-      notification_controller_(new NotificationControllerEfl)
+      notification_controller_(new NotificationControllerEfl),
 #endif
-{
+      browser_context_efl_(nullptr) {
+}
+
+ContentBrowserClientEfl::~ContentBrowserClientEfl() {
+  if (browser_context_efl_)
+    delete browser_context_efl_;
 }
 
 BrowserMainParts* ContentBrowserClientEfl::CreateBrowserMainParts(
index a07fdc0..57583f4 100644 (file)
@@ -16,6 +16,7 @@ class CommandLine;
 class Ewk_Notification;
 
 namespace content {
+class BrowserContextEfl;
 class BrowserMainPartsEfl;
 #if defined(ENABLE_NOTIFICATIONS)
 class NotificationControllerEfl;
@@ -30,6 +31,7 @@ class ContentBrowserClientEfl : public ContentBrowserClient {
   typedef void (*Notification_Cancel_Callback)(uint64_t, void*);
 
   ContentBrowserClientEfl();
+  ~ContentBrowserClientEfl() override;
 
   virtual BrowserMainParts* CreateBrowserMainParts(
       const MainFunctionParams& parameters) override;
@@ -108,6 +110,10 @@ class ContentBrowserClientEfl : public ContentBrowserClient {
   WebContentsViewDelegate* GetWebContentsViewDelegate(
       WebContents* web_contents) override;
 
+  void SetBrowserContext(BrowserContextEfl* context) {
+    browser_context_efl_ = context;
+  }
+
  private:
   static void SetCertificatePemOnUIThread(int render_process_id,
                                           int render_view_id,
@@ -118,10 +124,13 @@ class ContentBrowserClientEfl : public ContentBrowserClient {
   std::unique_ptr<ResourceDispatcherHostDelegateEfl>
       resource_disp_host_del_efl_;
   BrowserMainPartsEfl* browser_main_parts_efl_;
+
 #if defined(ENABLE_NOTIFICATIONS)
   std::unique_ptr<NotificationControllerEfl> notification_controller_;
 #endif
 
+  BrowserContextEfl* browser_context_efl_;
+
   DISALLOW_COPY_AND_ASSIGN(ContentBrowserClientEfl);
 };
 }
index f5aeb9b..79ccb0e 100644 (file)
@@ -7,6 +7,10 @@
 #include <string>
 #include <vector>
 
+#if defined(OS_TIZEN)
+#include <dlfcn.h>
+#endif
+
 #include "base/synchronization/waitable_event.h"
 #include "components/autofill/content/browser/content_autofill_driver.h"
 //#include "content/browser/memory/memory_pressure_controller_impl.h"
 #include "wrt/wrt_widget_host.h"
 
 #if defined(OS_TIZEN)
+#include "base/command_line.h"
+#include "common/content_switches_efl.h"
 #include "content/browser/zygote_host/zygote_communication_linux.h"
+#include "content/common/content_client_export.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/zygote_handle.h"
+#include "content_browser_client_efl.h"
 #endif
 
 using content::BrowserThread;
@@ -57,6 +66,11 @@ using std::map;
 
 namespace {
 
+#if defined(OS_TIZEN)
+const char* const kDynamicPreloading = "DynamicPreloading";
+typedef void (*DynamicPreloading)(void);
+#endif
+
 /**
  * @brief Helper class for obtaining WebStorage origins
  */
@@ -221,9 +235,32 @@ void EWebContext::SetWidgetInfo(const std::string& tizen_app_id,
   widget_encoded_bundle_ = encoded_bundle;
 
 #if defined(OS_TIZEN)
-  // Drop process privillages while web app is launching from WRT process pool.
-  content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_);
-#endif
+  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
+  // Add the switches in here to load injected bundle in renderer thread
+  // in single process mode
+  if (command_line.HasSwitch(switches::kSingleProcess)) {
+    command_line.AppendSwitchASCII(switches::kInjectedBundlePath,
+                                   injected_bundle_path_);
+    command_line.AppendSwitchASCII(switches::kTizenAppId, tizen_app_id_);
+    command_line.AppendSwitchASCII(switches::kWidgetScale,
+                                   std::to_string(widget_scale_));
+    command_line.AppendSwitchASCII(switches::kWidgetTheme, widget_theme_);
+    command_line.AppendSwitchASCII(switches::kWidgetEncodedBundle,
+                                   widget_encoded_bundle_);
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+    // Drop process privillages while web app is launching
+    // from WRT process pool. It should be handled in webengine side
+    // in product tv profile because this profile uses the zygote process.
+    content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_);
+#endif  // OS_TIZEN_TV_PRODUCT
+  } else {
+    // Drop process privillages while web app is launching
+    // from WRT process pool. It is not necessary in single process mode,
+    // because it is handled in crosswalk side in single process mode.
+    content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_);
+  }
+#endif  // OS_TIZEN
 }
 
 void EWebContext::SendWrtMessage(const Ewk_Wrt_Message_Data& data) {
@@ -262,6 +299,9 @@ EWebContext::EWebContext(const std::string& injectedBundlePath)
 
 EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath)
     : injected_bundle_path_(injectedBundlePath),
+#if defined(OS_TIZEN)
+      injected_bundle_handle_(nullptr),
+#endif
       widget_scale_(0),
       m_pixmap(0),
       inspector_server_(NULL) {
@@ -296,14 +336,54 @@ EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath)
   tizen_extensible_.reset(TizenExtensible::create());
 
 #if defined(OS_TIZEN)
-  // Preload injected bundle on zygote process for process pool.
   if (should_preload_injected_bundle) {
-    content::GetGenericZygote()->LoadInjectedBundlePath(injected_bundle_path_);
+    base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
+    if (command_line.HasSwitch(switches::kSingleProcess)) {
+      // Preload injected bundle on here for process pool,
+      // because the zygote process doesn't exist in single process mode.
+      // The loaded handle must be closed on termination.
+      injected_bundle_handle_ =
+          dlopen(injected_bundle_path_.c_str(), RTLD_LAZY);
+      if (!injected_bundle_handle_) {
+        LOG(ERROR) << "No handle to " << injected_bundle_path_.c_str()
+                   << " error " << dlerror();
+        return;
+      }
+
+      DynamicPreloading dp = reinterpret_cast<DynamicPreloading>(
+          dlsym(injected_bundle_handle_, kDynamicPreloading));
+      if (dp) {
+        dp();
+      } else {
+        LOG(ERROR) << "Fail to load symbol '" << kDynamicPreloading
+                   << "', error " << dlerror();
+      }
+    } else {
+      // Preload injected bundle on zygote process for process pool.
+      content::GetGenericZygote()
+          ->LoadInjectedBundlePath(injected_bundle_path_);
+    }
   }
 #endif
 }
 
-EWebContext::~EWebContext() {}
+EWebContext::~EWebContext() {
+#if defined(OS_TIZEN)
+  if (injected_bundle_handle_)
+    dlclose(injected_bundle_handle_);
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kSingleProcess)) {
+    // On single process mode, renderer thread works until ewk_shutdown.
+    // So we have to remain BrowserContextEfl include of ResourceContextEfl.
+    // It will be delete once ContentBrowserClientEfl is destroyed.
+    content::ContentBrowserClient* cbc =
+        content::GetContentClientExport()->browser();
+    auto cbce = static_cast<content::ContentBrowserClientEfl*>(cbc);
+    cbce->SetBrowserContext(browser_context_.release());
+  }
+#endif
+}
 
 void EWebContext::ClearNetworkCache() {
   BrowsingDataRemoverEfl* remover =
index d56befb..83c1d16 100644 (file)
@@ -186,6 +186,11 @@ class EWebContext {
   std::unique_ptr<EwkFaviconDatabase> ewk_favicon_database_;
   std::string proxy_uri_;
   std::string injected_bundle_path_;
+
+#if defined(OS_TIZEN)
+  void* injected_bundle_handle_;
+#endif
+
   // widget info
   std::string tizen_app_id_;
   std::string widget_theme_;