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