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 UnpackStep.cpp
19 * @brief This is the implementation file for %UnpackStep class.
22 #include <unique_ptr.h>
24 #include <app2ext_interface.h>
27 #include <FIoDirectory.h>
28 #include <FBaseUtilFileUnzipper.h>
29 #include <FBase_StringConverter.h>
31 #include "InstallationContext.h"
32 #include "UnpackStep.h"
33 #include "InstallerUtil.h"
34 #include "ConfigurationManager.h"
36 using namespace Tizen::App;
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Base::Utility;
40 using namespace Tizen::Io;
42 UnpackStep::UnpackStep(void)
43 :__state(STATE_BACKUP)
45 ,__pDirectoryList(null)
46 ,__uncompressedSize(0)
50 UnpackStep::~UnpackStep(void)
55 app2ext_dir_details* pDirDetails = null;
57 pList = g_list_first(__pDirectoryList);
60 pDirDetails = (app2ext_dir_details*)pList->data;
61 if (pDirDetails && pDirDetails->name)
63 free(pDirDetails->name);
65 pList = g_list_next(pList);
67 g_list_free(__pDirectoryList);
72 UnpackStep::Run(InstallationContext* pContext)
74 InstallerError error = INSTALLER_ERROR_NONE;
75 AppLog(" UnpackStep - START");
77 __pContext = pContext;
84 AppLog("[STATE_BACKUP]");
85 error = OnStateBackup();
89 AppLog("[STATE_UNZIP]");
94 AppLog("[STATE_FILE_MOVE]");
95 error = OnStateFileMove();
98 case STATE_CREATE_DIR:
99 AppLog("[STATE_CREATE_DIR]");
100 error = OnCreateDir();
104 AppLog("[STATE_DONE]");
105 error = OnStateDone();
112 if (error != INSTALLER_ERROR_NONE)
117 if (__state > STATE_DONE)
119 AppLog(" UnpackStep - END");
128 UnpackStep::GoNextState(void)
134 UnpackStep::OnStateBackup(void)
136 InstallerError error = INSTALLER_ERROR_NONE;
139 if ((__pContext->__isUpdated == true) && (__pContext->__isPreloaded == false))
141 ConfigurationManager configurationManager;
142 bool res = configurationManager.CreateBackup(__pContext);
143 TryReturn(res == true, INSTALLER_ERROR_BACKUP_FAILED, "configurationManager.CreateBackup(%ls) failed.", __pContext->__packageId.GetPointer());
152 UnpackStep::OnUnzip(void)
154 InstallerError error = INSTALLER_ERROR_NONE;
155 String newInstallPath;
156 app2ext_handle* pHandle = null;
159 installPath = PATH_OPT_USR_APPS;
161 installPath += __pContext->__packageId;
163 result r = E_SUCCESS;
164 FileUnzipper unzipper;
165 r = unzipper.Construct(__pContext->__packagePath);
166 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "unzipper.Construct() failed");
168 if (__pContext->__storage == INSTALLATION_STORAGE_EXTERNAL)
171 PackageId packageId = __pContext->__packageId;
173 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
174 TryReturn(pPackageId, INSTALLER_ERROR_INTERNAL_STATE, "pPackageId is null");
176 GetUncompressedInfo(unzipper);
177 TryReturn((__pDirectoryList && (__uncompressedSize > 0)), INSTALLER_ERROR_INTERNAL_STATE, "GetUncompressedInfo() failed");
179 pHandle = app2ext_init(APP2EXT_SD_CARD);
180 TryReturn(pHandle, INSTALLER_ERROR_INTERNAL_STATE, "app2ext_init() failed");
182 __pContext->__pApp2ExtHandle = (void*)pHandle;
184 res = pHandle->interface.pre_install(pPackageId.get(), __pDirectoryList, __uncompressedSize);
185 TryReturn(res == 0, INSTALLER_ERROR_INTERNAL_STATE, "pHandle->interface.pre_install() failed [%d]", res);
187 AppLog("[app2sd] pre_install(%s)", pPackageId.get());
190 if (File::IsFileExist(installPath) == false)
192 r = Directory::Create(installPath, false);
193 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "Directory::Create() failed, installPath=%ls", installPath.GetPointer());
196 InstallerUtil::CreateSymlinkForAppDirectory(installPath, newInstallPath);
197 __pContext->__installDir = newInstallPath;
198 __pContext->__rootPath = newInstallPath;
200 if (__pContext->__isUpdated == true)
202 RemoveRoDirectory(installPath);
205 AppLog("UnzipTo - START");
206 r = unzipper.UnzipTo(newInstallPath);
207 TryReturn(!IsFailed(r), INSTALLER_ERROR_PACKAGE_INVALID, "UnzipTo(%ls) failed.", newInstallPath.GetPointer());
208 AppLog("UnzipTo - END");
211 __state = STATE_DONE;
216 UnpackStep::OnStateFileMove(void)
218 InstallerError error = INSTALLER_ERROR_NONE;
225 UnpackStep::OnCreateDir(void)
227 InstallerError error = INSTALLER_ERROR_NONE;
234 UnpackStep::OnStateDone(void)
236 InstallerError error = INSTALLER_ERROR_NONE;
243 UnpackStep::CreateDefaultDir(void)
245 // Directory::Create(DIR_OSP_APPLICATION_PHONE, true);
246 // Directory::Create(DIR_OSP_APPLICATION_MMC, true);
252 UnpackStep::GetUncompressedInfo(const FileUnzipper& unzipper)
254 result r = E_SUCCESS;
255 unsigned long totalSize = 0;
258 ArrayList directoryList;
259 int entryCount = unzipper.GetEntryCount();
261 directoryList.Construct();
263 for(int i = 0; i < entryCount; i++)
267 unsigned long uncompressedSize = 0;
270 unzipper.GetEntry(i, zipEntry);
271 entryName = zipEntry.GetName();
273 while((r = entryName.IndexOf(L'/', startIndex, indexOf)) == E_SUCCESS)
275 String* pCurDirectory = new (std::nothrow) String;
276 TryReturn(pCurDirectory, false, "pCurDirectory is null.");
278 entryName.SubString(0, indexOf, *pCurDirectory);
280 if (directoryList.Contains(*pCurDirectory) == false)
284 AddDirectory(*pCurDirectory);
287 AppLog("Folder[%ls], Size[%d]", pCurDirectory->GetPointer(), INSTALLER_BLOCK_SIZE);
288 totalSize += INSTALLER_BLOCK_SIZE;
290 directoryList.Add(*pCurDirectory);
293 startIndex = indexOf + 1;
296 if (zipEntry.IsDirectory() == false)
298 uncompressedSize = zipEntry.GetUncompressedSize();
300 int blockCount = uncompressedSize / INSTALLER_BLOCK_SIZE;
302 if ((blockCount == 0) && (uncompressedSize != 0))
304 uncompressedSize = INSTALLER_BLOCK_SIZE;
308 int mod = uncompressedSize % INSTALLER_BLOCK_SIZE;
313 uncompressedSize = (INSTALLER_BLOCK_SIZE * blockCount);
316 totalSize += uncompressedSize;
317 AppLog(" -File[%ls], UncompressedSize[%d]", entryName.GetPointer(), (int)uncompressedSize);
321 directoryList.RemoveAll(true);
322 __uncompressedSize = (int)(totalSize / (1024 * 1024)) + 1;
324 AppLog("------------------------------------------");
325 AppLog("TotalSize = [%d]B", (int)totalSize);
326 AppLog("TotalSize = [%d]MB", __uncompressedSize);
327 AppLog("------------------------------------------");
334 UnpackStep::AddDirectory(const String& rootDirectory)
337 app2ext_dir_details* pDirDetails = null;
339 pDirDetails = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
340 TryReturn(pDirDetails, false, "pDirDetails is null");
342 length = rootDirectory.GetLength();
343 pDirDetails->name = (char*) calloc(1, (sizeof(char) * length) + 1);
344 snprintf(pDirDetails->name, length + 1, "%ls", rootDirectory.GetPointer());
346 if ((rootDirectory == L"data") || (rootDirectory == L"shared") || (rootDirectory == L"setting"))
348 pDirDetails->type = APP2EXT_DIR_RW;
352 pDirDetails->type = APP2EXT_DIR_RO;
355 AppLog("------------------------------------------");
356 AppLog("# Root Directory = [%s], Type = [%d]", pDirDetails->name, pDirDetails->type);
358 __pDirectoryList = g_list_append(__pDirectoryList, pDirDetails);
364 UnpackStep::RemoveRoDirectory(const String& rootPath)
366 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
367 TryReturn(pDir, false, "pDir is null.");
369 result r = pDir->Construct(rootPath);
370 TryReturn(!IsFailed(r), false, "pDir->Construct() failed. rootPath = [%ls]", rootPath.GetPointer());
372 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
373 TryReturn(pDirEnum, false, "pDirEnum is null.");
375 while (pDirEnum->MoveNext() == E_SUCCESS)
377 DirEntry entry = pDirEnum->GetCurrentDirEntry();
379 String entryName = entry.GetName();
380 String srcEntryDir = rootPath;
382 srcEntryDir += entryName;
384 if (entryName == L"." || entryName == L"..")
388 else if (entryName == L"data")
390 AppLog("skip, directory=[%ls]", srcEntryDir.GetPointer());
393 else if (entryName == L"shared")
395 RemoveSharedDirectory(srcEntryDir);
399 InstallerUtil::Remove(srcEntryDir);
406 UnpackStep::RemoveSharedDirectory(const String& sharedPath)
408 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
409 TryReturn(pDir, false, "pDir is null.");
411 result r = pDir->Construct(sharedPath);
412 TryReturn(!IsFailed(r), false, "pDir->Construct() failed. sharedPath = [%ls]", sharedPath.GetPointer());
414 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
415 TryReturn(pDirEnum, false, "pDirEnum is null.");
417 while (pDirEnum->MoveNext() == E_SUCCESS)
419 DirEntry entry = pDirEnum->GetCurrentDirEntry();
421 String entryName = entry.GetName();
422 String srcEntryDir = sharedPath;
424 srcEntryDir += entryName;
426 if (entryName == L"." || entryName == L"..")
430 else if (entryName == L"data" || entryName == L"trusted")
432 AppLog("skip, directory=[%ls]", srcEntryDir.GetPointer());
436 InstallerUtil::Remove(srcEntryDir);