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