Upstream version 9.38.207.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / common / manifest_handler.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/application/common/manifest_handler.h"
6
7 #include <set>
8
9 #include "base/stl_util.h"
10 #include "xwalk/application/common/manifest_handlers/csp_handler.h"
11 #if defined(OS_TIZEN)
12 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
13 #include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
14 #include "xwalk/application/common/manifest_handlers/tizen_metadata_handler.h"
15 #include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
16 #include "xwalk/application/common/manifest_handlers/tizen_splash_screen_handler.h"
17 #endif
18 #include "xwalk/application/common/manifest_handlers/permissions_handler.h"
19 #include "xwalk/application/common/manifest_handlers/warp_handler.h"
20 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
21
22 namespace xwalk {
23 namespace application {
24
25 ManifestHandler::~ManifestHandler() {
26 }
27
28 bool ManifestHandler::Validate(scoped_refptr<const ApplicationData> application,
29                                std::string* error) const {
30   return true;
31 }
32
33 bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
34   return false;
35 }
36
37 bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
38   return false;
39 }
40
41 std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
42   return std::vector<std::string>();
43 }
44
45 ManifestHandlerRegistry* ManifestHandlerRegistry::xpk_registry_ = NULL;
46 ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
47
48 ManifestHandlerRegistry::ManifestHandlerRegistry(
49     const std::vector<ManifestHandler*>& handlers) {
50   for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
51        it != handlers.end(); ++it) {
52     Register(*it);
53   }
54
55   ReorderHandlersGivenDependencies();
56 }
57
58 ManifestHandlerRegistry::~ManifestHandlerRegistry() {
59 }
60
61 ManifestHandlerRegistry*
62 ManifestHandlerRegistry::GetInstance(Manifest::Type type) {
63   if (type == Manifest::TYPE_WIDGET)
64     return GetInstanceForWGT();
65   return GetInstanceForXPK();
66 }
67
68 ManifestHandlerRegistry*
69 ManifestHandlerRegistry::GetInstanceForWGT() {
70   if (widget_registry_)
71     return widget_registry_;
72
73   std::vector<ManifestHandler*> handlers;
74   // We can put WGT specific manifest handlers here.
75   handlers.push_back(new WidgetHandler);
76   handlers.push_back(new WARPHandler);
77 #if defined(OS_TIZEN)
78   handlers.push_back(new CSPHandler(Manifest::TYPE_WIDGET));
79   handlers.push_back(new NavigationHandler);
80   handlers.push_back(new TizenApplicationHandler);
81   handlers.push_back(new TizenSettingHandler);
82   handlers.push_back(new TizenMetaDataHandler);
83   handlers.push_back(new TizenSplashScreenHandler);
84 #endif
85   widget_registry_ = new ManifestHandlerRegistry(handlers);
86   return widget_registry_;
87 }
88
89 ManifestHandlerRegistry*
90 ManifestHandlerRegistry::GetInstanceForXPK() {
91   if (xpk_registry_)
92     return xpk_registry_;
93
94   std::vector<ManifestHandler*> handlers;
95   // FIXME: Add manifest handlers here like this:
96   // handlers.push_back(new xxxHandler);
97   handlers.push_back(new CSPHandler(Manifest::TYPE_MANIFEST));
98   handlers.push_back(new PermissionsHandler);
99   xpk_registry_ = new ManifestHandlerRegistry(handlers);
100   return xpk_registry_;
101 }
102
103 void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
104   const std::vector<std::string>& keys = handler->Keys();
105   for (size_t i = 0; i < keys.size(); ++i) {
106     handlers_[keys[i]] = handler;
107   }
108 }
109
110 bool ManifestHandlerRegistry::ParseAppManifest(
111     scoped_refptr<ApplicationData> application, base::string16* error) {
112   std::map<int, ManifestHandler*> handlers_by_order;
113   for (ManifestHandlerMap::iterator iter = handlers_.begin();
114        iter != handlers_.end(); ++iter) {
115     ManifestHandler* handler = iter->second;
116     if (application->GetManifest()->HasPath(iter->first) ||
117         handler->AlwaysParseForType(application->manifest_type())) {
118       handlers_by_order[order_map_[handler]] = handler;
119     }
120   }
121   for (std::map<int, ManifestHandler*>::iterator iter =
122            handlers_by_order.begin();
123        iter != handlers_by_order.end(); ++iter) {
124     if (!(iter->second)->Parse(application, error))
125       return false;
126   }
127   return true;
128 }
129
130 bool ManifestHandlerRegistry::ValidateAppManifest(
131     scoped_refptr<const ApplicationData> application,
132     std::string* error) {
133   for (ManifestHandlerMap::iterator iter = handlers_.begin();
134        iter != handlers_.end(); ++iter) {
135     ManifestHandler* handler = iter->second;
136     if ((application->GetManifest()->HasPath(iter->first) ||
137          handler->AlwaysValidateForType(application->manifest_type())) &&
138         !handler->Validate(application, error))
139       return false;
140   }
141   return true;
142 }
143
144 // static
145 void ManifestHandlerRegistry::SetInstanceForTesting(
146     ManifestHandlerRegistry* registry, Manifest::Type type) {
147   if (type == Manifest::TYPE_WIDGET) {
148     widget_registry_ = registry;
149     return;
150   }
151
152   xpk_registry_ = registry;
153 }
154
155 void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
156   std::set<ManifestHandler*> unsorted_handlers;
157   for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
158        iter != handlers_.end(); ++iter) {
159     unsorted_handlers.insert(iter->second);
160   }
161
162   int order = 0;
163   while (true) {
164     std::set<ManifestHandler*> next_unsorted_handlers;
165     for (std::set<ManifestHandler*>::const_iterator iter =
166              unsorted_handlers.begin();
167          iter != unsorted_handlers.end(); ++iter) {
168       ManifestHandler* handler = *iter;
169       const std::vector<std::string>& prerequisites =
170           handler->PrerequisiteKeys();
171       int unsatisfied = prerequisites.size();
172       for (size_t i = 0; i < prerequisites.size(); ++i) {
173         ManifestHandlerMap::const_iterator prereq_iter =
174             handlers_.find(prerequisites[i]);
175         CHECK(prereq_iter != handlers_.end())
176             << "Application manifest handler depends on unrecognized key "
177             << prerequisites[i];
178         // Prerequisite is in our map.
179         if (ContainsKey(order_map_, prereq_iter->second))
180           unsatisfied--;
181       }
182       if (unsatisfied == 0) {
183         order_map_[handler] = order;
184         order++;
185       } else {
186         // Put in the list for next time.
187         next_unsorted_handlers.insert(handler);
188       }
189     }
190     if (next_unsorted_handlers.size() == unsorted_handlers.size())
191       break;
192     unsorted_handlers.swap(next_unsorted_handlers);
193   }
194
195   // If there are any leftover unsorted handlers, they must have had
196   // circular dependencies.
197   CHECK(unsorted_handlers.empty()) << "Application manifest handlers have "
198                                    << "circular dependencies!";
199 }
200
201 }  // namespace application
202 }  // namespace xwalk