[Release] wrt_0.8.166 for tizen_2.1 branch
authorTaejeong Lee <taejeong.lee@samsung.com>
Fri, 22 Mar 2013 10:31:45 +0000 (19:31 +0900)
committerTaejeong Lee <taejeong.lee@samsung.com>
Fri, 22 Mar 2013 10:31:45 +0000 (19:31 +0900)
Change-Id: I93c5298c1fecbabbe2213627ca385f0c6f9efffe

22 files changed:
CMakeLists.txt
debian/changelog
packaging/wrt.spec
src/api_new/ewk_context_manager.cpp
src/view/webkit/bundles/wrt-wk2-bundle.cpp
src/view/webkit/view_logic.cpp [changed mode: 0755->0644]
src/wrt-client/CMakeLists.txt
src/wrt-client/window_data.cpp
src/wrt-client/window_data.h
src/wrt-client/wrt-client.cpp
src/wrt-launchpad-daemon/CMakeLists.txt
src/wrt-launchpad-daemon/include/access_control.h [moved from src/wrt-launchpad-daemon/launchpad_src/access_control.h with 93% similarity]
src/wrt-launchpad-daemon/include/config.h [moved from src/wrt-launchpad-daemon/launchpad_src/config.h with 90% similarity]
src/wrt-launchpad-daemon/include/gl.h [moved from src/wrt-launchpad-daemon/launchpad_src/gl.h with 94% similarity]
src/wrt-launchpad-daemon/include/launchpad_util.h [new file with mode: 0644]
src/wrt-launchpad-daemon/include/menu_db_util.h
src/wrt-launchpad-daemon/include/process_pool.h [new file with mode: 0644]
src/wrt-launchpad-daemon/launchpad_src/launchpad.c
src/wrt-launchpad-daemon/legacy/preload_list_wrt.txt
src/wrt-launchpad-daemon/src/app_sock.c
src/wrt-launchpad-daemon/src/process_pool.c [new file with mode: 0644]
wrt_env.sh [new file with mode: 0644]

index 2350e23..993f380 100644 (file)
@@ -43,7 +43,7 @@ ENDIF(NOT CMAKE_BUILD_TYPE)
 OPTION(DPL_LOG "DPL logs status" ON)
 OPTION(WITH_TESTS "Build tests" OFF)
 #enable csp policy support
-OPTION(CSP_SUPPORT "Support for csp policy" ON)
+OPTION(CSP_SUPPORT "Support for csp policy" OFF)
 IF(CSP_SUPPORT)
     ADD_DEFINITIONS("-DCSP_ENABLED")
 ENDIF(CSP_SUPPORT)
@@ -232,6 +232,9 @@ ADD_CUSTOM_TARGET(generic_popup_horizontal ALL DEPENDS
 INSTALL(FILES   ${PROJECT_SOURCE_DIR}/data/generic_popup_horizontal.edj
     DESTINATION share/edje/ace/
     )
+INSTALL(FILES   ${CMAKE_SOURCE_DIR}/wrt_env.sh
+    DESTINATION /etc/profile.d/
+    )
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(po)
index dad8a95..b553fe6 100644 (file)
@@ -1,3 +1,12 @@
+wrt (0.8.16) unstable; urgency=low
+
+  * WRT Process Pool Model
+  * Source clean up (case of launch browser)
+  * Changed order of setting CSP policy
+  * Disable CSP
+
+ -- Tae-Jeong Lee <taejeong.lee@samsung.com>  Fri, 22 Mar 2013 19:21:40 +0900
+
 wrt (0.8.165) unstable; urgency=low
 
   * JS Global Context PluginModule starting and stoping bug fix
index 8e8034a..0faba51 100644 (file)
@@ -1,7 +1,7 @@
-#git:framework/web/wrt wrt_0.8.165
+#git:framework/web/wrt wrt_0.8.166
 Name:       wrt
 Summary:    web runtime
-Version:    0.8.165
+Version:    0.8.166
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
@@ -163,6 +163,7 @@ systemctl daemon-reload
     %attr(755,root,root) %{_bindir}/wrt-tests-general
     /opt/share/widget/tests/general/*
 %endif
+%attr(755,root,root) %{_sysconfdir}/profile.d/wrt_env.sh
 
 ## wrt-launchpad-daemon #######################################################
 %attr(755,root,root) %{_bindir}/wrt_launchpad_daemon
index 186173d..7d25150 100755 (executable)
@@ -125,6 +125,9 @@ bool EwkContextManager::initialize()
     setAutoFullscreenMode();
     setBackgroundSupport();
 
+    // ewk storage_path set
+    ewk_context_storage_path_reset(m_ewkContext);
+
     m_initialized = true;
 
     return true;
index 8a2bc07..ef9f90e 100644 (file)
@@ -49,6 +49,7 @@
 #include <dpl/wrt-dao-ro/WrtDatabase.h>
 #include <dpl/localization/localization_utils.h>
 #include <dpl/string.h>
+#include <dpl/wrt-dao-ro/global_config.h>
 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
 #include <dpl/utils/mime_type_utils.h>
 #include <dpl/localization/LanguageTagsProvider.h>
 
 #include <js_overlay_types.h>
 
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <privilege-control.h>
+
 // URI localization on WebProcess side
 #include "bundle_uri_handling.h"
 extern "C" {
@@ -94,6 +99,11 @@ const char * const PHP_MIME = "application/x-php";
 const char * const VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
 const char * const VIEWMODE_TYPE_MAXIMIZED = "maximized";
 const std::size_t FILE_BUF_MAX_SIZE = 1024; // bytes
+const std::size_t PLAIN_CHUNK_SIZE = 1008; // bytes
+const unsigned int UID_ROOT = 0;
+const unsigned int DEFAULT_PRIORITY = 0;
+const char * const PRIVILEGE_APP_TYPE = "wgt";
+
 static bool m_initWebApp = false;
 
 Tizen::Base::ByteBuffer *DecryptChunkByTrustZone(
@@ -412,6 +422,23 @@ void Bundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
             m_widgetTizenId = DPL::FromASCIIString(msgString);
 
             WrtDB::WidgetDAOReadOnly dao(m_widgetTizenId);
+
+            // process pool - set app_privilige
+            if (UID_ROOT == getuid())
+            {
+                using namespace WrtDB::GlobalConfig;
+
+                std::string appPath;
+                std::string tzAppId = DPL::ToUTF8String(dao.getTzAppId());
+                std::string tzPkgId = DPL::ToUTF8String(dao.getTizenPkgId());
+
+                appPath = appPath + GetUserInstalledWidgetPath() + "/" +
+                          tzPkgId + GetUserWidgetExecPath() + "/" + tzAppId;
+
+                LogDebug("set_app_privilege(" << appPath << ")");
+                set_app_privilege(tzPkgId.c_str(), PRIVILEGE_APP_TYPE, appPath.c_str());
+            }
+
             /* This type of message is received when widget is restarting
              * (proably in other situation too). Widget restart can be
              * called after system language change so language tags have to
@@ -797,6 +824,7 @@ WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationAction(
         WKRelease(urlStr);
         WKRelease(retVal);
         WKRelease(blockMessage);
+        return WKBundlePagePolicyActionPassThrough;
     }
 
     // get scheme string
@@ -1023,5 +1051,11 @@ void WKBundleInitialize(WKBundleRef bundle,
         &Bundle::didReceiveMessageCallback
     };
     WKBundleSetClient(bundle, &client);
+
+    // process pool - restore process priority
+    if (UID_ROOT == getuid())
+    {
+        setpriority(PRIO_PROCESS, 0, DEFAULT_PRIORITY);
+    }
 }
 }
old mode 100755 (executable)
new mode 100644 (file)
index f9a48bf..4c5042e
@@ -621,27 +621,29 @@ void ViewLogic::prepareEwkView(Evas_Object *wkView)
     //    EWK_ENFORCE_POLICY);
     //LogInfo("Default policy set");
 
-    DPL::OptionalString policy = m_model->CspPolicy.Get();
+    DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get();
 
     if (!(policy.IsNull()))
     {
-        LogDebug("CSP policy present in manifest: " << *policy);
+        LogDebug("CSP report only policy present in manifest: " << *policy);
         ewk_view_content_security_policy_set(
-            wkView, DPL::ToUTF8String(*policy).c_str(), EWK_ENFORCE_POLICY);
+            wkView, DPL::ToUTF8String(*policy).c_str(), EWK_REPORT_ONLY);
     } else {
-        LogDebug("Config CSP policy is not present");
+        LogDebug("Config CSP report only policy is not present");
     }
 
-    policy = m_model->CspReportOnlyPolicy.Get();
+    policy = m_model->CspPolicy.Get();
+
     if (!(policy.IsNull()))
     {
-        LogDebug("CSP report only policy present in manifest: " << *policy);
+        LogDebug("CSP policy present in manifest: " << *policy);
         ewk_view_content_security_policy_set(
-            wkView, DPL::ToUTF8String(*policy).c_str(), EWK_REPORT_ONLY);
+            wkView, DPL::ToUTF8String(*policy).c_str(), EWK_ENFORCE_POLICY);
     } else {
-        LogDebug("Config CSP report only policy is not present");
+        LogDebug("Config CSP policy is not present");
     }
 
+
     LogInfo("CSP set.");
 #endif
 
@@ -834,23 +836,6 @@ void ViewLogic::loadFinishedCallback(
         return;
     }
 
-    // check if this loading is for blocked url
-    if (This->m_blockedUri == url) {
-        if (ewk_view_back_possible(This->m_currentEwkView)) {
-            // go back to previous page
-            LogDebug("go to previous page");
-            ewk_view_back(This->m_currentEwkView);
-        } else {
-            // stop current page
-            LogDebug("remove current page");
-            ewk_view_stop(This->m_currentEwkView);
-            This->m_closedEwkView = This->m_currentEwkView;
-            ecore_idler_add(windowCloseIdlerCallback, This);
-        }
-        This->m_blockedUri = std::string();
-        return;
-    }
-
     DPL::OptionalString jsOptionalString =
         ViewModule::PasswordSupport::jsForAutoFillData(url);
     if (jsOptionalString.IsNull()) {
@@ -1036,6 +1021,17 @@ void ViewLogic::policyNavigationDecideCallback(
     Ewk_Policy_Decision* policyDecision =
         static_cast<Ewk_Policy_Decision*>(eventInfo);
 
+    // handle blocked url
+    const char* url = ewk_policy_decision_url_get(policyDecision);
+    if (url && strlen(url) != 0) {
+        if (This->m_blockedUri == url) {
+            LogDebug("Blocked url = " << url);
+            This->m_blockedUri = std::string();
+            ewk_policy_decision_ignore(policyDecision);
+            return;
+        }
+    }
+
     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
                                                  false,
                                                  This->m_model,
index 16eecce..eaec1e7 100644 (file)
@@ -19,6 +19,7 @@ SET(WRT_CLIENT_SRCS
     ${PROJECT_SOURCE_DIR}/src/wrt-client/window_data.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/splash_screen_support.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/wrt-client.cpp
+    ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/src/process_pool.c
 )
 
 PKG_CHECK_MODULES(CLIENT_DEP
@@ -31,6 +32,7 @@ PKG_CHECK_MODULES(CLIENT_DEP
 INCLUDE_DIRECTORIES(
     ${PROJECT_SOURCE_DIR}/src/wrt-client
     ${PROJECT_SOURCE_DIR}/src/api_new
+    ${PROJECT_SOURCE_DIR}/src/wrt-launchpad-daemon/include
     ${CLIENT_DEP_INCLUDE_DIRS}
 )
 
index dd64049..a4a2ead 100644 (file)
@@ -46,7 +46,8 @@ const std::string DESKTOP_PROFILE("desktop");
 
 WindowData::WindowData(unsigned long pid, bool manualInit) :
     m_win(NULL),
-    m_naviBackButton(NULL)
+    m_naviBackButton(NULL),
+    m_initialized(false)
 {
     m_win = createWindow(pid);
 
@@ -65,6 +66,12 @@ void WindowData::init()
 {
     Assert(m_win != NULL && "m_win is null");
 
+    if (m_initialized == true)
+    {
+        LogInfo("Already initilized");
+        return;
+    }
+
     // import button theme
     elm_theme_overlay_add(NULL, THEME_EDJ_PATH);
 
@@ -76,6 +83,8 @@ void WindowData::init()
     evas_object_show(m_navigation);
     m_user_layout = createUserLayout(m_navigation);
     evas_object_show(m_user_layout);
+
+    m_initialized = true;
 }
 
 void WindowData::setEvasObjectForLayout(Evas_Object* evas_object)
index 8c656e9..8411ac6 100644 (file)
@@ -111,6 +111,7 @@ class WindowData : private DPL::Noncopyable
     Evas_Object* m_naviBackButton;
     Evas_Object* m_floatBackButton;
     bool m_fullscreen;
+    bool m_initialized;
 
     Evas_Object* createWindow(unsigned long pid);
     Evas_Object* createPlatformLayout(Evas_Object* parent);
index 3ea7ea7..d0c7d8f 100644 (file)
@@ -14,6 +14,9 @@
  *    limitations under the License.
  */
 #include "wrt-client.h"
+#include <aul.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <appcore-efl.h>
 #include <appcore-common.h>
 #include <cstdlib>
 #include <dpl/localization/LanguageTagsProvider.h>
 #include "webkit/bundles/plugin_module_support.h"
 
+#include "process_pool.h"
+#include "menu_db_util.h"
+#include "launchpad_util.h"
+
 //W3C PACKAGING enviroment variable name
 #define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH"
 
@@ -41,7 +48,12 @@ const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
 const char* const BUNDLE_PATH = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
 
-static Ewk_Context* s_ewk_context = NULL;
+// process pool
+const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate";
+static Ewk_Context* s_preparedEwkContext = NULL;
+static WindowData*  s_preparedWindowData = NULL;
+static int    app_argc = 0;
+static char** app_argv = NULL;
 
 WrtClient::WrtClient(int argc, char **argv) :
     Application(argc, argv, "wrt-client", false),
@@ -475,8 +487,15 @@ void WrtClient::launchStep()
     //        languageChangedCallback, this);
 
     ADD_PROFILING_POINT("CreateWindow", "start");
-    m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()),
-                                      true));
+    if (s_preparedWindowData == NULL)
+    {
+        m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()), true));
+    }
+    else
+    {
+        m_windowData.reset(s_preparedWindowData);
+        s_preparedWindowData = NULL;
+    }
     ADD_PROFILING_POINT("CreateWindow", "stop");
 
     WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
@@ -493,7 +512,7 @@ void WrtClient::launchStep()
     ADD_PROFILING_POINT("Create splash screen", "stop");
     DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
     if (!m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
-            m_windowData->m_win, s_ewk_context))
+            m_windowData->m_win, s_preparedEwkContext))
     {
         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
             NextStepEvent());
@@ -540,7 +559,9 @@ void WrtClient::launchStep()
 
     m_widget->SetUserDelegates(cbs);
     m_widget->Show();
+
     m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
+
     ADD_PROFILING_POINT("launchStep", "stop");
 }
 
@@ -656,7 +677,7 @@ void WrtClient::shutdownStep()
         m_widgetState = WidgetState_Stopped;
         m_widget->Hide();
         m_widget.reset();
-        ewk_context_delete(s_ewk_context);
+        ewk_context_delete(s_preparedEwkContext);
         WRT::CoreModuleSingleton::Instance().Terminate();
     }
     if (m_initialized) {
@@ -700,9 +721,82 @@ void WrtClient::Quit()
     DPL::Application::Quit();
 }
 
+static Eina_Bool proces_pool_fd_handler(void* /*data*/, Ecore_Fd_Handler *handler)
+{
+    int fd = ecore_main_fd_handler_fd_get(handler);
+
+    if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
+    {
+        LogDebug("ECORE_FD_ERROR");
+        close(fd);
+        exit(-1);
+        return ECORE_CALLBACK_CANCEL;
+    }
+
+    if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
+    {
+        LogDebug("ECORE_FD_READ");
+        {
+            app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
+            memset(pkt, 0, AUL_SOCK_MAXBUFF);
+
+            int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
+
+            close(fd);
+
+            if (recv_ret == -1)
+            {
+                LogDebug("recv error!");
+                exit(-1);
+            }
+            LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len);
+
+            ecore_main_fd_handler_del(handler);
+
+            __wrt_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv);
+
+            free(pkt);
+        }
+
+        ecore_main_loop_quit();
+        return ECORE_CALLBACK_CANCEL;
+    }
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+
+void set_env()
+{
+    // set evas backend type
+    if (!getenv("ELM_ENGINE"))
+    {
+        if (!setenv("ELM_ENGINE", "gl", 1))
+        {
+            LogDebug("Enable backend");
+        }
+    }
+    else
+    {
+        LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
+    }
+
+#ifndef TIZEN_PUBLIC
+    setenv("COREGL_FASTPATH", "1", 1);
+#endif
+    setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
+    setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
+    setenv("ELM_IMAGE_CACHE", "0", 1);
+}
+
+
 int main(int argc,
          char *argv[])
 {
+    // process pool - store arg's value
+    app_argc = argc;
+    app_argv = argv;
+
     UNHANDLED_EXCEPTION_HANDLER_BEGIN
     {
         ADD_PROFILING_POINT("main-entered", "point");
@@ -710,37 +804,68 @@ int main(int argc,
         // Set log tagging
         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
 
-        // set evas backend type
-        if (!getenv("ELM_ENGINE")) {
-            if (!setenv("ELM_ENGINE", "gl", 1)) {
-                LogDebug("Enable backend");
-            }
-        } else {
-            LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
-        }
-
-    #ifndef TIZEN_PUBLIC
-        setenv("COREGL_FASTPATH", "1", 1);
-    #endif
-        setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
-        setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
-        setenv("ELM_IMAGE_CACHE", "0", 1);
+        // Set environment variables
+        set_env();
 
-        // This code is to fork a web process without exec.
-        std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
+        if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d"))
+        {
+            LogInfo("Entered dummy process mode");
+            sprintf(argv[0], "%s                                              ",
+                    DUMMY_PROCESS_PATH);
 
-        if (!tizenId.empty()) {
-            LogDebug("Launching by fork mode");
-            // Language env setup
+            LogInfo("Prepare ewk_context");
             appcore_set_i18n("wrt-client", NULL);
             ewk_init();
             ewk_set_arguments(argc, argv);
             setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
-            s_ewk_context = ewk_context_new_with_injected_bundle_path(
-                    BUNDLE_PATH);
+            s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
+
+            int client_fd = __connect_process_pool_server();
+
+            if (client_fd == -1)
+            {
+                LogInfo("Connecting process_pool_server was failed!");
+                exit(-1);
+            }
+
+            LogInfo("Prepare window_data");
+            LogInfo("elm_init()");
+            elm_init(argc, argv);
+            LogInfo("WindowData()");
+            s_preparedWindowData = new WindowData(static_cast<unsigned long>(getpid()));
 
-            // plugin init
-            PluginModuleSupport::init(s_ewk_context, tizenId);
+            ecore_main_fd_handler_add(client_fd, ECORE_FD_READ, proces_pool_fd_handler, NULL, NULL, NULL);
+            ecore_main_fd_handler_add(client_fd, ECORE_FD_ERROR, proces_pool_fd_handler, NULL, NULL, NULL);
+
+            setpriority(PRIO_PROCESS, 0, 0);
+
+            LogDebug("ecore_main_loop_begin()");
+            ecore_main_loop_begin();
+            LogDebug("ecore_main_loop_begin()_end");
+
+            std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
+            PluginModuleSupport::init(s_preparedEwkContext, tizenId);
+
+        }
+        else
+        {
+            // This code is to fork a web process without exec.
+            std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
+
+            if (!tizenId.empty())
+            {
+                LogDebug("Launching by fork mode");
+                // Language env setup
+                appcore_set_i18n("wrt-client", NULL);
+                ewk_init();
+                ewk_set_arguments(argc, argv);
+                setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
+                s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(
+                        BUNDLE_PATH);
+
+                // plugin init
+                PluginModuleSupport::init(s_preparedEwkContext, tizenId);
+            }
         }
 
         // Output on stdout will be flushed after every newline character,
@@ -751,7 +876,7 @@ int main(int argc,
         // the output may not be flushed).
         setlinebuf(stdout);
 
-        WrtClient app(argc, argv);
+        WrtClient app(app_argc, app_argv);
 
         ADD_PROFILING_POINT("Before appExec", "point");
         int ret = app.Exec();
index 33aa5b6..9d78b15 100644 (file)
@@ -51,6 +51,7 @@ ADD_EXECUTABLE( ${WRT_LAUNCH_PAD_NAME}
     src/simple_util.c
     launchpad_src/launchpad.c
     launchpad_src/util_x.c
+    src/process_pool.c
 )
 
 #link libraries
@@ -14,6 +14,9 @@
  *    limitations under the License.
  */
 
+#ifndef __ACCESS_CONTROL_H_
+#define __ACCESS_CONTROL_H_
+
 #ifdef DAC_ACTIVATE
 
 #include <privilege-control.h>
@@ -37,3 +40,5 @@ static inline int __set_access(const char* pkg_name,
 
 #endif
 
+#endif //__ACCESS_CONTROL_H_
+
similarity index 90%
rename from src/wrt-launchpad-daemon/launchpad_src/config.h
rename to src/wrt-launchpad-daemon/include/config.h
index a177ff5..dd2b4c5 100644 (file)
@@ -14,6 +14,9 @@
  *    limitations under the License.
  */
 
+#ifndef __LAUNCHPAD_CONFIG_H_
+#define __LAUNCHPAD_CONFIG_H_
+
 #define LAUNCHPAD_LOG
 #define DAC_ACTIVATE
 #define PRELOAD_ACTIVATE
@@ -22,3 +25,4 @@
 /*#define HEAPDGB_ACTIVATE*/
 /*#define PERF_ACTIVATE*/
 
+#endif // __LAUNCHPAD_CONFIG_H_
\ No newline at end of file
similarity index 94%
rename from src/wrt-launchpad-daemon/launchpad_src/gl.h
rename to src/wrt-launchpad-daemon/include/gl.h
index 47ac8e0..0c26111 100644 (file)
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
  */
+#ifndef __GL_H_
+#define __GL_H_
 
 #ifdef GL_ACTIVATE
-
 #define USE_ENGINE(engine) setenv("ELM_ENGINE", engine, 1);
-
 #else
-
 #define USE_ENGINE(engine)
-
 #endif
 
+#endif //__GL_H_
\ No newline at end of file
diff --git a/src/wrt-launchpad-daemon/include/launchpad_util.h b/src/wrt-launchpad-daemon/include/launchpad_util.h
new file mode 100644 (file)
index 0000000..8d61c46
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    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.
+ */
+/**
+ * @file    launchpad_util.h
+ * @author  Tae-Jeong Lee (taejeong.lee@samsung.com)
+ * @version 0.1
+ * @brief   Api library to support launchpad operation.
+ */
+
+#ifndef __LAUNCHPAD_UTIL_H_
+#define __LAUNCHPAD_UTIL_H_
+
+#include <aul.h>
+#include <bundle.h>
+#include <privilege-control.h>
+#include <sys/prctl.h>
+
+#include "config.h"
+#include "gl.h"
+#include "app_sock.h"
+#include "menu_db_util.h"
+#include "simple_util.h"
+#include "access_control.h"
+
+#define _static_ static inline
+#define WRT_AUL_PR_NAME 16
+#define PKG_ID_LENGTH   11
+#define SDK_CODE_COVERAGE "CODE_COVERAGE"
+#define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
+#define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
+#define PATH_APP_ROOT "/opt/usr/apps"
+#define PATH_DATA "/data"
+
+// Prototype
+_static_ char** __create_argc_argv(bundle * kb, int *margc);
+_static_ void   __set_sdk_env(app_info_from_db* menu_info, char* str);
+_static_ int    __parser(const char *arg, char *out, int out_size);
+_static_ void   __modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd);
+_static_ void   __set_oom();
+_static_ void   __set_env(app_info_from_db * menu_info, bundle * kb);
+_static_ int    __wrt_prepare_exec(const char *pkg_name, const char *app_path, app_info_from_db * menu_info, bundle * kb);
+_static_ void   __wrt_launchpad_main_loop(app_pkt_t* pkt, char* out_app_path, int* out_argc, char ***out_argv);
+
+// Implementation
+
+_static_ char** __create_argc_argv(bundle * kb, int *margc)
+{
+    char **argv;
+    int argc;
+
+    argc = bundle_export_to_argv(kb, &argv);
+
+    *margc = argc;
+    return argv;
+}
+
+_static_ void __set_sdk_env(app_info_from_db* menu_info, char* str)
+{
+    char buf[MAX_LOCAL_BUFSZ];
+    int ret;
+
+    _D("key : %s / value : %s", AUL_K_SDK, str);
+    /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
+    /* GCOV_PREFIX contains the prefix to add to the absolute paths in the
+     *object file. */
+    /*         Prefix can be absolute, or relative. The default is no prefix.
+     * */
+    /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
+    /*         to stripoff the hardwired absolute paths. Default value is 0. */
+    if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
+        snprintf(buf,
+                 MAX_LOCAL_BUFSZ,
+                 PATH_APP_ROOT "/%s"PATH_DATA,
+                 _get_pkgname(menu_info));
+        ret = setenv("GCOV_PREFIX", buf, 1);
+        _D("GCOV_PREFIX : %d", ret);
+        ret = setenv("GCOV_PREFIX_STRIP", "4096", 1);
+        _D("GCOV_PREFIX_STRIP : %d", ret);
+    } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
+        ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
+        _D("LD_PRELOAD : %d", ret);
+    }
+}
+
+
+/*
+ * Parsing original app path to retrieve default bundle
+ *
+ * -1 : Invalid sequence
+ * -2 : Buffer overflow
+ *
+ */
+_static_ int __parser(const char *arg, char *out, int out_size)
+{
+    register int i;
+    int state = 1;
+    char *start_out = out;
+
+    if (arg == NULL || out == NULL) {
+        /* Handles null buffer*/
+        return 0;
+    }
+
+    for (i = 0; out_size > 1; i++) {
+        switch (state) {
+        case 1:
+            switch (arg[i]) {
+            case ' ':
+            case '\t':
+                state = 5;
+                break;
+            case '\0':
+                state = 7;
+                break;
+            case '\"':
+                state = 2;
+                break;
+            case '\\':
+                state = 4;
+                break;
+            default:
+                *out = arg[i];
+                out++;
+                out_size--;
+                break;
+            }
+            break;
+        case 2:         /* escape start*/
+            switch (arg[i]) {
+            case '\0':
+                state = 6;
+                break;
+            case '\"':
+                state = 1;
+                break;
+            default:
+                *out = arg[i];
+                out++;
+                out_size--;
+                break;
+            }
+            break;
+        case 4:         /* character escape*/
+            if (arg[i] == '\0') {
+                state = 6;
+            } else {
+                *out = arg[i];
+                out++;
+                out_size--;
+                state = 1;
+            }
+            break;
+        case 5:         /* token*/
+            if (out != start_out) {
+                *out = '\0';
+                out_size--;
+                return i;
+            }
+            i--;
+            state = 1;
+            break;
+        case 6:
+            return -1;                  /* error*/
+        case 7:         /* terminate*/
+            *out = '\0';
+            out_size--;
+            return 0;
+        default:
+            state = 6;
+            break;              /* error*/
+        }
+    }
+
+    if (out_size == 1) {
+        *out = '\0';
+    }
+    /* Buffer overflow*/
+    return -2;
+}
+
+
+_static_ void __modify_bundle(bundle * kb, int caller_pid,
+                              app_info_from_db * menu_info, int cmd)
+{
+    // warning: unused parameter
+    caller_pid = caller_pid;
+
+    bundle_del(kb, AUL_K_PKG_NAME);
+    bundle_del(kb, AUL_K_EXEC);
+    bundle_del(kb, AUL_K_PACKAGETYPE);
+    bundle_del(kb, AUL_K_HWACC);
+
+    /* Parse app_path to retrieve default bundle*/
+    if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN || cmd ==
+        APP_RESUME)
+    {
+        char *ptr;
+        char exe[MAX_PATH_LEN];
+        int flag;
+
+        ptr = _get_original_app_path(menu_info);
+
+        flag = __parser(ptr, exe, sizeof(exe));
+        if (flag > 0) {
+            char key[256];
+            char value[256];
+
+            ptr += flag;
+            _D("parsing app_path: EXEC - %s\n", exe);
+
+            do {
+                flag = __parser(ptr, key, sizeof(key));
+                if (flag <= 0) {
+                    break;
+                }
+                ptr += flag;
+
+                flag = __parser(ptr, value, sizeof(value));
+                if (flag < 0) {
+                    break;
+                }
+                ptr += flag;
+
+                /*bundle_del(kb, key);*/
+                bundle_add(kb, key, value);
+            } while (flag > 0);
+        } else if (flag == 0) {
+            _D("parsing app_path: No arguments\n");
+        } else {
+            _D("parsing app_path: Invalid argument\n");
+        }
+    }
+}
+
+
+_static_ void __set_oom()
+{
+    char buf[MAX_LOCAL_BUFSZ];
+    FILE *fp;
+
+    /* we should reset oomadj value as default because child
+     * inherits from parent oom_adj*/
+    snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid());
+    fp = fopen(buf, "w");
+    if (fp == NULL) {
+        return;
+    }
+    fprintf(fp, "%d", -16);
+    fclose(fp);
+}
+
+_static_ void __set_env(app_info_from_db * menu_info, bundle * kb)
+{
+    const char *str;
+    const char **str_array;
+    int len;
+    int i;
+
+    setenv("PKG_NAME", _get_pkgname(menu_info), 1);
+
+    USE_ENGINE("gl")
+
+    str = bundle_get_val(kb, AUL_K_STARTTIME);
+    if (str != NULL) {
+        setenv("APP_START_TIME", str, 1);
+    }
+
+    if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
+        str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
+        if (str_array != NULL) {
+            for (i = 0; i < len; i++) {
+                _D("index : [%d]", i);
+                __set_sdk_env(menu_info, (char *)str_array[i]);
+            }
+        }
+    } else {
+        str = bundle_get_val(kb, AUL_K_SDK);
+        if (str != NULL) {
+            __set_sdk_env(menu_info, (char *)str);
+        }
+    }
+    if (menu_info->hwacc != NULL) {
+        setenv("HWACC", menu_info->hwacc, 1);
+    }
+}
+
+_static_ int __wrt_prepare_exec(const char *pkg_name,
+                            const char *app_path, app_info_from_db * menu_info,
+                            bundle * kb)
+{
+    const char *file_name;
+    char process_name[WRT_AUL_PR_NAME];
+
+    /* SET PRIVILEGES*/
+    char pkg_id[PKG_ID_LENGTH];
+    memset(pkg_id, '\0', PKG_ID_LENGTH);
+    snprintf(pkg_id, PKG_ID_LENGTH, "%s", pkg_name);
+
+    if (__set_access(pkg_id, menu_info->pkg_type, app_path) < 0) {
+        _D("fail to set privileges - check your package's credential\n");
+        return -1;
+    }
+
+    /* SET PROCESS NAME*/
+    if (app_path == NULL) {
+        _D("app_path should not be NULL - check menu db");
+        return -1;
+    }
+    file_name = strrchr(app_path, '/') + 1;
+    if (file_name == NULL) {
+        _D("can't locate file name to execute");
+        return -1;
+    }
+    memset(process_name, '\0', WRT_AUL_PR_NAME);
+    snprintf(process_name, WRT_AUL_PR_NAME, "%s", file_name);
+    prctl(PR_SET_NAME, process_name);
+
+    /* SET ENVIROMENT*/
+    __set_env(menu_info, kb);
+
+    return 0;
+}
+
+_static_ void __wrt_launchpad_main_loop(app_pkt_t* pkt, char* out_app_path, int* out_argc, char ***out_argv)
+
+{
+    bundle *kb = NULL;
+    app_info_from_db *menu_info = NULL;
+
+    const char *pkg_name = NULL;
+    const char *app_path = NULL;
+    struct ucred cr;
+
+    kb = bundle_decode(pkt->data, pkt->len);
+    if (!kb) {
+        _E("bundle decode error");
+        exit(-1);
+    }
+
+    pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
+    _D("pkg name : %s", pkg_name);
+
+    menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
+    if (menu_info == NULL) {
+        _D("such pkg no found");
+        exit(-1);
+    }
+
+    app_path = _get_app_path(menu_info);
+
+    if (app_path == NULL) {
+        _E("app_path is NULL");
+        exit(-1);
+    }
+
+    if (app_path[0] != '/') {
+        _E("app_path is not absolute path");
+        exit(-1);
+    }
+
+    __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
+    pkg_name = _get_pkgname(menu_info);
+    _D("pkg name : %s", pkg_name);
+
+    __wrt_prepare_exec(pkg_name, app_path, menu_info, kb);
+
+    if (out_app_path != NULL && out_argc != NULL && out_argv != NULL)
+    {
+        int i;
+
+        sprintf(out_app_path, "%s", app_path);
+
+        *out_argv = __create_argc_argv(kb, out_argc);
+        (*out_argv)[0] = out_app_path;
+
+        for (i = 0; i < *out_argc; i++)
+        {
+            _D("input argument %d : %s##", i, (*out_argv)[i]);
+        }
+    }
+    else
+    {
+        exit(-1);
+    }
+
+
+#if 0 // intentional
+    if (menu_info != NULL) {
+        _free_app_info_from_db(menu_info);
+    }
+
+    if (kb != NULL) {
+        bundle_free(kb);
+    }
+#endif
+}
+
+#endif // __LAUNCHPAD_UTIL_H_
index 7f8c8c5..c4d5d07 100644 (file)
@@ -14,6 +14,9 @@
  *    limitations under the License.
  */
 
+#ifndef __MENU_DB_UTIL_H_
+#define __MENU_DB_UTIL_H_
+
 #include <ail.h>
 #include <string.h>
 #include "simple_util.h"
@@ -75,7 +78,7 @@ static inline char *_get_app_path(app_info_from_db *menu_info)
         free(menu_info->app_path);
         menu_info->app_path = NULL;
     } else if (path_len > 0) {
-        char *tmp_app_path = malloc(sizeof(char) * (path_len + 1));
+        char *tmp_app_path = (char *)malloc(sizeof(char) * (path_len + 1));
         if (tmp_app_path == NULL) {
             return NULL;
         }
@@ -122,7 +125,7 @@ static inline app_info_from_db *_get_app_info_from_db_by_pkgname(
     ail_error_e ret;
     char *str = NULL;
 
-    menu_info = calloc(1, sizeof(app_info_from_db));
+    menu_info = (app_info_from_db *)calloc(1, sizeof(app_info_from_db));
     if (menu_info == NULL) {
         return NULL;
     }
@@ -193,7 +196,7 @@ static inline app_info_from_db *_get_app_info_from_db_by_apppath(
         return NULL;
     }
 
-    menu_info = calloc(1, sizeof(app_info_from_db));
+    menu_info = (app_info_from_db *)calloc(1, sizeof(app_info_from_db));
     if (menu_info == NULL) {
         return NULL;
     }
@@ -233,3 +236,30 @@ static inline app_info_from_db *_get_app_info_from_db_by_apppath(
     return menu_info;
 }
 
+
+static inline app_info_from_db *_get_app_info_from_bundle_by_pkgname(
+    const char *pkgname, bundle *kb)
+{
+    app_info_from_db *menu_info;
+
+    menu_info = (app_info_from_db*)calloc(1, sizeof(app_info_from_db));
+    if (menu_info == NULL) {
+        return NULL;
+    }
+
+    menu_info->pkg_name = strdup(pkgname);
+    menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
+    if (menu_info->app_path != NULL) {
+        menu_info->original_app_path = strdup(menu_info->app_path);
+    }
+    menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
+    menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
+
+    if (!_get_app_path(menu_info)) {
+        _free_app_info_from_db(menu_info);
+        return NULL;
+    }
+
+    return menu_info;
+}
+#endif //__MENU_DB_UTIL_H_
\ No newline at end of file
diff --git a/src/wrt-launchpad-daemon/include/process_pool.h b/src/wrt-launchpad-daemon/include/process_pool.h
new file mode 100644 (file)
index 0000000..4a1ed38
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    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.
+ */
+/**
+ * @file    process_pool.h
+ * @author  Tae-Jeong Lee (taejeong.lee@samsung.com)
+ * @version 0.1
+ * @brief   process pool socket api prototypes
+ */
+
+#ifndef __PROCESS_POOL_H_
+#define __PROCESS_POOL_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif //__cplusplus
+
+#include <app_sock.h>
+
+int  __create_process_pool_server();
+int  __connect_process_pool_server();
+int  __accept_dummy_process(int server_fd, int* out_client_fd, int* out_client_pid);
+void __refuse_dummy_process(int server_fd);
+int  __send_pkt_raw_data(int client_fd, app_pkt_t* pkt);
+
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+#endif //__PROCESS_POOL_H_
+
index 415519e..1dcab54 100644 (file)
@@ -30,6 +30,8 @@
 #include <sys/wait.h>
 #include <poll.h>
 #include <sys/prctl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <malloc.h>
 
 #include "app_sock.h"
 #include <app-checker.h>
 #include <sqlite3.h>
 
+#include "process_pool.h"
+#include "launchpad_util.h"
+
 #define _static_ static inline
-#define POLLFD_MAX 1
-#define SQLITE_FLUSH_MAX        (1048576)       /* (1024*1024) */
-#define AUL_POLL_CNT            15
-#define AUL_PR_NAME                     16
-#define PKG_ID_LENGTH   11
-#define PATH_APP_ROOT "/opt/usr/apps"
-#define PATH_DATA "/data"
-#define SDK_CODE_COVERAGE "CODE_COVERAGE"
-#define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
-#define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
+#define SQLITE_FLUSH_MAX    (1048576)       /* (1024*1024) */
+#define AUL_POLL_CNT        15
+#define AUL_PR_NAME         16
+#define PKG_ID_LENGTH       11
+
+#define EXEC_DUMMY_EXPIRED 5
+#define DIFF(a,b) (((a)>(b))?(a)-(b):(b)-(a))
+#define WRT_CLIENT_PATH "/usr/bin/wrt-client"
+#define LOWEST_PRIO 20
+#define DUMMY_NONE 0
 
 static char *launchpad_cmdline;
 static int initialized = 0;
+static int dummy_process_pid    = DUMMY_NONE;
+static int dummy_process_fd     = -1;
+static int last_dummy_exec_time = 0;
+static int process_pool_disable = 0;
 
-_static_ void __set_oom();
-_static_ void __set_env(app_info_from_db * menu_info, bundle * kb);
 _static_ int __prepare_exec(const char *pkg_name,
                             const char *app_path, app_info_from_db * menu_info,
                             bundle * kb);
@@ -77,9 +84,7 @@ _static_ int __fake_launch_app(int cmd, int pid, bundle * kb);
 _static_ char **__create_argc_argv(bundle * kb, int *margc);
 _static_ int __normal_fork_exec(int argc, char **argv);
 _static_ void __real_launch(const char *app_path, bundle * kb);
-static inline int __parser(const char *arg, char *out, int out_size);
-_static_ void __modify_bundle(bundle * kb, int caller_pid,
-                              app_info_from_db * menu_info, int cmd);
+_static_ int __dummy_launch(int dummy_client_fd, app_pkt_t* pkt);
 _static_ int __child_raise_win_by_x(int pid, void *priv);
 _static_ int __raise_win_by_x(int pid);
 _static_ int __send_to_sigkill(int pid);
@@ -87,91 +92,13 @@ _static_ int __term_app(int pid);
 _static_ int __resume_app(int pid);
 _static_ void __real_send(int clifd, int ret);
 _static_ void __send_result_to_caller(int clifd, int ret);
-_static_ void __launchpad_main_loop(int main_fd);
+_static_ void __launchpad_exec_dummy(int main_fd, int pool_fd, int client_fd);
+_static_ void __launchpad_main_loop(int main_fd, int pool_fd);
 _static_ int __launchpad_pre_init(int argc, char **argv);
 _static_ int __launchpad_post_init();
 
 extern ail_error_e ail_db_close(void);
 
-_static_ void __set_oom()
-{
-    char buf[MAX_LOCAL_BUFSZ];
-    FILE *fp;
-
-    /* we should reset oomadj value as default because child
-     * inherits from parent oom_adj*/
-    snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid());
-    fp = fopen(buf, "w");
-    if (fp == NULL) {
-        return;
-    }
-    fprintf(fp, "%d", -16);
-    fclose(fp);
-}
-
-_static_ void __set_sdk_env(app_info_from_db* menu_info, char* str)
-{
-    char buf[MAX_LOCAL_BUFSZ];
-    int ret;
-
-    _D("key : %s / value : %s", AUL_K_SDK, str);
-    /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
-    /* GCOV_PREFIX contains the prefix to add to the absolute paths in the
-     *object file. */
-    /*         Prefix can be absolute, or relative. The default is no prefix.
-     * */
-    /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
-    /*         to stripoff the hardwired absolute paths. Default value is 0. */
-    if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
-        snprintf(buf,
-                 MAX_LOCAL_BUFSZ,
-                 PATH_APP_ROOT "/%s"PATH_DATA,
-                 _get_pkgname(menu_info));
-        ret = setenv("GCOV_PREFIX", buf, 1);
-        _D("GCOV_PREFIX : %d", ret);
-        ret = setenv("GCOV_PREFIX_STRIP", "4096", 1);
-        _D("GCOV_PREFIX_STRIP : %d", ret);
-    } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
-        ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
-        _D("LD_PRELOAD : %d", ret);
-    }
-}
-
-_static_ void __set_env(app_info_from_db * menu_info, bundle * kb)
-{
-    const char *str;
-
-    setenv("PKG_NAME", _get_pkgname(menu_info), 1);
-
-    USE_ENGINE("gl")
-
-    str = bundle_get_val(kb, AUL_K_STARTTIME);
-    if (str != NULL) {
-        setenv("APP_START_TIME", str, 1);
-    }
-
-    if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
-        int len;
-        const char **str_array;
-        str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
-        if (str_array != NULL) {
-            int i;
-            for (i = 0; i < len; i++) {
-                _D("index : [%d]", i);
-                __set_sdk_env(menu_info, (char *)str_array[i]);
-            }
-        }
-    } else {
-        str = bundle_get_val(kb, AUL_K_SDK);
-        if (str != NULL) {
-            __set_sdk_env(menu_info, (char *)str);
-        }
-    }
-    if (menu_info->hwacc != NULL) {
-        setenv("HWACC", menu_info->hwacc, 1);
-    }
-}
-
 _static_ int __prepare_exec(const char *pkg_name,
                             const char *app_path, app_info_from_db * menu_info,
                             bundle * kb)
@@ -198,6 +125,7 @@ _static_ int __prepare_exec(const char *pkg_name,
         _D("fail to set privileges - check your package's credential\n");
         return -1;
     }
+
     /* SET DUMPABLE - for coredump*/
     prctl(PR_SET_DUMPABLE, 1);
 
@@ -235,17 +163,6 @@ _static_ int __fake_launch_app(int cmd, int pid, bundle * kb)
     return ret;
 }
 
-_static_ char **__create_argc_argv(bundle * kb, int *margc)
-{
-    char **argv;
-    int argc;
-
-    argc = bundle_export_to_argv(kb, &argv);
-
-    *margc = argc;
-    return argv;
-}
-
 _static_ int __normal_fork_exec(int argc, char **argv)
 {
     _D("start real fork and exec\n");
@@ -299,152 +216,9 @@ _static_ void __real_launch(const char *app_path, bundle * kb)
     __normal_fork_exec(app_argc, app_argv);
 }
 
-/*
- * Parsing original app path to retrieve default bundle
- *
- * -1 : Invalid sequence
- * -2 : Buffer overflow
- *
- */
-static inline int __parser(const char *arg, char *out, int out_size)
-{
-    register int i;
-    int state = 1;
-    char *start_out = out;
-
-    if (arg == NULL || out == NULL) {
-        /* Handles null buffer*/
-        return 0;
-    }
-
-    for (i = 0; out_size > 1; i++) {
-        switch (state) {
-        case 1:
-            switch (arg[i]) {
-            case ' ':
-            case '\t':
-                state = 5;
-                break;
-            case '\0':
-                state = 7;
-                break;
-            case '\"':
-                state = 2;
-                break;
-            case '\\':
-                state = 4;
-                break;
-            default:
-                *out = arg[i];
-                out++;
-                out_size--;
-                break;
-            }
-            break;
-        case 2:         /* escape start*/
-            switch (arg[i]) {
-            case '\0':
-                state = 6;
-                break;
-            case '\"':
-                state = 1;
-                break;
-            default:
-                *out = arg[i];
-                out++;
-                out_size--;
-                break;
-            }
-            break;
-        case 4:         /* character escape*/
-            if (arg[i] == '\0') {
-                state = 6;
-            } else {
-                *out = arg[i];
-                out++;
-                out_size--;
-                state = 1;
-            }
-            break;
-        case 5:         /* token*/
-            if (out != start_out) {
-                *out = '\0';
-                out_size--;
-                return i;
-            }
-            i--;
-            state = 1;
-            break;
-        case 6:
-            return -1;                  /* error*/
-        case 7:         /* terminate*/
-            *out = '\0';
-            out_size--;
-            return 0;
-        default:
-            state = 6;
-            break;              /* error*/
-        }
-    }
-
-    if (out_size == 1) {
-        *out = '\0';
-    }
-    /* Buffer overflow*/
-    return -2;
-}
-
-_static_ void __modify_bundle(bundle * kb, int caller_pid,
-                              app_info_from_db * menu_info, int cmd)
+_static_ int __dummy_launch(int dummy_client_fd, app_pkt_t* pkt)
 {
-    // warning: unused parameter
-    (void)caller_pid;
-
-    bundle_del(kb, AUL_K_PKG_NAME);
-    bundle_del(kb, AUL_K_EXEC);
-    bundle_del(kb, AUL_K_PACKAGETYPE);
-    bundle_del(kb, AUL_K_HWACC);
-
-    /* Parse app_path to retrieve default bundle*/
-    if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN || cmd ==
-        APP_RESUME)
-    {
-        char *ptr;
-        char exe[MAX_PATH_LEN];
-        int flag;
-
-        ptr = _get_original_app_path(menu_info);
-
-        flag = __parser(ptr, exe, sizeof(exe));
-        if (flag > 0) {
-            char key[256];
-            char value[256];
-
-            ptr += flag;
-            _D("parsing app_path: EXEC - %s\n", exe);
-
-            do {
-                flag = __parser(ptr, key, sizeof(key));
-                if (flag <= 0) {
-                    break;
-                }
-                ptr += flag;
-
-                flag = __parser(ptr, value, sizeof(value));
-                if (flag < 0) {
-                    break;
-                }
-                ptr += flag;
-
-                /*bundle_del(kb, key);*/
-                bundle_add(kb, key, value);
-            } while (flag > 0);
-        } else if (flag == 0) {
-            _D("parsing app_path: No arguments\n");
-        } else {
-            _D("parsing app_path: Invalid argument\n");
-        }
-    }
+    return __send_pkt_raw_data(dummy_client_fd, pkt);
 }
 
 _static_ int __child_raise_win_by_x(int pid, void *priv)
@@ -646,33 +420,84 @@ _static_ void __send_result_to_caller(int clifd, int ret)
     return;
 }
 
-static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
-    const char *pkgname, bundle *kb)
+_static_ void __launchpad_exec_dummy(int main_fd, int pool_fd, int client_fd)
 {
-    app_info_from_db *menu_info;
+    int pid;
 
-    menu_info = calloc(1, sizeof(app_info_from_db));
-    if (menu_info == NULL) {
-        return NULL;
-    }
+    last_dummy_exec_time = time(NULL);
 
-    menu_info->pkg_name = strdup(pkgname);
-    menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
-    if (menu_info->app_path != NULL) {
-        menu_info->original_app_path = strdup(menu_info->app_path);
-    }
-    menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
-    menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
+    pid = fork();
 
-    if (!_get_app_path(menu_info)) {
-        _free_app_info_from_db(menu_info);
-        return NULL;
-    }
+    if (pid == 0) // child
+    {
+        setpriority(PRIO_PROCESS, 0, LOWEST_PRIO);
+        _D("Launch dummy process...");
+
+        //temp - this requires some optimization.
+        sleep(1);
+        _D("sleeping 1sec...");
+
+        /* Set new session ID & new process group ID*/
+        /* In linux, child can set new session ID without check permission */
+        /* TODO : should be add to check permission in the kernel*/
+        setsid();
+
+        /* SET OOM*/
+        __set_oom();
+
+
+        if (main_fd != -1)
+        {
+            close(main_fd);
+        }
+
+        if (pool_fd != -1)
+        {
+            close(pool_fd);
+        }
+
+        if (client_fd != -1)
+        {
+            close(client_fd);
+        }
+
+        __signal_unset_sigchld();
+        __signal_fini();
+
+        /* SET DUMPABLE - for coredump*/
+        prctl(PR_SET_DUMPABLE, 1);
+
+        {
+            void *handle = NULL;
+            int (*dl_main) (int, char **);
+
+            handle = dlopen(WRT_CLIENT_PATH, RTLD_NOW | RTLD_GLOBAL);
+
+            if (handle == NULL)
+            {
+                _E("dlopen failed.");
+                exit(-1);
+            }
+
+            dl_main = dlsym(handle, "main");
+
+            sprintf(g_argv[1], "%s", "-d");
+
+            if (dl_main != NULL)
+            {
+                dl_main(g_argc, g_argv);
+            }
+            else
+            {
+                _E("dlsym not founded. bad preloaded app - check fpie pie");
+            }
 
-    return menu_info;
+            exit(0);
+        }
+    }
 }
 
-_static_ void __launchpad_main_loop(int main_fd)
+_static_ void __launchpad_main_loop(int main_fd, int pool_fd)
 {
     bundle *kb = NULL;
     app_pkt_t *pkt = NULL;
@@ -726,9 +551,33 @@ _static_ void __launchpad_main_loop(int main_fd)
 
     PERF("get package information & modify bundle done");
 
+    if (dummy_process_pid != DUMMY_NONE)
+    {
+        snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, dummy_process_pid);
+        unlink(sock_path);
+
+        __dummy_launch(dummy_process_fd, pkt);
+
+        pid = dummy_process_pid;
+        is_real_launch = 1;
+        close(dummy_process_fd);
+
+        dummy_process_pid = DUMMY_NONE;
+        dummy_process_fd  = -1;
+
+        /* Temporary log: launch time checking */
+        LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
+
+        __launchpad_exec_dummy(main_fd, pool_fd, clifd);
+
+        _D("==> dummy launch pid : %d %s\n", pid, app_path);
+    }
+    else
     {
         pid = fork();
-        if (pid == 0) {
+
+        if (pid == 0)
+        {
             PERF("fork done");
             _E("lock up test log(no error) : fork done");
 
@@ -846,38 +695,143 @@ _static_ int __launchpad_post_init()
 
 int main(int argc, char **argv)
 {
-    int main_fd;
+    enum {
+        LAUNCH_PAD = 0,
+        POOL_SERVER,
+        DUMMY_PROCESS,
+        POLLFD_MAX
+    };
+
+    int main_fd = -1, pool_fd = -1;
     struct pollfd pfds[POLLFD_MAX];
-    int i;
+
+    memset(pfds, 0x00, sizeof(pfds));
+
+    // process pool feature disable
+    if (getenv("WRT_PROCESS_POOL_DISABLE"))
+    {
+        process_pool_disable = 1;
+    }
 
     /* init without concerning X & EFL*/
     main_fd = __launchpad_pre_init(argc, argv);
-    if (main_fd < 0) {
+
+    if (main_fd < 0)
+    {
         _E("launchpad pre init failed");
-        exit(-1);
+        goto exit_main;
+    }
+
+    pfds[LAUNCH_PAD].fd      = main_fd;
+    pfds[LAUNCH_PAD].events  = POLLIN;
+    pfds[LAUNCH_PAD].revents = 0;
+
+    pool_fd = __create_process_pool_server();
+
+    if (pool_fd == -1)
+    {
+        _E("Error creationg pool server!");
+        goto exit_main;
     }
 
-    pfds[0].fd = main_fd;
-    pfds[0].events = POLLIN;
-    pfds[0].revents = 0;
+    pfds[POOL_SERVER].fd      = pool_fd;
+    pfds[POOL_SERVER].events  = POLLIN;
+    pfds[POOL_SERVER].revents = 0;
 
-    while (1) {
-        if (poll(pfds, POLLFD_MAX, -1) < 0) {
+    while (1)
+    {
+        if (dummy_process_pid == DUMMY_NONE)
+        {
+            pfds[DUMMY_PROCESS].fd      = -1;
+            pfds[DUMMY_PROCESS].events  = 0;
+            pfds[DUMMY_PROCESS].revents = 0;
+
+            if ( !process_pool_disable &&
+                 DIFF(last_dummy_exec_time, time(NULL)) > EXEC_DUMMY_EXPIRED)
+            {
+                __launchpad_exec_dummy(main_fd, pool_fd, -1);
+            }
+        }
+
+        if (poll(pfds, POLLFD_MAX, -1) < 0)
+        {
             continue;
         }
 
+        _D("pfds[LAUNCH_PAD].revents    : 0x%x", pfds[LAUNCH_PAD].revents) ;
+        _D("pfds[POOL_SERVER].revents   : 0x%x", pfds[POOL_SERVER].revents) ;
+        _D("pfds[DUMMY_PROCESS].revents : 0x%x", pfds[DUMMY_PROCESS].revents) ;
+
         /* init with concerning X & EFL (because of booting
-         * sequence problem)*/
-        if (__launchpad_post_init() < 0) {
+        * sequence problem)*/
+        if (__launchpad_post_init() < 0)
+        {
             _E("launcpad post init failed");
-            exit(-1);
+            goto exit_main;
+        }
+
+        if ((pfds[LAUNCH_PAD].revents & POLLIN) != 0)
+        {
+            _D("pfds[LAUNCH_PAD].revents & POLLIN");
+            __launchpad_main_loop(pfds[LAUNCH_PAD].fd, pfds[POOL_SERVER].fd);
         }
 
-        for (i = 0; i < POLLFD_MAX; i++) {
-            if ((pfds[i].revents & POLLIN) != 0) {
-                __launchpad_main_loop(pfds[i].fd);
+        if ((pfds[POOL_SERVER].revents & POLLIN) != 0)
+        {
+            int server_fd, client_fd, client_pid;
+
+            server_fd = pfds[POOL_SERVER].fd;
+
+            _D("pfds[POOL_SERVER].revents & POLLIN");
+
+            if (dummy_process_pid == DUMMY_NONE)
+            {
+                __accept_dummy_process(server_fd, &client_fd, &client_pid);
+
+                dummy_process_pid = client_pid;
+                dummy_process_fd  = client_fd;
+
+                pfds[DUMMY_PROCESS].fd     = dummy_process_fd;
+                pfds[DUMMY_PROCESS].events = POLLIN|POLLHUP;
+                pfds[DUMMY_PROCESS].revents = 0;
+
+                _D("Dummy process was connected! (pid:%d)", dummy_process_pid);
+            }
+            else
+            {
+                __refuse_dummy_process(server_fd);
+
+                _E("Refused dummy process connection!");
             }
         }
+
+        if ((pfds[DUMMY_PROCESS].revents & (POLLHUP|POLLNVAL)) != 0)
+        {
+            _D("pfds[DUMMY_PROCESS].revents & (POLLHUP|POLLNVAL) (pid:%d)", dummy_process_pid);
+            close(pfds[DUMMY_PROCESS].fd);
+
+            dummy_process_pid = DUMMY_NONE;
+            dummy_process_fd = -1;
+
+            pfds[DUMMY_PROCESS].fd      = -1;
+            pfds[DUMMY_PROCESS].events  = 0;
+            pfds[DUMMY_PROCESS].revents = 0;
+        }
     }
+
+    return 0;
+
+    exit_main:
+    if (main_fd != -1)
+    {
+        close(main_fd);
+    }
+
+    if (pool_fd != -1)
+    {
+        close(pool_fd);
+    }
+
+    return -1;
 }
 
index 01635cd..5197b66 100644 (file)
@@ -1,2 +1,4 @@
 /usr/bin/wrt-client
-/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so
\ No newline at end of file
+/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so
+/usr/lib/wrt-plugins/w3c-widget-interface/libwrt-plugins-w3c-widget-interface.so
+/usr/lib/wrt-plugins/tizen-tizen/libwrt-plugins-tizen-tizen.so
index 26edf9f..9089610 100644 (file)
@@ -153,10 +153,11 @@ int __create_client_sock(int pid)
 {
     int fd = -1;
     struct sockaddr_un saddr;
-    memset(&saddr, 0, sizeof(saddr));
     int retry = 1;
     int ret = -1;
 
+    memset(&saddr, 0x00, sizeof(struct sockaddr_un));
+
     fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
     /*  support above version 2.6.27*/
     if (fd < 0) {
@@ -329,11 +330,11 @@ app_pkt_t *__app_recv_raw(int fd, int *clifd, struct ucred *cr)
 {
     int len;
     struct sockaddr_un aul_addr;
-    memset(&aul_addr, 0, sizeof(aul_addr));
     int sun_size;
     app_pkt_t *pkt = NULL;
     int cl = sizeof(struct ucred);
 
+    memset(&aul_addr, 0x00, sizeof(struct sockaddr_un));
     sun_size = sizeof(struct sockaddr_un);
 
     if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr,
diff --git a/src/wrt-launchpad-daemon/src/process_pool.c b/src/wrt-launchpad-daemon/src/process_pool.c
new file mode 100644 (file)
index 0000000..11debe1
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    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.
+ */
+/**
+ * @file    process_pool.c
+ * @author  Tae-Jeong Lee (taejeong.lee@samsung.com)
+ * @version 0.1
+ * @brief   process pool socket apis
+ */
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/un.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "process_pool.h"
+#include "simple_util.h"
+
+#define TMP_PATH "/tmp"
+#define PROCESS_POOL_SERVER "wrt_process_pool_server"
+#define MAX_PENDING_CONNECTIONS 10
+#define CONNECT_RETRY_TIME 100 * 1000
+#define CONNECT_RETRY_COUNT 3
+
+int __create_process_pool_server()
+{
+    struct sockaddr_un addr;
+    int fd = -1;
+
+    memset(&addr, 0x00, sizeof(struct sockaddr_un));
+
+    fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+
+    if (fd < 0)
+    {
+        _E("socket error");
+        goto err_create_process_pool_server;
+    }
+
+    addr.sun_family = AF_UNIX;
+    snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER);
+    unlink(addr.sun_path);
+
+    _D("bind to %s", addr.sun_path);
+    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+    {
+        _E("bind error");
+        goto err_create_process_pool_server;
+    }
+
+    _D("chmod to %s", addr.sun_path);
+    if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)
+    {
+        _E("chmod error");
+        goto err_create_process_pool_server;
+    }
+
+    _D("listen to %s", addr.sun_path);
+    if (listen(fd, MAX_PENDING_CONNECTIONS) == -1)
+    {
+        _E("listen error");
+        goto err_create_process_pool_server;
+    }
+
+    _D("__create_process_pool_server done : %d", fd);
+    return fd;
+
+
+err_create_process_pool_server:
+
+    if (fd != -1)
+    {
+        close(fd);
+    }
+
+    return -1;
+}
+
+
+int __connect_process_pool_server()
+{
+    struct sockaddr_un addr;
+    int fd = -1;
+    int retry = CONNECT_RETRY_COUNT;
+    int send_ret = -1;
+    int client_pid = getpid();
+
+    memset(&addr, 0x00, sizeof(struct sockaddr_un));
+
+    fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+
+    if (fd < 0)
+    {
+        _E("socket error");
+
+        goto err_connect_process_pool_server;
+    }
+
+    addr.sun_family = AF_UNIX;
+    snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER);
+
+
+    _D("connect to %s", addr.sun_path);
+    while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+    {
+        if (errno != ETIMEDOUT || retry <= 0)
+        {
+            _E("connect error : %d", errno);
+
+            goto err_connect_process_pool_server;
+        }
+
+        usleep(CONNECT_RETRY_TIME);
+        retry--;
+        _D("re-connect to %s (%d)", addr.sun_path, retry);
+    }
+
+    send_ret = send(fd, &client_pid, sizeof(client_pid), 0);
+    _D("send(%d) : %d", client_pid, send_ret);
+
+    if (send_ret == -1)
+    {
+        _E("send error");
+
+        goto err_connect_process_pool_server;
+    }
+
+    _D("__connect_process_pool_server done : %d", fd);
+    return fd;
+
+err_connect_process_pool_server:
+
+    if (fd != -1)
+    {
+        close(fd);
+    }
+
+    return -1;
+}
+
+
+int __accept_dummy_process(int server_fd, int* out_client_fd, int* out_client_pid)
+{
+    int client_fd = -1, client_pid = 0, recv_ret = 0;
+
+    if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL)
+    {
+        _E("arguments error!");
+
+        goto err__accept_dummy_process;
+    }
+
+    client_fd = accept(server_fd, NULL, NULL);
+
+    if (client_fd == -1)
+    {
+        _E("accept error!");
+
+        goto err__accept_dummy_process;
+    }
+
+    recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL);
+
+    if (recv_ret == -1)
+    {
+        _E("recv error!");
+
+        goto err__accept_dummy_process;
+    }
+
+    *out_client_fd = client_fd;
+    *out_client_pid = client_pid;
+
+    return *out_client_fd;
+
+err__accept_dummy_process:
+
+    if (client_fd != -1)
+    {
+        close(client_fd);
+    }
+
+    return -1;
+}
+
+void __refuse_dummy_process(int server_fd)
+{
+    int client_fd = -1;
+
+    if (server_fd == -1)
+    {
+        _E("arguments error!");
+
+        goto err__refuse_dummy_process;
+    }
+
+    client_fd = accept(server_fd, NULL, NULL);
+
+    if (client_fd == -1)
+    {
+        _E("accept error!");
+
+        goto err__refuse_dummy_process;
+    }
+
+    close(client_fd);
+    _D("refuse connection!");
+
+    return;
+
+err__refuse_dummy_process:
+
+    if (client_fd != -1)
+    {
+        close(client_fd);
+    }
+
+    return;
+}
+
+
+int __send_pkt_raw_data(int client_fd, app_pkt_t* pkt)
+{
+    int send_ret = 0;
+    int pkt_size = 0;
+
+    if (client_fd == -1 || pkt == NULL)
+    {
+        _E("arguments error!");
+
+        goto err__send_pkt_raw_data;
+    }
+
+    pkt_size = sizeof(pkt->cmd) + sizeof(pkt->len) + pkt->len;
+
+    send_ret = send(client_fd, pkt, pkt_size, 0);
+    _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size);
+
+    if (send_ret == -1)
+    {
+        _E("send error!");
+
+        goto err__send_pkt_raw_data;
+    }
+    else if (send_ret != pkt_size)
+    {
+        _E("send byte fail!");
+
+        goto err__send_pkt_raw_data;
+    }
+
+    return 0;
+
+err__send_pkt_raw_data:
+
+    return -1;
+}
\ No newline at end of file
diff --git a/wrt_env.sh b/wrt_env.sh
new file mode 100644 (file)
index 0000000..d09621f
--- /dev/null
@@ -0,0 +1,2 @@
+# This env is enabled in private ONLY
+#export WRT_PROCESS_POOL_DISABLE=ON