Home | History | Annotate | Download | only in features
      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 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 
     30 ComplexFeature::~ComplexFeature() {
     31 }
     32 
     33 Feature::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 
     57 Feature::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 
     79 bool 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 
     89 bool 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 
     99 bool 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 
    105 std::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