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