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