Handle 'mouse-event' attribute differently according to configuration of web-provider...
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_manifest_file.cpp
index 95b53c5..18ddf7e 100644 (file)
@@ -33,6 +33,8 @@
 #include <widget_install/job_widget_install.h>
 #include <widget_install/widget_install_errors.h>
 #include <widget_install/widget_install_context.h>
+#include <web_provider_livebox_info.h>
+#include <web_provider_plugin_info.h>
 #include <dpl/wrt-dao-ro/global_config.h>
 #include <dpl/log/log.h>
 #include <dpl/file_input.h>
@@ -105,15 +107,7 @@ TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
     m_context(inCont),
     writer(NULL)
 {
-    if (false == m_context.existingWidgetInfo.isExist) {
-        AddStep(&TaskManifestFile::stepCopyIconFiles);
-        AddStep(&TaskManifestFile::stepCreateExecFile);
-        AddStep(&TaskManifestFile::stepGenerateManifest);
-        AddStep(&TaskManifestFile::stepParseManifest);
-        AddStep(&TaskManifestFile::stepFinalize);
-
-        AddAbortStep(&TaskManifestFile::stepAbortParseManifest);
-    } else {
+    if (m_context.isUpdateMode) {
         // for widget update.
         AddStep(&TaskManifestFile::stepBackupIconFiles);
         AddStep(&TaskManifestFile::stepCopyIconFiles);
@@ -122,6 +116,14 @@ TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
         AddStep(&TaskManifestFile::stepUpdateFinalize);
 
         AddAbortStep(&TaskManifestFile::stepAbortIconFiles);
+    } else {
+        AddStep(&TaskManifestFile::stepCopyIconFiles);
+        AddStep(&TaskManifestFile::stepCreateExecFile);
+        AddStep(&TaskManifestFile::stepGenerateManifest);
+        AddStep(&TaskManifestFile::stepParseManifest);
+        AddStep(&TaskManifestFile::stepFinalize);
+
+        AddAbortStep(&TaskManifestFile::stepAbortParseManifest);
     }
 }
 
@@ -133,18 +135,62 @@ void TaskManifestFile::stepCreateExecFile()
     std::string exec = m_context.locations->getExecFile();
     std::string clientExeStr = GlobalConfig::GetWrtClientExec();
 
-    LogInfo("link -s " << clientExeStr << " " << exec);
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget
+    std::stringstream postfix;
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    std::string controlExec = exec;
+    controlExec.append(postfix.str());
 
     errno = 0;
-    if (symlink(clientExeStr.c_str(), exec.c_str()) !=  0)
+    if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0)
+    {
+        int error = errno;
+        if (error)
+            LogPedantic("Failed to make a symbolic name for a file "
+                    << "[" <<  DPL::GetErrnoString(error) << "]");
+        ThrowMsg(Exceptions::FileOperationFailed,
+                "Symbolic link creating is not done.");
+    }
+
+    // app-control widgets
+    unsigned int indexMax = 0;
+    FOREACH(it, m_context.widgetConfig.configInfo.appControlList) {
+        if (it->m_index > indexMax) {
+            indexMax = it->m_index;
+        }
+    }
+
+    for (std::size_t i = 1; i <= indexMax; ++i) {
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << i;
+        std::string controlExec = exec;
+        controlExec.append(postfix.str());
+        errno = 0;
+        if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                LogPedantic("Failed to make a symbolic name for a file "
+                    << "[" <<  DPL::GetErrnoString(error) << "]");
+            }
+            ThrowMsg(Exceptions::FileOperationFailed,
+                     "Symbolic link creating is not done.");
+        }
+    }
+#else
+    //default widget
+    LogInfo("link -s " << clientExeStr << " " << exec);
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), exec.c_str()) != 0)
     {
         int error = errno;
-        if(error)
+        if (error)
             LogPedantic("Failed to make a symbolic name for a file "
                     << "[" <<  DPL::GetErrnoString(error) << "]");
-        ThrowMsg(Exceptions::InstallationFailed,
+        ThrowMsg(Exceptions::FileOperationFailed,
                 "Symbolic link creating is not done.");
     }
+#endif
     m_context.job->UpdateProgress(
             InstallerContext::INSTALL_CREATE_EXECFILE,
             "Widget execfile creation Finished");
@@ -374,33 +420,6 @@ void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
     file << "=";
 }
 
-void TaskManifestFile::updateAilInfo()
-{
-    // Update ail for desktop
-    std::string cfgAppid =
-        DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
-    const char* appid = cfgAppid.c_str();
-
-    LogDebug("Update ail desktop : " << appid);
-    ail_appinfo_h ai = NULL;
-    ail_error_e ret;
-
-    ret = ail_get_appinfo(appid, &ai);
-    if (ai) {
-        ail_destroy_appinfo(ai);
-    }
-
-    if (AIL_ERROR_NO_DATA == ret) {
-        if (ail_desktop_add(appid) < 0) {
-            LogWarning("Failed to add ail desktop : " << appid);
-        }
-    } else if (AIL_ERROR_OK == ret) {
-        if (ail_desktop_update(appid) < 0) {
-            LogWarning("Failed to update ail desktop : " << appid);
-        }
-    }
-}
-
 void TaskManifestFile::backupIconFiles()
 {
     LogInfo("Backup Icon Files");
@@ -461,7 +480,7 @@ void TaskManifestFile::getFileList(const char* path,
     DIR* dir = opendir(path);
     if (!dir) {
         LogError("icon directory doesn't exist");
-        ThrowMsg(Exceptions::InternalError, path);
+        ThrowMsg(Exceptions::FileOperationFailed, path);
     }
 
     struct dirent entry;
@@ -514,13 +533,9 @@ void TaskManifestFile::stepParseManifest()
 
     if (code != 0) {
         LogError("Manifest parser error: " << code);
-        ThrowMsg(ManifestParsingError, "Parser returncode: " << code);
+        ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
     }
 
-    // TODO : It will be removed. AIL update is temporary code request by pkgmgr
-    // team.
-    updateAilInfo();
-
     m_context.job->UpdateProgress(
         InstallerContext::INSTALL_CREATE_MANIFEST,
         "Widget Manifest Parsing Finished");
@@ -534,13 +549,9 @@ void TaskManifestFile::stepParseUpgradedManifest()
 
     if (code != 0) {
         LogError("Manifest parser error: " << code);
-        ThrowMsg(ManifestParsingError, "Parser returncode: " << code);
+        ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
     }
 
-    // TODO : It will be removed. AIL update is temporary code request by pkgmgr
-    // team.
-    updateAilInfo();
-
     m_context.job->UpdateProgress(
         InstallerContext::INSTALL_CREATE_MANIFEST,
         "Widget Manifest Parsing Finished");
@@ -552,7 +563,13 @@ void TaskManifestFile::commitManifest()
     LogDebug("Commiting manifest file : " << manifest_file);
 
     std::ostringstream destFile;
-    destFile << "/opt/share/packages" << "/"; //TODO constant with path
+    if (m_context.job->getInstallerStruct().m_installMode
+            == InstallMode::INSTALL_MODE_PRELOAD)
+    {
+        destFile << "/usr/share/packages" << "/"; //TODO constant with path
+    } else {
+        destFile << "/opt/share/packages" << "/"; //TODO constant with path
+    }
     destFile << DPL::ToUTF8String(manifest_name);
     LogInfo("cp " << manifest_file << " " << destFile.str());
 
@@ -572,29 +589,80 @@ void TaskManifestFile::writeManifest(const DPL::String & path)
     Manifest manifest;
     UiApplication uiApp;
 
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget content
+    std::stringstream postfix;
+    // index 0 is reserved
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    setWidgetExecPath(uiApp, postfix.str());
+    setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
+    setWidgetIcons(uiApp);
+    setWidgetDescription(manifest);
+    setWidgetManifest(manifest);
+    setWidgetOtherInfo(uiApp);
+    setAppCategory(uiApp);
+    setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
+    manifest.addUiApplication(uiApp);
+
+    //app-control content
+    ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+    FOREACH(it, appControlList) {
+        UiApplication uiApp;
+
+        uiApp.setTaskmanage(true);
+        uiApp.setNodisplay(true);
+#ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
+        uiApp.setTaskmanage(ConfigParserData::AppControlInfo::Disposition::INLINE != it->m_disposition);
+        uiApp.setMultiple(ConfigParserData::AppControlInfo::Disposition::INLINE == it->m_disposition);
+#endif
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << it->m_index;
+        setWidgetExecPath(uiApp, postfix.str());
+        setWidgetName(manifest, uiApp);
+        setWidgetIds(manifest, uiApp);
+        setWidgetIcons(uiApp);
+        setAppControlInfo(uiApp, *it);
+        setAppCategory(uiApp);
+        manifest.addUiApplication(uiApp);
+    }
+#else
+    //default widget content
     setWidgetExecPath(uiApp);
     setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
     setWidgetIcons(uiApp);
     setWidgetManifest(manifest);
     setWidgetOtherInfo(uiApp);
-    setAppServiceInfo(uiApp);
-    setAppControlInfo(uiApp);
+    setAppControlsInfo(uiApp);
     setAppCategory(uiApp);
     setLiveBoxInfo(manifest);
     setAccount(manifest);
     setPrivilege(manifest);
 
     manifest.addUiApplication(uiApp);
+#endif
+
     manifest.generate(path);
     LogDebug("Manifest file serialized");
 }
 
-void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp)
+void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp,
+                                         const std::string &postfix)
 {
-    uiApp.setExec(DPL::FromASCIIString(m_context.locations->getExecFile()));
+    std::string exec = m_context.locations->getExecFile();
+    if (!postfix.empty()) {
+        exec.append(postfix);
+    }
+    LogDebug("exec = " << exec);
+    uiApp.setExec(DPL::FromASCIIString(exec));
 }
 
-void TaskManifestFile::setWidgetName(Manifest & manifest, UiApplication & uiApp)
+void TaskManifestFile::setWidgetName(Manifest & manifest,
+                                     UiApplication & uiApp)
 {
     bool defaultNameSaved = false;
 
@@ -627,8 +695,17 @@ void TaskManifestFile::setWidgetName(Manifest & manifest, UiApplication & uiApp)
                            name,
                            defaultNameSaved);
     }
+}
+
+void TaskManifestFile::setWidgetIds(Manifest & manifest,
+                                    UiApplication & uiApp,
+                                    const std::string &postfix)
+{
     //appid
     TizenAppId appid = m_context.widgetConfig.tzAppid;
+    if (!postfix.empty()) {
+        appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix));
+    }
     uiApp.setAppid(appid);
 
     //extraid
@@ -743,6 +820,39 @@ void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp,
      m_context.job->SendProgressIconPath(iconPath.str());
 }
 
+void TaskManifestFile::setWidgetDescription(Manifest & manifest)
+{
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (tag.IsNull()) {
+            tag = i;
+        }
+        DPL::OptionalString description = localizedData->second.description;
+        generateWidgetDescription(manifest, tag, description);
+    }
+}
+
+void TaskManifestFile::generateWidgetDescription(Manifest & manifest,
+                                                 const DPL::OptionalString& tag,
+                                                  DPL::OptionalString description)
+{
+    if (!!description) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+            if (!locale.empty()) {
+                manifest.addDescription(DescriptionType(*description, locale));
+            } else {
+                manifest.addDescription(DescriptionType(*description));
+            }
+        } else {
+            manifest.addDescription(DescriptionType(*description));
+        }
+    }
+}
+
 void TaskManifestFile::setWidgetManifest(Manifest & manifest)
 {
     manifest.setPackage(m_context.widgetConfig.tzPkgid);
@@ -781,33 +891,7 @@ void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
     //that were in desktop file
 }
 
-void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp)
-{
-    WrtDB::ConfigParserData::ServiceInfoList appServiceList =
-        m_context.widgetConfig.configInfo.appServiceList;
-
-    if (appServiceList.empty()) {
-        LogInfo("Widget doesn't contain application service");
-        return;
-    }
-
-    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
-    FOREACH(it, appServiceList) {
-        AppControl appControl;
-        if (!it->m_operation.empty()) {
-            appControl.addOperation(it->m_operation); //TODO: encapsulation?
-        }
-        if (!it->m_scheme.empty()) {
-            appControl.addUri(it->m_scheme);
-        }
-        if (!it->m_mime.empty()) {
-            appControl.addMime(it->m_mime);
-        }
-        uiApp.addAppControl(appControl);
-    }
-}
-
-void TaskManifestFile::setAppControlInfo(UiApplication & uiApp)
+void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
 {
     WrtDB::ConfigParserData::AppControlInfoList appControlList =
         m_context.widgetConfig.configInfo.appControlList;
@@ -817,24 +901,31 @@ void TaskManifestFile::setAppControlInfo(UiApplication & uiApp)
         return;
     }
 
-    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
     FOREACH(it, appControlList) {
-        AppControl appControl;
-        if (!it->m_operation.empty()) {
-            appControl.addOperation(it->m_operation); //TODO: encapsulation?
-        }
-        if (!it->m_uriList.empty()) {
-            FOREACH(uri, it->m_uriList) {
-                appControl.addUri(*uri);
-            }
+        setAppControlInfo(uiApp, *it);
+    }
+}
+
+void TaskManifestFile::setAppControlInfo(UiApplication & uiApp,
+                                         const WrtDB::ConfigParserData::AppControlInfo & service)
+{
+    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    AppControl appControl;
+    if (!service.m_operation.empty()) {
+        appControl.addOperation(service.m_operation); //TODO: encapsulation?
+    }
+    if (!service.m_uriList.empty()) {
+        FOREACH(uri, service.m_uriList) {
+            appControl.addUri(*uri);
         }
-        if (!it->m_mimeList.empty()) {
-            FOREACH(mime, it->m_mimeList) {
-                appControl.addMime(*mime);
-            }
+    }
+    if (!service.m_mimeList.empty()) {
+        FOREACH(mime, service.m_mimeList) {
+            appControl.addMime(*mime);
         }
-        uiApp.addAppControl(appControl);
     }
+    uiApp.addAppControl(appControl);
 }
 
 void TaskManifestFile::setAppCategory(UiApplication &uiApp)
@@ -862,7 +953,7 @@ void TaskManifestFile::stepAbortParseManifest()
 
     if (0 != code) {
         LogWarning("Manifest parser error: " << code);
-        ThrowMsg(ManifestParsingError, "Parser returncode: " << code);
+        ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
     }
     int ret = unlink(DPL::ToUTF8String(manifest_file).c_str());
     if (0 != ret) {
@@ -899,10 +990,6 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
             liveBox.setPrimary(ConfigInfo->m_primary);
         }
 
-        if (ConfigInfo->m_autoLaunch == L"true") {
-            liveBox.setAutoLaunch(appid);
-        }
-
         if (ConfigInfo->m_updatePeriod != L"") {
             liveBox.setUpdatePeriod(ConfigInfo->m_updatePeriod);
         }
@@ -939,13 +1026,28 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
             }
 
             if (ConfigInfo->m_boxInfo.m_boxMouseEvent == L"true") {
-                box.boxMouseEvent = ConfigInfo->m_boxInfo.m_boxMouseEvent;
+                std::string boxType;
+                if (ConfigInfo->m_type == L"") {
+                    // in case of default livebox
+                    boxType = web_provider_livebox_get_default_type();
+                } else {
+                    boxType = DPL::ToUTF8String(ConfigInfo->m_type);
+                }
+
+                int box_scrollable =
+                    web_provider_plugin_get_box_scrollable(boxType.c_str());
+
+                if (box_scrollable) {
+                    box.boxMouseEvent = L"true";
+                } else {
+                    box.boxMouseEvent = L"false";
+                }
             } else {
                 box.boxMouseEvent = L"false";
             }
 
             if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
-                box.boxTouchEffect = ConfigInfo->m_boxInfo.m_boxTouchEffect;
+                box.boxTouchEffect = L"true";
             } else {
                 box.boxTouchEffect= L"false";
             }