Osp-Installer merge changes from tizen_2.2
[platform/framework/native/installer.git] / src / Manager / ConfigurationManager.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        ConfigurationManager.cpp
19  * @brief       This is the implementation file for %ConfigurationManager class.
20  */
21
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <unique_ptr.h>
26
27 #include <pkgmgr_parser.h>
28 #include <pkgmgr_installer.h>
29 #include <pkgmgr-info.h>
30 #include <app2ext_interface.h>
31
32 #include <FBaseUtilStringUtil.h>
33 #include <FIoFile.h>
34 #include <FIoDirectory.h>
35 #include <FApp_Aul.h>
36 #include <FAppPkg_PackageManagerImpl.h>
37 #include <FBase_StringConverter.h>
38
39 #include "ConfigurationManager.h"
40 #include "DatabaseManager.h"
41 #include "ManifestGenerator.h"
42 #include "InstallerUtil.h"
43 #include "SmackManager.h"
44
45 using namespace Tizen::App;
46 using namespace Tizen::App::Package;
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Collection;
49 using namespace Tizen::Base::Utility;
50 using namespace Tizen::Io;
51
52 ConfigurationManager::ConfigurationManager(void)
53 {
54 }
55
56 ConfigurationManager::~ConfigurationManager(void)
57 {
58 }
59
60 bool
61 ConfigurationManager::CreateFile(InstallationContext* pContext)
62 {
63         int err = 0;
64
65         String rootPath;
66         rootPath = pContext->__rootPath;
67
68         String apiVersion;
69         apiVersion = pContext->__apiVersion;
70         String versionInfoFile;
71         versionInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), VERSION_INFO_FILE);
72         InstallerUtil::CreateInfoFile(versionInfoFile, &apiVersion);
73
74         if (pContext->__isOspCompat == true)
75         {
76                 AppLog("[OspCompat] is detected");
77
78                 String compatInfoFile;
79                 compatInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), COMPAT_INFO_FILE);
80                 InstallerUtil::CreateInfoFile(compatInfoFile, null);
81         }
82
83         if (pContext->__virtualRootPath.IsEmpty() == false)
84         {
85                 AppLog("[VirtualRoot] is detected");
86
87                 String virtualRootInfoFile;
88                 virtualRootInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), VIRTUAL_ROOT_INFO_FILE);
89                 InstallerUtil::CreateInfoFile(virtualRootInfoFile, &pContext->__virtualRootPath);
90         }
91
92         String webServicePrivilege(TIZEN_PRIVILEGE_WEB_SERVICE);
93         if (FindPrivilege(pContext, webServicePrivilege) == true)
94         {
95                 AppLog("WEB_SERVICE privilege is detected. rootPath=[%ls]", rootPath.GetPointer());
96
97                 String webServiceInfoFile;
98                 webServiceInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), WEBSERVICE_INFO_FILE);
99                 InstallerUtil::CreateInfoFile(webServiceInfoFile, null);
100         }
101
102         IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
103         TryReturn(pAppDataList, false, "pAppDataList is null");
104
105         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
106         {
107                 AppData* pAppData = null;
108                 pAppDataList->GetAt(i, pAppData);
109                 TryReturn(pAppData, false, "pAppData is null");
110
111                 String appName = pAppData->__name;
112                 String appType = pAppData->__type;
113                 AppId appId = pAppData->__appId;
114
115                 String binaryPath;
116                 binaryPath.Format(1024, L"%ls%ls/%ls", rootPath.GetPointer(), DIR_BIN, appName.GetPointer());
117
118                 if (File::IsFileExist(binaryPath) == true)
119                 {
120                         InstallerUtil::Remove(binaryPath);
121                 }
122
123                 CreateAppInfoFile(pAppData, rootPath);
124
125                 if (appType == L"UiApp")
126                 {
127                         bool uiLoader = true;
128                         String loaderPath;
129                         HashMap* pMetadataMap = pAppData->__pMetadataMap;
130
131                         if (pMetadataMap)
132                         {
133                                 String key = METADATA_COMPATIBLE_MEMORY_LAYOUT;
134                                 if (pMetadataMap->ContainsKey(key) == true)
135                                 {
136                                         uiLoader = false;
137                                 }
138                         }
139
140                         if (uiLoader == true)
141                         {
142                                 AppLog("copy ui app loader");
143                                 loaderPath = UIAPP_LOADER_PATH;
144                         }
145                         else
146                         {
147                                 AppLog("copy exec loader");
148                                 loaderPath = EXEC_LOADER_PATH;
149                         }
150                         InstallerUtil::Copy(loaderPath, binaryPath);
151
152                         int categoryType = pAppData->__feature;
153                         if (categoryType != CATEGORY_TYPE_NONE)
154                         {
155                                 String category = InstallerUtil::GetCategory(categoryType);
156                                 category.ToLowerCase();
157
158                                 int type = _Aul::GetAppType(category);
159
160                                 if (category == L"ime")
161                                 {
162                                         CreateImeSymlink(binaryPath, appId);
163                                 }
164
165                                 String typeInfo;
166                                 typeInfo.Format(1024, L"%d", type);
167
168                                 String typeInfoFile;
169                                 typeInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), TYPE_INFO_FILE);
170
171                                 InstallerUtil::CreateInfoFile(typeInfoFile, &typeInfo);
172                         }
173                 }
174                 else if (appType == L"ServiceApp")
175                 {
176                         if ((pContext->__isPreloaded == true) && (pAppData->__isSystemService == true))
177                         {
178                                 AppLog("copy system service loader");
179                                 InstallerUtil::Copy(SYSTEMSERIVCE_LOADER_PATH, binaryPath);
180                         }
181                         else
182                         {
183                                 AppLog("copy service app loader");
184                                 InstallerUtil::Copy(SERVICEAPP_LOADER_PATH, binaryPath);
185                         }
186                 }
187
188                 InstallerUtil::ChangeMode(binaryPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
189         }
190
191         ArrayList* pContentDataList = pContext->GetContentDataList();
192         if (pContentDataList)
193         {
194                 int contentCount = pContentDataList->GetCount();
195                 for (int i = 0 ; i < contentCount; i++)
196                 {
197                         ContentData* pContentData = static_cast<ContentData*>(pContentDataList->GetAt(i));
198                         if (pContentData)
199                         {
200                                 String contentId = pContentData->GetContentId();
201                                 String oldPath = rootPath + DIR_CONTENTS + L"/" + contentId;
202
203                                 if (File::IsFileExist(SLP_FONT_PATH) == false)
204                                 {
205                                         Directory::Create(SLP_FONT_PATH, false);
206                                         InstallerUtil::ChangeMode(SLP_FONT_PATH, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
207                                 }
208
209                                 String newPath = SLP_FONT_PATH;
210                                 newPath += L"/" + pContext->__packageId;
211                                 Directory::Create(newPath, false);
212                                 InstallerUtil::ChangeMode(newPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
213
214                                 newPath += L"/";
215                                 newPath += contentId;
216                                 InstallerUtil::CreateSymlink(oldPath, newPath);
217                         }
218                 }
219         }
220
221         String roXmlPath;
222         roXmlPath.Format(1024, DIR_RO_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
223
224         String rwXmlPath;
225         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
226
227         if (pContext->__isPreloaded == true)
228         {
229                 pContext->__coreXmlPath = roXmlPath;
230         }
231         else
232         {
233                 pContext->__coreXmlPath = rwXmlPath;
234         }
235
236         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
237         TryReturn(pXmlPath != null, false, "pXmlPath is null");
238
239         CreateCoreXmlFile(pContext);
240
241         AppLog("------------------------------------------");
242         AppLog("sync() - START");
243         sync();
244         AppLog("sync() - END");
245         AppLog("------------------------------------------");
246         
247         err = pkgmgr_parser_check_manifest_validation(pXmlPath.get());
248         TryReturn(err == 0, false, "pkgmgr_parser_check_manifest_validation() is failed. error = [%d][%s]", err, pXmlPath.get());
249
250         return true;
251 }
252
253 bool
254 ConfigurationManager::RemoveFile(InstallationContext* pContext)
255 {
256         if (pContext->__isPreloaded == true)
257         {
258                 pContext->__coreXmlPath.Format(1024, DIR_RO_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
259         }
260         else
261         {
262                 pContext->__coreXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
263         }
264
265         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
266         TryReturn(pXmlPath != null, false, "pXmlPath is null");
267
268
269         AppLog("pkgmgr_parser_parse_manifest_for_uninstallation(%s) START", pXmlPath.get());
270         if (pkgmgr_parser_parse_manifest_for_uninstallation(pXmlPath.get(), null) != 0)
271         {
272                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() is failed.[%s]", pXmlPath.get());
273         }
274         AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() END");
275
276         InstallerUtil::Remove(pXmlPath.get());
277
278         return true;
279 }
280
281 bool
282 ConfigurationManager::PostInstall(InstallationContext* pContext, bool error) const
283 {
284         bool res = true;
285         PackageId packageId = pContext->__packageId;
286         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
287         TryReturn(pPackageId, false, "pPackageId is null.");
288
289         if (error == false)
290         {
291                 SmackManager smackManager;
292                 smackManager.Construct(pContext);
293                 smackManager.EnablePermissions(packageId);
294
295                 res = RegisterCoreXmlFile(pContext);
296                 TryReturn(res, false, "RegisterCoreXmlFile() failed.");
297
298 #if 0
299                 if ((pContext->__isUpdated == true) && (pContext->__isPreloaded == false))
300                 {
301                         CopyData(pContext);
302                         RemoveBackup(pContext);
303                 }
304 #endif
305         }
306         else
307         {
308 #if 0
309                 if ((pContext->__isUpdated == true) && (pContext->__isPreloaded == false))
310                 {
311                         RestoreBackup(pContext);
312                 }
313 #endif
314         }
315
316         app2ext_handle* pHandle = (app2ext_handle*)pContext->__pApp2ExtHandle;
317         if (pHandle)
318         {
319                 if (error == true)
320                 {
321                         pHandle->interface.post_install(pPackageId.get(), APP2EXT_STATUS_FAILED);
322                         AppLog("[app2sd] post_install(%s, APP2EXT_STATUS_FAILED)", pPackageId.get());
323                 }
324                 else
325                 {
326                         pHandle->interface.post_install(pPackageId.get(), APP2EXT_STATUS_SUCCESS);
327                         AppLog("[app2sd] post_install(%s, APP2EXT_STATUS_SUCCESS)", pPackageId.get());
328                 }
329
330                 app2ext_deinit(pHandle);
331         }
332
333         return true;
334 }
335
336 bool
337 ConfigurationManager::PostUninstall(InstallationContext* pContext) const
338 {
339         app2ext_handle* pHandle = (app2ext_handle*)pContext->__pApp2ExtHandle;
340
341         PackageId packageId = pContext->__packageId;
342         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
343         TryReturn(pPackageId, false, "pPackageId is null.");
344
345         if (pHandle)
346         {
347                 pHandle->interface.post_uninstall(pPackageId.get());
348                 AppLog("[app2sd] post_uninstall(%s)", pPackageId.get());
349
350                 app2ext_deinit(pHandle);
351         }
352
353         SmackManager smackManager;
354         smackManager.Construct(pContext);
355         smackManager.RevokePermissions(packageId);
356
357         return true;
358 }
359
360 #if 0
361 bool
362 ConfigurationManager::CreateBackup(InstallationContext* pContext) const
363 {
364         TryReturn(pContext, false, "pContext is null.");
365         TryReturn(pContext->__packageId.IsEmpty() == false, false, "packageId is empty.");
366
367         if (pContext->__isHybridService == true)
368         {
369                 return true;
370         }
371
372         bool res = true;
373         result r = E_SUCCESS;
374         PackageId packageId = pContext->__packageId;
375         String rootPath;
376
377         rootPath += PATH_OPT_USR_APPS;
378         rootPath += L"/";
379         rootPath += packageId;
380         TryReturn(File::IsFileExist(rootPath) == true, false, "rootPath[%ls] is not found.", rootPath.GetPointer());
381
382         String backupPath = rootPath + BACKUP_NAME_RULE;
383         if (File::IsFileExist(backupPath) == true)
384         {
385                 InstallerUtil::Remove(backupPath);
386         }
387
388         // folder
389         r = Directory::Rename(rootPath, backupPath);
390         TryReturn(r == E_SUCCESS, false, "Directory::Rename(%ls, %ls) failed.", rootPath.GetPointer(), backupPath.GetPointer());
391
392         AppLog("[%ls] -> [%ls] is renamed.", rootPath.GetPointer(), backupPath.GetPointer());
393
394         // database
395         DatabaseManager databaseManager;
396         res = databaseManager.BackupPackageInfo(pContext);
397         TryReturn(res == true, false, "databaseManager.BackupPackageInfo() failed.");
398
399         // core xml
400         String rwXmlPath;
401         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
402
403         if (File::IsFileExist(rwXmlPath) == true)
404         {
405                 String backupXmlPath = rwXmlPath + BACKUP_NAME_RULE;
406                 if (File::IsFileExist(backupXmlPath) == true)
407                 {
408                         InstallerUtil::Remove(backupXmlPath);
409                 }
410
411                 result r = File::Move(rwXmlPath, backupXmlPath);
412                 TryReturn(r == E_SUCCESS, false, "File::Move(%ls, %ls) failed.", rwXmlPath.GetPointer(), backupXmlPath.GetPointer());
413
414                 AppLog("[%ls] -> [%ls] is renamed.", rwXmlPath.GetPointer(), backupXmlPath.GetPointer());
415         }
416         else
417         {
418                 AppLog("It's updated from preloaded to downloaded, need not to backup xml file. [%ls]", packageId.GetPointer());
419         }
420
421         return true;
422 }
423
424 bool
425 ConfigurationManager::RemoveGarbage(const PackageId& packageId) const
426 {
427         TryReturn(packageId.IsEmpty() == false, false, "packageId is empty.");
428
429         String rootPath = PATH_OPT_USR_APPS;
430         rootPath += L"/";
431         rootPath += packageId;
432
433         // folder
434         String backupPath = rootPath + BACKUP_NAME_RULE;
435         if (File::IsFileExist(backupPath) == true)
436         {
437                 InstallerUtil::Remove(backupPath);
438                 AppLog("[%ls] is removed.", backupPath.GetPointer());
439         }
440
441         // database
442         DatabaseManager databaseManager;
443         databaseManager.UnregisterPackageInfo(packageId, true);
444
445         // core xml
446         String rwXmlPath;
447         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
448         String backupXmlPath = rwXmlPath + BACKUP_NAME_RULE;
449         if (File::IsFileExist(backupXmlPath) == true)
450         {
451                 InstallerUtil::Remove(backupXmlPath);
452         }
453
454         if (_PackageManagerImpl::GetInstance()->IsPackageInstalled(packageId) == false)
455         {
456                 AppLog("[%ls] is not installed.", packageId.GetPointer());
457
458                 if (File::IsFileExist(rootPath) == true)
459                 {
460                         InstallerUtil::Remove(rootPath);
461                 }
462                 else
463                 {
464                         AppLog("[%ls] is not existed.", rootPath.GetPointer());
465                 }
466
467                 DatabaseManager databaseManager;
468                 databaseManager.UnregisterPackageInfo(packageId, false);
469
470                 if (File::IsFileExist(rwXmlPath) == true)
471                 {
472                         InstallerUtil::Remove(rwXmlPath);
473                 }
474                 else
475                 {
476                         AppLog("[%ls] is not existed.", rwXmlPath.GetPointer());
477                 }
478         }
479
480         return true;
481 }
482
483 bool
484 ConfigurationManager::RemoveBackup(InstallationContext* pContext) const
485 {
486         TryReturn(pContext, false, "pContext is null.");
487         TryReturn(pContext->__packageId.IsEmpty() == false, false, "packageId is empty.");
488
489         if (pContext->__isHybridService == true)
490         {
491                 return true;
492         }
493
494         PackageId packageId = pContext->__packageId;
495         bool res = true;
496         String backupPath;
497
498         backupPath += PATH_OPT_USR_APPS;
499         backupPath += L"/";
500         backupPath += packageId;
501         backupPath += BACKUP_NAME_RULE;
502         TryReturn(File::IsFileExist(backupPath) == true, false, "backupPath[%ls] is not found.", backupPath.GetPointer());
503
504         // folder
505         InstallerUtil::Remove(backupPath);
506         AppLog("[%ls] is removed.", backupPath.GetPointer());
507
508         // database
509         DatabaseManager databaseManager;
510         res = databaseManager.UnregisterPackageInfo(packageId, true);
511         TryReturn(res == true, false, "databaseManager.UnregisterPackageInfo() failed.");
512
513         // core xml
514         String backupXmlPath;
515         backupXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
516         backupXmlPath += BACKUP_NAME_RULE;
517
518         if (File::IsFileExist(backupXmlPath) == true)
519         {
520                 InstallerUtil::Remove(backupXmlPath);
521         }
522         else
523         {
524                 AppLog("It's updated from preloaded to downloaded, There is no backup xml file. [%ls]", packageId.GetPointer());
525         }
526
527         return true;
528 }
529
530 bool
531 ConfigurationManager::RestoreBackup(InstallationContext* pContext) const
532 {
533         TryReturn(pContext, false, "pContext is null.");
534         TryReturn(pContext->__packageId.IsEmpty() == false, false, "packageId is empty.");
535
536         if (pContext->__isHybridService == true)
537         {
538                 return true;
539         }
540
541         bool res = true;
542         result r = E_SUCCESS;
543         PackageId packageId = pContext->__packageId;
544         String rootPath;
545         String backupPath;
546
547         rootPath += PATH_OPT_USR_APPS;
548         rootPath += L"/";
549         rootPath += packageId;
550
551         if (File::IsFileExist(rootPath) == true)
552         {
553                 InstallerUtil::Remove(rootPath);
554         }
555
556         backupPath = rootPath + BACKUP_NAME_RULE;
557         TryReturn(File::IsFileExist(backupPath) == true, false, "backupPath[%ls] is not found.", backupPath.GetPointer());
558
559         // folder
560         r = Directory::Rename(backupPath, rootPath);
561         TryReturn(r == E_SUCCESS, false, "Directory::Rename(%ls, %ls) failed.", backupPath.GetPointer(), rootPath.GetPointer());
562
563         AppLog("[%ls] -> [%ls] is renamed.", backupPath.GetPointer(), rootPath.GetPointer());
564
565         // database
566         DatabaseManager databaseManager;
567         res = databaseManager.RestorePackageInfo(pContext);
568         TryReturn(res == true, false, "databaseManager.RestorePackageInfo() failed.");
569
570         // core xml
571         String rwXmlPath;
572         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, packageId.GetPointer());
573
574         String backupXmlPath = rwXmlPath + BACKUP_NAME_RULE;
575         if (File::IsFileExist(backupXmlPath) == true)
576         {
577                 if (File::IsFileExist(rwXmlPath) == true)
578                 {
579                         InstallerUtil::Remove(rwXmlPath);
580                 }
581
582                 result r = File::Move(backupXmlPath, rwXmlPath);
583                 TryReturn(r == E_SUCCESS, false, "File::Move(%ls, %ls) failed.", backupXmlPath.GetPointer(), rwXmlPath.GetPointer());
584
585                 AppLog("[%ls] -> [%ls] is renamed.", backupXmlPath.GetPointer(), rwXmlPath.GetPointer());
586         }
587
588         return true;
589 }
590
591 bool
592 ConfigurationManager::CopyData(InstallationContext* pContext) const
593 {
594         TryReturn(pContext, false, "pContext is null.");
595         TryReturn(pContext->__packageId.IsEmpty() == false, false, "packageId is empty.");
596
597         if (pContext->__isHybridService == true)
598         {
599                 return true;
600         }
601
602         SmackManager smackManager;
603         smackManager.Construct(pContext);
604
605         PackageId packageId = pContext->__packageId;
606         String srcPath;
607         String destPath;
608         String rootPath;
609         String backupPath;
610
611         rootPath += PATH_OPT_USR_APPS;
612         rootPath += L"/";
613         rootPath += packageId;
614
615         backupPath = rootPath + BACKUP_NAME_RULE;
616         TryReturn(File::IsFileExist(backupPath) == true, false, "backupPath[%ls] is not found.", backupPath.GetPointer());
617
618         // data
619         srcPath = backupPath + DIR_DATA;
620         destPath = rootPath + DIR_DATA;
621         InstallerUtil::CopyDirectory(srcPath, destPath, true);
622         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
623         smackManager.SetupPath(packageId, destPath, APP_PATH_PRIVATE);
624
625         // setting
626         srcPath = backupPath + DIR_SETTING;
627         destPath = rootPath + DIR_SETTING;
628         InstallerUtil::CopyDirectory(srcPath, destPath, true);
629         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
630         smackManager.SetupPath(packageId, destPath, APP_PATH_SETTINGS_RW);
631
632         // shared/data
633         srcPath = backupPath + DIR_SHARED_DATA;
634         destPath = rootPath + DIR_SHARED_DATA;
635         InstallerUtil::CopyDirectory(srcPath, destPath, true);
636         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
637         smackManager.SetupPath(packageId, destPath, APP_PATH_PUBLIC_RO);
638
639         // shared/trust
640         srcPath = backupPath + DIR_SHARED_TRUSTED;
641         destPath = rootPath + DIR_SHARED_TRUSTED;
642         InstallerUtil::CopyDirectory(srcPath, destPath, true);
643         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
644         smackManager.SetupPath(packageId, destPath, APP_PATH_GROUP_RW);
645
646         return true;
647 }
648 #endif
649
650 bool
651 ConfigurationManager::CreateCoreXmlFile(InstallationContext* pContext) const
652 {
653         AppLog("------------------------------------------");
654         AppLog("CreateCoreXmlFile() - START");
655         bool ret = false;
656
657         ManifestGenerator manifestGenerator;
658         manifestGenerator.Construct(pContext);
659         ret = manifestGenerator.Write();
660
661         if (ret == false)
662         {
663                 AppLog("manifestGenerator.Write() is failed.");
664         }
665         AppLog("CreateCoreXmlFile() - END");
666         AppLog("------------------------------------------");
667
668         return ret;
669 }
670
671 bool
672 ConfigurationManager::RegisterCoreXmlFile(InstallationContext* pContext) const
673 {
674         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
675         TryReturn(pXmlPath != null, false, "pXmlPath is null.");
676
677         int err = 0;
678
679         if (pContext->__isCsc == true)
680         {
681                 char* pUpdateTag[3] = {null, };
682
683                 String preload("preload=true");
684                 String removable("removable=");
685                 if (pContext->__isUninstallable == false)
686                 {
687                         removable.Append("false");
688                 }
689                 else
690                 {
691                         removable.Append("true");
692                 }
693
694                 std::unique_ptr<char[]> pPreload(_StringConverter::CopyToCharArrayN(preload));
695                 TryReturn(pPreload, false, "pPreload is null.");
696
697                 std::unique_ptr<char[]> pRemovable(_StringConverter::CopyToCharArrayN(removable));
698                 TryReturn(pRemovable, false, "pRemovable is null.");
699
700                 pUpdateTag[0] = pPreload.get();
701                 pUpdateTag[1] = pRemovable.get();
702                 pUpdateTag[2] = null;
703
704                 for (int i = 0; pUpdateTag[i] != null; i++)
705                 {
706                         AppLog("pUpdateTag[%d] = [%s]", i, pUpdateTag[i]);
707                 }
708
709                 AppLog("pkgmgr_parser_parse_manifest_for_installation(%s) - START", pXmlPath.get());
710                 err = pkgmgr_parser_parse_manifest_for_installation(pXmlPath.get(), pUpdateTag);
711                 TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_installation() is failed. error = [%d][%s]", err, pXmlPath.get());
712
713                 AppLog("pkgmgr_parser_parse_manifest_for_installation() - END");
714         }
715         else
716         {
717                 if (pContext->__isUpdated == true)
718                 {
719                         AppLog("pkgmgr_parser_parse_manifest_for_upgrade(%s) - START", pXmlPath.get());
720                         err = pkgmgr_parser_parse_manifest_for_upgrade(pXmlPath.get(), null);
721                         TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_upgrade() is failed. error = [%d][%s]", err, pXmlPath.get());
722
723                         AppLog("pkgmgr_parser_parse_manifest_for_upgrade() - END");
724                 }
725                 else
726                 {
727                         AppLog("pkgmgr_parser_parse_manifest_for_installation(%s) - START", pXmlPath.get());
728                         err = pkgmgr_parser_parse_manifest_for_installation(pXmlPath.get(), null);
729                         TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_installation() is failed. error = [%d][%s]", err, pXmlPath.get());
730
731                         AppLog("pkgmgr_parser_parse_manifest_for_installation() - END");
732                 }
733         }
734
735         return true;
736 }
737
738 //bool
739 //ConfigurationManager::CreateHybridServiceDesktopFile(InstallationContext* pContext)
740 //{
741 //      AppLog("HybridServiceDesktopFile - START");
742 //
743 //      bool ret = true;
744 //      _PackageInfoImpl *pPackageInfoImpl = pContext->GetPackageInfoImpl();
745 //      _PackageAppInfoImpl* pAppInfoImpl = null;
746 //      ArrayList* pAppList = null;
747 //      pAppList = pPackageInfoImpl->GetAppInfoList();
748 //
749 //      for (int i = 0 ; i < pAppList->GetCount(); i++)
750 //      {
751 //              pAppInfoImpl = dynamic_cast<_PackageAppInfoImpl*>(pAppList->GetAt(i));
752 //
753 //              if (pAppInfoImpl)
754 //              {
755 //                      String name;
756 //                      name.Format(1024, L"%ls", pPackageInfoImpl->GetAppName().GetPointer());
757 //
758 //                      String binaryPath;
759 //                      binaryPath.Format(1024, L"%ls%ls/%ls", pPackageInfoImpl->GetAppRootPath().GetPointer(), DIR_BIN, pAppInfoImpl->GetName().GetPointer());
760 //
761 //                      String iconPath;
762 //                      iconPath.Format(1024, L"%ls%ls/%ls", pPackageInfoImpl->GetAppRootPath().GetPointer(), DIR_ICONS, pAppInfoImpl->GetMainmenuIcon().GetPointer());
763 //
764 //                      String version;
765 //                      version.Format(1024, L"%ls", pPackageInfoImpl->GetVersion().GetPointer());
766 //
767 //                      String desktop;
768 //                      desktop.Format(1024, L"[Desktop Entry]\n"
769 //                                                                                                        "Name=%ls\n"
770 //                                                                                                              "Name[en_GB]=%ls\n"
771 //                                                                                                              "Type=Application\n"
772 //                                                                                                      "Exec=%ls\n"
773 //                                                                                                        "Icon=%ls\n"
774 //                                                                                                        "Version=%ls\n"
775 //                                                                                                        "NoDisplay=true\n"
776 //                                                                                                        "X-TIZEN-TaskManage=False\n"
777 //                                                                                                        "X-TIZEN-PackageType=tpk\n",
778 //                                                                                                        name.GetPointer(), name.GetPointer(), binaryPath.GetPointer(), iconPath.GetPointer(), version.GetPointer());
779 //
780 //                      String desktopPath;
781 //                      desktopPath.Format(1024, L"/opt/share/applications/%ls.desktop", pAppInfoImpl->GetPackageName().GetPointer());
782 //
783 //                      if (File::IsFileExist(desktopPath) == true)
784 //                      {
785 //                              AppLog("removing desktop filePath=[%ls]", desktopPath.GetPointer());
786 //                              InstallerUtil::Remove(desktopPath);
787 //                      }
788 //
789 //                      InstallerUtil::CreateInfoFile(desktopPath, &desktop);
790 //              }
791 //      }
792 //
793 //      AppLog("HybridServiceDesktopFile - END");
794 //
795 //      return ret;
796 //}
797
798 bool
799 ConfigurationManager::MergeToSystemXmlFile(const String& systemXmlPath, const String& webXmlPath, const String& serviceXmlPath)
800 {
801         result r = E_SUCCESS;
802
803         FileAttributes webXmlAttr;
804         r = File::GetAttributes(webXmlPath, webXmlAttr);
805         TryReturn(!IsFailed(r), false, "File::GetAttributes() failed, webXmlPath=%ls", webXmlPath.GetPointer());
806
807         FileAttributes serviceAttr;
808         r = File::GetAttributes(serviceXmlPath, serviceAttr);
809         TryReturn(!IsFailed(r), false, "File::GetAttributes() failed, serviceXmlPath=%ls", serviceXmlPath.GetPointer());
810
811         long long webXmlFileSize = webXmlAttr.GetFileSize();
812         long long serviceXmlFileSize = serviceAttr.GetFileSize();
813         long long mergedSize = webXmlFileSize + serviceXmlFileSize;
814
815         File webXml;
816         r = webXml.Construct(webXmlPath, L"r");
817         TryReturn(!IsFailed(r), false, "webXmlPath.Construct is failed");
818
819         std::unique_ptr<char[]> pMergedBuf(new (std::nothrow) char[mergedSize + 1]);
820         TryReturn(pMergedBuf, false, "pMergedBuf is null");
821         memset(pMergedBuf.get(), 0, mergedSize + 1);
822
823         int readBytes = webXml.Read(pMergedBuf.get(), webXmlFileSize);
824         TryReturn(readBytes >= 0, false, "webXml.Read is failed");
825
826         File serviceXml;
827         r = serviceXml.Construct(serviceXmlPath, L"r");
828         TryReturn(!IsFailed(r), false, "serviceXmlPath.Construct is failed");
829
830         std::unique_ptr<char[]> pServiceBuf(new (std::nothrow) char[serviceXmlFileSize + 1]);
831         TryReturn(pServiceBuf, false, "pServiceBuf is null");
832         memset(pServiceBuf.get(), 0, serviceXmlFileSize + 1);
833
834         readBytes = serviceXml.Read(pServiceBuf.get(), serviceXmlFileSize);
835         TryReturn(readBytes >= 0, false, "serviceXml.Read is failed");
836
837         char* pManifestTag = strcasestr(pMergedBuf.get(), "</manifest>");
838         TryReturn(pManifestTag, false, "pManifestTag is null");
839
840         char* pAppTagStart = strcasestr(pServiceBuf.get(), "<ui-application");
841         TryReturn(pAppTagStart, false, "pAppTagStart is null");
842
843         char* pAppTagEnd = strcasestr(pServiceBuf.get(), "</ui-application>");
844         TryReturn(pAppTagEnd, false, "pAppTagEnd is null");
845
846         int serviceAppLen = pAppTagEnd - pAppTagStart + strlen("</ui-application>");
847
848         memcpy(pManifestTag, pAppTagStart, serviceAppLen);
849
850         char* pManifestEndTag = pManifestTag + serviceAppLen;
851         strcpy(pManifestEndTag, "\n</manifest>");
852
853         int fileSize = pManifestEndTag - pMergedBuf.get() + strlen("\n</manifest>");
854
855         AppLog("[0] File Size = [%d]", fileSize);
856
857         if (strcasestr(pServiceBuf.get(), "</privileges>") != null)
858         {
859                 AppLog("Privileges are detected in service app.");
860                 MergePrivileges(pMergedBuf.get(), pServiceBuf.get(), fileSize);
861         }
862         else
863         {
864                 AppLog("No privileges are detected in service app.");
865         }
866         AppLog("[1] File Size = [%d]", fileSize);
867
868         MergeAppWidgets(pMergedBuf.get(), pServiceBuf.get(), fileSize);
869         AppLog("[2] File Size = [%d]", fileSize);
870
871         MergeAccounts(pMergedBuf.get(), pServiceBuf.get(), fileSize);
872         AppLog("[3] File Size = [%d]", fileSize);
873
874         MergeNotifications(pMergedBuf.get(), pServiceBuf.get(), fileSize);
875         AppLog("[4] File Size = [%d]", fileSize);
876
877         MergeIme(pMergedBuf.get(), pServiceBuf.get(), fileSize);
878         AppLog("[5] File Size = [%d]", fileSize);
879
880         File systemXml;
881         r = systemXml.Construct(systemXmlPath, L"w");
882         TryReturn(!IsFailed(r), false, "systemXmlPath.Construct() is failed.");
883
884         r = systemXml.Write(pMergedBuf.get(), fileSize);
885         TryReturn(!IsFailed(r), false, "systemXmlPath.Write() is failed.");
886
887         AppLog("pMergedBuf.get()=0x%0x, length=%d", (unsigned int)pMergedBuf.get(), fileSize);
888         InstallerUtil::DumpLogData(pMergedBuf.get(), fileSize);
889
890         return true;
891 }
892
893 bool
894 ConfigurationManager::MergePrivileges(char* pMergedBuf, char* pServiceBuf, int& fileSize)
895 {
896         char* pMergedPrivilegeDetected = strcasestr(pMergedBuf, "</privileges>");
897         char* pMergedPoint = null;
898         char* pServicePrivilegeStart = null;
899         char* pServicePrivilegeEnd = null;
900         int privilegeLen = 0;
901         int serviceBufLen = strlen(pServiceBuf);
902         std::unique_ptr<char[]> pSelectedPrivBuf(new char[serviceBufLen + 1]);
903         memset(pSelectedPrivBuf.get(), 0, serviceBufLen + 1);
904
905         if (pMergedPrivilegeDetected == null)
906         {
907                 AppLog("No privileges are detected in web app.");
908
909                 pServicePrivilegeStart = strcasestr(pServiceBuf, "<privileges>");
910                 pServicePrivilegeEnd = strcasestr(pServiceBuf, "</privileges>");
911
912                 privilegeLen = pServicePrivilegeEnd - pServicePrivilegeStart + strlen("</privileges>");
913                 pMergedPoint = strcasestr(pMergedBuf, "<ui-application");
914
915                 AppLog("Inserted privileges of service app");
916                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
917         }
918         else
919         {
920                 AppLog("Privileges are detected in web app.");
921
922                 pServicePrivilegeStart = strcasestr(pServiceBuf, "<privilege>");
923                 pServicePrivilegeEnd = strcasestr(pServiceBuf, "</privileges>");
924
925                 privilegeLen = pServicePrivilegeEnd - pServicePrivilegeStart;
926                 pMergedPoint = strcasestr(pMergedBuf, "</privileges>");
927
928                 AppLog("Original privileges of service app");
929                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
930
931                 std::unique_ptr<char[]> pPrivBuf(new char[privilegeLen + 1]);
932                 memset(pPrivBuf.get(), 0, privilegeLen + 1);
933                 strncpy(pPrivBuf.get(), pServicePrivilegeStart, privilegeLen);
934
935                 char* pEachPrivStart = pPrivBuf.get();
936                 char* pEachPrivEnd = null;
937                 int eachPrivLen = 0;
938                 char eachPrivBuf[512] = {0};
939
940                 while (pEachPrivStart && (pEachPrivStart < pPrivBuf.get() + privilegeLen))
941                 {
942                         pEachPrivEnd = strcasestr(pEachPrivStart, "</privilege>");
943                         eachPrivLen = pEachPrivEnd - pEachPrivStart + strlen("</privilege>");
944                         if ((pEachPrivEnd > 0) && (eachPrivLen > 0))
945                         {
946                                 memset(eachPrivBuf, 0, sizeof(eachPrivBuf));
947                                 memcpy(eachPrivBuf, pEachPrivStart, eachPrivLen);
948                                 AppLog("[%s]", eachPrivBuf);
949
950                                 if (strcasestr(pMergedBuf, eachPrivBuf) == 0)
951                                 {
952                                         strncat(pSelectedPrivBuf.get(), eachPrivBuf, serviceBufLen);
953                                 }
954                                 else
955                                 {
956                                         AppLog("This privilege is discarded, [%s]", eachPrivBuf);
957                                 }
958                         }
959                         else
960                         {
961                                 AppLog("End of privileges merging.");
962                                 break;
963                         }
964
965                         pEachPrivStart = strcasestr(pEachPrivEnd, "<privilege>");
966                 }
967
968                 pServicePrivilegeStart = pSelectedPrivBuf.get();
969                 privilegeLen = strlen(pServicePrivilegeStart);
970
971                 AppLog("Filtered privileges of service app");
972                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
973         }
974
975         if ((pMergedPoint > 0) && (pServicePrivilegeStart > 0) && (privilegeLen > 0))
976         {
977                 int lastPartLen = fileSize - (pMergedPoint - pMergedBuf);
978                 std::unique_ptr<char[]> pLastPartBuf(new (std::nothrow) char[fileSize + 1]);
979                 memset(pLastPartBuf.get(), 0, fileSize + 1);
980
981                 if (lastPartLen > 0)
982                 {
983                         memcpy(pLastPartBuf.get(), pMergedPoint, lastPartLen);
984
985                         AppLog("Last part of merged xml for backup");
986                         InstallerUtil::DumpLogData(pLastPartBuf.get(), lastPartLen);
987
988                         memcpy(pMergedPoint, pServicePrivilegeStart, privilegeLen);
989
990                         memcpy(pMergedPoint + privilegeLen, pLastPartBuf.get(), lastPartLen);
991                         fileSize += privilegeLen;
992                 }
993         }
994
995         return true;
996 }
997
998 bool
999 ConfigurationManager::MergeAppWidgets(char* pMergedBuf, char* pServiceBuf, int& fileSize)
1000 {
1001         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
1002         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
1003         TryReturn(fileSize > 0, false, "fileSize is invalid.");
1004
1005         if (strcasestr(pServiceBuf, "</livebox>") == null)
1006         {
1007                 AppLog("<livebox> is NOT detected in service app.");
1008                 return true;
1009         }
1010
1011         AppLog("<livebox> is detected in service app.");
1012         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<livebox", "</livebox>");
1013
1014         return true;
1015 }
1016
1017 bool
1018 ConfigurationManager::MergeAccounts(char* pMergedBuf, char* pServiceBuf, int& fileSize)
1019 {
1020         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
1021         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
1022         TryReturn(fileSize > 0, false, "fileSize is invalid.");
1023
1024         if (strcasestr(pServiceBuf, "</account>") == null)
1025         {
1026                 AppLog("<account> is NOT detected in service app.");
1027                 return true;
1028         }
1029
1030         AppLog("<account> is detected in service app.");
1031         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<account", "</account>");
1032
1033         return true;
1034 }
1035
1036 bool
1037 ConfigurationManager::MergeNotifications(char* pMergedBuf, char* pServiceBuf, int& fileSize)
1038 {
1039         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
1040         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
1041         TryReturn(fileSize > 0, false, "fileSize is invalid.");
1042
1043         if (strcasestr(pServiceBuf, "</notifications>") == null)
1044         {
1045                 AppLog("<notifications> is NOT detected in service app.");
1046                 return true;
1047         }
1048
1049         AppLog("<notifications> is detected in service app.");
1050         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<notifications", "</notifications>");
1051
1052         return true;
1053 }
1054
1055 bool
1056 ConfigurationManager::MergeIme(char* pMergedBuf, char* pServiceBuf, int& fileSize)
1057 {
1058         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
1059         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
1060         TryReturn(fileSize > 0, false, "fileSize is invalid.");
1061
1062         if (strcasestr(pServiceBuf, "</ime>") == null)
1063         {
1064                 AppLog("<ime> is NOT detected in service app.");
1065                 return true;
1066         }
1067
1068         AppLog("<ime> is detected in service app.");
1069         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<ime", "</ime>");
1070
1071         return true;
1072 }
1073
1074 bool
1075 ConfigurationManager::MergeTags(char* pMergedBuf, char* pServiceBuf, int& fileSize, const char* pStartTag, const char* pEndTag)
1076 {
1077         do
1078         {
1079                 char* pBuf = null;
1080                 int length = 0;
1081                 char* pNext = null;
1082
1083                 AppLog("pServiceBuf = [0x%08x]", pServiceBuf);
1084                 GetPart(pServiceBuf, pStartTag, pEndTag, &pBuf, &length, &pNext);
1085                 if (length > 0)
1086                 {
1087                         MergeTo(pMergedBuf, fileSize, "</manifest>", pBuf, length);
1088                 }
1089
1090                 delete [] pBuf;
1091
1092                 pServiceBuf = pNext;
1093         }
1094         while (pServiceBuf > 0);
1095
1096         return true;
1097 }
1098
1099 bool
1100 ConfigurationManager::GetPart(const char* pStartPoint, const char* pStartTag, const char* pEndTag, char** ppBuf, int* pLength, char** ppNext)
1101 {
1102         TryReturn(pStartPoint, false, "pStartPoint is null.");
1103         TryReturn(pStartTag, false, "pStartTag is null.");
1104         TryReturn(pEndTag, false, "pEndTag is null.");
1105         TryReturn(ppBuf, false, "ppBuf is null.");
1106         TryReturn(pLength, false, "pLength is null.");
1107         TryReturn(ppNext, false, "ppNext is null.");
1108
1109         const char* pStartBufPoint = strcasestr(pStartPoint, pStartTag);
1110         TryReturn(pStartBufPoint, false, "pStartBufPoint is null.");
1111
1112         const char* pEndBufPoint = strcasestr(pStartBufPoint, pEndTag);
1113         TryReturn(pEndBufPoint, false, "pEndBufPoint is null.");
1114
1115         int len = pEndBufPoint - pStartBufPoint + strlen(pEndTag);
1116         TryReturn(len > 0, false, "len is invalid.");
1117
1118         char *pBuf = null;
1119         pBuf = new char[len + 1];
1120         TryReturn(pBuf, false, "pBuf is null.");
1121         memset(pBuf, 0, len + 1);
1122         memcpy(pBuf, pStartBufPoint, len);
1123
1124         AppLog("Extracted Part, len = [%d]", len);
1125         InstallerUtil::DumpLogData(pBuf, len);
1126
1127         *ppBuf = pBuf;
1128         *pLength = len;
1129         *ppNext = (char *)pEndBufPoint;
1130
1131         return true;
1132 }
1133
1134 bool
1135 ConfigurationManager::MergeTo(const char* pMergedBuf, int& fileSize, const char* pTag, const char* pBuf, int length)
1136 {
1137         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
1138         TryReturn(fileSize > 0, false, "fileSize is invalid.");
1139         TryReturn(pTag, false, "pTag is null.");
1140         TryReturn(pBuf, false, "pBuf is null.");
1141         TryReturn(length > 0, false, "length is invalid.");
1142
1143         char* pMergedPoint = null;
1144         pMergedPoint = (char *)strcasestr(pMergedBuf, pTag);
1145         TryReturn(pMergedPoint > 0, true, "pTag is not found, pTag=[%s]", pTag);
1146
1147         int lastPartLen = fileSize - (pMergedPoint - pMergedBuf);
1148         std::unique_ptr<char[]> pLastPartBuf(new (std::nothrow) char[fileSize + 1]);
1149         memset(pLastPartBuf.get(), 0, fileSize + 1);
1150
1151         if (lastPartLen > 0)
1152         {
1153                 memcpy(pLastPartBuf.get(), pMergedPoint, lastPartLen);
1154
1155                 AppLog("Last part of merged xml for backup");
1156                 InstallerUtil::DumpLogData(pLastPartBuf.get(), lastPartLen);
1157
1158                 memcpy(pMergedPoint, pBuf, length);
1159                 memcpy(pMergedPoint + length, pLastPartBuf.get(), lastPartLen);
1160                 fileSize += length;
1161         }
1162
1163         return true;
1164 }
1165
1166 bool
1167 ConfigurationManager::CreateImeSymlink(const String& binaryPath, const String& appId)
1168 {
1169         bool res = true;
1170         int err = 0;
1171         const char* pExePath = null;
1172         const char* pSymlinkPath = null;
1173
1174         Directory::Create(IME_PATH, true);
1175
1176         String exePath;
1177         exePath.Format(1024, L"%ls.exe", binaryPath.GetPointer());
1178
1179         String symlinkPath;
1180         symlinkPath.Format(1024, L"%s/%ls.so", IME_PATH, appId.GetPointer());
1181
1182         pExePath = _StringConverter::CopyToCharArrayN(exePath);
1183         TryCatch(pExePath, res = false, "pExePath is null");
1184
1185         pSymlinkPath = _StringConverter::CopyToCharArrayN(symlinkPath);
1186         TryCatch(pSymlinkPath, res = false, "pSymlinkPath is null");
1187
1188         err = symlink(pExePath, pSymlinkPath);
1189
1190         AppLog("[%s] -> [%s]", pSymlinkPath, pExePath);
1191
1192 CATCH:
1193         delete[] pExePath;
1194         delete[] pSymlinkPath;
1195
1196         return res;
1197 }
1198
1199 bool
1200 ConfigurationManager::FindPrivilege(InstallationContext* pContext, const String& privilege) const
1201 {
1202         TryReturn(pContext, false, "pContext is null.");
1203
1204         bool ret = false;
1205         const ArrayList* pPrivilegeList = pContext->GetPrivilegeList();
1206
1207         if (pPrivilegeList)
1208         {
1209                 if (pPrivilegeList->Contains(privilege) == true)
1210                 {
1211                         AppLog("Privilege = [%ls]", privilege.GetPointer());
1212                         ret = true;
1213                 }
1214         }
1215
1216         return ret;
1217 }
1218
1219 bool
1220 ConfigurationManager::CreateAppInfoFile(AppData* pAppData, const String& rootPath) const
1221 {
1222         TryReturn(pAppData, false, "pAppData is null.");
1223         TryReturn(rootPath.IsEmpty() == false, false, "rootPath is empty.");
1224
1225         String appFolder = rootPath + DIR_INFO + L"/" + pAppData->__appId;
1226         Directory::Create(appFolder);
1227
1228         HashMap* pFeatureList = pAppData->__pFeatureList;
1229         if (pFeatureList)
1230         {
1231                 String coordinateSystem;
1232                 String baseScreenSize;
1233                 String logicalCoordinate;
1234                 String systemTheme;
1235                 String userDefinedTheme;
1236
1237                 std::unique_ptr< IMapEnumerator > pEnum(pFeatureList->GetMapEnumeratorN());
1238                 TryReturn(pEnum, false, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
1239
1240                 while (pEnum->MoveNext() == E_SUCCESS)
1241                 {
1242                         String* pKey = static_cast< String* > (pEnum->GetKey());
1243                         TryReturn(pEnum, false, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
1244
1245                         String* pValue = static_cast< String* > (pEnum->GetValue());
1246                         TryReturn(pEnum, false, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
1247
1248                         if ((*pKey) == L"CoordinateSystem")
1249                         {
1250                                 coordinateSystem = (*pValue);
1251                         }
1252
1253                         if ((*pKey) == L"BaseScreenSize")
1254                         {
1255                                 baseScreenSize = (*pValue);
1256                         }
1257
1258                         if ((*pKey) == L"LogicalCoordinate")
1259                         {
1260                                 logicalCoordinate = (*pValue);
1261                         }
1262
1263                         if ((*pKey) == L"SystemTheme")
1264                         {
1265                                 systemTheme = (*pValue);
1266                         }
1267
1268                         if ((*pKey) == L"UserDefinedTheme")
1269                         {
1270                                 userDefinedTheme = (*pValue);
1271                         }
1272                 }
1273
1274                 if (coordinateSystem.IsEmpty() == false)
1275                 {
1276                         String uiScalability;
1277                         uiScalability.Format(1024, UISCALABILITY_INFO, coordinateSystem.GetPointer(), baseScreenSize.GetPointer(), logicalCoordinate.GetPointer());
1278
1279                         String uiScalabilityInfoFile;
1280                         uiScalabilityInfoFile.Format(1024, L"%ls%ls", appFolder.GetPointer(), UISCALABILITY_INFO_FILE);
1281
1282                         InstallerUtil::CreateInfoFile(uiScalabilityInfoFile, &uiScalability);
1283                 }
1284
1285                 if (systemTheme.IsEmpty() == false)
1286                 {
1287                         String uiTheme;
1288                         uiTheme.Format(1024, UITHEME_INFO, systemTheme.GetPointer(), userDefinedTheme.GetPointer());
1289
1290                         String uiThemeInfoFile;
1291                         uiThemeInfoFile.Format(1024, L"%ls%ls", appFolder.GetPointer(), UITHEME_INFO_FILE);
1292
1293                         InstallerUtil::CreateInfoFile(uiThemeInfoFile, &uiTheme);
1294                 }
1295         }
1296
1297         HashMap* pMetadataMap = pAppData->__pMetadataMap;
1298         if (pMetadataMap)
1299         {
1300                 String screenReaderOff(METADATA_DISABLE_SCREEN_READER);
1301                 if (pMetadataMap->ContainsKey(screenReaderOff) == true)
1302                 {
1303                         String screenReaderOffInfoFile;
1304                         screenReaderOffInfoFile.Format(1024, L"%ls%ls", appFolder.GetPointer(), DISABLE_SCREEN_READER_INFO_FILE);
1305
1306                         InstallerUtil::CreateInfoFile(screenReaderOffInfoFile, null);
1307                 }
1308         }
1309
1310         return true;
1311 }