2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file InstallerManager.cpp
19 * @brief This is the implementation file for %InstallerManager class.
23 #include <unique_ptr.h>
26 #include <app2ext_interface.h>
29 #include <FIoDirectory.h>
30 #include <FBase_StringConverter.h>
31 #include <FAppPkgPackageInfo.h>
32 #include <FAppPkg_PackageManagerImpl.h>
33 #include <FAppPkg_PackageInfoImpl.h>
34 #include <FSysSystemTime.h>
36 #include "InstallerManager.h"
37 #include "GuestInstaller.h"
38 #include "IDEInstaller.h"
39 #include "PreloadedInstaller.h"
40 #include "RestorationInstaller.h"
41 #include "InstallerUtil.h"
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Utility;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Io;
47 using namespace Tizen::App;
48 using namespace Tizen::App::Package;
50 const int BUFSIZE = 512;
51 InstallerManager* InstallerManager::__pInstallerManager = null;
53 InstallerManager::InstallerManager(void)
57 ,__operation(INSTALLER_OPERATION_INSTALL)
64 InstallerManager::~InstallerManager(void)
74 InstallerManager::GetInstance()
76 if (__pInstallerManager == null)
78 __pInstallerManager = new InstallerManager();
79 TryReturn(__pInstallerManager, null, "__pInstallerManager is null");
82 return __pInstallerManager;
86 InstallerManager::Construct(const String& path, InstallerOperation operation, InstallerOption option)
88 InstallerError error = INSTALLER_ERROR_NONE;
89 InstallerType installerType = INSTALLER_TYPE_INSTALLER;
91 String newPath = path;
93 Tizen::System::SystemTime::GetTicks(__startTick);
94 SetInstallerOperation(operation);
96 if (option & INSTALLER_OPTION_FILELOG_ON)
98 r = Directory::Create(DIR_OSP_APPLICATIONS_TEMP, false);
101 __logFilePath = DIR_OSP_APPLICATIONS_TEMP;
102 __logFilePath += L"/log.txt";
103 InstallerUtil::CreateLog(__logFilePath);
105 __isFileLogOn = true;
109 AppLog("------------------------------------------");
110 AppLog("InstallerManager");
111 AppLog("------------------------------------------");
112 AppLog(" # operation = [%s]", (operation == INSTALLER_OPERATION_INSTALL)?"Install":"Uninstall");
113 AppLog(" # path = [%ls]", path.GetPointer());
114 AppLog("------------------------------------------");
116 __pContext = new InstallationContext();
117 TryReturn(__pContext, INSTALLER_ERROR_OUT_OF_MEMORY, "__pContext is null.");
119 error = __pContext->Construct();
120 TryReturn(error == INSTALLER_ERROR_NONE, INSTALLER_ERROR_INTERNAL_STATE, "__pContext->Construct() failed.");
122 if (operation == INSTALLER_OPERATION_INSTALL)
125 r = File::GetAttributes(newPath, attr);
126 TryReturn(!IsFailed(r), INSTALLER_ERROR_PACKAGE_NOT_FOUND, "File::GetAttributes() failed");
128 if (attr.IsDirectory())
130 installerType = INSTALLER_TYPE_DIRECTORY;
132 if (newPath.EndsWith("/") == true)
134 int length = newPath.GetLength();
135 newPath.Remove(length - 1, 1);
136 AppLog("newPath=[%ls]", newPath.GetPointer());
139 if (newPath.StartsWith(PATH_USR_APPS, 0) == true)
141 installerType = INSTALLER_TYPE_PRELOADED;
142 __pContext->__isPreloaded = true;
145 __pContext->__inputPath = newPath;
146 __pContext->__installDir = newPath;
150 installerType = INSTALLER_TYPE_PACKAGE;
151 __pContext->__packagePath = newPath;
154 else if (operation == INSTALLER_OPERATION_UNINSTALL)
156 installerType = INSTALLER_TYPE_INSTALLER;
158 AppLog("operation is INSTALLER_OPERATION_UNINSTALL");
159 __pContext->SetCurrentInstallationStep(INSTALLER_STEP_INIT_UNINSTALL);
160 __pContext->__packageId = newPath;
163 __pContext->SetInstallerOperation(operation);
165 if (option & INSTALLER_OPTION_HYBRID)
167 AppLog("Request to install HybridService app!");
168 __pContext->__isHybridService = true;
171 __pInstaller = CreateInstaller(installerType);
172 TryReturn(__pInstaller, INSTALLER_ERROR_INTERNAL_STATE, "__pInstaller is null.");
174 error = __pInstaller->Construct(__pContext);
175 TryReturn(error == INSTALLER_ERROR_NONE, INSTALLER_ERROR_INTERNAL_STATE, "__pInstaller->Construct() failed");
181 InstallerManager::Release(void)
183 delete __pInstallerManager;
184 __pInstallerManager = null;
188 InstallerManager::CreateInstaller(InstallerType installerType)
190 Installer* pInstaller = null;
192 switch (installerType)
194 case INSTALLER_TYPE_INSTALLER:
195 AppLog("InstallerType = [Installer]");
196 pInstaller = new (std::nothrow) Installer();
199 case INSTALLER_TYPE_PACKAGE:
200 AppLog("InstallerType = [PackageInstaller]");
201 pInstaller = new (std::nothrow) PackageInstaller();
204 case INSTALLER_TYPE_DIRECTORY:
205 AppLog("InstallerType = [DirectoryInstaller]");
206 pInstaller = new (std::nothrow) DirectoryInstaller();
209 case INSTALLER_TYPE_GUEST:
210 AppLog("InstallerType = [GuestInstaller]");
211 pInstaller = new (std::nothrow) GuestInstaller();
214 case INSTALLER_TYPE_PRELOADED:
215 AppLog("InstallerType = [PreloadedInstaller]");
216 pInstaller = new (std::nothrow) PreloadedInstaller();
219 case INSTALLER_TYPE_IDE:
220 AppLog("InstallerType = [IDEInstaller]");
221 pInstaller = new (std::nothrow) IDEInstaller();
224 case INSTALLER_TYPE_RESTORATION:
225 AppLog("InstallerType = [RestorationInstaller]");
226 pInstaller = new (std::nothrow) RestorationInstaller();
230 AppLogExceptionTag(OSP_INSTALLER, "Installer is not found.");
238 InstallerManager::GetNext(void)
240 InstallationStep step = __pContext->GetCurrentInstallationStep();
241 return __pInstaller->GetNext(step);
245 InstallerManager::Init(void)
247 return __pInstaller->OnInit();
251 InstallerManager::Error(void)
253 return __pInstaller->OnError();
257 InstallerManager::Register(void)
259 return __pInstaller->OnRegister();
263 InstallerManager::End(void)
265 return __pInstaller->OnEnd();
269 InstallerManager::Rollback(void)
271 return __pInstaller->OnRollback();
275 InstallerManager::UserCancel(void)
277 return __pInstaller->OnUserCancel();
281 InstallerManager::Activate(void)
283 InstallerError error = INSTALLER_ERROR_NONE;
284 IInstallationStep* pStep = null;
285 InstallationStep currentStep;
287 while (__pContext->GetState() == INSTALLER_STATE_RUNNING)
289 currentStep = GetNext();
290 __pContext->ChangeStep(currentStep);
292 pStep = __pContext->GetStep();
295 error = pStep->Run(__pContext);
297 if (error != INSTALLER_ERROR_NONE)
299 __pContext->SetError(error);
305 if (currentStep == INSTALLER_STEP_INIT)
308 TryReturn(error == INSTALLER_ERROR_NONE, error, "error is occurred.");
310 else if (currentStep == INSTALLER_STEP_END)
313 TryReturn(error == INSTALLER_ERROR_NONE, error, "error is occurred.");
316 TryReturn(error == INSTALLER_ERROR_NONE, error, "error is occurred.");
319 if (__pContext->IsContinue() == false)
324 if (__pContext->GetCurrentInstallationStep() >= INSTALLER_STEP_MAX)
334 InstallerManager::Progress(void)
336 return INSTALLER_ERROR_NONE;
340 InstallerManager::GetContext(void)
346 InstallerManager::ParseCommandArg(int argc, char **argv, int *mode, char *buf, bool *output)
348 const char* pOpts_str = "u:i:r:v";
353 AppLog("mode is null");
361 s = getopt(argc, argv, pOpts_str);
376 AppLog("__osp_installer_parse_options: i");
377 *mode = INSTALLER_MODE_INSTALL;
378 if (optarg[0] == 'v')
380 AppLog("__osp_installer_parse_options: v");
382 strncpy(buf, argv[optind++], BUFSIZE);
383 AppLog("__osp_installer_parse_options: buf = [%s]", buf);
387 strncpy(buf, optarg, BUFSIZE);
388 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
398 AppLog("__osp_installer_parse_options: u");
399 *mode = INSTALLER_MODE_UNINSTALL;
400 if (optarg[0] == 'v')
402 AppLog("__osp_installer_parse_options: v");
404 strncpy(buf, argv[optind++], BUFSIZE);
405 AppLog("__osp_installer_parse_options: buf = [%s]", buf);
409 strncpy(buf, optarg, BUFSIZE);
410 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
420 AppLog("__osp_installer_parse_options: r");
421 *mode = INSTALLER_MODE_RECURSIVE_DIRECTORY_INSTALL;
422 strncpy(buf, optarg, BUFSIZE);
423 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
427 AppLog("__osp_installer_parse_options: v");
429 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
433 AppLog("Invalid option");
441 AppLog("Invalid mode");
449 InstallerManager::RemoveGarbage(const String& filePath)
451 AppLog("RemoveGarbage Directory = [%ls]", filePath.GetPointer());
454 if (InstallerUtil::IsSymlink(filePath) == true)
456 if (InstallerUtil::GetRealPath(filePath, realPath) == true)
458 InstallerUtil::Remove(realPath);
462 InstallerUtil::Remove(filePath);
468 InstallerManager::ReqeustByTest(void)
472 Tizen::Io::File file;
473 Tizen::Io::FileAttributes attr;
474 result r = E_SUCCESS;
475 char readBuf[512] = {0};
478 r = File::GetAttributes(L"/opt/apps/cmtamb4mtv/data/configuration", attr);
479 TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_PACKAGE_NOT_FOUND, "file not found");
481 r = file.Construct(L"/opt/apps/cmtamb4mtv/data/configuration", L"r");
482 TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_PACKAGE_NOT_FOUND, "file.Construct failed");
484 if (file.Read(readBuf, sizeof(readBuf)-1) > 1)
487 path.Format(1024, L"%s", &readBuf[1]);
489 if (readBuf[0] == '+')
491 errorType = InstallerManager::Request(path, INSTALLER_OPERATION_INSTALL, INSTALLER_OPTION_NORMAL, packageId);
493 else if (readBuf[0] == '-')
495 errorType = InstallerManager::Request(path, INSTALLER_OPERATION_UNINSTALL, INSTALLER_OPTION_NORMAL, packageId);
497 else if (readBuf[0] == '*')
499 errorType = InstallerManager::RequestRecursiveDirectory(path, errorType);
501 else if (readBuf[0] == '>')
503 errorType = InstallerManager::RequestMove(path, PM_MOVE_TO_SDCARD);
505 else if (readBuf[0] == '<')
507 errorType = InstallerManager::RequestMove(path, PM_MOVE_TO_INTERNAL);
516 InstallerManager::PrintResult(void)
518 int errorType = GetErrorType();
519 InstallerOperation operation = GetInstallerOperation();
521 Tizen::System::SystemTime::GetTicks(__endTick);
523 const char* pOperation = null;
524 (operation == INSTALLER_OPERATION_INSTALL)? (pOperation = "Install"): (pOperation = "Uninstall");
526 const wchar_t* pPackageId = L"Unknown";
527 if (__pContext && !__pContext->__packageId.IsEmpty())
529 pPackageId = __pContext->__packageId.GetPointer();
532 const wchar_t* pMainAppName = L"Unknown";
533 if (__pContext && !__pContext->__mainAppName.IsEmpty())
535 pMainAppName = __pContext->__mainAppName.GetPointer();
538 const char* pError = null;
539 (errorType == 0)?(pError = "Success"):(pError = "Failure");
541 int duration = (int)(__endTick - __startTick);
543 AppLog("==========================================");
544 AppLog(" # operation = %s", pOperation);
545 AppLog(" # %s", OSP_INSTALLER_VERSION);
546 AppLog(" # PackageId = [%ls]", pPackageId);
547 AppLog(" # MainApp = [%ls]", pMainAppName);
548 AppLog(" # Time = [%d]ms", duration);
549 PrintError(errorType);
550 AppLog("==========================================");
552 fprintf(stderr, " ## osp-installer: operation=[%s] result=[%s(%03d)] package id=[%ls] main appname=[%ls] time=[%d]ms\n",
553 pOperation, pError, errorType, pPackageId, pMainAppName, duration);
557 InstallerManager::PrintError(int errorType)
559 const char* pError = null;
563 case INSTALLER_ERROR_NONE:
567 case INSTALLER_ERROR_PACKAGE_NOT_FOUND:
568 pError = "[PACKAGE_NOT_FOUND] Thrown when package file is not found.";
571 case INSTALLER_ERROR_PACKAGE_INVALID:
572 pError = "[PACKAGE_INVALID] Thrown when package file is not valid due to file operation or directory hierarchy.";
575 case INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
576 pError = "[PACKAGE_LOWER_VERSION] Thrown when the lower version package is tried to install.";
579 case INSTALLER_ERROR_EXECUTABLE_NOT_FOUND:
580 pError = "[EXECUTABLE_NOT_FOUND] Thrown when executable file is not found in the package.";
583 case INSTALLER_ERROR_MANIFEST_NOT_FOUND:
584 pError = "[MANIFEST_NOT_FOUND] Thrown when manifest.xml is not found in the package.";
587 case INSTALLER_ERROR_MANIFEST_INVALID:
588 pError = "[MANIFEST_INVALID] Thrown when manifest.xml is not valid due to schema or parsing failure.";
591 case INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
592 pError = "[SIGNATURE_NOT_FOUND] Thrown when the signature files are not found in the package.";
595 case INSTALLER_ERROR_SIGNATURE_INVALID:
596 pError = "[SIGNATURE_INVALID] Thrown when the signature files are not valid due to schema or parsing failure.";
599 case INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
600 pError = "[SIGNATURE_VERIFICATION_FAILED] Thrown when the signature verification has failed due to be modified illegally.";
603 case INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
604 pError = "[ROOT_CERTIFICATE_NOT_FOUND] Thrown when the root certificate is not found.";
607 case INSTALLER_ERROR_CERTIFICATE_INVALID:
608 pError = "[CERTIFICATE_INVALID] Thrown when the certificate verification has failed.";
611 case INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
612 pError = "[CERTIFICATE_CHAIN_VERIFICATION_FAILED] Thrown when the certificate chain verification has failed.";
615 case INSTALLER_ERROR_CERTIFICATE_EXPIRED:
616 pError = "[CERTIFICATE_EXPIRED] Thrown when the used certificates have expired.";
619 case INSTALLER_ERROR_PRIVILEGE_INVALID:
620 pError = "[PRIVILEGE_INVALID] Thrown when unsupported privilege strings are detected.";
623 case INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
624 pError = "[MENU_ICON_NOT_FOUND] Thrown when an icon for menu is not found. This icon is mandatory.";
627 case INSTALLER_ERROR_FATAL_ERROR:
628 pError = "[FATAL_ERROR] Thrown when an icon for menu is not found. This icon is mandatory.";
631 case INSTALLER_ERROR_OUT_OF_STORAGE:
632 pError = "[OUT_OF_STORAGE] Thrown when the storage is full.";
635 case INSTALLER_ERROR_OUT_OF_MEMORY:
636 pError = "[OUT_OF_MEMORY] Thrown when the memory is not sufficient to perform the requested installation or uninstallation.";
640 pError = "fatal error";
644 AppLog(" # Error = %s(%d)", pError, errorType);
648 InstallerManager::GetId(void) const
654 InstallerManager::SetId(const PackageId& packageId)
656 __packageId = packageId;
660 InstallerManager::GetErrorType(void) const
666 InstallerManager::SetErrorType(int errorType)
668 __errorType = errorType;
672 InstallerManager::SetInstallerOperation(InstallerOperation op)
678 InstallerManager::GetInstallerOperation(void) const
684 InstallerManager::GetLogFilePath() const
686 return __logFilePath;
690 InstallerManager::IsFileLogOn() const
692 return __isFileLogOn;
696 InstallerManager::Request(const String& path, InstallerOperation operation, InstallerOption option, PackageId& packageId)
698 InstallationContext* pContext = null;
699 InstallerError errorType = INSTALLER_ERROR_NONE;
700 InstallerManager* pInstallManager = null;
702 if (File::IsFileExist(DIR_OSP_APPLICATIONS_TEMP) == true)
704 InstallerUtil::Remove(DIR_OSP_APPLICATIONS_TEMP);
706 pInstallManager = InstallerManager::GetInstance();
707 TryCatch(pInstallManager, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pInstallManager is null.");
709 errorType = pInstallManager->Construct(path, operation, option);
710 TryCatch(errorType == INSTALLER_ERROR_NONE, , "pInstallManager->Construct() failed.");
712 errorType = pInstallManager->Activate();
713 TryCatch(errorType == INSTALLER_ERROR_NONE, , "pInstallManager->Activate() failed.");
715 pContext = pInstallManager->GetContext();
716 TryCatch(pContext, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pInstallManager->GetContext failed.");
717 packageId = pContext->__packageId;
720 pInstallManager->SetErrorType(errorType);
724 if (!(option & INSTALLER_OPTION_NO_INPUT))
726 pInstallManager->PrintResult();
729 if (errorType != INSTALLER_ERROR_NONE)
731 InstallerUtil::PrintLog(pInstallManager->GetLogFilePath());
734 pInstallManager->Release();
737 if (File::IsFileExist(DIR_OSP_APPLICATIONS_TEMP) == true)
739 InstallerUtil::Remove(DIR_OSP_APPLICATIONS_TEMP);
746 InstallerManager::RequestRecursiveDirectory(const Tizen::Base::String& path, int& errorType)
748 Directory* pDir = null;
749 DirEnumerator* pDirEnum = null;
750 result r = E_SUCCESS;
753 InstallerError error = INSTALLER_ERROR_NONE;
755 int successCount = 0;
756 int failureCount = 0;
759 pDir = new (std::nothrow) Directory; // Allocate %Directory instance
760 TryCatch(pDir, res = false, "pDir is null");
762 r = pDir->Construct(path);
763 TryCatch(!IsFailed(r), res = false, "pDir->Construct() failed, path = [%ls]", path.GetPointer());
765 pDirEnum = pDir->ReadN();
766 TryCatch(pDirEnum, res = false, "pDirEnum is null");
768 while (pDirEnum->MoveNext() == E_SUCCESS)
770 DirEntry entry = pDirEnum->GetCurrentDirEntry();
772 String entryName = entry.GetName();
773 String entryDir = path;
775 entryDir += entryName;
777 if (entryName == L"." || entryName == L"..")
782 if (entry.IsDirectory() == false)
787 const int entryLength = entryName.GetLength();
788 if (entryLength == PACKAGE_ID_LENGTH)
792 else if (entryLength == APP_DIR_LENGTH)
794 if (entryName.Contains(PACKAGE_NAME_PREFIX_ORG) == false)
796 AppLog(" - Not osp = [%ls]: prefix mismatch", entryDir.GetPointer());
802 AppLog(" - Not osp = [%ls]: length(%d) mismatch", entryDir.GetPointer(), entryLength);
807 xmlFile.Format(1024, L"%ls%ls", entryDir.GetPointer(), PACKAGE_XML_FILE);
810 r = File::GetAttributes(xmlFile, attr);
813 AppLog(" - Not osp = [%ls]: No manifest.xml", entryDir.GetPointer());
819 AppLog("------------------------------------------");
820 AppLog(" # Directory = [%ls]", entryDir.GetPointer());
822 errorType = Request(entryDir, INSTALLER_OPERATION_INSTALL, INSTALLER_OPTION_NORMAL, packageId);
832 AppLog("------------------------------------------");
835 AppLog("------------------------------------------");
836 AppLog("recursive directory installation");
837 AppLog(" # totalCount = [%d]", totalCount);
838 AppLog(" # successCount = [%d]", successCount);
839 AppLog(" # failureCount = [%d]", failureCount);
848 InstallerManager::RequestByCommand(int argc, char **argv)
851 char buf[BUFSIZE] = {0};
855 InstallerOption option = INSTALLER_OPTION_NORMAL;
857 AppLog(" # argc = [%d]", argc);
859 for (int i = 0; i < argc; i++)
861 AppLog(" # argv[%d] = [%s]", i, argv[i]);
864 InstallerManager::ParseCommandArg(argc, argv, &mode, buf, &output);
867 AppLog("HybridService is detected in ParseCommandArg()");
868 option = (InstallerOption)(option | INSTALLER_OPTION_HYBRID);
873 case INSTALLER_MODE_INSTALL:
875 AppLog("------------------------------------------");
876 AppLog(" # Directory = [%s]", buf);
878 option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
879 errorType = InstallerManager::Request(buf, INSTALLER_OPERATION_INSTALL, option, packageId);
882 // in case of command, garbage directory is not deleted.
883 // RemoveGarbage(buf);
888 case INSTALLER_MODE_UNINSTALL:
890 AppLog("------------------------------------------");
891 AppLog(" # Directory = [%s]", buf);
893 option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
894 errorType = InstallerManager::Request(buf, INSTALLER_OPERATION_UNINSTALL, option, packageId);
898 case INSTALLER_MODE_RECURSIVE_DIRECTORY_INSTALL:
900 AppLog("------------------------------------------");
902 errorType = InstallerManager::RequestRecursiveDirectory(buf, errorType);
908 AppLog("__install_package_by_cmd, Invalid mode");
913 AppLog("==========================================");
917 AppLog("stdout is updated by errorType");
918 fprintf(stdout, "%d", errorType);
925 InstallerManager::RequestMove(const PackageId& packageId, int moveType)
927 result r = E_SUCCESS;
929 InstallerError errorType = INSTALLER_ERROR_NONE;
930 app2ext_handle* pHandle = null;
931 app2ext_move_type location = APP2EXT_MOVE_TO_EXT;
932 GList* pDirectoryList = null;
933 Directory* pDir = null;
934 DirEnumerator* pDirEnum = null;
935 PackageInfo* pPackageInfo = null;
936 _PackageInfoImpl* pPackageInfoImpl = null;
939 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
940 TryReturn(pPackageId, INSTALLER_ERROR_OUT_OF_MEMORY, "pPackageId is null");
942 if (moveType == PM_MOVE_TO_INTERNAL)
944 location = APP2EXT_MOVE_TO_PHONE;
947 pPackageInfo = _PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId);
948 TryCatch(pPackageInfo != null, errorType = INSTALLER_ERROR_INTERNAL_STATE, "GetPackageInfoN() failed");
950 pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo);
951 TryCatch(pPackageInfoImpl, errorType = INSTALLER_ERROR_INTERNAL_STATE, "GetInstance() failed");
953 rootPath = pPackageInfoImpl->GetAppRootPath();
955 pHandle = app2ext_init(APP2EXT_SD_CARD);
956 TryCatch(pHandle, errorType = INSTALLER_ERROR_INTERNAL_STATE, "app2ext_init() failed");
958 if (location == APP2EXT_MOVE_TO_PHONE)
960 res = pHandle->interface.enable(pPackageId.get());
963 pDir = new (std::nothrow) Directory;
964 TryCatch(pDir, errorType = INSTALLER_ERROR_OUT_OF_MEMORY, "pDir is null");
966 r = pDir->Construct(rootPath);
967 TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDir->Construct() failed, path = [%ls]", rootPath.GetPointer());
969 pDirEnum = pDir->ReadN();
970 TryCatch(pDirEnum, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDirEnum is null");
972 while (pDirEnum->MoveNext() == E_SUCCESS)
974 DirEntry entry = pDirEnum->GetCurrentDirEntry();
976 String entryName = entry.GetName();
977 //String rootDirectory = rootPath;
978 //rootDirectory += L"/";
979 //rootDirectory += entryName;
981 if (entryName == L"." || entryName == L"..")
987 app2ext_dir_details* pDirDetails = null;
989 pDirDetails = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
990 TryCatch(pDirDetails, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDirDetails is null");
992 length = entryName.GetLength();
993 pDirDetails->name = (char*) calloc(1, (sizeof(char) * length) + 1);
994 snprintf(pDirDetails->name, length + 1, "%ls", entryName.GetPointer());
998 String icons(L"icons");
1000 if (entryName.Contains(bin) || entryName.Contains(res) || entryName.Contains(icons))
1002 pDirDetails->type = APP2EXT_DIR_RO;
1006 pDirDetails->type = APP2EXT_DIR_RW;
1009 AppLog("------------------------------------------");
1010 AppLog("# Root Directory = [%s], Type = [%d]", pDirDetails->name, pDirDetails->type);
1012 pDirectoryList = g_list_append(pDirectoryList, pDirDetails);
1015 res = pHandle->interface.move(pPackageId.get(), pDirectoryList, location);
1016 TryCatch(res == 0, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pHandle->interface.move() failed [%d]", res);
1018 app2ext_deinit(pHandle);
1023 GList* pList = null;
1024 app2ext_dir_details* pDirDetails = null;
1026 pList = g_list_first(pDirectoryList);
1029 pDirDetails = (app2ext_dir_details*)pList->data;
1030 if (pDirDetails && pDirDetails->name)
1032 free(pDirDetails->name);
1034 pList = g_list_next(pList);
1036 g_list_free(pDirectoryList);
1041 delete pPackageInfo;