1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/features/complex_feature.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComplexFeature::ComplexFeature(scoped_ptr<FeatureList> features) { 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(features->size(), 0UL); 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) features_.swap(*features); 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) no_parent_ = features_[0]->no_parent(); 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Verify IsInternal and no_parent is consistent across all features. 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool first_is_internal = features_[0]->IsInternal(); 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (FeatureList::const_iterator it = features_.begin() + 1; 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch it != features_.end(); 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ++it) { 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(first_is_internal == (*it)->IsInternal()) 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << "Complex feature must have consistent values of " 22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "internal across all sub features."; 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(no_parent_ == (*it)->no_parent()) 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << "Complex feature must have consistent values of " 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "no_parent across all sub features."; 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ComplexFeature::~ComplexFeature() { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability ComplexFeature::IsAvailableToManifest( 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& extension_id, 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Manifest::Type type, 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Manifest::Location location, 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int manifest_version, 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Platform platform) const { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Feature::Availability first_availability = 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) features_[0]->IsAvailableToManifest( 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_id, type, location, manifest_version, platform); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (first_availability.is_available()) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return first_availability; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (FeatureList::const_iterator it = features_.begin() + 1; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != features_.end(); ++it) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Availability availability = (*it)->IsAvailableToManifest( 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_id, type, location, manifest_version, platform); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (availability.is_available()) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return availability; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If none of the SimpleFeatures are available, we return the availability 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // info of the first SimpleFeature that was not available. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return first_availability; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Feature::Availability ComplexFeature::IsAvailableToContext( 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Context context, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Platform platform) const { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Feature::Availability first_availability = 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) features_[0]->IsAvailableToContext(extension, context, url, platform); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (first_availability.is_available()) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return first_availability; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (FeatureList::const_iterator it = features_.begin() + 1; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != features_.end(); ++it) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Availability availability = 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*it)->IsAvailableToContext(extension, context, url, platform); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (availability.is_available()) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return availability; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If none of the SimpleFeatures are available, we return the availability 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // info of the first SimpleFeature that was not available. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return first_availability; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ComplexFeature::IsIdInBlacklist(const std::string& extension_id) const { 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (FeatureList::const_iterator it = features_.begin(); 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != features_.end(); 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((*it)->IsIdInBlacklist(extension_id)) 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool ComplexFeature::IsIdInWhitelist(const std::string& extension_id) const { 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (FeatureList::const_iterator it = features_.begin(); 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch it != features_.end(); 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ++it) { 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if ((*it)->IsIdInWhitelist(extension_id)) 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return true; 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return false; 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComplexFeature::IsInternal() const { 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Constructor verifies that composed features are consistent, thus we can 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // return just the first feature's value. 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return features_[0]->IsInternal(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ComplexFeature::GetAvailabilityMessage(AvailabilityResult result, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Type type, 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const GURL& url, 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Context context) const { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result == IS_AVAILABLE) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(justinlin): Form some kind of combined availabilities/messages from 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SimpleFeatures. 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return features_[0]->GetAvailabilityMessage(result, type, url, context); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 118