828978dc2bf219c3928d6d0400097f55a640da99
[platform/framework/native/installer.git] / src / Manager / InstallerManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17 /**
18  * @file        InstallerManager.cpp
19  * @brief       This is the implementation file for %InstallerManager class.
20  */
21
22 #include <unistd.h>
23 #include <unique_ptr.h>
24 #include <stdio.h>
25
26 #include <app2ext_interface.h>
27 #include <pkgmgr_installer.h>
28
29 #include <FIoFile.h>
30 #include <FIoDirectory.h>
31 #include <FBase_StringConverter.h>
32 #include <FAppPkgPackageInfo.h>
33 #include <FAppPkg_PackageManagerImpl.h>
34 #include <FAppPkg_PackageInfoImpl.h>
35 #include <FSysSystemTime.h>
36
37 #include "InstallerManager.h"
38 #include "GuestInstaller.h"
39 #include "IDEInstaller.h"
40 #include "PreloadedInstaller.h"
41 #include "RestorationInstaller.h"
42 #include "InstallerUtil.h"
43
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Utility;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Io;
48 using namespace Tizen::App;
49 using namespace Tizen::App::Package;
50
51 const int BUFSIZE = 512;
52 InstallerManager* InstallerManager::__pInstallerManager = null;
53
54 InstallerManager::InstallerManager(void)
55 :__pContext(null)
56 ,__pInstaller(null)
57 ,__errorType(0)
58 ,__operation(INSTALLER_OPERATION_INSTALL)
59 ,__startTick(0)
60 ,__endTick(0)
61 ,__isFileLogOn(false)
62 ,__isHistoryFileLogOn(false)
63 {
64 }
65
66 InstallerManager::~InstallerManager(void)
67 {
68         delete __pContext;
69         __pContext = null;
70
71         delete __pInstaller;
72         __pInstaller = null;
73 }
74
75 InstallerManager*
76 InstallerManager::GetInstance()
77 {
78         if (__pInstallerManager == null)
79         {
80                 __pInstallerManager = new InstallerManager();
81                 TryReturn(__pInstallerManager, null, "__pInstallerManager is null");
82         }
83
84         return __pInstallerManager;
85 }
86
87 InstallerError
88 InstallerManager::Construct(const String& path, InstallerOperation operation, InstallerOption option, void* pPkgmgrInstaller, const String* pOptionalData)
89 {
90         InstallerError error = INSTALLER_ERROR_NONE;
91         InstallerType installerType = INSTALLER_TYPE_INSTALLER;
92         result r = E_SUCCESS;
93         String newPath = path;
94
95         Tizen::System::SystemTime::GetTicks(__startTick);
96         SetInstallerOperation(operation);
97
98         if (option & INSTALLER_OPTION_FILELOG_ON)
99         {
100                 r = Directory::Create(DIR_OSP_APPLICATIONS_TEMP, false);
101                 if (!IsFailed(r))
102                 {
103                         __logFilePath = DIR_OSP_APPLICATIONS_TEMP;
104                         __logFilePath += L"/log.txt";
105                         InstallerUtil::CreateLog(__logFilePath);
106
107                         __isFileLogOn = true;
108                 }
109
110                 if (File::IsFileExist(DIR_INSTALL_LOGS) == false)
111                 {
112                         r = Directory::Create(DIR_INSTALL_LOGS, false);
113                         if (IsFailed(r))
114                         {
115                                 // logs
116                         }
117                 }
118
119                 String logPath = path;
120                 String logId;
121                 int length = logPath.GetLength();
122                 if (logPath.EndsWith("/") == true)
123                 {
124                         logPath.Remove(length - 1, 1);
125                         length--;
126                 }
127                 logPath.SubString(length - PACKAGE_ID_LENGTH, PACKAGE_ID_LENGTH, logId);
128                 AppLog("logPath = [%ls], logId = [%ls]", __historyLogFilePath.GetPointer(), logId.GetPointer());
129
130                 __historyLogFilePath = DIR_INSTALL_LOGS;
131                 __historyLogFilePath += L"/";
132                 __historyLogFilePath += logId;
133                 __historyLogFilePath += L".txt";
134                 InstallerUtil::CreateLog(__historyLogFilePath);
135
136                 AppLog("__historyLogFilePath = [%ls]", __historyLogFilePath.GetPointer());
137
138                 __isHistoryFileLogOn = true;
139         }
140
141         AppLog("------------------------------------------");
142         AppLog("InstallerManager");
143         AppLog("------------------------------------------");
144         AppLog(" # operation = [%s]", InstallerUtil::GetInstallerOperationString(operation));
145         AppLog(" # path      = [%ls]", path.GetPointer());
146         AppLog("------------------------------------------");
147
148         __pContext = new InstallationContext();
149         TryReturn(__pContext, INSTALLER_ERROR_OUT_OF_MEMORY, "__pContext is null.");
150
151         error = __pContext->Construct();
152         TryReturn(error == INSTALLER_ERROR_NONE, INSTALLER_ERROR_INTERNAL_STATE, "__pContext->Construct() failed.");
153
154         __pContext->__pPkgmgrInstaller = pPkgmgrInstaller;
155
156         if (operation == INSTALLER_OPERATION_INSTALL)
157         {
158                 FileAttributes attr;
159                 r = File::GetAttributes(newPath, attr);
160                 TryReturn(!IsFailed(r), INSTALLER_ERROR_PACKAGE_NOT_FOUND, "File::GetAttributes() failed");
161
162                 if (attr.IsDirectory())
163                 {
164                         installerType = INSTALLER_TYPE_DIRECTORY;
165
166                         if (newPath.EndsWith("/") == true)
167                         {
168                                 int length = newPath.GetLength();
169                                 newPath.Remove(length - 1, 1);
170                                 AppLog("newPath=[%ls]", newPath.GetPointer());
171                         }
172
173                         if (newPath.StartsWith(PATH_USR_APPS, 0) == true)
174                         {
175                                 installerType = INSTALLER_TYPE_PRELOADED;
176                                 __pContext->__isPreloaded = true;
177                         }
178
179                         __pContext->__inputPath = newPath;
180                         __pContext->__installDir = newPath;
181                         __pContext->__packageSize = InstallerUtil::GetDisplaySize(newPath);
182                 }
183                 else
184                 {
185                         if (option & INSTALLER_OPTION_CSC)
186                         {
187                                 AppLog("INSTALLER_OPTION_CSC is detected.");
188                                 __pContext->__isCsc = true;
189                                 __pContext->__cscInfo = *pOptionalData;
190                         }
191
192                         installerType = INSTALLER_TYPE_PACKAGE;
193                         __pContext->__packagePath = newPath;
194                         __pContext->__packageSize = InstallerUtil::GetDisplaySize(newPath);
195                 }
196
197                 if (pOptionalData)
198                 {
199                         ParseOptionalData(pOptionalData);
200                         SendEvent(__pContext, __pContext->__packageId, "start", "install");
201                 }
202                 else
203                 {
204                         AppLog("Input param(package) is null in case of cmd, hybrid package.");
205                 }
206
207                 if (option & INSTALLER_OPTION_RESET_PRELOADED)
208                 {
209                         TryReturn(__pContext->__packageId.IsEmpty() == false, INSTALLER_ERROR_INTERNAL_STATE, "packageId is empty.");
210
211                         String rootPath(PATH_OPT_USR_APPS);
212                         rootPath += L"/";
213                         rootPath += __pContext->__packageId;
214
215                         AppLog("rootPath[%ls] is deleted.", rootPath.GetPointer());
216                         InstallerUtil::Remove(rootPath);
217                 }
218         }
219         else if (operation == INSTALLER_OPERATION_UNINSTALL)
220         {
221                 installerType = INSTALLER_TYPE_INSTALLER;
222
223                 AppLog("operation is INSTALLER_OPERATION_UNINSTALL");
224                 __pContext->SetCurrentInstallationStep(INSTALLER_STEP_INIT_UNINSTALL);
225                 __pContext->__packageId = newPath;
226
227                 SendEvent(__pContext, __pContext->__packageId, "start", "uninstall");
228         }
229         else if (operation == INSTALLER_OPERATION_REINSTALL)
230         {
231                 installerType = INSTALLER_TYPE_INSTALLER;
232                 AppLog("operation is INSTALLER_OPERATION_REINSTALL");
233                 installerType = INSTALLER_TYPE_DIRECTORY;
234
235                 __pContext->SetCurrentInstallationStep(INSTALLER_STEP_RDS_INIT);
236                 __pContext->__packageId = newPath;
237
238                 SendEvent(__pContext, __pContext->__packageId, "start", "install");
239         }
240
241         __pContext->SetInstallerOperation(operation);
242
243         if (option & INSTALLER_OPTION_HYBRID)
244         {
245                 AppLog("Request to install HybridService app!");
246                 __pContext->__isHybridService = true;
247         }
248
249         __pInstaller = CreateInstaller(installerType);
250         TryReturn(__pInstaller, INSTALLER_ERROR_INTERNAL_STATE, "__pInstaller is null.");
251
252         error = __pInstaller->Construct(__pContext);
253         TryReturn(error == INSTALLER_ERROR_NONE, INSTALLER_ERROR_INTERNAL_STATE, "__pInstaller->Construct() failed");
254
255         return error;
256 }
257
258 void
259 InstallerManager::Release(void)
260 {
261         delete __pInstallerManager;
262         __pInstallerManager = null;
263 }
264
265 Installer*
266 InstallerManager::CreateInstaller(InstallerType installerType)
267 {
268         Installer* pInstaller = null;
269
270         switch (installerType)
271         {
272         case INSTALLER_TYPE_INSTALLER:
273                 AppLog("InstallerType = [Installer]");
274                 pInstaller = new (std::nothrow) Installer();
275                 break;
276
277         case INSTALLER_TYPE_PACKAGE:
278                 AppLog("InstallerType = [PackageInstaller]");
279                 pInstaller = new (std::nothrow) PackageInstaller();
280                 break;
281
282         case INSTALLER_TYPE_DIRECTORY:
283                 AppLog("InstallerType = [DirectoryInstaller]");
284                 pInstaller = new (std::nothrow) DirectoryInstaller();
285                 break;
286
287         case INSTALLER_TYPE_GUEST:
288                 AppLog("InstallerType = [GuestInstaller]");
289                 pInstaller = new (std::nothrow) GuestInstaller();
290                 break;
291
292         case INSTALLER_TYPE_PRELOADED:
293                 AppLog("InstallerType = [PreloadedInstaller]");
294                 pInstaller = new (std::nothrow) PreloadedInstaller();
295                 break;
296
297         case INSTALLER_TYPE_IDE:
298                 AppLog("InstallerType = [IDEInstaller]");
299                 pInstaller = new (std::nothrow) IDEInstaller();
300                 break;
301
302         case INSTALLER_TYPE_RESTORATION:
303                 AppLog("InstallerType = [RestorationInstaller]");
304                 pInstaller = new (std::nothrow) RestorationInstaller();
305                 break;
306
307         default:
308                 AppLogExceptionTag(OSP_INSTALLER, "Installer is not found.");
309                 break;
310         }
311
312         return pInstaller;
313 }
314
315 InstallationStep
316 InstallerManager::GetNext(void)
317 {
318         InstallationStep step = __pContext->GetCurrentInstallationStep();
319         return __pInstaller->GetNext(step);
320 }
321
322 InstallerError
323 InstallerManager::Init(void)
324 {
325         SendEvent(__pContext, __pContext->__packageId, "install_percent", "0");
326         return __pInstaller->OnInit();
327 }
328
329 InstallerError
330 InstallerManager::Error(void)
331 {
332         return __pInstaller->OnError();
333 }
334
335 InstallerError
336 InstallerManager::Register(void)
337 {
338         SendEvent(__pContext, __pContext->__packageId, "install_percent", "60");
339         return __pInstaller->OnRegister();
340 }
341
342 InstallerError
343 InstallerManager::End(void)
344 {
345         return __pInstaller->OnEnd();
346 }
347
348 InstallerError
349 InstallerManager::Rollback(void)
350 {
351         return __pInstaller->OnRollback();
352 }
353
354 InstallerError
355 InstallerManager::UserCancel(void)
356 {
357         return __pInstaller->OnUserCancel();
358 }
359
360 InstallerError
361 InstallerManager::Activate(void)
362 {
363         InstallerError error = INSTALLER_ERROR_NONE;
364         IInstallationStep* pStep = null;
365         InstallationStep currentStep;
366
367         while (__pContext->GetState() == INSTALLER_STATE_RUNNING)
368         {
369                 currentStep = GetNext();
370                 __pContext->ChangeStep(currentStep);
371
372                 pStep = __pContext->GetStep();
373                 if (pStep)
374                 {
375                         error = pStep->Run(__pContext);
376
377                         if (error != INSTALLER_ERROR_NONE)
378                         {
379                                 __pContext->SetError(error);
380                                 Error();
381                                 goto CATCH;
382                         }
383                 }
384
385                 if (currentStep == INSTALLER_STEP_INIT)
386                 {
387                         error = Init();
388                         TryCatch(error == INSTALLER_ERROR_NONE, , "error is occurred.");
389                 }
390                 else if (currentStep == INSTALLER_STEP_END)
391                 {
392                         error = Register();
393                         TryCatch(error == INSTALLER_ERROR_NONE, , "error is occurred.");
394
395                         error = End();
396                         TryCatch(error == INSTALLER_ERROR_NONE, , "error is occurred.");
397                 }
398                 else if (currentStep == INSTALLER_STEP_RDS)
399                 {
400                         AppLog("currentStep is INSTALLER_STEP_RDS");
401                         __pContext->SetCurrentInstallationStep(INSTALLER_STEP_NONE);
402                 }
403
404                 if (__pContext->IsContinue() == false)
405                 {
406                         break;
407                 }
408
409                 if (__pContext->GetCurrentInstallationStep() >= INSTALLER_STEP_MAX)
410                 {
411                         break;
412                 }
413         }
414
415 CATCH:
416         if (error == INSTALLER_ERROR_NONE)
417         {
418                 SendEvent(__pContext, __pContext->__packageId, "install_percent", "100");
419                 SendEvent(__pContext, __pContext->__packageId, "end", "ok");
420         }
421         else
422         {
423                 String errorString;
424                 errorString.Insert(error, 0);
425
426                 if (__pContext->__additionalErrorString.IsEmpty() == false)
427                 {
428                         errorString += L":";
429                         errorString += __pContext->__additionalErrorString;
430                 }
431                 SendEvent(__pContext, __pContext->__packageId, "error", errorString);
432                 SendEvent(__pContext, __pContext->__packageId, "end", "fail");
433         }
434
435         return error;
436 }
437
438 InstallerError
439 InstallerManager::Progress(void)
440 {
441         return INSTALLER_ERROR_NONE;
442 }
443
444 InstallationContext*
445 InstallerManager::GetContext(void)
446 {
447         return __pContext;
448 }
449
450 bool
451 InstallerManager::ParseOptionalData(const String* pOptionalData)
452 {
453         TryReturn(__pContext, false, "__pContext is null.");
454
455         if (pOptionalData == null)
456         {
457                 AppLog("pOptionalData is null.");
458                 return true;
459         }
460
461         // format -> pOptionalData = "abcde12345:StoreClientId=12345abcde.TizenStore"
462         // format -> pOptionalData = "abcde12345"
463         // format -> pOptionalData = "path=/opt/usr/apps/22VoFBmj2I/:op=install:removable=true"
464
465         AppLog(" # optionalData = [%ls]", pOptionalData->GetPointer());
466
467         if ((pOptionalData->GetLength() == 10) || (pOptionalData->StartsWith(L":", 10) == true))
468         {
469                 PackageId packageId;
470                 pOptionalData->SubString(0, PACKAGE_ID_LENGTH, packageId);
471                 __pContext->__packageId = packageId;
472                 AppLog(" # package = [%ls]", packageId.GetPointer());
473         }
474
475         String tokenDelimiter(":");
476
477         std::unique_ptr< IMap > pMap(InstallerUtil::ParseN(*pOptionalData, tokenDelimiter));
478         if (pMap)
479         {
480                 std::unique_ptr< IMapEnumerator > pEnum(pMap->GetMapEnumeratorN());
481                 TryReturn(pEnum, false, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
482
483                 String storeClientId;
484                 String removable;
485                 String path;
486
487                 while (pEnum->MoveNext() == E_SUCCESS)
488                 {
489                         String* pKey = static_cast< String* > (pEnum->GetKey());
490                         TryReturn(pEnum, false, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
491
492                         String* pValue = static_cast< String* > (pEnum->GetValue());
493                         TryReturn(pEnum, false, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
494
495                         AppLog("key = [%ls], value = [%ls]", pKey->GetPointer(), pValue->GetPointer());
496
497                         if (pKey->Equals(L"StoreClientId", false) == true)
498                         {
499                                 storeClientId = (*pValue);
500                         }
501
502                         if (pKey->Equals(L"removable", false) == true)
503                         {
504                                 removable = (*pValue);
505                         }
506
507                         if (pKey->Equals(L"path", false) == true)
508                         {
509                                 path = (*pValue);
510                         }
511                 }
512
513                 if (storeClientId.IsEmpty() == false)
514                 {
515                         __pContext->__storeClientId = storeClientId;
516                         AppLog(" # storeClient = [%ls]", storeClientId.GetPointer());
517                 }
518
519                 if (removable.Equals(L"true", false) == true)
520                 {
521                         __pContext->__isUninstallable = true;
522                         AppLog(" # removable = [true]");
523                 }
524
525                 if (__pContext->__isCsc == true)
526                 {
527                         if (path.IsEmpty() == false)
528                         {
529                                 std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoFromFileN(path));
530                                 TryReturn(pPackageInfo, false, "GetPackageInfoFromFileN() failed. [%s]", GetErrorMessage(GetLastResult()));
531
532                                 __pContext->__packageId = pPackageInfo->GetId();
533                                 AppLog(" # packageId = [%ls]", __pContext->__packageId.GetPointer());
534                         }
535                 }
536         }
537
538         return true;
539 }
540
541 int
542 InstallerManager::ParseCommandArg(int argc, char **argv, int *mode, char *buf, InstallerOption& option)
543 {
544         const char* pOpts_str = "u:i:r:v:m:c";
545         int s = 0;
546
547         if (mode == NULL)
548         {
549                 AppLog("mode is null");
550                 exit(-1);
551         }
552
553         *mode = 0;
554
555         while (1)
556         {
557                 s = getopt(argc, argv, pOpts_str);
558
559                 if (s == -1)
560                 {
561                         break;
562                 }
563
564                 switch (s)
565                 {
566                 case 'i':
567                         if (*mode)
568                         {
569                                 break;
570                         }
571
572                         AppLog("__osp_installer_parse_options: i");
573                         *mode = INSTALLER_MODE_INSTALL;
574                         if (optarg[0] == 'v')
575                         {
576                                 AppLog("__osp_installer_parse_options: v");
577                                 option = (InstallerOption)(option | INSTALLER_OPTION_HYBRID);
578                                 option = (InstallerOption)(option | INSTALLER_OPTION_UPDATE_STDOUT);
579                                 strncpy(buf, argv[optind++], BUFSIZE);
580                                 AppLog("__osp_installer_parse_options: buf = [%s]", buf);
581                         }
582                         else
583                         {
584                                 strncpy(buf, optarg, BUFSIZE);
585                                 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
586                         }
587                         break;
588
589                 case 'u':
590                         if (*mode)
591                         {
592                                 break;
593                         }
594
595                         AppLog("__osp_installer_parse_options: u");
596                         *mode = INSTALLER_MODE_UNINSTALL;
597                         if (optarg[0] == 'v')
598                         {
599                                 AppLog("__osp_installer_parse_options: v");
600                                 option = (InstallerOption)(option | INSTALLER_OPTION_HYBRID);
601                                 option = (InstallerOption)(option | INSTALLER_OPTION_UPDATE_STDOUT);
602                                 strncpy(buf, argv[optind++], BUFSIZE);
603                                 AppLog("__osp_installer_parse_options: buf = [%s]", buf);
604                         }
605                         else
606                         {
607                                 strncpy(buf, optarg, BUFSIZE);
608                                 AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
609                         }
610                         break;
611
612                 case 'r':
613                         if (*mode)
614                         {
615                                 break;
616                         }
617
618                         AppLog("__osp_installer_parse_options: r");
619                         *mode = INSTALLER_MODE_REINSTALL;
620                         strncpy(buf, optarg, BUFSIZE);
621                         AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
622                         break;
623
624                 case 'v':
625                         AppLog("__osp_installer_parse_options: v");
626                         option = (InstallerOption)(option | INSTALLER_OPTION_UPDATE_STDOUT);
627                         AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
628                         break;
629
630                 case 'm':
631                         if (*mode)
632                         {
633                                 break;
634                         }
635
636                         AppLog("__osp_installer_parse_options: m");
637                         *mode = INSTALLER_MODE_RECURSIVE_DIRECTORY_INSTALL;
638                         strncpy(buf, optarg, BUFSIZE);
639                         AppLog("__osp_installer_parse_options: optarg = [%s]", optarg);
640                         break;
641
642                 case 'c':
643                         if (*mode)
644                         {
645                                 break;
646                         }
647
648                         AppLog("__osp_installer_parse_options: c");
649                         option = (InstallerOption)(option | INSTALLER_OPTION_UPDATE_STDOUT);
650                         option = (InstallerOption)(option | INSTALLER_OPTION_CSC);
651                         *mode = INSTALLER_MODE_PARSE_CSC_STRING;
652                         AppLog("__osp_installer_parse_options: argv[optind] = [%s]", argv[optind]);
653                         strncpy(buf, argv[optind], BUFSIZE);
654
655                         break;
656
657                 default:
658                         AppLog("Invalid option");
659                         exit(-1);
660                         break;
661                 }
662         }
663
664         if (mode == 0)
665         {
666                 AppLog("Invalid mode");
667                 exit(-1);
668         }
669
670         return 0;
671 }
672
673 bool
674 InstallerManager::RemoveGarbage(const String& filePath)
675 {
676         AppLog("RemoveGarbage Directory = [%ls]", filePath.GetPointer());
677
678         String realPath;
679         if (InstallerUtil::IsSymlink(filePath) == true)
680         {
681                 if (InstallerUtil::GetRealPath(filePath, realPath) == true)
682                 {
683                         InstallerUtil::Remove(realPath);
684                 }
685         }
686
687         InstallerUtil::Remove(filePath);
688
689         return true;
690 }
691
692 int
693 InstallerManager::ReqeustByTest(void)
694 {
695         int errorType = 0;
696         String appId;
697         Tizen::Io::File file;
698         Tizen::Io::FileAttributes attr;
699         result r = E_SUCCESS;
700         char readBuf[512] = {0};
701
702         r = File::GetAttributes(L"/opt/apps/cmtamb4mtv/data/configuration", attr);
703         TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_PACKAGE_NOT_FOUND, "file not found");
704
705         r = file.Construct(L"/opt/apps/cmtamb4mtv/data/configuration", L"r");
706         TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_PACKAGE_NOT_FOUND, "file.Construct failed");
707
708         if (file.Read(readBuf, sizeof(readBuf)-1) > 1)
709         {
710                 String path;
711                 path.Format(1024, L"%s", &readBuf[1]);
712
713                 if (readBuf[0] == '+')
714                 {
715                         errorType = InstallerManager::Request(path, INSTALLER_OPERATION_INSTALL, INSTALLER_OPTION_NORMAL, null);
716                 }
717                 else if (readBuf[0] == '-')
718                 {
719                         errorType = InstallerManager::Request(path, INSTALLER_OPERATION_UNINSTALL, INSTALLER_OPTION_NORMAL, null);
720                 }
721                 else if (readBuf[0] == '*')
722                 {
723                         errorType = InstallerManager::RequestRecursiveDirectory(path, errorType);
724                 }
725                 else if (readBuf[0] == '>')
726                 {
727                         errorType = InstallerManager::RequestMove(path, PM_MOVE_TO_SDCARD);
728                 }
729                 else if (readBuf[0] == '<')
730                 {
731                         errorType = InstallerManager::RequestMove(path, PM_MOVE_TO_INTERNAL);
732                 }
733                 else if (readBuf[0] == '#')
734                 {
735                         errorType = InstallerManager::Request(path, INSTALLER_OPERATION_REINSTALL, INSTALLER_OPTION_NORMAL, null);
736                 }
737         }
738
739 CATCH:
740         return errorType;
741 }
742
743 void
744 InstallerManager::PrintResult(void)
745 {
746         TryReturnVoid(__pContext, "__pContext is null.");
747
748         int errorType = GetErrorType();
749         InstallerOperation operation = __pContext->GetInstallerOperation();
750
751         Tizen::System::SystemTime::GetTicks(__endTick);
752
753         const char* pOperation = InstallerUtil::GetInstallerOperationString(operation);
754
755         const wchar_t* pPackageId = L"Unknown";
756         if (!__pContext->__packageId.IsEmpty())
757         {
758                 pPackageId = __pContext->__packageId.GetPointer();
759         }
760
761         const wchar_t* pPackageSize = L"0 B";
762         if (!__pContext->__packageSize.IsEmpty())
763         {
764                 pPackageSize = __pContext->__packageSize.GetPointer();
765         }
766
767         const wchar_t* pAppInfoStr = L"Unknown";
768         String appInfoStr = GetAppInfoString();
769         if (!appInfoStr.IsEmpty())
770         {
771                 pAppInfoStr = appInfoStr.GetPointer();
772         }
773
774         String error = GetErrorString(errorType);
775         int duration = (int)(__endTick - __startTick);
776
777         AppLog("==========================================");
778         AppLog(" # osp-installer: %s", OSP_INSTALLER_VERSION);
779         AppLog("------------------------------------------");
780         AppLog(" # Operation = [%s]", pOperation);
781         AppLog(" # Package   = [%ls](%ls)", pPackageId, pPackageSize);
782         AppLog(" # Apps      = [%ls]", pAppInfoStr);
783         AppLog(" # Time      = [%d]ms", duration);
784         AppLog(" # Result    = [%ls(%03d)]", error.GetPointer(), errorType);
785         AppLog("==========================================");
786
787         fprintf(stderr, "  ## osp-installer: package=[%ls](%ls) operation=[%s] result=[%ls](%03d)\n",
788                         pPackageId, pPackageSize, pOperation, error.GetPointer(), errorType);
789         fprintf(stderr, "  ## osp-installer: apps=[%ls] time=[%d]ms\n", pAppInfoStr, duration);
790 }
791
792 String
793 InstallerManager::GetErrorString(int errorType)
794 {
795         const char* pError = null;
796
797         switch (errorType)
798         {
799         case INSTALLER_ERROR_NONE:
800                 pError = "Success";
801                 break;
802
803         case INSTALLER_ERROR_PACKAGE_NOT_FOUND:
804                 pError = "[PACKAGE_NOT_FOUND] Thrown when package file is not found.";
805                 break;
806
807         case INSTALLER_ERROR_PACKAGE_INVALID:
808                 pError = "[PACKAGE_INVALID] Thrown when package file is not valid due to file operation or directory hierarchy.";
809                 break;
810
811         case INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
812                 pError = "[PACKAGE_LOWER_VERSION] Thrown when the lower version package is tried to install.";
813                 break;
814
815         case INSTALLER_ERROR_EXECUTABLE_NOT_FOUND:
816                 pError = "[EXECUTABLE_NOT_FOUND] Thrown when executable file is not found in the package.";
817                 break;
818
819         case INSTALLER_ERROR_MANIFEST_NOT_FOUND:
820                 pError = "[MANIFEST_NOT_FOUND] Thrown when manifest.xml is not found in the package.";
821                 break;
822
823         case INSTALLER_ERROR_MANIFEST_INVALID:
824                 pError = "[MANIFEST_INVALID] Thrown when manifest.xml is not valid due to schema or parsing failure.";
825                 break;
826
827         case INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
828                 pError = "[SIGNATURE_NOT_FOUND] Thrown when the signature files are not found in the package.";
829                 break;
830
831         case INSTALLER_ERROR_SIGNATURE_INVALID:
832                 pError = "[SIGNATURE_INVALID] Thrown when the signature files are not valid due to schema or parsing failure.";
833                 break;
834
835         case INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
836                 pError = "[SIGNATURE_VERIFICATION_FAILED] Thrown when the signature verification has failed due to be modified illegally.";
837                 break;
838
839         case INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
840                 pError = "[ROOT_CERTIFICATE_NOT_FOUND] Thrown when the root certificate is not found.";
841                 break;
842
843         case INSTALLER_ERROR_CERTIFICATE_INVALID:
844                 pError = "[CERTIFICATE_INVALID] Thrown when the certificate verification has failed.";
845                 break;
846
847         case INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
848                 pError = "[CERTIFICATE_CHAIN_VERIFICATION_FAILED] Thrown when the certificate chain verification has failed.";
849                 break;
850
851         case INSTALLER_ERROR_CERTIFICATE_EXPIRED:
852                 pError = "[CERTIFICATE_EXPIRED] Thrown when the used certificates have expired.";
853                 break;
854
855         case INSTALLER_ERROR_PRIVILEGE_INVALID:
856                 pError = "[PRIVILEGE_INVALID] Thrown when unsupported privilege strings are detected.";
857                 break;
858
859         case INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
860                 pError = "[MENU_ICON_NOT_FOUND] Thrown when an icon for menu is not found. This icon is mandatory.";
861                 break;
862
863         case INSTALLER_ERROR_FATAL_ERROR:
864                 pError = "[FATAL_ERROR] Thrown when an icon for menu is not found. This icon is mandatory.";
865                 break;
866
867         case INSTALLER_ERROR_OUT_OF_STORAGE:
868                 pError = "[OUT_OF_STORAGE] Thrown when the storage is full.";
869                 break;
870
871         case INSTALLER_ERROR_OUT_OF_MEMORY:
872                 pError = "[OUT_OF_MEMORY] Thrown when the memory is not sufficient to perform the requested installation or uninstallation.";
873                 break;
874
875         default:
876                 pError = "fatal error";
877                 break;
878         }
879
880         String error = pError;
881         return error;
882 }
883
884 String
885 InstallerManager::GetAppInfoString()
886 {
887         String appInfoStr;
888         TryReturn(__pContext, appInfoStr, "__pContext is null");
889
890         String appRootPath = __pContext->__rootPath;
891
892         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
893         TryReturn(pAppDataList, appInfoStr, "pAppDataList is null.");
894
895         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
896         {
897                 AppData* pAppData = null;
898                 pAppDataList->GetAt(i, pAppData);
899                 TryReturn(pAppData, appInfoStr, "pAppData is null.");
900
901                 String destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
902
903                 if (i != 0)
904                 {
905                         appInfoStr += L" ";
906                 }
907
908                 appInfoStr += pAppData->__name;
909                 if (pAppData->__main.Equals("True", false) == true)
910                 {
911                         appInfoStr += L"(main)";
912                 }
913
914                 String sizeStr = L"(" + InstallerUtil::GetDisplaySize(destPath) + L")";
915                 appInfoStr += sizeStr;
916         }
917
918         return appInfoStr;
919 }
920
921 int
922 InstallerManager::GetErrorType(void) const
923 {
924         return __errorType;
925 }
926
927 void
928 InstallerManager::SetErrorType(int errorType)
929 {
930         __errorType = errorType;
931 }
932
933 void
934 InstallerManager::SetInstallerOperation(InstallerOperation op)
935 {
936         __operation = op;
937 }
938
939 InstallerOperation
940 InstallerManager::GetInstallerOperation(void) const
941 {
942         return __operation;
943 }
944
945 String
946 InstallerManager::GetLogFilePath() const
947 {
948         return __logFilePath;
949 }
950
951 String
952 InstallerManager::GetHistoryLogFilePath() const
953 {
954         return __historyLogFilePath;
955 }
956
957 bool
958 InstallerManager::IsFileLogOn() const
959 {
960         return __isFileLogOn;
961 }
962
963 bool
964 InstallerManager::IsHistoryFileLogOn() const
965 {
966         return __isHistoryFileLogOn;
967 }
968
969 bool
970 InstallerManager::SendEvent(InstallationContext* pContext, const PackageId& packageId, const String& key, const String& val)
971 {
972         TryReturn(pContext, false, "pContext is null.");
973         TryReturn(key.IsEmpty() == false, false, "key is empty.");
974         TryReturn(val.IsEmpty() == false, false, "val is empty.");
975
976         InstallerOperation operation = pContext->GetInstallerOperation();
977
978         if (pContext->__pPkgmgrInstaller == null)
979         {
980                 AppLog("pContext->__pPkgmgrInstaller is null. [%ls]", packageId.GetPointer());
981                 return false;
982         }
983
984         if (operation == INSTALLER_OPERATION_UNINSTALL)
985         {
986                 if (key == L"install_percent")
987                 {
988                         AppLog("install_percent is skipped. [%ls]", packageId.GetPointer());
989                         return true;
990                 }
991         }
992
993         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
994         TryReturn(pPackageId, false, "pPackageId is null.");
995
996         std::unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(key));
997         TryReturn(pKey, false, "pKey is null.");
998
999         std::unique_ptr<char[]> pVal(_StringConverter::CopyToCharArrayN(val));
1000         TryReturn(pVal, false, "pVal is null.");
1001
1002         pkgmgr_installer_send_signal((pkgmgr_installer*) pContext->__pPkgmgrInstaller, "tpk", pPackageId.get(), pKey.get(), pVal.get());
1003         AppLog("pkgmgr_installer_send_signal(tpk, %s, %s, %s)", pPackageId.get(), pKey.get(), pVal.get());
1004
1005         return true;
1006 }
1007
1008 bool
1009 InstallerManager::IsUninstallUpdates(const PackageId& packageId, String& originPath, bool& isCscPackage)
1010 {
1011         String cscInfo;
1012         String roXmlPath;
1013         roXmlPath.Format(1024, DIR_RO_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
1014
1015         if (File::IsFileExist(roXmlPath) == true)
1016         {
1017                 String rwXmlPath;
1018                 rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
1019                 if (File::IsFileExist(rwXmlPath) == true)
1020                 {
1021                         InstallerUtil::Remove(rwXmlPath);
1022
1023                         String preloadedAppPath(PATH_USR_APPS);
1024                         preloadedAppPath += L"/";
1025                         preloadedAppPath += packageId;
1026
1027                         AppLog("uninstall updates for preloaded app. [%ls]", preloadedAppPath.GetPointer());
1028                         originPath = preloadedAppPath;
1029
1030                         return true;
1031                 }
1032         }
1033         else if(InstallerUtil::IsCscPackage(packageId, cscInfo) == true)
1034         {
1035                 String tokenDelimiter(":");
1036
1037                 std::unique_ptr< IMap > pMap(InstallerUtil::ParseN(cscInfo, tokenDelimiter));
1038                 TryReturn(pMap, false, "ParseN() failed. [%s]", GetErrorMessage(GetLastResult()));
1039
1040                 std::unique_ptr< IMapEnumerator > pEnum(pMap->GetMapEnumeratorN());
1041                 TryReturn(pEnum, false, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
1042
1043                 String removable;
1044                 String path;
1045
1046                 while (pEnum->MoveNext() == E_SUCCESS)
1047                 {
1048                         String* pKey = static_cast< String* > (pEnum->GetKey());
1049                         TryReturn(pEnum, false, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
1050
1051                         String* pValue = static_cast< String* > (pEnum->GetValue());
1052                         TryReturn(pEnum, false, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
1053
1054                         AppLog("key = [%ls], value = [%ls]", pKey->GetPointer(), pValue->GetPointer());
1055
1056                         if (pKey->Equals(L"removable", false) == true)
1057                         {
1058                                 removable = (*pValue);
1059                         }
1060
1061                         if (pKey->Equals(L"path", false) == true)
1062                         {
1063                                 path = (*pValue);
1064                         }
1065                 }
1066
1067                 if (removable.Equals(L"false", false) == true)
1068                 {
1069                         isCscPackage = true;
1070
1071                         AppLog("uninstall updates for csc-preloaded app [%ls]", path.GetPointer());
1072                         originPath = cscInfo;
1073
1074                         return true;
1075                 }
1076                 else
1077                 {
1078                         AppLog("uninstall package for csc-preloaded app. [%ls]");
1079                 }
1080         }
1081
1082         return false;
1083 }
1084
1085 int
1086 InstallerManager::Request(const String& path, InstallerOperation operation, InstallerOption option, void* pPkgmgrInstaller, const String* pOptionalData)
1087 {
1088         InstallerError errorType = INSTALLER_ERROR_NONE;
1089         InstallerManager* pInstallManager = null;
1090
1091         if (File::IsFileExist(DIR_OSP_APPLICATIONS_TEMP) == true)
1092         {
1093                 InstallerUtil::Remove(DIR_OSP_APPLICATIONS_TEMP);
1094         }
1095
1096         if (File::IsFileExist(DIR_MEMORYCARD_OSP_APPLICATIONS_TEMP) == true)
1097         {
1098                 InstallerUtil::Remove(DIR_MEMORYCARD_OSP_APPLICATIONS_TEMP);
1099         }
1100
1101         pInstallManager = InstallerManager::GetInstance();
1102         TryCatch(pInstallManager, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pInstallManager is null.");
1103
1104         errorType = pInstallManager->Construct(path, operation, option, pPkgmgrInstaller, pOptionalData);
1105         TryCatch(errorType == INSTALLER_ERROR_NONE, , "pInstallManager->Construct() failed.");
1106
1107         errorType = pInstallManager->Activate();
1108         TryCatch(errorType == INSTALLER_ERROR_NONE, , "pInstallManager->Activate() failed.");
1109
1110 CATCH:
1111         if (pInstallManager)
1112         {
1113                 pInstallManager->SetErrorType(errorType);
1114
1115                 if (!(option & INSTALLER_OPTION_NO_INPUT))
1116                 {
1117                         pInstallManager->PrintResult();
1118                 }
1119
1120                 if (errorType != INSTALLER_ERROR_NONE)
1121                 {
1122                         InstallerUtil::PrintLog(pInstallManager->GetLogFilePath());
1123                 }
1124                 else
1125                 {
1126                         InstallerUtil::Remove(pInstallManager->GetHistoryLogFilePath());
1127                 }
1128
1129                 pInstallManager->Release();
1130         }
1131
1132         if (File::IsFileExist(DIR_OSP_APPLICATIONS_TEMP) == true)
1133         {
1134                 InstallerUtil::Remove(DIR_OSP_APPLICATIONS_TEMP);
1135         }
1136
1137         if (File::IsFileExist(DIR_MEMORYCARD_OSP_APPLICATIONS) == true)
1138         {
1139                 InstallerUtil::Remove(DIR_MEMORYCARD_OSP_APPLICATIONS);
1140         }
1141
1142         return errorType;
1143 }
1144
1145 int
1146 InstallerManager::RequestRecursiveDirectory(const Tizen::Base::String& path, int& errorType)
1147 {
1148         Directory* pDir = null;
1149         DirEnumerator* pDirEnum = null;
1150         result r = E_SUCCESS;
1151         int res = false;
1152         String appid;
1153         InstallerError error = INSTALLER_ERROR_NONE;
1154         int totalCount = 0;
1155         int successCount = 0;
1156         int failureCount = 0;
1157
1158         pDir = new (std::nothrow) Directory; // Allocate %Directory instance
1159         TryCatch(pDir, res = false, "pDir is null");
1160
1161         r = pDir->Construct(path);
1162         TryCatch(!IsFailed(r), res = false, "pDir->Construct() failed, path = [%ls]", path.GetPointer());
1163
1164         pDirEnum = pDir->ReadN();
1165         TryCatch(pDirEnum, res = false, "pDirEnum is null");
1166
1167         while (pDirEnum->MoveNext() == E_SUCCESS)
1168         {
1169                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
1170
1171                 String entryName = entry.GetName();
1172                 String entryDir = path;
1173                 entryDir += L"/";
1174                 entryDir += entryName;
1175
1176                 if (entryName == L"." || entryName == L"..")
1177                 {
1178                         continue;
1179                 }
1180
1181                 if (entry.IsDirectory() == false)
1182                 {
1183                         continue;
1184                 }
1185
1186                 const int entryLength = entryName.GetLength();
1187                 if (entryLength == PACKAGE_ID_LENGTH)
1188                 {
1189                         // PackageId
1190                 }
1191                 else if (entryLength == APP_DIR_LENGTH)
1192                 {
1193                         if (entryName.Contains(PACKAGE_NAME_PREFIX_ORG) == false)
1194                         {
1195                                 AppLog(" - Not osp = [%ls]: prefix mismatch", entryDir.GetPointer());
1196                                 continue;
1197                         }
1198                 }
1199                 else
1200                 {
1201                         AppLog(" - Not osp = [%ls]: length(%d) mismatch", entryDir.GetPointer(), entryLength);
1202                         continue;
1203                 }
1204
1205                 String xmlFile;
1206                 xmlFile.Format(1024, L"%ls%ls", entryDir.GetPointer(), PACKAGE_XML_FILE);
1207
1208                 FileAttributes attr;
1209                 r = File::GetAttributes(xmlFile, attr);
1210                 if (IsFailed(r))
1211                 {
1212                         AppLog(" - Not osp = [%ls]: No manifest.xml", entryDir.GetPointer());
1213                         continue;
1214                 }
1215
1216                 totalCount++;
1217
1218                 AppLog("------------------------------------------");
1219                 AppLog(" # Directory = [%ls]", entryDir.GetPointer());
1220
1221                 errorType = Request(entryDir, INSTALLER_OPERATION_INSTALL, INSTALLER_OPTION_NORMAL, null);
1222                 if (errorType == 0)
1223                 {
1224                         successCount++;
1225                 }
1226                 else
1227                 {
1228                         failureCount++;
1229                 }
1230
1231                 AppLog("------------------------------------------");
1232         }
1233
1234         AppLog("------------------------------------------");
1235         AppLog("recursive directory installation");
1236         AppLog(" # totalCount   = [%d]", totalCount);
1237         AppLog(" # successCount = [%d]", successCount);
1238         AppLog(" # failureCount = [%d]", failureCount);
1239
1240 CATCH:
1241         delete pDirEnum;
1242         delete pDir;
1243         return error;
1244 }
1245
1246 int
1247 InstallerManager::RequestByCommand(int argc, char **argv)
1248 {
1249         int mode = 0;
1250         char buf[BUFSIZE] = {0};
1251         int errorType = 0;
1252         InstallerOption option = INSTALLER_OPTION_NORMAL;
1253
1254         AppLog(" # argc = [%d]", argc);
1255
1256         for (int i = 0; i < argc; i++)
1257         {
1258                 AppLog(" # argv[%d] = [%s]", i, argv[i]);
1259         }
1260
1261         InstallerManager::ParseCommandArg(argc, argv, &mode, buf, option);
1262
1263         AppLog("option = [%d]", (int)option);
1264
1265         switch (mode)
1266         {
1267         case INSTALLER_MODE_INSTALL:
1268                 {
1269                         AppLog("------------------------------------------");
1270                         AppLog(" # Directory = [%s]", buf);
1271
1272                         option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
1273                         errorType = InstallerManager::Request(buf, INSTALLER_OPERATION_INSTALL, option, null);
1274                         if (errorType != 0)
1275                         {
1276                                 // in case of command, garbage directory is not deleted.
1277                                 // RemoveGarbage(buf);
1278                         }
1279                 }
1280                 break;
1281
1282         case INSTALLER_MODE_UNINSTALL:
1283                 {
1284                         AppLog("------------------------------------------");
1285                         AppLog(" # Directory = [%s]", buf);
1286
1287                         option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
1288                         errorType = InstallerManager::Request(buf, INSTALLER_OPERATION_UNINSTALL, option, null);
1289                 }
1290                 break;
1291
1292         case INSTALLER_MODE_RECURSIVE_DIRECTORY_INSTALL:
1293                 {
1294                         AppLog("------------------------------------------");
1295
1296                         errorType = InstallerManager::RequestRecursiveDirectory(buf, errorType);
1297                 }
1298                 break;
1299
1300         case INSTALLER_MODE_REINSTALL:
1301                 {
1302                         AppLog("------------------------------------------");
1303                         AppLog(" # Directory = [%s]", buf);
1304
1305                         option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
1306                         errorType = InstallerManager::Request(buf, INSTALLER_OPERATION_REINSTALL, option, null);
1307                 }
1308                 break;
1309
1310         case INSTALLER_MODE_PARSE_CSC_STRING:
1311                 {
1312                         AppLog("------------------------------------------");
1313                         AppLog(" # CSC = [%s]", buf);
1314
1315                         option = (InstallerOption)(option | INSTALLER_OPTION_FILELOG_ON);
1316                         errorType = InstallerManager::RequestCsc(buf, option);
1317                 }
1318                 break;
1319
1320         default:
1321                 {
1322                         AppLog("__install_package_by_cmd, Invalid mode");
1323                 }
1324                 break;
1325         }
1326
1327         AppLog("==========================================");
1328
1329         if (option & INSTALLER_OPTION_UPDATE_STDOUT)
1330         {
1331                 AppLog("stdout is updated by errorType [%d]", errorType);
1332                 fprintf(stdout, "%d", errorType);
1333         }
1334
1335         return errorType;
1336 }
1337
1338 int
1339 InstallerManager::RequestMove(const PackageId& packageId, int moveType)
1340 {
1341         result r = E_SUCCESS;
1342         int res = 0;
1343         InstallerError errorType = INSTALLER_ERROR_NONE;
1344         app2ext_handle* pHandle = null;
1345         app2ext_move_type location = APP2EXT_MOVE_TO_EXT;
1346         GList* pDirectoryList = null;
1347         Directory* pDir = null;
1348         DirEnumerator* pDirEnum = null;
1349         PackageInfo* pPackageInfo = null;
1350         _PackageInfoImpl* pPackageInfoImpl = null;
1351         String rootPath;
1352
1353         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
1354         TryReturn(pPackageId, INSTALLER_ERROR_OUT_OF_MEMORY, "pPackageId is null");
1355
1356         if (moveType == PM_MOVE_TO_INTERNAL)
1357         {
1358                 location = APP2EXT_MOVE_TO_PHONE;
1359         }
1360
1361         pPackageInfo = _PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId);
1362         TryCatch(pPackageInfo != null, errorType = INSTALLER_ERROR_INTERNAL_STATE, "GetPackageInfoN() failed");
1363
1364         pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo);
1365         TryCatch(pPackageInfoImpl, errorType = INSTALLER_ERROR_INTERNAL_STATE, "GetInstance() failed");
1366
1367         rootPath = pPackageInfoImpl->GetAppRootPath();
1368
1369         pHandle = app2ext_init(APP2EXT_SD_CARD);
1370         TryCatch(pHandle, errorType = INSTALLER_ERROR_INTERNAL_STATE, "app2ext_init() failed");
1371
1372         if (location == APP2EXT_MOVE_TO_PHONE)
1373         {
1374                 res = pHandle->interface.enable(pPackageId.get());
1375         }
1376
1377         pDir = new (std::nothrow) Directory;
1378         TryCatch(pDir, errorType = INSTALLER_ERROR_OUT_OF_MEMORY, "pDir is null");
1379
1380         r = pDir->Construct(rootPath);
1381         TryCatch(!IsFailed(r), errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDir->Construct() failed, path = [%ls]", rootPath.GetPointer());
1382
1383         pDirEnum = pDir->ReadN();
1384         TryCatch(pDirEnum, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDirEnum is null");
1385
1386         while (pDirEnum->MoveNext() == E_SUCCESS)
1387         {
1388                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
1389
1390                 String entryName = entry.GetName();
1391
1392                 if (entryName == L"." || entryName == L"..")
1393                 {
1394                         continue;
1395                 }
1396
1397                 if (entry.IsDirectory() == false)
1398                 {
1399                         continue;
1400                 }
1401
1402                 if (entryName.StartsWith(L".", 0) == true)
1403                 {
1404                         continue;
1405                 }
1406
1407                 int length = 0;
1408                 app2ext_dir_details* pDirDetails = null;
1409
1410                 pDirDetails = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
1411                 TryCatch(pDirDetails, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pDirDetails is null");
1412
1413                 length = entryName.GetLength();
1414                 pDirDetails->name = (char*) calloc(1, (sizeof(char) * length) + 1);
1415                 snprintf(pDirDetails->name, length + 1, "%ls", entryName.GetPointer());
1416
1417                 String data(L"data");
1418                 String shared(L"shared");
1419                 String setting(L"setting");
1420
1421                 if (entryName.Contains(data) || entryName.Contains(shared) || entryName.Contains(setting))
1422                 {
1423                         pDirDetails->type = APP2EXT_DIR_RW;
1424                 }
1425                 else
1426                 {
1427                         pDirDetails->type = APP2EXT_DIR_RO;
1428                 }
1429
1430                 AppLog("------------------------------------------");
1431                 AppLog("# Root Directory = [%s], Type = [%d]", pDirDetails->name, pDirDetails->type);
1432
1433                 pDirectoryList = g_list_append(pDirectoryList, pDirDetails);
1434         }
1435
1436         res = pHandle->interface.move(pPackageId.get(), pDirectoryList, location);
1437         TryCatch(res == 0, errorType = INSTALLER_ERROR_INTERNAL_STATE, "pHandle->interface.move() failed [%d]", res);
1438
1439 CATCH:
1440         if (pHandle)
1441         {
1442                 app2ext_deinit(pHandle);
1443         }
1444
1445         if (pDirectoryList)
1446         {
1447                 GList* pList = null;
1448                 app2ext_dir_details* pDirDetails = null;
1449
1450                 pList = g_list_first(pDirectoryList);
1451                 while (pList)
1452                 {
1453                         pDirDetails = (app2ext_dir_details*)pList->data;
1454                         if (pDirDetails && pDirDetails->name)
1455                         {
1456                                 free(pDirDetails->name);
1457                         }
1458                         pList = g_list_next(pList);
1459                 }
1460                 g_list_free(pDirectoryList);
1461         }
1462
1463         delete pDirEnum;
1464         delete pDir;
1465         delete pPackageInfo;
1466
1467         return errorType;
1468 }
1469
1470 int
1471 InstallerManager::RequestCsc(const String& buffer, InstallerOption option, void* pPkgmgrInstaller)
1472 {
1473         int errorType = 0;
1474
1475         String str(buffer);
1476         String tokenDelimiter(":");
1477
1478         std::unique_ptr< IMap > pMap(InstallerUtil::ParseN(str, tokenDelimiter));
1479         TryReturn(pMap, INSTALLER_ERROR_FATAL_ERROR, "CSC String[%ls] is invalid.", buffer.GetPointer());
1480
1481         std::unique_ptr< IMapEnumerator > pEnum(pMap->GetMapEnumeratorN());
1482         TryReturn(pEnum, INSTALLER_ERROR_FATAL_ERROR, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
1483
1484         String op;
1485         String path;
1486         String removable;
1487
1488         // format -> "path=/opt/usr/apps/22VoFBmj2I/:op=install:removable=true"
1489         // format -> "path=yandexmaps:op=uninstall"
1490
1491         while (pEnum->MoveNext() == E_SUCCESS)
1492         {
1493                 String* pKey = static_cast< String* > (pEnum->GetKey());
1494                 TryReturn(pEnum, -1, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
1495
1496                 String* pValue = static_cast< String* > (pEnum->GetValue());
1497                 TryReturn(pEnum, -1, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
1498
1499                 AppLog("key = [%ls], value = [%ls]", pKey->GetPointer(), pValue->GetPointer());
1500
1501                 if (pKey->Equals(L"path", false) == true)
1502                 {
1503                         path = (*pValue);
1504                 }
1505
1506                 if (pKey->Equals(L"op", false) == true)
1507                 {
1508                         op = (*pValue);
1509                 }
1510
1511                 if (pKey->Equals(L"removable", false) == true)
1512                 {
1513                         removable = (*pValue);
1514                 }
1515         }
1516
1517         AppLog("path = [%ls], op = [%ls], removable = [%ls]", path.GetPointer(), op.GetPointer(), removable.GetPointer());
1518
1519         if (op.Equals(L"install", false) == true)
1520         {
1521                 errorType = InstallerManager::Request(path, INSTALLER_OPERATION_INSTALL, option, pPkgmgrInstaller, &buffer);
1522         }
1523         else if (op.Equals(L"uninstall", false) == true)
1524         {
1525                 errorType = InstallerManager::Request(path, INSTALLER_OPERATION_UNINSTALL, option, null);
1526         }
1527         else
1528         {
1529                 AppLog("Operation[%ls] is invalid.", op.GetPointer());
1530                 errorType = INSTALLER_ERROR_FATAL_ERROR;
1531         }
1532
1533         return errorType;
1534 }