Service runs as separate process
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_manifest_file.cpp
index 298a06d..f6bc038 100644 (file)
@@ -102,17 +102,10 @@ const char * TaskManifestFile::encoding = "UTF-8";
 
 TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
     DPL::TaskDecl<TaskManifestFile>(this),
-    m_context(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);
@@ -121,6 +114,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);
     }
 }
 
@@ -132,12 +133,46 @@ void TaskManifestFile::stepCreateExecFile()
     std::string exec = m_context.locations->getExecFile();
     std::string clientExeStr = GlobalConfig::GetWrtClientExec();
 
+    //default widget
     LogInfo("link -s " << clientExeStr << " " << exec);
-    symlink(clientExeStr.c_str(), exec.c_str());
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), exec.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.");
+    }
+
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //services
+    std::size_t serviceCount =
+        m_context.widgetConfig.configInfo.appControlList.size();
+    serviceCount += m_context.widgetConfig.configInfo.appServiceList.size();
+    for (std::size_t i = 0; i < serviceCount; ++i) {
+        std::stringstream postfix;
+        postfix << "-__SERVICE_PROCESS__" << i;
+        std::string serviceExec = exec;
+        serviceExec.append(postfix.str());
+        errno = 0;
+        if (symlink(clientExeStr.c_str(), serviceExec.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.");
+        }
+
+    }
+#endif
 
     m_context.job->UpdateProgress(
-        InstallerContext::INSTALL_CREATE_EXECFILE,
-        "Widget execfile creation Finished");
+            InstallerContext::INSTALL_CREATE_EXECFILE,
+            "Widget execfile creation Finished");
 }
 
 void TaskManifestFile::stepCopyIconFiles()
@@ -161,7 +196,7 @@ void TaskManifestFile::stepCopyIconFiles()
     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_reverse_iterator
          icon = icons.rbegin();
          icon != icons.rend();
-         icon++)
+         ++icon)
     {
         FOREACH(locale, icon->availableLocales)
         {
@@ -375,9 +410,9 @@ void TaskManifestFile::updateAilInfo()
     ail_appinfo_h ai = NULL;
     ail_error_e ret;
 
-    ret = ail_package_get_appinfo(appid, &ai);
+    ret = ail_get_appinfo(appid, &ai);
     if (ai) {
-        ail_package_destroy_appinfo(ai);
+        ail_destroy_appinfo(ai);
     }
 
     if (AIL_ERROR_NO_DATA == ret) {
@@ -451,21 +486,30 @@ 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* d_ent;
-    do {
-        if ((d_ent = readdir(dir))) {
-            if (strcmp(d_ent->d_name, ".") == 0 ||
-                strcmp(d_ent->d_name, "..") == 0)
-            {
-                continue;
-            }
-            std::string file_name = d_ent->d_name;
-            list.push_back(file_name);
+    struct dirent entry;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(dir, &entry, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(dir, &entry, &result))
+    {
+        if (strcmp(entry.d_name, ".") == 0 ||
+            strcmp(entry.d_name, "..") == 0)
+        {
+            continue;
         }
-    } while (d_ent);
+        std::string file_name = entry.d_name;
+        list.push_back(file_name);
+    }
+
+    if (return_code != 0 || errno != 0) {
+        LogError("readdir_r() failed with " << DPL::GetErrnoString());
+    }
+
     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
         LogError("Failed to close dir: " << path << " with error: "
                                          << DPL::GetErrnoString());
@@ -495,7 +539,7 @@ 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
@@ -515,7 +559,7 @@ 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
@@ -553,27 +597,93 @@ void TaskManifestFile::writeManifest(const DPL::String & path)
     Manifest manifest;
     UiApplication uiApp;
 
+    //default widget content
     setWidgetExecPath(uiApp);
     setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
     setWidgetIcons(uiApp);
     setWidgetManifest(manifest);
     setWidgetOtherInfo(uiApp);
-    setAppServiceInfo(uiApp);
-    setAppControlInfo(uiApp);
+#ifndef MULTIPROCESS_SERVICE_SUPPORT
+    setAppServicesInfo(uiApp);
+    setAppControlsInfo(uiApp);
+#endif
     setAppCategory(uiApp);
     setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
 
     manifest.addUiApplication(uiApp);
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //services AppControl tag
+    ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+    unsigned count = 0;
+
+    FOREACH(it, appControlList) {
+        it->m_index = count;
+        UiApplication uiApp;
+
+        uiApp.setTaskmanage(true);
+        uiApp.setNodisplay(true);
+
+        std::stringstream postfix;
+        postfix << "-__SERVICE_PROCESS__" << count++;
+
+        setWidgetExecPath(uiApp, postfix.str());
+        setWidgetName(manifest, uiApp);
+        setWidgetIds(manifest, uiApp, postfix.str());
+        setWidgetIcons(uiApp);
+        setAppControlInfo(uiApp, *it);
+        setAppCategory(uiApp);
+        setAccount(manifest);
+        setPrivilege(manifest);
+
+        manifest.addUiApplication(uiApp);
+    }
+    //TODO: AppService tag will be removed
+    //services AppService tag
+    WrtDB::ConfigParserData::ServiceInfoList appServiceList =
+        m_context.widgetConfig.configInfo.appServiceList;
+    FOREACH(it, appServiceList) {
+        it->m_index = count;
+        UiApplication uiApp;
+
+        uiApp.setTaskmanage(true);
+        uiApp.setNodisplay(true);
+
+        std::stringstream postfix;
+        postfix << "-__SERVICE_PROCESS__" << count++;
+
+        setWidgetExecPath(uiApp, postfix.str());
+        setWidgetName(manifest, uiApp);
+        setWidgetIds(manifest, uiApp, postfix.str());
+        setWidgetIcons(uiApp);
+        setAppServiceInfo(uiApp, *it);
+        setAppCategory(uiApp);
+        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;
 
@@ -606,8 +716,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
@@ -667,7 +786,7 @@ void TaskManifestFile::setWidgetIcons(UiApplication & uiApp)
     for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_reverse_iterator
          icon = icons.rbegin();
          icon != icons.rend();
-         icon++)
+         ++icon)
     {
         FOREACH(locale, icon->availableLocales)
         {
@@ -760,7 +879,7 @@ void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
     //that were in desktop file
 }
 
-void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp)
+void TaskManifestFile::setAppServicesInfo(UiApplication & uiApp)
 {
     WrtDB::ConfigParserData::ServiceInfoList appServiceList =
         m_context.widgetConfig.configInfo.appServiceList;
@@ -772,21 +891,11 @@ void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp)
 
     // 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);
-    }
-}
+        setAppServiceInfo(uiApp, *it);
+     }
+ }
 
-void TaskManifestFile::setAppControlInfo(UiApplication & uiApp)
+void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
 {
     WrtDB::ConfigParserData::AppControlInfoList appControlList =
         m_context.widgetConfig.configInfo.appControlList;
@@ -796,24 +905,47 @@ 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::setAppServiceInfo(UiApplication & uiApp,
+                                         const ConfigParserData::ServiceInfo & service)
+{
+    AppControl appControl;
+    if (!service.m_operation.empty()) {
+        appControl.addOperation(service.m_operation); //TODO: encapsulation?
+    }
+    if (!service.m_scheme.empty()) {
+        appControl.addUri(service.m_scheme);
+    }
+    if (!service.m_mime.empty()) {
+        appControl.addMime(service.m_mime);
+    }
+    uiApp.addAppControl(appControl);
+}
+
+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)
@@ -841,7 +973,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) {
@@ -856,10 +988,9 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
         LiveBoxInfo liveBox;
         DPL::Optional<WrtDB::ConfigParserData::LiveboxInfo> ConfigInfo = *it;
         DPL::String appid = m_context.widgetConfig.tzAppid;
-        size_t found;
 
         if (ConfigInfo->m_liveboxId != L"") {
-            found = ConfigInfo->m_liveboxId.find_last_of(L".");
+            size_t found = ConfigInfo->m_liveboxId.find_last_of(L".");
             if (found != std::string::npos) {
                 if (0 == ConfigInfo->m_liveboxId.compare(0, found, appid)) {
                     liveBox.setLiveboxId(ConfigInfo->m_liveboxId);
@@ -879,10 +1010,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);
         }
@@ -924,6 +1051,12 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
                 box.boxMouseEvent = L"false";
             }
 
+            if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
+                box.boxTouchEffect = ConfigInfo->m_boxInfo.m_boxTouchEffect;
+            } else {
+                box.boxTouchEffect= L"false";
+            }
+
             std::list<std::pair<DPL::String, DPL::String> > BoxSizeList
                 = ConfigInfo->m_boxInfo.m_boxSize;
             FOREACH(im, BoxSizeList) {
@@ -938,7 +1071,13 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
                 && !ConfigInfo->m_boxInfo.m_pdWidth.empty()
                 && !ConfigInfo->m_boxInfo.m_pdHeight.empty())
             {
-                box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
+                if ((0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 4, L"http"))
+                    || (0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 5, L"https")))
+                {
+                    box.pdSrc = ConfigInfo->m_boxInfo.m_pdSrc;
+                } else {
+                    box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
+                }
                 box.pdWidth = ConfigInfo->m_boxInfo.m_pdWidth;
                 box.pdHeight = ConfigInfo->m_boxInfo.m_pdHeight;
             }
@@ -947,5 +1086,65 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
         manifest.addLivebox(liveBox);
     }
 }
+
+void TaskManifestFile::setAccount(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::AccountProvider account =
+        m_context.widgetConfig.configInfo.accountProvider;
+
+    AccountProviderType provider;
+
+    if (account.m_iconSet.empty()) {
+        LogInfo("Widget doesn't contain Account");
+        return;
+    }
+    if (account.m_multiAccountSupport) {
+        provider.multiAccount = L"ture";
+    } else {
+        provider.multiAccount = L"false";
+    }
+    provider.appid = m_context.widgetConfig.tzAppid;
+
+    FOREACH(it, account.m_iconSet) {
+        std::pair<DPL::String, DPL::String> icon;
+
+        if (it->first == ConfigParserData::IconSectionType::DefaultIcon) {
+            icon.first = L"account";
+        } else if (it->first == ConfigParserData::IconSectionType::SmallIcon) {
+            icon.first = L"account-small";
+        }
+        icon.second = it->second;
+
+        provider.icon.push_back(icon);
+    }
+
+    FOREACH(it, account.m_displayNameSet) {
+        provider.name.push_back(LabelType(it->second, it->first));
+    }
+
+    FOREACH(it, account.m_capabilityList) {
+        provider.capability.push_back(*it);
+    }
+
+    Account accountInfo;
+    accountInfo.addAccountProvider(provider);
+    manifest.addAccount(accountInfo);
+}
+
+void TaskManifestFile::setPrivilege(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::PrivilegeList privileges =
+        m_context.widgetConfig.configInfo.privilegeList;
+
+    PrivilegeType privilege;
+
+    FOREACH(it, privileges)
+    {
+        privilege.addPrivilegeName(it->name);
+    }
+
+    manifest.addPrivileges(privilege);
+}
+
 } //namespace WidgetInstall
 } //namespace Jobs