293f7eed001f22093298c56709837bdc3ee119b7
[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 "ManifestGenerator.h"
41 #include "InstallerUtil.h"
42 #include "SmackManager.h"
43
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Utility;
47 using namespace Tizen::Security::Cert;
48 using namespace Tizen::App;
49 using namespace Tizen::Io;
50
51 ConfigurationManager::ConfigurationManager(void)
52 {
53 }
54
55 ConfigurationManager::~ConfigurationManager(void)
56 {
57 }
58
59 bool
60 ConfigurationManager::CreateFile(InstallationContext* pContext)
61 {
62         int err = 0;
63
64         String rootPath;
65         rootPath = pContext->__rootPath;
66
67         String apiVersion;
68         apiVersion = pContext->__apiVersion;
69         String versionInfoFile;
70         versionInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), VERSION_INFO_FILE);
71         InstallerUtil::CreateInfoFile(versionInfoFile, &apiVersion);
72
73         if (pContext->__isOspCompat == true)
74         {
75                 AppLog("[OspCompat] is detected");
76
77                 String compatInfoFile;
78                 compatInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), COMPAT_INFO_FILE);
79                 InstallerUtil::CreateInfoFile(compatInfoFile, null);
80         }
81
82         String webServicePrivilege(TIZEN_PRIVILEGE_WEB_SERVICE);
83         if (FindPrivilege(pContext, webServicePrivilege) == true)
84         {
85                 AppLog("WEB_SERVICE privilege is detected. rootPath=[%ls]", rootPath.GetPointer());
86
87                 String webServiceInfoFile;
88                 webServiceInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), WEBSERVICE_INFO_FILE);
89                 InstallerUtil::CreateInfoFile(webServiceInfoFile, null);
90         }
91
92         IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
93         TryReturn(pAppDataList, false, "pAppDataList is null");
94
95         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
96         {
97                 AppData* pAppData = null;
98                 pAppDataList->GetAt(i, pAppData);
99                 TryReturn(pAppData, false, "pAppData is null");
100
101                 String appName = pAppData->__name;
102                 String appType = pAppData->__type;
103                 AppId appId = pAppData->__appId;
104
105                 String binaryPath;
106                 binaryPath.Format(1024, L"%ls%ls/%ls", rootPath.GetPointer(), DIR_BIN, appName.GetPointer());
107
108                 if (File::IsFileExist(binaryPath) == true)
109                 {
110                         InstallerUtil::Remove(binaryPath);
111                 }
112
113                 if (appType == L"UiApp")
114                 {
115                         //err = symlink(UIAPP_LOADER_PATH, pBinaryPath);
116
117                         AppLog("copy ui app loader");
118                         InstallerUtil::Copy(UIAPP_LOADER_PATH, binaryPath);
119
120                         HashMap* pFeatureList = pAppData->__pFeatureList;
121                         TryReturn(pFeatureList, false, "pFeatureList is null");
122
123                         String coordinateSystem;
124                         String baseScreenSize;
125                         String logicalCoordinate;
126
127                         std::unique_ptr< IMapEnumerator > pEnum(pFeatureList->GetMapEnumeratorN());
128                         TryReturn(pEnum, false, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
129
130                         while (pEnum->MoveNext() == E_SUCCESS)
131                         {
132                                 String* pKey = static_cast< String* > (pEnum->GetKey());
133                                 TryReturn(pEnum, false, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
134
135                                 String* pValue = static_cast< String* > (pEnum->GetValue());
136                                 TryReturn(pEnum, false, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
137
138                                 if ((*pKey) == L"CoordinateSystem")
139                                 {
140                                         coordinateSystem = (*pValue);
141                                 }
142
143                                 if ((*pKey) == L"BaseScreenSize")
144                                 {
145                                         baseScreenSize = (*pValue);
146                                 }
147
148                                 if ((*pKey) == L"LogicalCoordinate")
149                                 {
150                                         logicalCoordinate = (*pValue);
151                                 }
152                         }
153
154                         String uiScalability;
155                         uiScalability.Format(1024, UISCALABILITY_INFO, coordinateSystem.GetPointer(), baseScreenSize.GetPointer(), logicalCoordinate.GetPointer());
156
157                         String uiScalabilityInfoFile;
158                         uiScalabilityInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), UISCALABILITY_INFO_FILE);
159
160                         InstallerUtil::CreateInfoFile(uiScalabilityInfoFile, &uiScalability);
161
162                         int categoryType = pAppData->__feature;
163                         if (categoryType != CATEGORY_TYPE_NONE)
164                         {
165                                 String category = InstallerUtil::GetCategory(categoryType);
166                                 category.ToLowerCase();
167
168                                 int type = _Aul::GetAppType(category);
169
170                                 if (category == L"ime")
171                                 {
172                                         CreateImeSymlink(binaryPath, appId);
173                                 }
174
175                                 String typeInfo;
176                                 typeInfo.Format(1024, L"%d", type);
177
178                                 String typeInfoFile;
179                                 typeInfoFile.Format(1024, L"%ls%ls", rootPath.GetPointer(), TYPE_INFO_FILE);
180
181                                 InstallerUtil::CreateInfoFile(typeInfoFile, &typeInfo);
182                         }
183                 }
184                 else if (appType == L"ServiceApp")
185                 {
186                         if (pContext->__isPreloaded == true || pAppData->__isSystemService == true)
187                         {
188                                 AppLog("copy system service loader");
189                                 InstallerUtil::Copy(SYSTEMSERIVCE_LOADER_PATH, binaryPath);
190                         }
191                         else
192                         {
193                                 AppLog("copy service app loader");
194                                 InstallerUtil::Copy(SERVICEAPP_LOADER_PATH, binaryPath);
195                         }
196                 }
197
198                 InstallerUtil::ChangeMode(binaryPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
199         }
200
201         ArrayList* pContentDataList = pContext->GetContentDataList();
202         if (pContentDataList)
203         {
204                 int contentCount = pContentDataList->GetCount();
205                 for (int i = 0 ; i < contentCount; i++)
206                 {
207                         ContentData* pContentData = static_cast<ContentData*>(pContentDataList->GetAt(i));
208                         if (pContentData)
209                         {
210                                 String contentId = pContentData->GetContentId();
211                                 String oldPath = rootPath + DIR_CONTENTS + L"/" + contentId;
212
213                                 if (File::IsFileExist(SLP_FONT_PATH) == false)
214                                 {
215                                         Directory::Create(SLP_FONT_PATH, false);
216                                         InstallerUtil::ChangeMode(SLP_FONT_PATH, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
217                                 }
218
219                                 String newPath = SLP_FONT_PATH;
220                                 newPath += L"/" + pContext->__packageId;
221                                 Directory::Create(newPath, false);
222                                 InstallerUtil::ChangeMode(newPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
223
224                                 newPath += L"/";
225                                 newPath += contentId;
226                                 InstallerUtil::CreateSymlink(oldPath, newPath);
227                         }
228                 }
229         }
230
231         bool firstPreloadedUpdate = false;
232
233         String roXmlPath;
234         roXmlPath.Format(1024, DIR_RO_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
235
236         String rwXmlPath;
237         rwXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
238
239         if (pContext->__isPreloaded == true)
240         {
241                 pContext->__coreXmlPath = roXmlPath;
242         }
243         else
244         {
245                 pContext->__coreXmlPath = rwXmlPath;
246                 if ((File::IsFileExist(roXmlPath) == true) && (File::IsFileExist(rwXmlPath) == false))
247                 {
248                         AppLog("First preloaded app update");
249                         firstPreloadedUpdate = true;
250                 }
251         }
252
253         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
254         TryReturn(pXmlPath != null, false, "pXmlPath is null");
255
256         if (pContext->__isHybridService == true)
257         {
258                 String webXmlPath = pXmlPath.get();
259                 webXmlPath += L".wgt";
260                 InstallerUtil::Copy(pXmlPath.get(), webXmlPath);
261
262                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation(%s) - START", pXmlPath.get());
263                 pkgmgr_parser_parse_manifest_for_uninstallation(pXmlPath.get(), null);
264                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() - END");
265                 CreateCoreXmlFile(pContext);
266
267                 String serviceXmlPath = pXmlPath.get();
268                 serviceXmlPath += L".tpk";
269                 InstallerUtil::Copy(pXmlPath.get(), serviceXmlPath);
270                 InstallerUtil::Remove(pXmlPath.get());
271
272                 MergeToSystemXmlFile(pXmlPath.get(), webXmlPath, serviceXmlPath);
273                 InstallerUtil::Remove(webXmlPath);
274                 InstallerUtil::Remove(serviceXmlPath);
275         }
276         else
277         {
278 #if 0
279                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() - START");
280                 if (firstPreloadedUpdate == false)
281                 {
282                         AppLog(" - uninstall path=[%s]", pXmlPath.get());
283                         pkgmgr_parser_parse_manifest_for_uninstallation(pXmlPath.get(), null);
284                 }
285                 else
286                 {
287                         std::unique_ptr<char[]> pRoXmlPath(_StringConverter::CopyToCharArrayN(roXmlPath));
288                         AppLog(" - uninstall path=[%s]", pRoXmlPath.get());
289                         pkgmgr_parser_parse_manifest_for_uninstallation(pRoXmlPath.get(), null);
290                 }
291
292                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() - END");
293 #endif
294
295                 CreateCoreXmlFile(pContext);
296         }
297         
298         AppLog("------------------------------------------");
299         AppLog("sync() - START");
300         sync();
301         AppLog("sync() - END");
302         AppLog("------------------------------------------");
303         
304         err = pkgmgr_parser_check_manifest_validation(pXmlPath.get());
305         TryReturn(err == 0, false, "pkgmgr_parser_check_manifest_validation() is failed. error = [%d][%s]", err, pXmlPath.get());
306
307         return true;
308 }
309
310 bool
311 ConfigurationManager::RemoveFile(InstallationContext* pContext)
312 {
313         if (pContext->__isPreloaded == true)
314         {
315                 pContext->__coreXmlPath.Format(1024, DIR_RO_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
316         }
317         else
318         {
319                 pContext->__coreXmlPath.Format(1024, DIR_RW_PACKAGE_SYSTEM_MANIFEST, pContext->__packageId.GetPointer());
320         }
321
322         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
323         TryReturn(pXmlPath != null, false, "pXmlPath is null");
324
325         if (pContext->__isHybridService == true)
326         {
327                 AppLog("Uninstallation for HybridService - skip");
328
329         }
330         else
331         {
332                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation(%s) START", pXmlPath.get());
333                 if (pkgmgr_parser_parse_manifest_for_uninstallation(pXmlPath.get(), null) != 0)
334                 {
335                         AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() is failed.[%s]", pXmlPath.get());
336                 }
337                 AppLog("pkgmgr_parser_parse_manifest_for_uninstallation() END");
338
339                 InstallerUtil::Remove(pXmlPath.get());
340         }
341
342         return true;
343 }
344
345 bool
346 ConfigurationManager::PostInstall(InstallationContext* pContext, bool error) const
347 {
348         app2ext_handle* pHandle = (app2ext_handle*)pContext->__pApp2ExtHandle;
349
350         PackageId packageId = pContext->__packageId;
351         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
352         TryReturn(pPackageId, false, "pPackageId is null.");
353
354         if (error == false)
355         {
356                 RegisterCoreXmlFile(pContext);
357
358                 SmackManager smackManager;
359                 smackManager.Construct(pContext);
360                 smackManager.EnablePermissions(packageId);
361         }
362
363         if (pHandle)
364         {
365                 if (error == true)
366                 {
367                         pHandle->interface.post_install(pPackageId.get(), APP2EXT_STATUS_FAILED);
368                         AppLog("[app2sd] post_install(%s, APP2EXT_STATUS_FAILED)", pPackageId.get());
369                 }
370                 else
371                 {
372                         pHandle->interface.post_install(pPackageId.get(), APP2EXT_STATUS_SUCCESS);
373                         AppLog("[app2sd] post_install(%s, APP2EXT_STATUS_SUCCESS)", pPackageId.get());
374                 }
375
376                 app2ext_deinit(pHandle);
377         }
378
379         return true;
380 }
381
382 bool
383 ConfigurationManager::PostUninstall(InstallationContext* pContext) const
384 {
385         app2ext_handle* pHandle = (app2ext_handle*)pContext->__pApp2ExtHandle;
386
387         PackageId packageId = pContext->__packageId;
388         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
389         TryReturn(pPackageId, false, "pPackageId is null.");
390
391         if (pHandle)
392         {
393                 pHandle->interface.post_uninstall(pPackageId.get());
394                 AppLog("[app2sd] post_uninstall(%s)", pPackageId.get());
395
396                 app2ext_deinit(pHandle);
397         }
398
399         SmackManager smackManager;
400         smackManager.Construct(pContext);
401         smackManager.RevokePermissions(packageId);
402
403         return true;
404 }
405
406 bool
407 ConfigurationManager::CreateCoreXmlFile(InstallationContext* pContext) const
408 {
409         AppLog("------------------------------------------");
410         AppLog("CreateCoreXmlFile() - START");
411         bool ret = false;
412
413         ManifestGenerator manifestGenerator;
414         manifestGenerator.Construct(pContext);
415         ret = manifestGenerator.Write();
416
417         if (ret == false)
418         {
419                 AppLog("manifestGenerator.Write() is failed.");
420         }
421         AppLog("CreateCoreXmlFile() - END");
422         AppLog("------------------------------------------");
423
424         return ret;
425 }
426
427 bool
428 ConfigurationManager::RegisterCoreXmlFile(InstallationContext* pContext) const
429 {
430         if (pContext->__isHybridService == true)
431         {
432                 AppLog("HybridService is skipped.");
433                 return true;
434         }
435
436         std::unique_ptr<char[]> pXmlPath(_StringConverter::CopyToCharArrayN(pContext->__coreXmlPath));
437         TryReturn(pXmlPath != null, false, "pXmlPath is null.");
438
439         int err = 0;
440
441         if (pContext->__isCsc == true)
442         {
443                 char* pUpdateTag[3] = {null, };
444
445                 String preload("preload=true");
446                 String removable("removable=");
447                 if (pContext->__isUninstallable == false)
448                 {
449                         removable.Append("false");
450                 }
451                 else
452                 {
453                         removable.Append("true");
454                 }
455
456                 std::unique_ptr<char[]> pPreload(_StringConverter::CopyToCharArrayN(preload));
457                 TryReturn(pPreload, false, "pPreload is null.");
458
459                 std::unique_ptr<char[]> pRemovable(_StringConverter::CopyToCharArrayN(removable));
460                 TryReturn(pRemovable, false, "pRemovable is null.");
461
462                 pUpdateTag[0] = pPreload.get();
463                 pUpdateTag[1] = pRemovable.get();
464                 pUpdateTag[2] = null;
465
466                 for (int i = 0; pUpdateTag[i] != null; i++)
467                 {
468                         AppLog("pUpdateTag[%d] = [%s]", i, pUpdateTag[i]);
469                 }
470
471                 AppLog("pkgmgr_parser_parse_manifest_for_installation(%s) - START", pXmlPath.get());
472                 err = pkgmgr_parser_parse_manifest_for_installation(pXmlPath.get(), pUpdateTag);
473                 TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_installation() is failed. error = [%d][%s]", err, pXmlPath.get());
474
475                 AppLog("pkgmgr_parser_parse_manifest_for_installation() - END");
476         }
477         else
478         {
479                 if (pContext->__isUpdated == true)
480                 {
481                         AppLog("pkgmgr_parser_parse_manifest_for_upgrade(%s) - START", pXmlPath.get());
482                         err = pkgmgr_parser_parse_manifest_for_upgrade(pXmlPath.get(), null);
483                         TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_upgrade() is failed. error = [%d][%s]", err, pXmlPath.get());
484
485                         AppLog("pkgmgr_parser_parse_manifest_for_upgrade() - END");
486                 }
487                 else
488                 {
489                         AppLog("pkgmgr_parser_parse_manifest_for_installation(%s) - START", pXmlPath.get());
490                         err = pkgmgr_parser_parse_manifest_for_installation(pXmlPath.get(), null);
491                         TryReturn(err == 0, false, "pkgmgr_parser_parse_manifest_for_installation() is failed. error = [%d][%s]", err, pXmlPath.get());
492
493                         AppLog("pkgmgr_parser_parse_manifest_for_installation() - END");
494                 }
495         }
496
497         return true;
498 }
499
500 //bool
501 //ConfigurationManager::CreateHybridServiceDesktopFile(InstallationContext* pContext)
502 //{
503 //      AppLog("HybridServiceDesktopFile - START");
504 //
505 //      bool ret = true;
506 //      _PackageInfoImpl *pPackageInfoImpl = pContext->GetPackageInfoImpl();
507 //      _PackageAppInfoImpl* pAppInfoImpl = null;
508 //      ArrayList* pAppList = null;
509 //      pAppList = pPackageInfoImpl->GetAppInfoList();
510 //
511 //      for (int i = 0 ; i < pAppList->GetCount(); i++)
512 //      {
513 //              pAppInfoImpl = dynamic_cast<_PackageAppInfoImpl*>(pAppList->GetAt(i));
514 //
515 //              if (pAppInfoImpl)
516 //              {
517 //                      String name;
518 //                      name.Format(1024, L"%ls", pPackageInfoImpl->GetAppName().GetPointer());
519 //
520 //                      String binaryPath;
521 //                      binaryPath.Format(1024, L"%ls%ls/%ls", pPackageInfoImpl->GetAppRootPath().GetPointer(), DIR_BIN, pAppInfoImpl->GetName().GetPointer());
522 //
523 //                      String iconPath;
524 //                      iconPath.Format(1024, L"%ls%ls/%ls", pPackageInfoImpl->GetAppRootPath().GetPointer(), DIR_ICONS, pAppInfoImpl->GetMainmenuIcon().GetPointer());
525 //
526 //                      String version;
527 //                      version.Format(1024, L"%ls", pPackageInfoImpl->GetVersion().GetPointer());
528 //
529 //                      String desktop;
530 //                      desktop.Format(1024, L"[Desktop Entry]\n"
531 //                                                                                                        "Name=%ls\n"
532 //                                                                                                              "Name[en_GB]=%ls\n"
533 //                                                                                                              "Type=Application\n"
534 //                                                                                                      "Exec=%ls\n"
535 //                                                                                                        "Icon=%ls\n"
536 //                                                                                                        "Version=%ls\n"
537 //                                                                                                        "NoDisplay=true\n"
538 //                                                                                                        "X-TIZEN-TaskManage=False\n"
539 //                                                                                                        "X-TIZEN-PackageType=tpk\n",
540 //                                                                                                        name.GetPointer(), name.GetPointer(), binaryPath.GetPointer(), iconPath.GetPointer(), version.GetPointer());
541 //
542 //                      String desktopPath;
543 //                      desktopPath.Format(1024, L"/opt/share/applications/%ls.desktop", pAppInfoImpl->GetPackageName().GetPointer());
544 //
545 //                      if (File::IsFileExist(desktopPath) == true)
546 //                      {
547 //                              AppLog("removing desktop filePath=[%ls]", desktopPath.GetPointer());
548 //                              InstallerUtil::Remove(desktopPath);
549 //                      }
550 //
551 //                      InstallerUtil::CreateInfoFile(desktopPath, &desktop);
552 //              }
553 //      }
554 //
555 //      AppLog("HybridServiceDesktopFile - END");
556 //
557 //      return ret;
558 //}
559
560 bool
561 ConfigurationManager::MergeToSystemXmlFile(const String& systemXmlPath, const String& webXmlPath, const String& serviceXmlPath)
562 {
563         result r = E_SUCCESS;
564
565         FileAttributes webXmlAttr;
566         r = File::GetAttributes(webXmlPath, webXmlAttr);
567         TryReturn(!IsFailed(r), false, "File::GetAttributes() failed, webXmlPath=%ls", webXmlPath.GetPointer());
568
569         FileAttributes serviceAttr;
570         r = File::GetAttributes(serviceXmlPath, serviceAttr);
571         TryReturn(!IsFailed(r), false, "File::GetAttributes() failed, serviceXmlPath=%ls", serviceXmlPath.GetPointer());
572
573         long long webXmlFileSize = webXmlAttr.GetFileSize();
574         long long serviceXmlFileSize = serviceAttr.GetFileSize();
575         long long mergedSize = webXmlFileSize + serviceXmlFileSize;
576
577         File webXml;
578         r = webXml.Construct(webXmlPath, L"r");
579         TryReturn(!IsFailed(r), false, "webXmlPath.Construct is failed");
580
581         std::unique_ptr<char[]> pMergedBuf(new (std::nothrow) char[mergedSize + 1]);
582         TryReturn(pMergedBuf, false, "pMergedBuf is null");
583         memset(pMergedBuf.get(), 0, mergedSize + 1);
584
585         int readBytes = webXml.Read(pMergedBuf.get(), webXmlFileSize);
586         TryReturn(readBytes >= 0, false, "webXml.Read is failed");
587
588         File serviceXml;
589         r = serviceXml.Construct(serviceXmlPath, L"r");
590         TryReturn(!IsFailed(r), false, "serviceXmlPath.Construct is failed");
591
592         std::unique_ptr<char[]> pServiceBuf(new (std::nothrow) char[serviceXmlFileSize + 1]);
593         TryReturn(pServiceBuf, false, "pServiceBuf is null");
594         memset(pServiceBuf.get(), 0, serviceXmlFileSize + 1);
595
596         readBytes = serviceXml.Read(pServiceBuf.get(), serviceXmlFileSize);
597         TryReturn(readBytes >= 0, false, "serviceXml.Read is failed");
598
599         char* pManifestTag = strcasestr(pMergedBuf.get(), "</manifest>");
600         TryReturn(pManifestTag, false, "pManifestTag is null");
601
602         char* pAppTagStart = strcasestr(pServiceBuf.get(), "<ui-application");
603         TryReturn(pAppTagStart, false, "pAppTagStart is null");
604
605         char* pAppTagEnd = strcasestr(pServiceBuf.get(), "</ui-application>");
606         TryReturn(pAppTagEnd, false, "pAppTagEnd is null");
607
608         int serviceAppLen = pAppTagEnd - pAppTagStart + strlen("</ui-application>");
609
610         memcpy(pManifestTag, pAppTagStart, serviceAppLen);
611
612         char* pManifestEndTag = pManifestTag + serviceAppLen;
613         strcpy(pManifestEndTag, "\n</manifest>");
614
615         int fileSize = pManifestEndTag - pMergedBuf.get() + strlen("\n</manifest>");
616
617         AppLog("[0] File Size = [%d]", fileSize);
618
619         if (strcasestr(pServiceBuf.get(), "</privileges>") != null)
620         {
621                 AppLog("Privileges are detected in service app.");
622                 MergePrivileges(pMergedBuf.get(), pServiceBuf.get(), fileSize);
623         }
624         else
625         {
626                 AppLog("No privileges are detected in service app.");
627         }
628         AppLog("[1] File Size = [%d]", fileSize);
629
630         MergeAppWidgets(pMergedBuf.get(), pServiceBuf.get(), fileSize);
631         AppLog("[2] File Size = [%d]", fileSize);
632
633         MergeAccounts(pMergedBuf.get(), pServiceBuf.get(), fileSize);
634         AppLog("[3] File Size = [%d]", fileSize);
635
636         MergeNotifications(pMergedBuf.get(), pServiceBuf.get(), fileSize);
637         AppLog("[4] File Size = [%d]", fileSize);
638
639         MergeIme(pMergedBuf.get(), pServiceBuf.get(), fileSize);
640         AppLog("[5] File Size = [%d]", fileSize);
641
642         File systemXml;
643         r = systemXml.Construct(systemXmlPath, L"w");
644         TryReturn(!IsFailed(r), false, "systemXmlPath.Construct() is failed.");
645
646         r = systemXml.Write(pMergedBuf.get(), fileSize);
647         TryReturn(!IsFailed(r), false, "systemXmlPath.Write() is failed.");
648
649         AppLog("pMergedBuf.get()=0x%0x, length=%d", (unsigned int)pMergedBuf.get(), fileSize);
650         InstallerUtil::DumpLogData(pMergedBuf.get(), fileSize);
651
652         return true;
653 }
654
655 bool
656 ConfigurationManager::MergePrivileges(char* pMergedBuf, char* pServiceBuf, int& fileSize)
657 {
658         char* pMergedPrivilegeDetected = strcasestr(pMergedBuf, "</privileges>");
659         char* pMergedPoint = null;
660         char* pServicePrivilegeStart = null;
661         char* pServicePrivilegeEnd = null;
662         int privilegeLen = 0;
663         int serviceBufLen = strlen(pServiceBuf);
664         std::unique_ptr<char[]> pSelectedPrivBuf(new char[serviceBufLen + 1]);
665         memset(pSelectedPrivBuf.get(), 0, serviceBufLen + 1);
666
667         if (pMergedPrivilegeDetected == null)
668         {
669                 AppLog("No privileges are detected in web app.");
670
671                 pServicePrivilegeStart = strcasestr(pServiceBuf, "<privileges>");
672                 pServicePrivilegeEnd = strcasestr(pServiceBuf, "</privileges>");
673
674                 privilegeLen = pServicePrivilegeEnd - pServicePrivilegeStart + strlen("</privileges>");
675                 pMergedPoint = strcasestr(pMergedBuf, "<ui-application");
676
677                 AppLog("Inserted privileges of service app");
678                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
679         }
680         else
681         {
682                 AppLog("Privileges are detected in web app.");
683
684                 pServicePrivilegeStart = strcasestr(pServiceBuf, "<privilege>");
685                 pServicePrivilegeEnd = strcasestr(pServiceBuf, "</privileges>");
686
687                 privilegeLen = pServicePrivilegeEnd - pServicePrivilegeStart;
688                 pMergedPoint = strcasestr(pMergedBuf, "</privileges>");
689
690                 AppLog("Original privileges of service app");
691                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
692
693                 std::unique_ptr<char[]> pPrivBuf(new char[privilegeLen + 1]);
694                 memset(pPrivBuf.get(), 0, privilegeLen + 1);
695                 strncpy(pPrivBuf.get(), pServicePrivilegeStart, privilegeLen);
696
697                 char* pEachPrivStart = pPrivBuf.get();
698                 char* pEachPrivEnd = null;
699                 int eachPrivLen = 0;
700                 char eachPrivBuf[512] = {0};
701
702                 while (pEachPrivStart && (pEachPrivStart < pPrivBuf.get() + privilegeLen))
703                 {
704                         pEachPrivEnd = strcasestr(pEachPrivStart, "</privilege>");
705                         eachPrivLen = pEachPrivEnd - pEachPrivStart + strlen("</privilege>");
706                         if ((pEachPrivEnd > 0) && (eachPrivLen > 0))
707                         {
708                                 memset(eachPrivBuf, 0, sizeof(eachPrivBuf));
709                                 memcpy(eachPrivBuf, pEachPrivStart, eachPrivLen);
710                                 AppLog("[%s]", eachPrivBuf);
711
712                                 if (strcasestr(pMergedBuf, eachPrivBuf) == 0)
713                                 {
714                                         strncat(pSelectedPrivBuf.get(), eachPrivBuf, serviceBufLen);
715                                 }
716                                 else
717                                 {
718                                         AppLog("This privilege is discarded, [%s]", eachPrivBuf);
719                                 }
720                         }
721                         else
722                         {
723                                 AppLog("End of privileges merging.");
724                                 break;
725                         }
726
727                         pEachPrivStart = strcasestr(pEachPrivEnd, "<privilege>");
728                 }
729
730                 pServicePrivilegeStart = pSelectedPrivBuf.get();
731                 privilegeLen = strlen(pServicePrivilegeStart);
732
733                 AppLog("Filtered privileges of service app");
734                 InstallerUtil::DumpLogData(pServicePrivilegeStart, privilegeLen);
735         }
736
737         if ((pMergedPoint > 0) && (pServicePrivilegeStart > 0) && (privilegeLen > 0))
738         {
739                 int lastPartLen = fileSize - (pMergedPoint - pMergedBuf);
740                 std::unique_ptr<char[]> pLastPartBuf(new (std::nothrow) char[fileSize + 1]);
741                 memset(pLastPartBuf.get(), 0, fileSize + 1);
742
743                 if (lastPartLen > 0)
744                 {
745                         memcpy(pLastPartBuf.get(), pMergedPoint, lastPartLen);
746
747                         AppLog("Last part of merged xml for backup");
748                         InstallerUtil::DumpLogData(pLastPartBuf.get(), lastPartLen);
749
750                         memcpy(pMergedPoint, pServicePrivilegeStart, privilegeLen);
751
752                         memcpy(pMergedPoint + privilegeLen, pLastPartBuf.get(), lastPartLen);
753                         fileSize += privilegeLen;
754                 }
755         }
756
757         return true;
758 }
759
760 bool
761 ConfigurationManager::MergeAppWidgets(char* pMergedBuf, char* pServiceBuf, int& fileSize)
762 {
763         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
764         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
765         TryReturn(fileSize > 0, false, "fileSize is invalid.");
766
767         if (strcasestr(pServiceBuf, "</livebox>") == null)
768         {
769                 AppLog("<livebox> is NOT detected in service app.");
770                 return true;
771         }
772
773         AppLog("<livebox> is detected in service app.");
774         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<livebox", "</livebox>");
775
776         return true;
777 }
778
779 bool
780 ConfigurationManager::MergeAccounts(char* pMergedBuf, char* pServiceBuf, int& fileSize)
781 {
782         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
783         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
784         TryReturn(fileSize > 0, false, "fileSize is invalid.");
785
786         if (strcasestr(pServiceBuf, "</account>") == null)
787         {
788                 AppLog("<account> is NOT detected in service app.");
789                 return true;
790         }
791
792         AppLog("<account> is detected in service app.");
793         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<account", "</account>");
794
795         return true;
796 }
797
798 bool
799 ConfigurationManager::MergeNotifications(char* pMergedBuf, char* pServiceBuf, int& fileSize)
800 {
801         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
802         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
803         TryReturn(fileSize > 0, false, "fileSize is invalid.");
804
805         if (strcasestr(pServiceBuf, "</notifications>") == null)
806         {
807                 AppLog("<notifications> is NOT detected in service app.");
808                 return true;
809         }
810
811         AppLog("<notifications> is detected in service app.");
812         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<notifications", "</notifications>");
813
814         return true;
815 }
816
817 bool
818 ConfigurationManager::MergeIme(char* pMergedBuf, char* pServiceBuf, int& fileSize)
819 {
820         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
821         TryReturn(pServiceBuf, false, "pServiceBuf is null.");
822         TryReturn(fileSize > 0, false, "fileSize is invalid.");
823
824         if (strcasestr(pServiceBuf, "</ime>") == null)
825         {
826                 AppLog("<ime> is NOT detected in service app.");
827                 return true;
828         }
829
830         AppLog("<ime> is detected in service app.");
831         MergeTags(pMergedBuf, pServiceBuf, fileSize, "<ime", "</ime>");
832
833         return true;
834 }
835
836 bool
837 ConfigurationManager::MergeTags(char* pMergedBuf, char* pServiceBuf, int& fileSize, const char* pStartTag, const char* pEndTag)
838 {
839         do
840         {
841                 char* pBuf = null;
842                 int length = 0;
843                 char* pNext = null;
844
845                 AppLog("pServiceBuf = [0x%08x]", pServiceBuf);
846                 GetPart(pServiceBuf, pStartTag, pEndTag, &pBuf, &length, &pNext);
847                 if (length > 0)
848                 {
849                         MergeTo(pMergedBuf, fileSize, "</manifest>", pBuf, length);
850                 }
851
852                 delete [] pBuf;
853
854                 pServiceBuf = pNext;
855         }
856         while (pServiceBuf > 0);
857
858         return true;
859 }
860
861 bool
862 ConfigurationManager::GetPart(const char* pStartPoint, const char* pStartTag, const char* pEndTag, char** ppBuf, int* pLength, char** ppNext)
863 {
864         TryReturn(pStartPoint, false, "pStartPoint is null.");
865         TryReturn(pStartTag, false, "pStartTag is null.");
866         TryReturn(pEndTag, false, "pEndTag is null.");
867         TryReturn(ppBuf, false, "ppBuf is null.");
868         TryReturn(pLength, false, "pLength is null.");
869         TryReturn(ppNext, false, "ppNext is null.");
870
871         const char* pStartBufPoint = strcasestr(pStartPoint, pStartTag);
872         TryReturn(pStartBufPoint, false, "pStartBufPoint is null.");
873
874         const char* pEndBufPoint = strcasestr(pStartBufPoint, pEndTag);
875         TryReturn(pEndBufPoint, false, "pEndBufPoint is null.");
876
877         int len = pEndBufPoint - pStartBufPoint + strlen(pEndTag);
878         TryReturn(len > 0, false, "len is invalid.");
879
880         char *pBuf = null;
881         pBuf = new char[len + 1];
882         TryReturn(pBuf, false, "pBuf is null.");
883         memset(pBuf, 0, len + 1);
884         memcpy(pBuf, pStartBufPoint, len);
885
886         AppLog("Extracted Part, len = [%d]", len);
887         InstallerUtil::DumpLogData(pBuf, len);
888
889         *ppBuf = pBuf;
890         *pLength = len;
891         *ppNext = (char *)pEndBufPoint;
892
893         return true;
894 }
895
896 bool
897 ConfigurationManager::MergeTo(const char* pMergedBuf, int& fileSize, const char* pTag, const char* pBuf, int length)
898 {
899         TryReturn(pMergedBuf, false, "pMergedBuf is null.");
900         TryReturn(fileSize > 0, false, "fileSize is invalid.");
901         TryReturn(pTag, false, "pTag is null.");
902         TryReturn(pBuf, false, "pBuf is null.");
903         TryReturn(length > 0, false, "length is invalid.");
904
905         char* pMergedPoint = null;
906         pMergedPoint = (char *)strcasestr(pMergedBuf, pTag);
907         TryReturn(pMergedPoint > 0, true, "pTag is not found, pTag=[%s]", pTag);
908
909         int lastPartLen = fileSize - (pMergedPoint - pMergedBuf);
910         std::unique_ptr<char[]> pLastPartBuf(new (std::nothrow) char[fileSize + 1]);
911         memset(pLastPartBuf.get(), 0, fileSize + 1);
912
913         if (lastPartLen > 0)
914         {
915                 memcpy(pLastPartBuf.get(), pMergedPoint, lastPartLen);
916
917                 AppLog("Last part of merged xml for backup");
918                 InstallerUtil::DumpLogData(pLastPartBuf.get(), lastPartLen);
919
920                 memcpy(pMergedPoint, pBuf, length);
921                 memcpy(pMergedPoint + length, pLastPartBuf.get(), lastPartLen);
922                 fileSize += length;
923         }
924
925         return true;
926 }
927
928 bool
929 ConfigurationManager::CreateImeSymlink(const String& binaryPath, const String& appId)
930 {
931         bool res = true;
932         int err = 0;
933         const char* pExePath = null;
934         const char* pSymlinkPath = null;
935
936         Directory::Create(IME_PATH, true);
937
938         String exePath;
939         exePath.Format(1024, L"%ls.exe", binaryPath.GetPointer());
940
941         String symlinkPath;
942         symlinkPath.Format(1024, L"%s/%ls.so", IME_PATH, appId.GetPointer());
943
944         pExePath = _StringConverter::CopyToCharArrayN(exePath);
945         TryCatch(pExePath, res = false, "pExePath is null");
946
947         pSymlinkPath = _StringConverter::CopyToCharArrayN(symlinkPath);
948         TryCatch(pSymlinkPath, res = false, "pSymlinkPath is null");
949
950         err = symlink(pExePath, pSymlinkPath);
951
952         AppLog("[%s] -> [%s]", pSymlinkPath, pExePath);
953
954 CATCH:
955         delete[] pExePath;
956         delete[] pSymlinkPath;
957
958         return res;
959 }
960
961 bool
962 ConfigurationManager::FindPrivilege(InstallationContext* pContext, const String& privilege) const
963 {
964         TryReturn(pContext, false, "pContext is null.");
965
966         bool ret = false;
967         const ArrayList* pPrivilegeList = pContext->GetPrivilegeList();
968
969         if (pPrivilegeList)
970         {
971                 if (pPrivilegeList->Contains(privilege) == true)
972                 {
973                         AppLog("Privilege = [%ls]", privilege.GetPointer());
974                         ret = true;
975                 }
976         }
977
978         return ret;
979 }