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"
35 using namespace Tizen::App;
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Base::Utility;
39 using namespace Tizen::Io;
41 UnpackStep::UnpackStep(void)
44 ,__pDirectoryList(null)
45 ,__uncompressedSize(0)
49 UnpackStep::~UnpackStep(void)
54 app2ext_dir_details* pDirDetails = null;
56 pList = g_list_first(__pDirectoryList);
59 pDirDetails = (app2ext_dir_details*)pList->data;
60 if (pDirDetails && pDirDetails->name)
62 free(pDirDetails->name);
64 pList = g_list_next(pList);
66 g_list_free(__pDirectoryList);
71 UnpackStep::Run(InstallationContext* pContext)
73 InstallerError error = INSTALLER_ERROR_NONE;
74 AppLog(" UnpackStep - START");
76 __pContext = pContext;
83 AppLog("[STATE_UNZIP]");
88 AppLog("[STATE_FILE_MOVE]");
89 error = OnStateFileMove();
92 case STATE_CREATE_DIR:
93 AppLog("[STATE_CREATE_DIR]");
94 error = OnCreateDir();
98 AppLog("[STATE_DONE]");
99 error = OnStateDone();
106 if (error != INSTALLER_ERROR_NONE)
111 if (__state > STATE_DONE)
113 AppLog(" UnpackStep - END");
122 UnpackStep::GoNextState(void)
128 UnpackStep::OnUnzip(void)
130 InstallerError error = INSTALLER_ERROR_NONE;
131 String newInstallPath;
132 app2ext_handle* pHandle = null;
135 installPath = PATH_OPT_USR_APPS;
137 installPath += __pContext->__packageId;
139 result r = E_SUCCESS;
140 FileUnzipper unzipper;
141 r = unzipper.Construct(__pContext->__packagePath);
142 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "unzipper.Construct() failed");
144 if (__pContext->__storage == INSTALLATION_STORAGE_EXTERNAL)
147 PackageId packageId = __pContext->__packageId;
149 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
150 TryReturn(pPackageId, INSTALLER_ERROR_INTERNAL_STATE, "pPackageId is null");
152 GetUncompressedInfo(unzipper);
153 TryReturn((__pDirectoryList && (__uncompressedSize > 0)), INSTALLER_ERROR_INTERNAL_STATE, "GetUncompressedInfo() failed");
155 pHandle = app2ext_init(APP2EXT_SD_CARD);
156 TryReturn(pHandle, INSTALLER_ERROR_INTERNAL_STATE, "app2ext_init() failed");
158 __pContext->__pApp2ExtHandle = (void*)pHandle;
160 res = pHandle->interface.pre_install(pPackageId.get(), __pDirectoryList, __uncompressedSize);
161 TryReturn(res == 0, INSTALLER_ERROR_INTERNAL_STATE, "pHandle->interface.pre_install() failed [%d]", res);
163 AppLog("[app2sd] pre_install(%s)", pPackageId.get());
166 if (File::IsFileExist(installPath) == false)
168 r = Directory::Create(installPath, false);
169 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "Directory::Create() failed, installPath=%ls", installPath.GetPointer());
172 InstallerUtil::CreateSymlinkForAppDirectory(installPath, newInstallPath);
173 __pContext->__installDir = newInstallPath;
174 __pContext->__rootPath = newInstallPath;
176 if (__pContext->__isUpdated == true)
178 RemoveRoDirectory(installPath);
181 AppLog("UnzipTo - START");
182 r = unzipper.UnzipTo(newInstallPath);
183 TryReturn(!IsFailed(r), INSTALLER_ERROR_PACKAGE_INVALID, "UnzipTo(%ls) failed.", newInstallPath.GetPointer());
184 AppLog("UnzipTo - END");
187 __state = STATE_DONE;
192 UnpackStep::OnStateFileMove(void)
194 InstallerError error = INSTALLER_ERROR_NONE;
201 UnpackStep::OnCreateDir(void)
203 InstallerError error = INSTALLER_ERROR_NONE;
210 UnpackStep::OnStateDone(void)
212 InstallerError error = INSTALLER_ERROR_NONE;
219 UnpackStep::CreateDefaultDir(void)
221 // Directory::Create(DIR_OSP_APPLICATION_PHONE, true);
222 // Directory::Create(DIR_OSP_APPLICATION_MMC, true);
228 UnpackStep::GetUncompressedInfo(const FileUnzipper& unzipper)
230 result r = E_SUCCESS;
231 unsigned long totalSize = 0;
234 ArrayList directoryList;
235 int entryCount = unzipper.GetEntryCount();
237 directoryList.Construct();
239 for(int i = 0; i < entryCount; i++)
243 unsigned long uncompressedSize = 0;
246 unzipper.GetEntry(i, zipEntry);
247 entryName = zipEntry.GetName();
249 while((r = entryName.IndexOf(L'/', startIndex, indexOf)) == E_SUCCESS)
251 String* pCurDirectory = new (std::nothrow) String;
252 TryReturn(pCurDirectory, false, "pCurDirectory is null.");
254 entryName.SubString(0, indexOf, *pCurDirectory);
256 if (directoryList.Contains(*pCurDirectory) == false)
260 AddDirectory(*pCurDirectory);
263 AppLog("Folder[%ls], Size[%d]", pCurDirectory->GetPointer(), INSTALLER_BLOCK_SIZE);
264 totalSize += INSTALLER_BLOCK_SIZE;
266 directoryList.Add(*pCurDirectory);
269 startIndex = indexOf + 1;
272 if (zipEntry.IsDirectory() == false)
274 uncompressedSize = zipEntry.GetUncompressedSize();
276 int blockCount = uncompressedSize / INSTALLER_BLOCK_SIZE;
278 if ((blockCount == 0) && (uncompressedSize != 0))
280 uncompressedSize = INSTALLER_BLOCK_SIZE;
284 int mod = uncompressedSize % INSTALLER_BLOCK_SIZE;
289 uncompressedSize = (INSTALLER_BLOCK_SIZE * blockCount);
292 totalSize += uncompressedSize;
293 AppLog(" -File[%ls], UncompressedSize[%d]", entryName.GetPointer(), (int)uncompressedSize);
297 directoryList.RemoveAll(true);
298 __uncompressedSize = (int)(totalSize / (1024 * 1024)) + 1;
300 AppLog("------------------------------------------");
301 AppLog("TotalSize = [%d]B", (int)totalSize);
302 AppLog("TotalSize = [%d]MB", __uncompressedSize);
303 AppLog("------------------------------------------");
310 UnpackStep::AddDirectory(const String& rootDirectory)
313 app2ext_dir_details* pDirDetails = null;
315 pDirDetails = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
316 TryReturn(pDirDetails, false, "pDirDetails is null");
318 length = rootDirectory.GetLength();
319 pDirDetails->name = (char*) calloc(1, (sizeof(char) * length) + 1);
320 snprintf(pDirDetails->name, length + 1, "%ls", rootDirectory.GetPointer());
322 if ((rootDirectory == L"data") || (rootDirectory == L"shared") || (rootDirectory == L"setting"))
324 pDirDetails->type = APP2EXT_DIR_RW;
328 pDirDetails->type = APP2EXT_DIR_RO;
331 AppLog("------------------------------------------");
332 AppLog("# Root Directory = [%s], Type = [%d]", pDirDetails->name, pDirDetails->type);
334 __pDirectoryList = g_list_append(__pDirectoryList, pDirDetails);
340 UnpackStep::RemoveRoDirectory(const String& rootPath)
342 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
343 TryReturn(pDir, false, "pDir is null.");
345 result r = pDir->Construct(rootPath);
346 TryReturn(!IsFailed(r), false, "pDir->Construct() failed. rootPath = [%ls]", rootPath.GetPointer());
348 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
349 TryReturn(pDirEnum, false, "pDirEnum is null.");
351 while (pDirEnum->MoveNext() == E_SUCCESS)
353 DirEntry entry = pDirEnum->GetCurrentDirEntry();
355 String entryName = entry.GetName();
356 String srcEntryDir = rootPath;
358 srcEntryDir += entryName;
360 if (entryName == L"." || entryName == L"..")
364 else if (entryName == L"data")
366 AppLog("skip, directory=[%ls]", srcEntryDir.GetPointer());
369 else if (entryName == L"shared")
371 RemoveSharedDirectory(srcEntryDir);
375 InstallerUtil::Remove(srcEntryDir);
382 UnpackStep::RemoveSharedDirectory(const String& sharedPath)
384 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
385 TryReturn(pDir, false, "pDir is null.");
387 result r = pDir->Construct(sharedPath);
388 TryReturn(!IsFailed(r), false, "pDir->Construct() failed. sharedPath = [%ls]", sharedPath.GetPointer());
390 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
391 TryReturn(pDirEnum, false, "pDirEnum is null.");
393 while (pDirEnum->MoveNext() == E_SUCCESS)
395 DirEntry entry = pDirEnum->GetCurrentDirEntry();
397 String entryName = entry.GetName();
398 String srcEntryDir = sharedPath;
400 srcEntryDir += entryName;
402 if (entryName == L"." || entryName == L"..")
406 else if (entryName == L"data" || entryName == L"trusted")
408 AppLog("skip, directory=[%ls]", srcEntryDir.GetPointer());
412 InstallerUtil::Remove(srcEntryDir);