Performance histograms for extension content verification
[chromium-blink-merge.git] / extensions / common / features / complex_feature.cc
blobeeb4f776a4df21ed07a1eea2d2550a89557a036c
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"
7 namespace extensions {
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();
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.";
37 #endif
40 ComplexFeature::~ComplexFeature() {
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;
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;
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,
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;
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;
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();
92 ++it) {
93 if ((*it)->IsIdInBlacklist(extension_id))
94 return true;
96 return false;
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;
106 return false;
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,
129 Manifest::Type type,
130 const GURL& url,
131 Context context) const {
132 if (result == IS_AVAILABLE)
133 return std::string();
135 // TODO(justinlin): Form some kind of combined availabilities/messages from
136 // SimpleFeatures.
137 return features_[0]->GetAvailabilityMessage(result, type, url, context);
140 } // namespace extensions