Installer SignatureValidator implementation
[platform/framework/native/installer.git] / src / XmlHandler / ManifestGenerator.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        ManifestGenerator.cpp
19  * @brief       This is the implementation file for %ManifestGenerator class.
20  */
21
22 #include <unique_ptr.h>
23 #include <sys/stat.h>
24
25 #include <FLclLocale.h>
26 #include <FApp_Aul.h>
27 #include <FIoFile.h>
28
29 #include "ManifestGenerator.h"
30 #include "InstallerUtil.h"
31
32 using namespace Tizen::Base;
33 using namespace Tizen::Base::Collection;
34 using namespace Tizen::App;
35 using namespace Tizen::Locales;
36 using namespace Tizen::Io;
37
38 ManifestGenerator::ManifestGenerator(void)
39 :__pContext(null)
40 ,__pWriter(null)
41 {
42 }
43
44 ManifestGenerator::~ManifestGenerator(void)
45 {
46         delete __pWriter;
47         __pWriter = null;
48 }
49
50 bool
51 ManifestGenerator::Construct(InstallationContext* pContext)
52 {
53         __pContext = pContext;
54
55         __pWriter = new (std::nothrow) XmlWriter;
56         TryReturn(__pWriter, false, "__pWriter is null.");
57
58         return true;
59 }
60
61 bool
62 ManifestGenerator::Write()
63 {
64         String location;
65         String appSetting(L"false");
66
67         if (__pContext->__isPreloaded == true)
68         {
69                 location = L"internal-only";
70         }
71         else
72         {
73                 location = L"auto";
74         }
75
76         String appSettingPath = __pContext->__rootPath + DIR_SETTING;
77         if (File::IsFileExist(appSettingPath) == true)
78         {
79                 __pContext->__isAppSetting = true;
80                 appSetting = L"true";
81         }
82
83         __pWriter->Construct(__pContext->__coreXmlPath);
84
85         __pWriter->StartElement("manifest");
86         __pWriter->WriteAttribute("xmlns", "http://tizen.org/ns/packages");
87         __pWriter->WriteAttribute("package", __pContext->__packageId);
88         __pWriter->WriteAttribute("type", "tpk");
89         __pWriter->WriteAttribute("version", __pContext->__version);
90         __pWriter->WriteAttribute("install-location", location);
91         __pWriter->WriteAttribute("root_path", __pContext->__rootPath);
92         __pWriter->WriteAttribute("appsetting", appSetting);
93
94         __pWriter->StartElement("label");
95         __pWriter->WriteString(__pContext->__displayName);
96         __pWriter->EndElement();
97
98         __pWriter->StartElement("author");
99         __pWriter->EndElement();
100
101         __pWriter->StartElement("description");
102         __pWriter->WriteString(__pContext->__description);
103         __pWriter->EndElement();
104
105         WritePrivileges(__pContext->__pPrivilegeList);
106
107         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
108         TryReturn(pAppDataList, false, "pAppDataList is null");
109
110         int appCount = pAppDataList->GetCount();
111         AppLog("Write(): appCount=%d", appCount);
112
113         for (int i = 0 ; i < appCount; i++)
114         {
115                 AppData* pAppData = null;
116                 pAppDataList->GetAt(i, pAppData);
117                 TryReturn(pAppData, false, "pAppData is null");
118
119                 WriteApp(i, pAppData);
120
121                 if (pAppData->__isSubMode == true)
122                 {
123                         AppLog("Write(): pAppData->__isSubMode is detected");
124
125                         if (pAppData->__isSubModeAllowed == true)
126                         {
127                                 AppLog("Write(): WriteSubModeApp()");
128                                 WriteSubModeApp(i, pAppData);
129                         }
130                         else
131                         {
132                                 AppLog("Write(): WriteSubModeApp() is skipped because __isSubModeAllowed is false.");
133                         }
134                 }
135         }
136
137         __pWriter->EndElement();
138
139         return true;
140 }
141
142 String
143 ManifestGenerator::GetGlFrameValue(HashMap* pFeatureList) const
144 {
145         if (pFeatureList == null)
146         {
147                 return "use-system-setting";
148         }
149
150         std::unique_ptr< IMapEnumerator > pEnum(pFeatureList->GetMapEnumeratorN());
151         TryReturn(pEnum, "use-system-setting", "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
152
153         while (pEnum->MoveNext() == E_SUCCESS)
154         {
155                 String* pKey = static_cast< String* > (pEnum->GetKey());
156                 TryReturn(pKey, "use-system-setting", "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
157
158                 if ((*pKey) == L"HwAcceleration" || (*pKey) == L"GlFrame")
159                 {
160                         String* pValue = static_cast< String* > (pEnum->GetValue());
161                         TryReturn(pValue, "use-system-setting", "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
162
163                         if ((*pValue) == L"On")
164                         {
165                                 return "use-GL";
166                         }
167                         else if ((*pValue) == L"Off")
168                         {
169                                 return "not-use-GL";
170                         }
171                 }
172         }
173
174         return "use-system-setting";
175 }
176
177 bool
178 ManifestGenerator::WriteLanguageValue(IMap* pList, const String& element) const
179 {
180         TryReturn(pList, false, "pNameList is null.");
181
182         IMapEnumerator*         pMapEnum = pList->GetMapEnumeratorN();
183         while (pMapEnum->MoveNext() == E_SUCCESS)
184         {
185                 String* pLanguage = null;
186                 String* pValue = null;
187                 String threeLetterCode;
188                 String countryCode;
189                 String launguage;
190
191                 pLanguage = static_cast<String*> (pMapEnum->GetKey());
192                 pValue = static_cast<String*> (pMapEnum->GetValue());
193
194                 pLanguage->SubString(0, 3, threeLetterCode);
195                 pLanguage->SubString(4, 2, countryCode);
196
197                 LanguageCode code = Locale::StringToLanguageCode(threeLetterCode);
198                 String twoLetterLanguage = Locale::LanguageCodeToTwoLetterLanguageCodeString(code);
199
200                 launguage = twoLetterLanguage + L"-" + countryCode;
201                 launguage.ToLowerCase();
202
203                 if (((*pLanguage) == L"eng-GB") || ((*pLanguage) == L"eng-US"))
204                 {
205                         __pWriter->StartElement(element);
206                         __pWriter->WriteString(*pValue);
207                         __pWriter->EndElement();
208                 }
209
210                 __pWriter->StartElement(element);
211                 __pWriter->WriteAttribute("xml:lang", launguage);
212                 __pWriter->WriteString(*pValue);
213                 __pWriter->EndElement();
214         }
215
216         delete pMapEnum;
217         return true;
218 }
219
220 bool
221 ManifestGenerator::WriteLiveboxes(AppData* pAppData) const
222 {
223         TryReturn(__pContext, false, "__pContext is null.");
224         TryReturn(__pWriter, false, "__pWriter is null.");
225         TryReturn(pAppData, false, "pAppData is null.");
226
227         ArrayList* pLiveboxDataList = pAppData->__pLiveboxDataList;
228         String label("label");
229
230         if (pLiveboxDataList == null)
231         {
232                 return true;
233         }
234
235         for (int j = 0 ; j < pLiveboxDataList->GetCount(); j++)
236         {
237                 LiveboxData* pLiveboxData = dynamic_cast<LiveboxData*>(pLiveboxDataList->GetAt(j));
238                 if (pLiveboxData == null)
239                 {
240                         AppLog("pLiveboxData is null [%d]", j);
241                         continue;
242                 }
243
244                 long long updatePeriod = pLiveboxData->GetUpdatePeriod();
245                 String period = LongLong::ToString(updatePeriod/1000);
246                 IMap* pLiveboxNameList = pLiveboxData->GetNameList();
247                 IMap* pSizeList = pLiveboxData->GetSizeList();
248                 String popupEnabled = pLiveboxData->GetPopupEnabled();
249                 String primary = pLiveboxData->__default;
250
251                 __pWriter->StartElement("livebox");
252
253                 __pWriter->WriteAttribute("appid", pAppData->__appId + "." + pLiveboxData->GetProviderName());
254                 __pWriter->WriteAttribute("period", period);
255                 __pWriter->WriteAttribute("pinup", "false");
256
257                 if (primary.IsEmpty() == false)
258                 {
259                         primary.ToLowerCase();
260                         __pWriter->WriteAttribute("primary", primary);
261                 }
262
263                 __pWriter->WriteAttribute("auto_launch", "false");
264                 __pWriter->WriteAttribute("abi", "osp");
265
266                 WriteLanguageValue(pLiveboxNameList, label);
267
268                 String menuIcon = pAppData->__menuIcon;
269                 if (menuIcon.IsEmpty() == false)
270                 {
271                         String menuIconPath;
272                         GetIconPath(menuIcon, menuIconPath);
273
274                         __pWriter->StartElement("icon");
275                         __pWriter->WriteString(menuIconPath);
276                         __pWriter->EndElement();
277                 }
278
279                 if (pSizeList)
280                 {
281                         String previewDir;
282
283                         __pWriter->StartElement("box");
284                         __pWriter->WriteAttribute("type", "buffer");
285
286                         previewDir.Format(1024, L"%ls%ls", __pContext->__rootPath.GetPointer(), DIR_SHARED_RES);
287                         WriteLiveboxSizeValue(pSizeList, "size", previewDir);
288
289                         __pWriter->EndElement();
290                 }
291
292                 if (pLiveboxData->__configurationAppControlAppId.IsEmpty() == false)
293                 {
294                         __pWriter->StartElement("setup");
295                         __pWriter->WriteString(pLiveboxData->__configurationAppControlAppId);
296                         __pWriter->EndElement();
297                 }
298
299                 popupEnabled.ToLowerCase();
300                 if (popupEnabled == L"true")
301                 {
302                         __pWriter->StartElement("pd");
303                         __pWriter->WriteAttribute("type", "buffer");
304
305                         __pWriter->StartElement("size");
306                         __pWriter->WriteString("720x250");
307                         __pWriter->EndElement();
308
309                         __pWriter->EndElement();
310                 }
311                 __pWriter->EndElement();
312         }
313
314         return true;
315 }
316
317 bool
318 ManifestGenerator::WriteLiveboxSizeValue(IMap* pList, const String& element, const String& previewDir) const
319 {
320         TryReturn(pList, false, "pList is null.");
321
322         IMapEnumerator* pMapEnum = pList->GetMapEnumeratorN();
323         TryReturn(pMapEnum, true, "pMapEnum is null.");
324
325         while (pMapEnum->MoveNext() == E_SUCCESS)
326         {
327                 String* pSize = static_cast<String*> (pMapEnum->GetKey());
328                 String* pPriviewImage = static_cast<String*> (pMapEnum->GetValue());
329
330                 __pWriter->StartElement(element);
331                 if (pPriviewImage && (pPriviewImage->IsEmpty() == false))
332                 {
333                         String previewImagePath;
334                         previewImagePath.Format(1024, L"%ls/%ls", previewDir.GetPointer(), pPriviewImage->GetPointer());
335                         __pWriter->WriteAttribute("preview", previewImagePath);
336                 }
337                 __pWriter->WriteString(*pSize);
338                 __pWriter->EndElement();
339         }
340
341         delete pMapEnum;
342         return true;
343 }
344
345 bool
346 ManifestGenerator::WriteAppControl(AppData* pAppData) const
347 {
348         TryReturn(pAppData, false, "pAppData is null.");
349
350         IListT<_AppControlInfo*>* pAppControlImplList = pAppData->__pAppControlImplList;
351         TryReturn(pAppControlImplList, false, "pAppControlImplList is null.");
352
353         _AppControlInfo* pAppControl = null;
354         pAppControlImplList->GetAt(0, pAppControl);
355         TryReturn(pAppControl, false, "pAppControl is null.");
356
357         ArrayList* pCapabilityList = pAppControl->GetCapabilityList();
358         TryReturn(pCapabilityList, false, "pCapabilityList is null.");
359
360         int capaCount = pCapabilityList->GetCount();
361         for (int capaIndex = 0 ; capaIndex < capaCount; capaIndex++)
362         {
363                 _AppControlCapabilityInfo* pCapability = dynamic_cast<_AppControlCapabilityInfo*>(pCapabilityList->GetAt(capaIndex));
364                 if (pCapability == null) continue;
365
366                 String operationId = pCapability->GetOperationId();
367
368                 ArrayList* pResolutionList = pCapability->GetResolutionList();
369                 int resCount = pResolutionList->GetCount();
370
371                 if (resCount == 0)
372                 {
373                         __pWriter->StartElement("application-service");
374                         __pWriter->StartElement("operation");
375                         __pWriter->WriteAttribute("name", operationId);
376                         __pWriter->EndElement();
377                         __pWriter->EndElement();
378                         continue;
379                 }
380
381                 for (int resIndex = 0 ; resIndex < resCount; resIndex++)
382                 {
383                         __pWriter->StartElement("application-service");
384                         __pWriter->StartElement("operation");
385                         __pWriter->WriteAttribute("name", operationId);
386                         __pWriter->EndElement();
387
388                         _AppControlResolutionInfo* pResolution = dynamic_cast <_AppControlResolutionInfo*>(pResolutionList->GetAt(resIndex));
389                         if (pResolution == null) continue;
390
391                         String* pUriScheme = pResolution->GetUriScheme();
392                         if (pUriScheme && pUriScheme->IsEmpty() == false)
393                         {
394                                 __pWriter->StartElement("uri");
395                                 __pWriter->WriteAttribute("name", *pUriScheme);
396                                 __pWriter->EndElement();
397                         }
398
399                         String* pMimeType = pResolution->GetMimeType();
400                         if (pMimeType && pMimeType->IsEmpty() == false)
401                         {
402                                 __pWriter->StartElement("mime");
403                                 __pWriter->WriteAttribute("name", *pMimeType);
404                                 __pWriter->EndElement();
405                         }
406
407                         __pWriter->EndElement();
408                 }
409         }
410
411         return true;
412 }
413
414 bool
415 ManifestGenerator::WriteCategory(int index) const
416 {
417         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
418         TryReturn(pAppDataList, true, "pAppDataList is null");
419
420         AppData* pAppData = null;
421         pAppDataList->GetAt(index, pAppData);
422         TryReturn(pAppData, true, "pAppData is null");
423
424         IListT<String*>* pCategoryList = pAppData->__pCategoryList;
425         TryReturn(pCategoryList, true, "pCategoryList is null");
426
427         for (int i = 0; i < pCategoryList->GetCount(); i++)
428         {
429                 String *pStr = null;
430                 pCategoryList->GetAt(i, pStr);
431                 TryReturn(pStr, false, "pStr is null");
432
433                 AppLog("WriteCategory(): Category String=[%ls]", pStr->GetPointer());
434
435                 __pWriter->StartElement("category");
436                 __pWriter->WriteAttribute("name", *pStr);
437                 __pWriter->EndElement();
438         }
439
440         return true;
441 }
442
443 bool
444 ManifestGenerator::FindCategory(int index, const String& category) const
445 {
446         result r = E_SUCCESS;
447
448         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
449         TryReturn(pAppDataList, false, "pAppDataList is null");
450
451         AppData* pAppData = null;
452         r = pAppDataList->GetAt(index, pAppData);
453         TryReturn(pAppData, false, "pAppData is null");
454
455         IListT<String*>* pCategoryList = pAppData->__pCategoryList;
456         TryReturn(pCategoryList, false, "pCategoryList is null");
457
458         for (int i = 0; i < pCategoryList->GetCount(); i++)
459         {
460                 String *pStr = null;
461                 pCategoryList->GetAt(i, pStr);
462                 TryReturn(pStr, false, "pStr is null");
463
464                 if (*pStr == category)
465                 {
466                         AppLog("FindCategory(): Category is found=[%ls]", pStr->GetPointer());
467                         return true;
468                 }
469
470         }
471
472         return false;
473 }
474
475 bool
476 ManifestGenerator::WriteApp(int index, AppData* pAppData)
477 {
478         IMap* pNameList = pAppData->__pNameList;
479         String label("label");
480         String type("c++app");
481         String binaryPath;
482         binaryPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_BIN, pAppData->__name.GetPointer());
483
484         if (pAppData->__main.Equals(L"True", false) == true)
485         {
486                 WriteLanguageValue(pNameList, label);
487
488                 if (pAppData->__menuIcon.IsEmpty() == false)
489                 {
490                         String iconPath;
491                         GetIconPath(pAppData->__menuIcon, iconPath);
492
493                         __pWriter->StartElement("icon");
494                         __pWriter->WriteString(iconPath);
495                         __pWriter->EndElement();
496                 }
497         }
498
499         String nodisplay("true");
500         String taskmanage("false");
501         String category;
502         String mainapp("true");
503
504         if (pAppData->__type == L"UiApp")
505         {
506                 if (pAppData->__launchingHistoryVisible.IsEmpty() == true)
507                 {
508                         if (pAppData->__menuIconVisible == true)
509                         {
510                                 taskmanage = L"true";
511                         }
512                         else
513                         {
514                                 taskmanage = L"false";
515                         }
516                 }
517                 else
518                 {
519                         String history;
520                         pAppData->__launchingHistoryVisible.ToLowerCase(history);
521                         taskmanage = history;
522                 }
523
524                 if (pAppData->__menuIconVisible == true)
525                 {
526                         nodisplay = L"false";
527                 }
528                 else
529                 {
530                         nodisplay = L"true";
531                 }
532
533                 const char* pCategory = null;
534                 pCategory = TIZEN_CATEGORY_IME;
535                 if (FindCategory(index, pCategory) == true)
536                 {
537                         AppLog("Write(): [%s] is detected. taskmanage=false, nodisplay=true", pCategory);
538                         taskmanage = L"false";
539                         nodisplay = L"true";
540                 }
541
542                 pCategory = TIZEN_CATEGORY_HOMESCREEN;
543                 if (FindCategory(index, pCategory) == true)
544                 {
545                         AppLog("Write(): [%s] is detected. taskmanage=false", pCategory);
546                         taskmanage = L"false";
547                 }
548
549                 pCategory = TIZEN_CATEGORY_LOCKSCREEN;
550                 if (FindCategory(index, pCategory) == true)
551                 {
552                         AppLog("Write(): [%s] is detected. taskmanage=false", pCategory);
553                         taskmanage = L"false";
554                 }
555
556                 pCategory = TIZEN_CATEGORY_MENUSCREEN;
557                 if (FindCategory(index, pCategory) == true)
558                 {
559                         AppLog("Write(): [%s] is detected. taskmanage=false", pCategory);
560                         taskmanage = L"false";
561                 }
562         }
563
564         if (pAppData->__main != L"True")
565         {
566                 mainapp = L"false";
567         }
568
569         HashMap* pFeatureList = pAppData->__pFeatureList;
570         String glFrame = GetGlFrameValue(pFeatureList);
571
572         __pWriter->StartElement("ui-application");
573         __pWriter->WriteAttribute("appid", pAppData->__appId);
574         __pWriter->WriteAttribute("exec", binaryPath);
575         __pWriter->WriteAttribute("nodisplay", nodisplay);
576         __pWriter->WriteAttribute("taskmanage", taskmanage);
577         __pWriter->WriteAttribute("multiple", "false");
578         __pWriter->WriteAttribute("type", type);
579         __pWriter->WriteAttribute("hw-acceleration", glFrame);
580         __pWriter->WriteAttribute("mainapp", mainapp);
581
582         if (pAppData->__permissionType.IsEmpty() == false)
583         {
584                 String type = pAppData->__permissionType;
585                 type.ToLowerCase();
586
587                 __pWriter->StartElement("permission");
588                 __pWriter->WriteAttribute("type", type);
589                 __pWriter->EndElement();
590         }
591
592         HashMap* pMetadataMap = pAppData->__pMetadataMap;
593         if (pMetadataMap->GetCount() > 0)
594         {
595                 WriteMetadata(pMetadataMap);
596         }
597
598         WriteCategory(index);
599
600 #if 0
601         if (pAppInfoImpl->GetType() == L"UiApp")
602         {
603                 String nodisplay;
604
605                 if (pAppInfoImpl->IsMainmenuVisible() == true)
606                 {
607                         nodisplay = "false";
608                 }
609                 else
610                 {
611                         nodisplay = "true";
612                 }
613
614                 __pWriter->StartElement("ui-application");
615                 __pWriter->WriteAttribute("appid", pAppInfoImpl->GetPackageName());
616                 __pWriter->WriteAttribute("exec", binaryPath);
617                 __pWriter->WriteAttribute("nodisplay", nodisplay);
618                 __pWriter->WriteAttribute("taskmanage", "true");
619                 __pWriter->WriteAttribute("multiple", "false");
620                 __pWriter->WriteAttribute("type", type);
621         }
622         else if (pAppInfoImpl->GetType() == L"ServiceApp")
623         {
624                 ArrayList* pFeatureList = pAppInfoImpl->GetAppFeatureList();
625                 String onBoot("false");
626                 String autoRestart("false");
627
628                 if (FindFeatureValue(pFeatureList, "LaunchOnBoot", "True") == true)
629                 {
630                         onBoot = L"true";
631                 }
632
633                 if (FindFeatureValue(pFeatureList, "AutoRestart", "True") == true)
634                 {
635                         autoRestart = L"true";
636                 }
637
638                 __pWriter->StartElement("service-application");
639                 __pWriter->WriteAttribute("appid", pAppInfoImpl->GetPackageName());
640                 __pWriter->WriteAttribute("exec", binaryPath);
641                 __pWriter->WriteAttribute("type", type);
642                 __pWriter->WriteAttribute("on-boot", onBoot);
643                 __pWriter->WriteAttribute("auto-restart", autoRestart);
644         }
645         else
646         {
647                 AppLog("Type is invalid! [%ls]", pAppInfoImpl->GetType().GetPointer());
648                 return false;
649         }
650         #endif
651
652         WriteLanguageValue(pNameList, label);
653
654         if (pAppData->__menuIcon.IsEmpty() == false)
655         {
656                 String iconPath;
657                 GetIconPath(pAppData->__menuIcon, iconPath);
658
659                 __pWriter->StartElement("icon");
660                 __pWriter->WriteString(iconPath);
661                 __pWriter->EndElement();
662         }
663
664         if (pAppData->__settingIcon.IsEmpty() == false)
665         {
666                 String iconPath;
667                 GetIconPath(pAppData->__settingIcon, iconPath);
668
669                 __pWriter->StartElement("icon");
670                 __pWriter->WriteAttribute("section", "setting");
671                 __pWriter->WriteString(iconPath);
672                 __pWriter->EndElement();
673         }
674
675         if (pAppData->__notificationIcon.IsEmpty() == false)
676         {
677                 String iconPath;
678                 GetIconPath(pAppData->__notificationIcon, iconPath);
679
680                 __pWriter->StartElement("icon");
681                 __pWriter->WriteAttribute("section", "notification");
682                 __pWriter->WriteString(iconPath);
683                 __pWriter->EndElement();
684         }
685
686         if (pAppData->__legacyAppControls == true)
687         {
688                 AppLog("Write(): AppControls spec is legacy");
689                 WriteAppControl(pAppData);
690         }
691         else
692         {
693                 WriteAppControl(index);
694         }
695
696         __pWriter->EndElement(); // end of "ui-application"
697
698         if (pAppData->__type == L"ServiceApp")
699         {
700                 WriteLiveboxes(pAppData);
701         }
702
703         WriteAccounts(index);
704         WriteNotifications(index);
705
706         return true;
707 }
708
709 bool
710 ManifestGenerator::WriteSubModeApp(int index, AppData* pAppData)
711 {
712         // SUB_MODE_APPCONTROL_NAME -> AppName
713         String subBinaryPath;
714         subBinaryPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_BIN, SUB_MODE_APPCONTROL_NAME);
715
716         String binaryPath;
717         binaryPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_BIN, pAppData->__subModeAppName.GetPointer());
718
719         if (File::IsFileExist(subBinaryPath) == true)
720         {
721                 InstallerUtil::Remove(subBinaryPath);
722         }
723         InstallerUtil::CreateSymlink(binaryPath, subBinaryPath);
724
725         // SUB_MODE_APPCONTROL_NAME.exe -> AppName.exe
726         String subBinaryExecPath = subBinaryPath + ".exe";
727         String binaryExecPath = binaryPath + ".exe";
728
729         if (File::IsFileExist(subBinaryExecPath) == true)
730         {
731                 InstallerUtil::Remove(subBinaryExecPath);
732         }
733         InstallerUtil::CreateSymlink(binaryExecPath, subBinaryExecPath);
734
735         PackageId packageId = __pContext->__packageId;
736         AppId appId = packageId + L"." + SUB_MODE_APPCONTROL_NAME;
737
738         __pWriter->StartElement("ui-application");
739         __pWriter->WriteAttribute("appid", appId);
740         __pWriter->WriteAttribute("exec", subBinaryPath);
741         __pWriter->WriteAttribute("nodisplay", "true");
742         __pWriter->WriteAttribute("taskmanage", "false");
743         __pWriter->WriteAttribute("multiple", "true");
744         __pWriter->WriteAttribute("type", "c++app");
745
746         __pWriter->StartElement("label");
747         __pWriter->WriteString(__pContext->__displayName);
748         __pWriter->EndElement();
749
750         if (pAppData->__menuIcon.IsEmpty() == false)
751         {
752                 String iconPath;
753                 GetIconPath(pAppData->__menuIcon, iconPath);
754
755                 __pWriter->StartElement("icon");
756                 __pWriter->WriteString(iconPath);
757                 __pWriter->EndElement();
758         }
759
760         WriteAppControl(index, true);
761
762         __pWriter->EndElement();        // end of "ui-application"
763
764         return true;
765 }
766
767 bool
768 ManifestGenerator::WriteAppControl(int index, bool subMode)
769 {
770         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
771         TryReturn(pAppDataList, false, "pAppDataList is null");
772
773         AppData* pAppData = null;
774         pAppDataList->GetAt(index, pAppData);
775         TryReturn(pAppData, false, "pAppData is null");
776
777         IListT<AppControlData*>* pAppControlDataList = null;
778
779         if (subMode == false)
780         {
781                 pAppControlDataList = pAppData->__pAppControlDataList;
782                 TryReturn(pAppControlDataList, false, "pAppControlDataList is null");
783         }
784         else
785         {
786                 pAppControlDataList = pAppData->__pSubModeAppControlDataList;
787                 TryReturn(pAppControlDataList, false, "pAppControlDataList is null");
788         }
789
790         for (int i = 0; i < pAppControlDataList->GetCount(); i++)
791         {
792                 __pWriter->StartElement("application-service");
793
794                 AppControlData* pAppControlData = null;
795                 pAppControlDataList->GetAt(i, pAppControlData);
796                 TryReturn(pAppControlData, false, "pAppControlData is null");
797
798                 IListT<String*>* pOperationList = pAppControlData->__pOperationList;
799                 TryReturn(pOperationList, false, "pOperationList is null");
800                 for (int sub = 0; sub < pOperationList->GetCount(); sub++)
801                 {
802                         String* pOperation = null;
803                         pOperationList->GetAt(sub, pOperation);
804                         TryReturn(pOperation, false, "pOperation is null");
805
806                         __pWriter->StartElement("operation");
807                         __pWriter->WriteAttribute("name", *pOperation);
808                         __pWriter->EndElement();        // end of "operation"
809                 }
810
811                 IListT<String*>* pMimeTypeList = pAppControlData->__pMimeTypeList;
812                 TryReturn(pMimeTypeList, false, "pMimeTypeList is null");
813                 for (int sub = 0; sub < pMimeTypeList->GetCount(); sub++)
814                 {
815                         String* pMimeType = null;
816                         pMimeTypeList->GetAt(sub, pMimeType);
817                         TryReturn(pMimeType, false, "pMimeType is null");
818
819                         if (pMimeType->IsEmpty() == true) continue;
820
821                         __pWriter->StartElement("mime");
822                         __pWriter->WriteAttribute("name", *pMimeType);
823                         __pWriter->EndElement();        // end of "mime"
824                 }
825
826                 IListT<String*>* pUriList = pAppControlData->__pUriList;
827                 TryReturn(pUriList, false, "pUriList is null");
828                 for (int sub = 0; sub < pUriList->GetCount(); sub++)
829                 {
830                         String* pUri = null;
831                         pUriList->GetAt(sub, pUri);
832                         TryReturn(pUri, false, "pUri is null");
833
834                         if (pUri->IsEmpty() == true) continue;
835
836                         __pWriter->StartElement("uri");
837                         __pWriter->WriteAttribute("name", *pUri);
838                         __pWriter->EndElement();        // end of "uri"
839                 }
840
841                 __pWriter->EndElement();        // end of "application-service"
842         }
843
844         return true;
845 }
846
847 bool
848 ManifestGenerator::WriteAccounts(int index)
849 {
850         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
851         TryReturn(pAppDataList, false, "pAppDataList is null");
852
853         AppData* pAppData = null;
854         pAppDataList->GetAt(index, pAppData);
855         TryReturn(pAppData, false, "pAppData is null");
856
857         IListT<AccountData*>* pAccountDataList = pAppData->__pAccountDataList;
858         TryReturn(pAccountDataList, false, "pAccountDataList is null");
859
860         int accountCount = pAccountDataList->GetCount();
861         if (accountCount <= 0)
862         {
863                 return true;
864         }
865
866         __pWriter->StartElement("account");
867
868         for (int i = 0; i < accountCount; i++)
869         {
870                 __pWriter->StartElement("account-provider");
871
872                 AccountData* pAccountData = null;
873                 pAccountDataList->GetAt(i, pAccountData);
874                 TryReturn(pAccountData, false, "pAccountData is null");
875
876                 String multipleAccountsSupport = pAccountData->__multipleAccountsSupport;
877                 multipleAccountsSupport.ToLowerCase();
878
879                 __pWriter->WriteAttribute("appid", pAppData->__appId);
880                 __pWriter->WriteAttribute("providerid", pAccountData->__providerId);
881                 __pWriter->WriteAttribute("multiple-accounts-support", multipleAccountsSupport);
882
883                 String accountIcon = pAccountData->__accountIcon;
884                 if (accountIcon.IsEmpty() == false)
885                 {
886                         String accountIconPath;
887                         accountIconPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_SHARED_RES, accountIcon.GetPointer());
888
889                         __pWriter->StartElement("icon");
890                         __pWriter->WriteAttribute("section", "account");
891                         __pWriter->WriteString(accountIconPath);
892                         __pWriter->EndElement();
893                 }
894
895                 String accountSmallIcon = pAccountData->__accountSmallIcon;
896                 if (accountSmallIcon.IsEmpty() == false)
897                 {
898                         String accountSmallIconPath;
899                         accountSmallIconPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_SHARED_RES, accountSmallIcon.GetPointer());
900
901                         __pWriter->StartElement("icon");
902                         __pWriter->WriteAttribute("section", "account-small");
903                         __pWriter->WriteString(accountSmallIconPath);
904                         __pWriter->EndElement();
905                 }
906
907                 WriteLanguageValue(pAccountData->__pNameList, L"label");
908
909                 IListT<String*>* pCapabilityList = pAccountData->__pCapabilityList;
910                 TryReturn(pCapabilityList, false, "pCapabilityList is null");
911
912                 for (int capa = 0; capa < pCapabilityList->GetCount(); capa++)
913                 {
914                         String* pCapability = null;
915                         pCapabilityList->GetAt(capa, pCapability);
916                         TryReturn(pCapability, false, "pCapability is null");
917
918                         __pWriter->StartElement("capability");
919                         __pWriter->WriteString(*pCapability);
920                         __pWriter->EndElement(); // end of "capability"
921                 }
922
923                 __pWriter->EndElement(); // end of "account-provider"
924         }
925
926         __pWriter->EndElement(); // end of "account"
927
928         return true;
929 }
930
931 bool
932 ManifestGenerator::WriteNotifications(int index)
933 {
934         IListT<AppData*>* pAppDataList = __pContext->__pAppDataList;
935         TryReturn(pAppDataList, false, "pAppDataList is null");
936
937         AppData* pAppData = null;
938         pAppDataList->GetAt(index, pAppData);
939         TryReturn(pAppData, false, "pAppData is null");
940
941         HashMap* pNotificationMap = pAppData->__pNotificationMap;
942         TryReturn(pNotificationMap, false, "pNotificationMap is null");
943
944         int count = pNotificationMap->GetCount();
945         if (count <= 0)
946         {
947                 return true;
948         }
949
950         IMapEnumerator* pMapEnum = pNotificationMap->GetMapEnumeratorN();
951         TryReturn(pMapEnum, false, "pMapEnum is null");
952
953         __pWriter->StartElement("notifications");
954         __pWriter->WriteAttribute("appid", pAppData->__appId);
955
956         while (pMapEnum->MoveNext() == E_SUCCESS)
957         {
958                 String* pKey = null;
959                 String* pValue = null;
960
961                 pKey = static_cast<String*> (pMapEnum->GetKey());
962                 pValue = static_cast<String*> (pMapEnum->GetValue());
963
964                 __pWriter->StartElement("notification");
965                 __pWriter->WriteAttribute("section", *pKey);
966                 __pWriter->WriteString(*pValue);
967                 __pWriter->EndElement(); // end of "notification"
968         }
969
970         __pWriter->EndElement(); // end of "notifications"
971
972         delete pMapEnum;
973         return true;
974 }
975
976 bool
977 ManifestGenerator::WriteMetadata(HashMap* pMetadataMap)
978 {
979         std::unique_ptr< IMapEnumerator > pEnum(pMetadataMap->GetMapEnumeratorN());
980         TryReturn(pEnum, false, "GetMapEnumeratorN() failed. [%s]", GetErrorMessage(GetLastResult()));
981
982         while (pEnum->MoveNext() == E_SUCCESS)
983         {
984                 String* pKey = static_cast< String* > (pEnum->GetKey());
985                 TryReturn(pEnum, false, "GetKey() failed. [%s]", GetErrorMessage(GetLastResult()));
986
987                 String* pValue = static_cast< String* > (pEnum->GetValue());
988                 TryReturn(pEnum, false, "GetValue() failed. [%s]", GetErrorMessage(GetLastResult()));
989
990                 __pWriter->StartElement("metadata");
991                 __pWriter->WriteAttribute("key", *pKey);
992                 __pWriter->WriteAttribute("value", *pValue);
993                 __pWriter->EndElement();
994         }
995
996         return true;
997 }
998
999 bool
1000 ManifestGenerator::WritePrivileges(ArrayList* pPrivilegeList)
1001 {
1002         if (pPrivilegeList == null)
1003         {
1004                 return true;
1005         }
1006
1007         __pWriter->StartElement("privileges");
1008
1009         for (int i = 0; i < pPrivilegeList->GetCount(); i++)
1010         {
1011                 String* pPrivilege = dynamic_cast < String* >(pPrivilegeList->GetAt(i));
1012                 if (pPrivilege)
1013                 {
1014                         __pWriter->StartElement("privilege");
1015                         __pWriter->WriteString(*pPrivilege);
1016                         __pWriter->EndElement();
1017                 }
1018          }
1019
1020         __pWriter->EndElement();
1021
1022         return true;
1023 }
1024
1025 bool
1026 ManifestGenerator::GetIconPath(const String& icon, String& iconPath) const
1027 {
1028         String tempIconPath;
1029         tempIconPath.Format(1024, L"%ls%ls/%ls", __pContext->__rootPath.GetPointer(), DIR_SHARED_RES, icon.GetPointer());
1030
1031         if (File::IsFileExist(tempIconPath) == false)
1032         {
1033                 AppLog("fallback, old path = [%ls]", tempIconPath.GetPointer());
1034
1035                 String densityXhigh("screen-density-xhigh/");
1036                 String densityHigh("screen-density-high/");
1037
1038                 if (icon.Contains(densityXhigh) == true)
1039                 {
1040                         tempIconPath.Replace(densityXhigh, densityHigh);
1041                 }
1042                 else if (icon.Contains(densityHigh) == true)
1043                 {
1044                         tempIconPath.Replace(densityHigh, densityXhigh);
1045                 }
1046                 else
1047                 {
1048                         AppLog("invalid icon [%ls]", icon.GetPointer());
1049                         return false;
1050                 }
1051
1052                 AppLog("fallback, new path = [%ls]", tempIconPath.GetPointer());
1053
1054                 if (File::IsFileExist(tempIconPath) == false)
1055                 {
1056                         AppLog("fallback, but file is not found. [%ls]", tempIconPath.GetPointer());
1057                         return false;
1058                 }
1059         }
1060
1061         iconPath = tempIconPath;
1062
1063         AppLog("icon[%ls], iconPath[%ls]", icon.GetPointer(), iconPath.GetPointer());
1064
1065         return true;
1066 }