1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/common/features/complex_feature.h"
#include "extensions/common/mojom/context_type.mojom.h"
namespace extensions {
ComplexFeature::ComplexFeature(std::vector<Feature*>* features) {
DCHECK_GT(features->size(), 1UL);
for (Feature* f : *features) {
features_.push_back(std::unique_ptr<Feature>(f));
requires_delegated_availability_check_ |=
f->RequiresDelegatedAvailabilityCheck();
}
features->clear();
no_parent_ = features_[0]->no_parent();
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
// Verify IsInternal and no_parent are consistent across all features.
bool first_is_internal = features_[0]->IsInternal();
for (FeatureList::const_iterator it = features_.begin() + 1;
it != features_.end();
++it) {
DCHECK(first_is_internal == (*it)->IsInternal())
<< "Complex feature must have consistent values of "
"internal across all sub features.";
DCHECK(no_parent_ == (*it)->no_parent())
<< "Complex feature must have consistent values of "
"no_parent across all sub features.";
}
#endif
}
ComplexFeature::~ComplexFeature() = default;
Feature::Availability ComplexFeature::IsAvailableToManifest(
const HashedExtensionId& hashed_id,
Manifest::Type type,
mojom::ManifestLocation location,
int manifest_version,
Platform platform,
int context_id) const {
Feature::Availability first_availability =
features_[0]->IsAvailableToManifest(
hashed_id, type, location, manifest_version, platform, context_id);
if (first_availability.is_available())
return first_availability;
for (auto it = features_.cbegin() + 1; it != features_.cend(); ++it) {
Availability availability = (*it)->IsAvailableToManifest(
hashed_id, type, location, manifest_version, platform, context_id);
if (availability.is_available())
return availability;
}
// If none of the SimpleFeatures are available, we return the availability
// info of the first SimpleFeature that was not available.
return first_availability;
}
Feature::Availability ComplexFeature::IsAvailableToContextImpl(
const Extension* extension,
mojom::ContextType context,
const GURL& url,
Platform platform,
int context_id,
bool check_developer_mode,
const ContextData& context_data) const {
Feature::Availability first_availability =
features_[0]->IsAvailableToContextImpl(extension, context, url, platform,
context_id, check_developer_mode,
context_data);
if (first_availability.is_available())
return first_availability;
for (auto it = features_.cbegin() + 1; it != features_.cend(); ++it) {
Availability availability = (*it)->IsAvailableToContextImpl(
extension, context, url, platform, context_id, check_developer_mode,
context_data);
if (availability.is_available())
return availability;
}
// If none of the SimpleFeatures are available, we return the availability
// info of the first SimpleFeature that was not available.
return first_availability;
}
Feature::Availability ComplexFeature::IsAvailableToEnvironment(
int context_id) const {
Feature::Availability first_availability =
features_[0]->IsAvailableToEnvironment(context_id);
if (first_availability.is_available())
return first_availability;
for (auto iter = features_.cbegin() + 1; iter != features_.cend(); ++iter) {
Availability availability = (*iter)->IsAvailableToEnvironment(context_id);
if (availability.is_available())
return availability;
}
// If none of the SimpleFeatures are available, we return the availability
// info of the first SimpleFeature that was not available.
return first_availability;
}
bool ComplexFeature::IsIdInBlocklist(const HashedExtensionId& hashed_id) const {
for (auto it = features_.cbegin(); it != features_.cend(); ++it) {
if ((*it)->IsIdInBlocklist(hashed_id))
return true;
}
return false;
}
bool ComplexFeature::IsIdInAllowlist(const HashedExtensionId& hashed_id) const {
for (auto it = features_.cbegin(); it != features_.cend(); ++it) {
if ((*it)->IsIdInAllowlist(hashed_id))
return true;
}
return false;
}
bool ComplexFeature::IsInternal() const {
// Constructor verifies that composed features are consistent, thus we can
// return just the first feature's value.
return features_[0]->IsInternal();
}
bool ComplexFeature::RequiresDelegatedAvailabilityCheck() const {
return requires_delegated_availability_check_;
}
void ComplexFeature::SetDelegatedAvailabilityCheckHandler(
DelegatedAvailabilityCheckHandler handler) {
DCHECK(RequiresDelegatedAvailabilityCheck());
DCHECK(!HasDelegatedAvailabilityCheckHandler());
// Set the given handler on all of the sub-feature that need a delegated
// availability check handler and set
// |has_delegated_availability_check_handler_| to true.
for (auto& feature : features_) {
if (feature->RequiresDelegatedAvailabilityCheck()) {
feature->SetDelegatedAvailabilityCheckHandler(handler);
}
}
has_delegated_availability_check_handler_ = true;
}
bool ComplexFeature::HasDelegatedAvailabilityCheckHandler() const {
return has_delegated_availability_check_handler_;
}
} // namespace extensions
|