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 7namespace extensions { 8 9ComplexFeature::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 IsInternal and no_parent is consistent across all features. 16 bool first_is_internal = features_[0]->IsInternal(); 17 for (FeatureList::const_iterator it = features_.begin() + 1; 18 it != features_.end(); 19 ++it) { 20 DCHECK(first_is_internal == (*it)->IsInternal()) 21 << "Complex feature must have consistent values of " 22 "internal across all sub features."; 23 DCHECK(no_parent_ == (*it)->no_parent()) 24 << "Complex feature must have consistent values of " 25 "no_parent across all sub features."; 26 } 27#endif 28} 29 30ComplexFeature::~ComplexFeature() { 31} 32 33Feature::Availability ComplexFeature::IsAvailableToManifest( 34 const std::string& extension_id, 35 Manifest::Type type, 36 Manifest::Location location, 37 int manifest_version, 38 Platform platform) const { 39 Feature::Availability first_availability = 40 features_[0]->IsAvailableToManifest( 41 extension_id, type, location, manifest_version, platform); 42 if (first_availability.is_available()) 43 return first_availability; 44 45 for (FeatureList::const_iterator it = features_.begin() + 1; 46 it != features_.end(); ++it) { 47 Availability availability = (*it)->IsAvailableToManifest( 48 extension_id, type, location, manifest_version, platform); 49 if (availability.is_available()) 50 return availability; 51 } 52 // If none of the SimpleFeatures are available, we return the availability 53 // info of the first SimpleFeature that was not available. 54 return first_availability; 55} 56 57Feature::Availability ComplexFeature::IsAvailableToContext( 58 const Extension* extension, 59 Context context, 60 const GURL& url, 61 Platform platform) const { 62 Feature::Availability first_availability = 63 features_[0]->IsAvailableToContext(extension, context, url, platform); 64 if (first_availability.is_available()) 65 return first_availability; 66 67 for (FeatureList::const_iterator it = features_.begin() + 1; 68 it != features_.end(); ++it) { 69 Availability availability = 70 (*it)->IsAvailableToContext(extension, context, url, platform); 71 if (availability.is_available()) 72 return availability; 73 } 74 // If none of the SimpleFeatures are available, we return the availability 75 // info of the first SimpleFeature that was not available. 76 return first_availability; 77} 78 79bool ComplexFeature::IsIdInBlacklist(const std::string& extension_id) const { 80 for (FeatureList::const_iterator it = features_.begin(); 81 it != features_.end(); 82 ++it) { 83 if ((*it)->IsIdInBlacklist(extension_id)) 84 return true; 85 } 86 return false; 87} 88 89bool ComplexFeature::IsIdInWhitelist(const std::string& extension_id) const { 90 for (FeatureList::const_iterator it = features_.begin(); 91 it != features_.end(); 92 ++it) { 93 if ((*it)->IsIdInWhitelist(extension_id)) 94 return true; 95 } 96 return false; 97} 98 99bool ComplexFeature::IsInternal() const { 100 // Constructor verifies that composed features are consistent, thus we can 101 // return just the first feature's value. 102 return features_[0]->IsInternal(); 103} 104 105std::string ComplexFeature::GetAvailabilityMessage(AvailabilityResult result, 106 Manifest::Type type, 107 const GURL& url, 108 Context context) const { 109 if (result == IS_AVAILABLE) 110 return std::string(); 111 112 // TODO(justinlin): Form some kind of combined availabilities/messages from 113 // SimpleFeatures. 114 return features_[0]->GetAvailabilityMessage(result, type, url, context); 115} 116 117} // namespace extensions 118