Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / extensions / common / features / complex_feature.cc
1 // Copyright 2014 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 "extensions/common/features/complex_feature.h"
6
7 namespace extensions {
8
9 ComplexFeature::ComplexFeature(scoped_ptr<FeatureList> features) {
10   DCHECK_GT(features->size(), 0UL);
11   features_.swap(*features);
12   no_parent_ = features_[0]->no_parent();
13
14 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
15   // Verify GetContexts, IsInternal, & IsBlockedInServiceWorker are consistent
16   // across all features.
17   std::set<Feature::Context>* first_contexts = features_[0]->GetContexts();
18   bool first_is_internal = features_[0]->IsInternal();
19   bool first_blocked_in_service_worker =
20       features_[0]->IsBlockedInServiceWorker();
21   for (FeatureList::const_iterator it = features_.begin() + 1;
22        it != features_.end();
23        ++it) {
24     DCHECK(*first_contexts == *(*it)->GetContexts())
25         << "Complex feature must have consistent values of "
26            "contexts across all sub features.";
27     DCHECK(first_is_internal == (*it)->IsInternal())
28         << "Complex feature must have consistent values of "
29            "internal across all sub features.";
30     DCHECK(first_blocked_in_service_worker == (*it)->IsBlockedInServiceWorker())
31         << "Complex feature must have consistent values of "
32            "blocked_in_service_worker across all sub features.";
33     DCHECK(no_parent_ == (*it)->no_parent())
34         << "Complex feature must have consistent values of "
35            "no_parent across all sub features.";
36   }
37 #endif
38 }
39
40 ComplexFeature::~ComplexFeature() {
41 }
42
43 Feature::Availability ComplexFeature::IsAvailableToManifest(
44     const std::string& extension_id,
45     Manifest::Type type,
46     Manifest::Location location,
47     int manifest_version,
48     Platform platform) const {
49   Feature::Availability first_availability =
50       features_[0]->IsAvailableToManifest(
51           extension_id, type, location, manifest_version, platform);
52   if (first_availability.is_available())
53     return first_availability;
54
55   for (FeatureList::const_iterator it = features_.begin() + 1;
56        it != features_.end(); ++it) {
57     Availability availability = (*it)->IsAvailableToManifest(
58         extension_id, type, location, manifest_version, platform);
59     if (availability.is_available())
60       return availability;
61   }
62   // If none of the SimpleFeatures are available, we return the availability
63   // info of the first SimpleFeature that was not available.
64   return first_availability;
65 }
66
67 Feature::Availability ComplexFeature::IsAvailableToContext(
68     const Extension* extension,
69     Context context,
70     const GURL& url,
71     Platform platform) const {
72   Feature::Availability first_availability =
73       features_[0]->IsAvailableToContext(extension, context, url, platform);
74   if (first_availability.is_available())
75     return first_availability;
76
77   for (FeatureList::const_iterator it = features_.begin() + 1;
78        it != features_.end(); ++it) {
79     Availability availability =
80         (*it)->IsAvailableToContext(extension, context, url, platform);
81     if (availability.is_available())
82       return availability;
83   }
84   // If none of the SimpleFeatures are available, we return the availability
85   // info of the first SimpleFeature that was not available.
86   return first_availability;
87 }
88
89 bool ComplexFeature::IsIdInBlacklist(const std::string& extension_id) const {
90   for (FeatureList::const_iterator it = features_.begin();
91        it != features_.end();
92        ++it) {
93     if ((*it)->IsIdInBlacklist(extension_id))
94       return true;
95   }
96   return false;
97 }
98
99 bool ComplexFeature::IsIdInWhitelist(const std::string& extension_id) const {
100   for (FeatureList::const_iterator it = features_.begin();
101        it != features_.end();
102        ++it) {
103     if ((*it)->IsIdInWhitelist(extension_id))
104       return true;
105   }
106   return false;
107 }
108
109 bool ComplexFeature::IsBlockedInServiceWorker() const {
110   // Constructor verifies that composed features are consistent, thus we can
111   // return just the first feature's value.
112   return features_[0]->IsBlockedInServiceWorker();
113 }
114
115 std::set<Feature::Context>* ComplexFeature::GetContexts() {
116   // TODO(justinlin): Current use cases for ComplexFeatures are simple (e.g.
117   // allow API in dev channel for everyone but stable channel for a whitelist),
118   // but if they get more complicated, we need to return some meaningful context
119   // set. Either that or remove this method from the Feature interface.
120   return features_[0]->GetContexts();
121 }
122
123 bool ComplexFeature::IsInternal() const {
124   // TODO(justinlin): Same as the above TODO.
125   return features_[0]->IsInternal();
126 }
127
128 std::string ComplexFeature::GetAvailabilityMessage(AvailabilityResult result,
129                                                    Manifest::Type type,
130                                                    const GURL& url,
131                                                    Context context) const {
132   if (result == IS_AVAILABLE)
133     return std::string();
134
135   // TODO(justinlin): Form some kind of combined availabilities/messages from
136   // SimpleFeatures.
137   return features_[0]->GetAvailabilityMessage(result, type, url, context);
138 }
139
140 }  // namespace extensions