OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/common/features/base_feature_provider.h" | 5 #include "extensions/common/features/base_feature_provider.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 | 8 |
9 #include "base/json/json_reader.h" | |
10 #include "base/lazy_instance.h" | |
11 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
13 #include "extensions/common/extensions_client.h" | 11 #include "extensions/common/extensions_client.h" |
14 #include "extensions/common/features/api_feature.h" | |
15 #include "extensions/common/features/complex_feature.h" | 12 #include "extensions/common/features/complex_feature.h" |
16 #include "extensions/common/features/manifest_feature.h" | 13 #include "extensions/common/features/simple_feature.h" |
17 #include "extensions/common/features/permission_feature.h" | |
18 #include "grit/common_resources.h" | |
19 #include "ui/base/resource/resource_bundle.h" | |
20 | 14 |
21 namespace extensions { | 15 namespace extensions { |
22 | 16 |
23 namespace { | 17 namespace { |
24 | 18 |
25 template<class FeatureClass> | |
26 SimpleFeature* CreateFeature() { | |
27 SimpleFeature* feature = new FeatureClass(); | |
28 ExtensionsClient::Get()->AddExtraFeatureFilters(feature); | |
29 return feature; | |
30 } | |
31 | |
32 static BaseFeatureProvider* LoadProvider( | |
33 const std::string& name, | |
34 BaseFeatureProvider::FeatureFactory factory, | |
35 int resource_id) { | |
36 const std::string& features_file = | |
37 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
38 resource_id).as_string(); | |
39 int error_code = 0; | |
40 std::string error_message; | |
41 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | |
42 features_file, base::JSON_PARSE_RFC, | |
43 &error_code, &error_message)); | |
44 DCHECK(value) << "Could not load features: " << name << " " | |
45 << error_message; | |
46 scoped_ptr<base::DictionaryValue> value_as_dict; | |
47 if (value) { | |
48 CHECK(value->IsType(base::Value::TYPE_DICTIONARY)) << name; | |
49 value_as_dict.reset(static_cast<base::DictionaryValue*>(value.release())); | |
50 } else { | |
51 // http://crbug.com/176381 | |
52 value_as_dict.reset(new base::DictionaryValue()); | |
53 } | |
54 return new BaseFeatureProvider(*value_as_dict, factory); | |
55 } | |
56 | |
57 struct Static { | |
58 Static() { | |
59 feature_providers["api"] = make_linked_ptr( | |
60 LoadProvider("api", | |
61 &CreateFeature<APIFeature>, | |
62 IDR_EXTENSION_API_FEATURES)); | |
63 feature_providers["permission"] = make_linked_ptr( | |
64 LoadProvider("permission", | |
65 &CreateFeature<PermissionFeature>, | |
66 IDR_EXTENSION_PERMISSION_FEATURES)); | |
67 feature_providers["manifest"] = make_linked_ptr( | |
68 LoadProvider("manifest", | |
69 &CreateFeature<ManifestFeature>, | |
70 IDR_EXTENSION_MANIFEST_FEATURES)); | |
71 } | |
72 | |
73 typedef std::map<std::string, linked_ptr<FeatureProvider> > | |
74 FeatureProviderMap; | |
75 | |
76 FeatureProvider* GetFeatures(const std::string& name) const { | |
77 FeatureProviderMap::const_iterator it = feature_providers.find(name); | |
78 CHECK(it != feature_providers.end()); | |
79 return it->second.get(); | |
80 } | |
81 | |
82 FeatureProviderMap feature_providers; | |
83 }; | |
84 | |
85 base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER; | |
86 | |
87 bool ParseFeature(const base::DictionaryValue* value, | 19 bool ParseFeature(const base::DictionaryValue* value, |
88 const std::string& name, | 20 const std::string& name, |
89 SimpleFeature* feature) { | 21 SimpleFeature* feature) { |
90 feature->set_name(name); | 22 feature->set_name(name); |
91 std::string error = feature->Parse(value); | 23 std::string error = feature->Parse(value); |
92 if (!error.empty()) | 24 if (!error.empty()) |
93 LOG(ERROR) << error; | 25 LOG(ERROR) << error; |
94 return error.empty(); | 26 return error.empty(); |
95 } | 27 } |
96 | 28 |
97 } // namespace | 29 } // namespace |
98 | 30 |
99 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root, | 31 BaseFeatureProvider::BaseFeatureProvider(const base::DictionaryValue& root, |
100 FeatureFactory factory) | 32 FeatureFactory factory) |
101 : factory_(factory ? factory : | 33 : factory_(factory) { |
102 static_cast<FeatureFactory>(&CreateFeature<SimpleFeature>)) { | |
103 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); | 34 for (base::DictionaryValue::Iterator iter(root); !iter.IsAtEnd(); |
104 iter.Advance()) { | 35 iter.Advance()) { |
105 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) { | 36 if (iter.value().GetType() == base::Value::TYPE_DICTIONARY) { |
106 linked_ptr<SimpleFeature> feature((*factory_)()); | 37 linked_ptr<SimpleFeature> feature((*factory_)()); |
107 | 38 |
108 std::vector<std::string> split; | 39 std::vector<std::string> split; |
109 base::SplitString(iter.key(), '.', &split); | 40 base::SplitString(iter.key(), '.', &split); |
110 | 41 |
111 // Push parent features on the stack, starting with the current feature. | 42 // Push parent features on the stack, starting with the current feature. |
112 // If one of the features has "noparent" set, stop pushing features on | 43 // If one of the features has "noparent" set, stop pushing features on |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 } else { | 109 } else { |
179 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" | 110 LOG(ERROR) << iter.key() << ": Feature description must be dictionary or" |
180 << " list of dictionaries."; | 111 << " list of dictionaries."; |
181 } | 112 } |
182 } | 113 } |
183 } | 114 } |
184 | 115 |
185 BaseFeatureProvider::~BaseFeatureProvider() { | 116 BaseFeatureProvider::~BaseFeatureProvider() { |
186 } | 117 } |
187 | 118 |
188 // static | |
189 FeatureProvider* BaseFeatureProvider::GetByName( | |
190 const std::string& name) { | |
191 return g_static.Get().GetFeatures(name); | |
192 } | |
193 | |
194 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() | 119 const std::vector<std::string>& BaseFeatureProvider::GetAllFeatureNames() |
195 const { | 120 const { |
196 if (feature_names_.empty()) { | 121 if (feature_names_.empty()) { |
197 for (FeatureMap::const_iterator iter = features_.begin(); | 122 for (FeatureMap::const_iterator iter = features_.begin(); |
198 iter != features_.end(); ++iter) { | 123 iter != features_.end(); ++iter) { |
199 feature_names_.push_back(iter->first); | 124 feature_names_.push_back(iter->first); |
200 } | 125 } |
201 // A std::map is sorted by its keys, so we don't need to sort feature_names_ | 126 // A std::map is sorted by its keys, so we don't need to sort feature_names_ |
202 // now. | 127 // now. |
203 } | 128 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 std::vector<Feature*> result; | 165 std::vector<Feature*> result; |
241 result.reserve(std::distance(first_child, after_children)); | 166 result.reserve(std::distance(first_child, after_children)); |
242 for (FeatureMap::const_iterator it = first_child; it != after_children; | 167 for (FeatureMap::const_iterator it = first_child; it != after_children; |
243 ++it) { | 168 ++it) { |
244 result.push_back(it->second.get()); | 169 result.push_back(it->second.get()); |
245 } | 170 } |
246 return result; | 171 return result; |
247 } | 172 } |
248 | 173 |
249 } // namespace extensions | 174 } // namespace extensions |
OLD | NEW |