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.
5 #include "extensions/common/features/complex_feature.h"
9 ComplexFeature::ComplexFeature(scoped_ptr
<FeatureList
> features
) {
10 DCHECK_GT(features
->size(), 0UL);
11 features_
.swap(*features
);
12 no_parent_
= features_
[0]->no_parent();
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();
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.";
40 ComplexFeature::~ComplexFeature() {
43 Feature::Availability
ComplexFeature::IsAvailableToManifest(
44 const std::string
& extension_id
,
46 Manifest::Location location
,
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
;
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())
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
;
67 Feature::Availability
ComplexFeature::IsAvailableToContext(
68 const Extension
* extension
,
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
;
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())
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
;
89 bool ComplexFeature::IsIdInBlacklist(const std::string
& extension_id
) const {
90 for (FeatureList::const_iterator it
= features_
.begin();
91 it
!= features_
.end();
93 if ((*it
)->IsIdInBlacklist(extension_id
))
99 bool ComplexFeature::IsIdInWhitelist(const std::string
& extension_id
) const {
100 for (FeatureList::const_iterator it
= features_
.begin();
101 it
!= features_
.end();
103 if ((*it
)->IsIdInWhitelist(extension_id
))
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();
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();
123 bool ComplexFeature::IsInternal() const {
124 // TODO(justinlin): Same as the above TODO.
125 return features_
[0]->IsInternal();
128 std::string
ComplexFeature::GetAvailabilityMessage(AvailabilityResult result
,
131 Context context
) const {
132 if (result
== IS_AVAILABLE
)
133 return std::string();
135 // TODO(justinlin): Form some kind of combined availabilities/messages from
137 return features_
[0]->GetAvailabilityMessage(result
, type
, url
, context
);
140 } // namespace extensions