From 83377f423956236b367926d464bf01ac90dc6f47 Mon Sep 17 00:00:00 2001 From: Duyoung Jang Date: Fri, 8 Mar 2013 14:10:25 +0900 Subject: [PATCH] Update logic is added. Change-Id: I86e39272f892b162b3a2f4eacd0eadd00de0d09b Signed-off-by: Duyoung Jang --- inc/InstallerDefs.h | 5 +- src/Context/InstallationContext.cpp | 1 + src/Context/InstallationContext.h | 1 + src/Installer/DirectoryInstaller.cpp | 8 +- src/Installer/PreloadedInstaller.cpp | 15 ++- src/Manager/ConfigurationManager.cpp | 18 +++- src/Step/ManifestXmlStep.cpp | 22 +++- src/Step/SystemCheckStep.cpp | 189 ++++++++++++++++++++++++++++++++++- src/Step/SystemCheckStep.h | 16 ++- src/Step/UnpackStep.cpp | 101 ++++++++++++++++--- src/Step/UnpackStep.h | 7 +- src/Util/InstallerUtil.cpp | 4 +- src/backend/backend.cpp | 12 +++ 13 files changed, 349 insertions(+), 50 deletions(-) mode change 100644 => 100755 src/Step/SystemCheckStep.h mode change 100644 => 100755 src/Step/UnpackStep.h diff --git a/inc/InstallerDefs.h b/inc/InstallerDefs.h index a2ca9d0..15320d5 100755 --- a/inc/InstallerDefs.h +++ b/inc/InstallerDefs.h @@ -23,7 +23,7 @@ #include "InstallerUtil.h" -#define OSP_INSTALLER_VERSION "version=[20130227.3]" +#define OSP_INSTALLER_VERSION "version=[20130308.1]" #define DIR_BIN L"/bin" #define DIR_INFO L"/info" @@ -86,6 +86,7 @@ #define TEST_ARG_COUNT 1 #define COMMAND_ARG_COUNT 3 +#define TERMINATE_RETRY_COUNT 300 #define DIR_OSP_APPLICATIONS_TEMP L"/opt/usr/apps/__@@osp_tmp@@__" @@ -157,10 +158,10 @@ enum InstallationStep { INSTALLER_STEP_NONE = 0, INSTALLER_STEP_INIT, - INSTALLER_STEP_CHECK_SYSTEM, INSTALLER_STEP_CHECK_PACKAGE, INSTALLER_STEP_DRM, INSTALLER_STEP_PARSE_MANIFEST, + INSTALLER_STEP_CHECK_SYSTEM, INSTALLER_STEP_UNPACK, INSTALLER_STEP_LICENSE, INSTALLER_STEP_PARSE_SIGNATURE, diff --git a/src/Context/InstallationContext.cpp b/src/Context/InstallationContext.cpp index b9bba8d..2caeffa 100755 --- a/src/Context/InstallationContext.cpp +++ b/src/Context/InstallationContext.cpp @@ -49,6 +49,7 @@ InstallationContext::InstallationContext(void) ,__isPreloaded(false) ,__isHybridService(false) ,__isVerificationMode(false) +,__isUpdated(false) ,__operation(INSTALLER_OPERATION_INSTALL) ,__storage(INSTALLATION_STORAGE_INTERNAL) ,__rootCertType(ROOT_CERTIFICATE_NONE) diff --git a/src/Context/InstallationContext.h b/src/Context/InstallationContext.h index 13ea6b8..da99136 100755 --- a/src/Context/InstallationContext.h +++ b/src/Context/InstallationContext.h @@ -108,6 +108,7 @@ public: bool __isPreloaded; bool __isHybridService; bool __isVerificationMode; + bool __isUpdated; InstallerOperation __operation; InstallationStorage __storage; diff --git a/src/Installer/DirectoryInstaller.cpp b/src/Installer/DirectoryInstaller.cpp index 39d72ec..b1626e9 100755 --- a/src/Installer/DirectoryInstaller.cpp +++ b/src/Installer/DirectoryInstaller.cpp @@ -46,14 +46,14 @@ DirectoryInstaller::GetNext(InstallationStep step) } else if (step == INSTALLER_STEP_INIT) { - return INSTALLER_STEP_CHECK_SYSTEM; - } - else if (step == INSTALLER_STEP_CHECK_SYSTEM) - { return INSTALLER_STEP_PARSE_MANIFEST; } else if (step == INSTALLER_STEP_PARSE_MANIFEST) { + return INSTALLER_STEP_CHECK_SYSTEM; + } + else if (step == INSTALLER_STEP_CHECK_SYSTEM) + { return INSTALLER_STEP_PARSE_SIGNATURE; } else if (step == INSTALLER_STEP_PARSE_SIGNATURE) diff --git a/src/Installer/PreloadedInstaller.cpp b/src/Installer/PreloadedInstaller.cpp index 2b85ab0..9b11de8 100755 --- a/src/Installer/PreloadedInstaller.cpp +++ b/src/Installer/PreloadedInstaller.cpp @@ -59,23 +59,24 @@ PreloadedInstaller::OnInit(void) destRootPath += L"/"; destRootPath += appId; - InstallerUtil::Remove(destRootPath); Directory::Create(destRootPath); String srcPath; String destPath; + // /setting + srcPath = path + DIR_SETTING; + destPath = destRootPath + DIR_SETTING; + InstallerUtil::CopyDirectory(srcPath, destPath); + // /data srcPath = path + DIR_DATA; destPath = destRootPath + DIR_DATA; InstallerUtil::CopyDirectory(srcPath, destPath); - // /info srcPath = path + DIR_INFO; destPath = destRootPath + DIR_INFO; - InstallerUtil::CopyDirectory(srcPath, destPath); - - // appRoot - signature + InstallerUtil::CreateSymlink(srcPath, destPath); srcPath = path + DIR_BIN; destPath = destRootPath + DIR_BIN; @@ -108,10 +109,6 @@ PreloadedInstaller::OnInit(void) InstallerUtil::CreateSymlink(srcPath, destPath); } - srcPath = path + DIR_SETTING; - destPath = destRootPath + DIR_SETTING; - InstallerUtil::CreateSymlink(srcPath, destPath); - pContext->__installDir = destRootPath; return DirectoryInstaller::OnInit(); diff --git a/src/Manager/ConfigurationManager.cpp b/src/Manager/ConfigurationManager.cpp index c4e173e..0043092 100755 --- a/src/Manager/ConfigurationManager.cpp +++ b/src/Manager/ConfigurationManager.cpp @@ -336,8 +336,13 @@ ConfigurationManager::RemoveFile(InstallationContext* pContext) bool ConfigurationManager::RegisterCertInfo(InstallationContext* pContext) const { - AppLog("------------------------------------------"); - AppLog("RegisterCertInfo - START"); + if (pContext->__isHybridService == true) + { + AppLog("Skip - HybridService"); + return true; + } + + AppLog("START"); int res = 0; bool result = true; @@ -448,8 +453,13 @@ CATCH: bool ConfigurationManager::UnregisterCertInfo(InstallationContext* pContext) const { - AppLog("------------------------------------------"); - AppLog("UnregisterCertInfo - START"); + if (pContext->__isHybridService == true) + { + AppLog("Skip - HybridService"); + return true; + } + + AppLog("START"); int res = 0; bool result = true; String appId = pContext->__packageId; diff --git a/src/Step/ManifestXmlStep.cpp b/src/Step/ManifestXmlStep.cpp index d15f970..e6131d3 100755 --- a/src/Step/ManifestXmlStep.cpp +++ b/src/Step/ManifestXmlStep.cpp @@ -29,6 +29,7 @@ #include "ManifestHandler.h" #include "ManifestXmlStep.h" +using namespace Tizen::App; using namespace Tizen::Base; using namespace Tizen::Io; @@ -102,7 +103,24 @@ ManifestXmlStep::OnStateManifestXml(void) String manifestXmlPath; result r = E_SUCCESS; - manifestXmlPath = __pContext->__installDir + PACKAGE_XML_FILE; + if (__pContext->__isPreloaded == true) + { + PackageId packageId; + String preloadedAppPath(PATH_USR_APPS); + preloadedAppPath += L"/"; + String path = __pContext->__installDir; + + path.SubString(preloadedAppPath.GetLength(), PACKAGE_ID_LENGTH, packageId); + preloadedAppPath += packageId; + + manifestXmlPath = preloadedAppPath + PACKAGE_XML_FILE; + } + else + { + manifestXmlPath = __pContext->__installDir + PACKAGE_XML_FILE; + } + + AppLog("manifest file=[%ls]", manifestXmlPath.GetPointer()); FileAttributes attr; r = File::GetAttributes(manifestXmlPath, attr); @@ -111,8 +129,6 @@ ManifestXmlStep::OnStateManifestXml(void) std::unique_ptr pFilepath(_StringConverter::CopyToCharArrayN(manifestXmlPath)); TryReturn(pFilepath, INSTALLER_ERROR_OUT_OF_MEMORY, "pFilepath is null"); - AppLog("manifest file=[%ls]", manifestXmlPath.GetPointer()); - ManifestHandler manifestHandler; manifestHandler.Construct(__pContext); ret = manifestHandler.Parse(pFilepath.get()); diff --git a/src/Step/SystemCheckStep.cpp b/src/Step/SystemCheckStep.cpp index 462d1f0..5e7fe19 100755 --- a/src/Step/SystemCheckStep.cpp +++ b/src/Step/SystemCheckStep.cpp @@ -19,11 +19,22 @@ * @brief This is the implementation file for %SystemCheckStep class. */ +#include +#include +#include +#include +#include + #include "InstallationContext.h" #include "SystemCheckStep.h" +using namespace Tizen::App; +using namespace Tizen::App::Package; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; + SystemCheckStep::SystemCheckStep(void) -:__state(STATE_SYSTEM_CHECK) +:__state(STATE_VERSION_CHECK) ,__pContext(null) { } @@ -43,8 +54,8 @@ SystemCheckStep::Run(InstallationContext* pContext) { switch (__state) { - case STATE_SYSTEM_CHECK: - error = OnStateSystemCheck(); + case STATE_VERSION_CHECK: + error = OnStateVersionCheck(); break; case STATE_AGENT_CHECK: @@ -84,9 +95,58 @@ SystemCheckStep::GoNextState(void) } InstallerError -SystemCheckStep::OnStateSystemCheck(void) +SystemCheckStep::OnStateVersionCheck(void) { InstallerError error = INSTALLER_ERROR_NONE; + int res = 0; + + std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(__pContext->__packageId)); + if (pPackageInfo) + { + String oldVersion = pPackageInfo->GetVersion(); + String newVersion = __pContext->__version; + + res = CompareVersion(oldVersion, newVersion); + + if (res == VERSION_SAME) + { + AppLog("Same version: packageId = [%ls], version = [%ls]", __pContext->__packageId.GetPointer(), oldVersion.GetPointer()); + } + else if (res == VERSION_NEW) + { + __pContext->__isUpdated = true; + + AppLog("Update version: packageId = [%ls]", __pContext->__packageId.GetPointer()); + AppLog("Update version: oldVersion = [%ls] -> newVersion = [%ls]", oldVersion.GetPointer(), newVersion.GetPointer()); + + _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get()); + TryReturn(pPackageInfoImpl, INSTALLER_ERROR_INTERNAL_STATE, "GetInstance() failed."); + + std::unique_ptr< IList > pPackageAppList(pPackageInfoImpl->GetPackageAppInfoListN()); + TryReturn(pPackageAppList, INSTALLER_ERROR_INTERNAL_STATE, "GetPackageAppInfoListN() failed."); + + for (int i = 0; i < pPackageAppList->GetCount(); i++) + { + PackageAppInfo* pPackageAppInfo = dynamic_cast (pPackageAppList->GetAt(i)); + TryReturn(pPackageAppInfo, INSTALLER_ERROR_INTERNAL_STATE, "pPackageAppList->GetAt(%d) failed.", i); + + AppId appId = pPackageAppInfo->GetAppId(); + + res = CheckAppStatus(appId); + TryReturn(res, INSTALLER_ERROR_FATAL_ERROR, "CheckAppStatus(%ls) failed.", appId.GetPointer()); + } + } + else if (res == VERSION_OLD) + { + AppLog("Lower version: oldVersion = [%ls] -> newVersion = [%ls]", oldVersion.GetPointer(), newVersion.GetPointer()); + return INSTALLER_ERROR_PACKAGE_LOWER_VERSION; + } + else + { + AppLog("Invalid version: oldVersion = [%ls] -> newVersion = [%ls]", oldVersion.GetPointer(), newVersion.GetPointer()); + return INSTALLER_ERROR_MANIFEST_INVALID; + } + } // Check preferred storage __pContext->__storage = INSTALLATION_STORAGE_INTERNAL; @@ -121,3 +181,124 @@ SystemCheckStep::OnStateDone(void) GoNextState(); return error; } + +int +SystemCheckStep::CompareVersion(const String& oldVersion, const String& newVersion) +{ + bool res = true; + int oldVersionMajor = 0; + int oldVersionMinor = 0; + int oldVersionMacro = 0; + int newVersionMajor = 0; + int newVersionMinor = 0; + int newVersionMacro = 0; + + res = ExtractVersion(oldVersion, oldVersionMajor, oldVersionMinor, oldVersionMacro); + TryReturn(res, VERSION_ERROR, "ExtractVersion() failed. [%ls]", oldVersion.GetPointer()); + + res = ExtractVersion(newVersion, newVersionMajor, newVersionMinor, newVersionMacro); + TryReturn(res, VERSION_ERROR, "ExtractVersion() failed. [%ls]", newVersion.GetPointer()); + + if (newVersionMajor > oldVersionMajor) + { + return VERSION_NEW; + } + else if (newVersionMajor < oldVersionMajor) + { + return VERSION_OLD; + } + + if (newVersionMinor > oldVersionMinor) + { + return VERSION_NEW; + } + else if (newVersionMinor < oldVersionMinor) + { + return VERSION_OLD; + } + + if (newVersionMacro > oldVersionMacro) + { + return VERSION_NEW; + } + else if (newVersionMacro < oldVersionMacro) + { + return VERSION_OLD; + } + + return VERSION_SAME; +} + +bool +SystemCheckStep::ExtractVersion(const String& version, int& major, int& minor, int& macro) +{ + result r = E_SUCCESS; + int indexOf = 0; + int startIndex = 0; + String majorStr; + String minorStr; + String macroStr; + + r = version.IndexOf(L'.', startIndex, indexOf); + TryReturn(r == E_SUCCESS, false, "version.IndexOf() failed. [%ls]", version.GetPointer()); + + version.SubString(startIndex, indexOf - startIndex, majorStr); + startIndex = indexOf + 1; + + r = version.IndexOf(L'.', startIndex, indexOf); + TryReturn(r == E_SUCCESS, false, "version.IndexOf() failed. [%ls]", version.GetPointer()); + + version.SubString(startIndex, indexOf - startIndex, minorStr); + startIndex = indexOf + 1; + + version.SubString(startIndex, macroStr); + + Integer::Decode(majorStr, major); + Integer::Decode(minorStr, minor); + Integer::Decode(macroStr, macro); + + AppLog("version = [%ls] -> major = [%d], minor = [%d], macro = [%d]", version.GetPointer(), major, minor, macro); + + return true; +} + +bool +SystemCheckStep::CheckAppStatus(const AppId& appId) +{ + bool res = true; + + if (_Aul::IsRunning(appId) == true) + { + AppLog("App(%ls) is running.", appId.GetPointer()); + + result r = _Aul::TerminateApplication(appId); + TryReturn(r == E_SUCCESS, false, "TerminateApplication() failed. [%ls]", appId.GetPointer()); + + for (int j = 0; j < TERMINATE_RETRY_COUNT; j++) + { + res = _Aul::IsRunning(appId); + if (res == false) + { + AppLog("App(%ls) is terminated.", appId.GetPointer()); + break; + } + else + { + AppLog("App(%ls) is not terminated yet. wait count = [%d]", appId.GetPointer(), j); + usleep(100000); + } + } + + if (res == true) + { + AppLog("App(%ls) can't be terminated.", appId.GetPointer()); + return false; + } + } + else + { + AppLog("App(%ls) is not running.", appId.GetPointer()); + } + + return true; +} diff --git a/src/Step/SystemCheckStep.h b/src/Step/SystemCheckStep.h old mode 100644 new mode 100755 index 506f587..0585f73 --- a/src/Step/SystemCheckStep.h +++ b/src/Step/SystemCheckStep.h @@ -45,18 +45,30 @@ public: private: enum { - STATE_SYSTEM_CHECK, + STATE_VERSION_CHECK, STATE_AGENT_CHECK, STATE_AGENT_TIMER, STATE_DONE }; + enum + { + VERSION_ERROR, + VERSION_OLD, + VERSION_SAME, + VERSION_NEW + }; + void GoNextState(void); - InstallerError OnStateSystemCheck(void); + InstallerError OnStateVersionCheck(void); InstallerError OnStateAgentCheck(void); InstallerError OnStateAgentTimer(void); InstallerError OnStateDone(void); + int CompareVersion(const Tizen::Base::String& oldVersion, const Tizen::Base::String& newVersion); + bool ExtractVersion(const Tizen::Base::String& version, int& major, int& minor, int& macro); + bool CheckAppStatus(const Tizen::App::AppId& appId); + private: int __state; InstallationContext* __pContext; diff --git a/src/Step/UnpackStep.cpp b/src/Step/UnpackStep.cpp index 28e5444..31e3aaa 100755 --- a/src/Step/UnpackStep.cpp +++ b/src/Step/UnpackStep.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -33,10 +32,10 @@ #include "UnpackStep.h" #include "InstallerUtil.h" +using namespace Tizen::App; using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::Base::Utility; -using namespace Tizen::App; using namespace Tizen::Io; UnpackStep::UnpackStep(void) @@ -85,11 +84,6 @@ UnpackStep::Run(InstallationContext* pContext) error = OnUnzip(); break; - case STATE_VERSION_CHECK: - AppLog("[STATE_VERSION_CHECK]"); - error = OnStateVersionCheck(); - break; - case STATE_FILE_MOVE: AppLog("[STATE_FILE_MOVE]"); error = OnStateFileMove(); @@ -179,6 +173,11 @@ UnpackStep::OnUnzip(void) __pContext->__installDir = newInstallPath; __pContext->__rootPath = newInstallPath; + if (__pContext->__isUpdated == true) + { + RemoveRoDirectory(installPath); + } + AppLog("UnzipTo - START"); unzipper.UnzipTo(newInstallPath); AppLog("UnzipTo - END"); @@ -189,15 +188,6 @@ UnpackStep::OnUnzip(void) } InstallerError -UnpackStep::OnStateVersionCheck(void) -{ - InstallerError error = INSTALLER_ERROR_NONE; - - GoNextState(); - return error; -} - -InstallerError UnpackStep::OnStateFileMove(void) { InstallerError error = INSTALLER_ERROR_NONE; @@ -344,3 +334,82 @@ UnpackStep::AddDirectory(const String& rootDirectory) return true; } + +bool +UnpackStep::RemoveRoDirectory(const String& rootPath) +{ + std::unique_ptr pDir(new (std::nothrow) Directory); + TryReturn(pDir, false, "pDir is null."); + + result r = pDir->Construct(rootPath); + TryReturn(!IsFailed(r), false, "pDir->Construct() failed. rootPath = [%ls]", rootPath.GetPointer()); + + std::unique_ptr pDirEnum(pDir->ReadN()); + TryReturn(pDirEnum, false, "pDirEnum is null."); + + while (pDirEnum->MoveNext() == E_SUCCESS) + { + DirEntry entry = pDirEnum->GetCurrentDirEntry(); + + String entryName = entry.GetName(); + String srcEntryDir = rootPath; + srcEntryDir += L"/"; + srcEntryDir += entryName; + + if (entryName == L"." || entryName == L"..") + { + continue; + } + else if (entryName == L"data") + { + AppLog("skip - directory[%ls]", srcEntryDir.GetPointer()); + continue; + } + else if (entryName == L"shared") + { + RemoveSharedDirectory(srcEntryDir); + continue; + } + + InstallerUtil::Remove(srcEntryDir); + } + + return true; +} + +bool +UnpackStep::RemoveSharedDirectory(const String& sharedPath) +{ + std::unique_ptr pDir(new (std::nothrow) Directory); + TryReturn(pDir, false, "pDir is null."); + + result r = pDir->Construct(sharedPath); + TryReturn(!IsFailed(r), false, "pDir->Construct() failed. sharedPath = [%ls]", sharedPath.GetPointer()); + + std::unique_ptr pDirEnum(pDir->ReadN()); + TryReturn(pDirEnum, false, "pDirEnum is null."); + + while (pDirEnum->MoveNext() == E_SUCCESS) + { + DirEntry entry = pDirEnum->GetCurrentDirEntry(); + + String entryName = entry.GetName(); + String srcEntryDir = sharedPath; + srcEntryDir += L"/"; + srcEntryDir += entryName; + + if (entryName == L"." || entryName == L"..") + { + continue; + } + else if (entryName == L"data" || entryName == L"trusted") + { + AppLog("skip - directory[%ls]", srcEntryDir.GetPointer()); + continue; + } + + InstallerUtil::Remove(srcEntryDir); + } + + return true; +} diff --git a/src/Step/UnpackStep.h b/src/Step/UnpackStep.h old mode 100644 new mode 100755 index db7feff..08c5d02 --- a/src/Step/UnpackStep.h +++ b/src/Step/UnpackStep.h @@ -25,8 +25,6 @@ #include -#include - #include "IInstallationStep.h" /** @@ -50,7 +48,6 @@ private: enum { STATE_UNZIP, - STATE_VERSION_CHECK, STATE_FILE_MOVE, STATE_CREATE_DIR, STATE_DONE @@ -58,7 +55,6 @@ private: void GoNextState(void); InstallerError OnUnzip(void); - InstallerError OnStateVersionCheck(void); InstallerError OnStateFileMove(void); InstallerError OnCreateDir(void); InstallerError OnStateDone(void); @@ -67,6 +63,9 @@ private: bool GetUncompressedInfo(const Tizen::Base::Utility::FileUnzipper& unzipper); bool AddDirectory(const Tizen::Base::String& directory); + bool RemoveRoDirectory(const Tizen::Base::String& rootPath); + bool RemoveSharedDirectory(const Tizen::Base::String& sharedPath); + private: int __state; InstallationContext* __pContext; diff --git a/src/Util/InstallerUtil.cpp b/src/Util/InstallerUtil.cpp index 28dbe30..4cc09b0 100755 --- a/src/Util/InstallerUtil.cpp +++ b/src/Util/InstallerUtil.cpp @@ -292,7 +292,7 @@ InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode, bool res = File::IsFileExist(filePath); if (res == false) { - AppLog("ChangeDirectoryPermission(): path=[%ls]: skip", filePath.GetPointer()); + AppLog("path=[%ls]: skip", filePath.GetPointer()); return true; } @@ -352,7 +352,7 @@ InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode, bool } } - AppLog("ChangeDirectoryPermission(): path=[%ls], mode=[%04o], appOwner=[%s]", + AppLog("path=[%ls], mode=[%04o], appOwner=[%s]", filePath.GetPointer(), mode, appOwner?"true":"false"); return true; diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index 1ea57a0..ece1f6a 100755 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -111,6 +111,12 @@ main(int argc, char **argv) char resultBuf[128] = {0}; snprintf(resultBuf, sizeof(resultBuf), "%ls", packageId.GetPointer()); pkgmgr_installer_send_signal(_pi, "tpk", resultBuf, "start", "install"); + + // temp + pkgmgr_installer_send_signal(_pi, "tpk", resultBuf, "install_percent", "0"); + usleep(50000); + pkgmgr_installer_send_signal(_pi, "tpk", resultBuf, "install_percent", "30"); + usleep(50000); } else { @@ -240,6 +246,12 @@ __osp_installer_report_result(const PackageId& packageId, int errorType) snprintf(resultBuf, sizeof(resultBuf), "%ls", packageId.GetPointer()); } + // temp + pkgmgr_installer_send_signal(_pi, pPkgType, resultBuf, "install_percent", "65"); + usleep(50000); + pkgmgr_installer_send_signal(_pi, pPkgType, resultBuf, "install_percent", "100"); + usleep(50000); + ret = pkgmgr_installer_send_signal(_pi, pPkgType, resultBuf, pKey, pValue); AppLog("------------------------------------------"); AppLog("pkgmgr_installer_send_signal"); -- 2.7.4