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
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/common/extensions/simple_feature_provider.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "chrome/common/extensions/manifest_feature.h"
#include "chrome/common/extensions/permission_feature.h"
#include "grit/common_resources.h"
#include "ui/base/resource/resource_bundle.h"
namespace extensions {
namespace {
template<class FeatureClass>
Feature* CreateFeature() {
return new FeatureClass();
}
struct Static {
Static()
: manifest_features(
LoadProvider("manifest",
&CreateFeature<ManifestFeature>,
IDR_EXTENSION_MANIFEST_FEATURES)),
permission_features(
LoadProvider("permissions",
&CreateFeature<PermissionFeature>,
IDR_EXTENSION_PERMISSION_FEATURES)) {
}
scoped_ptr<SimpleFeatureProvider> manifest_features;
scoped_ptr<SimpleFeatureProvider> permission_features;
private:
scoped_ptr<SimpleFeatureProvider> LoadProvider(
const std::string& debug_string,
SimpleFeatureProvider::FeatureFactory factory,
int resource_id) {
std::string manifest_features =
ResourceBundle::GetSharedInstance().GetRawDataResource(
resource_id).as_string();
int error_code = 0;
std::string error_message;
Value* value = base::JSONReader::ReadAndReturnError(
manifest_features, base::JSON_PARSE_RFC,
&error_code, &error_message);
CHECK(value) << "Could not load features: " << debug_string << " "
<< error_message;
CHECK(value->IsType(Value::TYPE_DICTIONARY)) << debug_string;
scoped_ptr<DictionaryValue> dictionary_value(
static_cast<DictionaryValue*>(value));
return scoped_ptr<SimpleFeatureProvider>(
new SimpleFeatureProvider(dictionary_value.get(), factory));
}
};
base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER;
} // namespace
SimpleFeatureProvider::SimpleFeatureProvider(DictionaryValue* root,
FeatureFactory factory)
: factory_(factory ? factory :
static_cast<FeatureFactory>(&CreateFeature<Feature>)) {
for (DictionaryValue::Iterator iter(*root); iter.HasNext(); iter.Advance()) {
if (iter.value().GetType() != Value::TYPE_DICTIONARY) {
LOG(ERROR) << iter.key() << ": Feature description must be dictionary.";
continue;
}
linked_ptr<Feature> feature((*factory_)());
feature->set_name(iter.key());
feature->Parse(static_cast<const DictionaryValue*>(&iter.value()));
if (feature->extension_types()->empty()) {
LOG(ERROR) << iter.key() << ": Simple features must specify atleast one "
<< "value for extension_types.";
continue;
}
if (!feature->contexts()->empty()) {
LOG(ERROR) << iter.key() << ": Simple features do not support contexts.";
continue;
}
features_[iter.key()] = feature;
}
}
SimpleFeatureProvider::~SimpleFeatureProvider() {
}
// static
SimpleFeatureProvider* SimpleFeatureProvider::GetManifestFeatures() {
return g_static.Get().manifest_features.get();
}
// static
SimpleFeatureProvider* SimpleFeatureProvider::GetPermissionFeatures() {
return g_static.Get().permission_features.get();
}
std::set<std::string> SimpleFeatureProvider::GetAllFeatureNames() const {
std::set<std::string> result;
for (FeatureMap::const_iterator iter = features_.begin();
iter != features_.end(); ++iter) {
result.insert(iter->first);
}
return result;
}
Feature* SimpleFeatureProvider::GetFeature(const std::string& name) {
FeatureMap::iterator iter = features_.find(name);
if (iter != features_.end())
return iter->second.get();
else
return NULL;
}
} // namespace
|