Ignore non-active fullscreen windows for shelf state.
[chromium-blink-merge.git] / extensions / common / manifest_handlers / shared_module_info.cc
blob09df879b739cc64a723d7cc6a2ccb0b338558d04
1 // Copyright 2013 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.
5 #include "extensions/common/manifest_handlers/shared_module_info.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/version.h"
13 #include "extensions/common/constants.h"
14 #include "extensions/common/error_utils.h"
15 #include "extensions/common/manifest_constants.h"
16 #include "extensions/common/permissions/permission_set.h"
18 namespace extensions {
20 namespace keys = manifest_keys;
21 namespace values = manifest_values;
22 namespace errors = manifest_errors;
24 namespace {
26 const char kSharedModule[] = "shared_module";
28 static base::LazyInstance<SharedModuleInfo> g_empty_shared_module_info =
29 LAZY_INSTANCE_INITIALIZER;
31 const SharedModuleInfo& GetSharedModuleInfo(const Extension* extension) {
32 SharedModuleInfo* info = static_cast<SharedModuleInfo*>(
33 extension->GetManifestData(kSharedModule));
34 if (!info)
35 return g_empty_shared_module_info.Get();
36 return *info;
39 } // namespace
41 SharedModuleInfo::SharedModuleInfo() {
44 SharedModuleInfo::~SharedModuleInfo() {
47 // static
48 void SharedModuleInfo::ParseImportedPath(const std::string& path,
49 std::string* import_id,
50 std::string* import_relative_path) {
51 std::vector<std::string> tokens;
52 Tokenize(path, std::string("/"), &tokens);
53 if (tokens.size() > 2 && tokens[0] == kModulesDir &&
54 Extension::IdIsValid(tokens[1])) {
55 *import_id = tokens[1];
56 *import_relative_path = tokens[2];
57 for (size_t i = 3; i < tokens.size(); ++i)
58 *import_relative_path += "/" + tokens[i];
62 // static
63 bool SharedModuleInfo::IsImportedPath(const std::string& path) {
64 std::vector<std::string> tokens;
65 Tokenize(path, std::string("/"), &tokens);
66 if (tokens.size() > 2 && tokens[0] == kModulesDir &&
67 Extension::IdIsValid(tokens[1])) {
68 return true;
70 return false;
73 // static
74 bool SharedModuleInfo::IsSharedModule(const Extension* extension) {
75 CHECK(extension);
76 return extension->manifest()->is_shared_module();
79 // static
80 bool SharedModuleInfo::IsExportAllowed(const Extension* extension,
81 const std::string& relative_path) {
82 return GetSharedModuleInfo(extension).
83 exported_set_.MatchesURL(extension->url().Resolve(relative_path));
86 // static
87 bool SharedModuleInfo::ImportsExtensionById(const Extension* extension,
88 const std::string& other_id) {
89 const SharedModuleInfo& info = GetSharedModuleInfo(extension);
90 for (size_t i = 0; i < info.imports_.size(); i++) {
91 if (info.imports_[i].extension_id == other_id)
92 return true;
94 return false;
97 // static
98 bool SharedModuleInfo::ImportsModules(const Extension* extension) {
99 return GetSharedModuleInfo(extension).imports_.size() > 0;
102 // static
103 const std::vector<SharedModuleInfo::ImportInfo>& SharedModuleInfo::GetImports(
104 const Extension* extension) {
105 return GetSharedModuleInfo(extension).imports_;
108 bool SharedModuleInfo::Parse(const Extension* extension, string16* error) {
109 bool has_import = extension->manifest()->HasKey(keys::kImport);
110 bool has_export = extension->manifest()->HasKey(keys::kExport);
111 if (!has_import && !has_export)
112 return true;
114 if (has_import && has_export) {
115 *error = ASCIIToUTF16(errors::kInvalidImportAndExport);
116 return false;
119 if (has_export) {
120 const base::DictionaryValue* export_value = NULL;
121 if (!extension->manifest()->GetDictionary(keys::kExport, &export_value)) {
122 *error = ASCIIToUTF16(errors::kInvalidExport);
123 return false;
125 const base::ListValue* resources_list = NULL;
126 if (!export_value->GetList(keys::kResources, &resources_list)) {
127 *error = ASCIIToUTF16(errors::kInvalidExportResources);
128 return false;
130 for (size_t i = 0; i < resources_list->GetSize(); ++i) {
131 std::string resource_path;
132 if (!resources_list->GetString(i, &resource_path)) {
133 *error = ErrorUtils::FormatErrorMessageUTF16(
134 errors::kInvalidExportResourcesString, base::IntToString(i));
135 return false;
137 const GURL& resolved_path = extension->url().Resolve(resource_path);
138 if (!resolved_path.is_valid()) {
139 *error = ErrorUtils::FormatErrorMessageUTF16(
140 errors::kInvalidExportResourcesString, base::IntToString(i));
141 return false;
143 exported_set_.AddPattern(
144 URLPattern(URLPattern::SCHEME_EXTENSION, resolved_path.spec()));
148 if (has_import) {
149 const base::ListValue* import_list = NULL;
150 if (!extension->manifest()->GetList(keys::kImport, &import_list)) {
151 *error = ASCIIToUTF16(errors::kInvalidImport);
152 return false;
154 for (size_t i = 0; i < import_list->GetSize(); ++i) {
155 const base::DictionaryValue* import_entry = NULL;
156 if (!import_list->GetDictionary(i, &import_entry)) {
157 *error = ASCIIToUTF16(errors::kInvalidImport);
158 return false;
160 std::string extension_id;
161 imports_.push_back(ImportInfo());
162 if (!import_entry->GetString(keys::kId, &extension_id) ||
163 !Extension::IdIsValid(extension_id)) {
164 *error = ErrorUtils::FormatErrorMessageUTF16(
165 errors::kInvalidImportId, base::IntToString(i));
166 return false;
168 imports_.back().extension_id = extension_id;
169 if (import_entry->HasKey(keys::kMinimumVersion)) {
170 std::string min_version;
171 if (!import_entry->GetString(keys::kMinimumVersion, &min_version)) {
172 *error = ErrorUtils::FormatErrorMessageUTF16(
173 errors::kInvalidImportVersion, base::IntToString(i));
174 return false;
176 imports_.back().minimum_version = min_version;
177 Version v(min_version);
178 if (!v.IsValid()) {
179 *error = ErrorUtils::FormatErrorMessageUTF16(
180 errors::kInvalidImportVersion, base::IntToString(i));
181 return false;
186 return true;
190 SharedModuleHandler::SharedModuleHandler() {
193 SharedModuleHandler::~SharedModuleHandler() {
196 bool SharedModuleHandler::Parse(Extension* extension, string16* error) {
197 scoped_ptr<SharedModuleInfo> info(new SharedModuleInfo);
198 if (!info->Parse(extension, error))
199 return false;
200 extension->SetManifestData(kSharedModule, info.release());
201 return true;
204 bool SharedModuleHandler::Validate(
205 const Extension* extension,
206 std::string* error,
207 std::vector<InstallWarning>* warnings) const {
208 // Extensions that export resources should not have any permissions of their
209 // own, instead they rely on the permissions of the extensions which import
210 // them.
211 if (SharedModuleInfo::IsSharedModule(extension) &&
212 !extension->GetActivePermissions()->IsEmpty()) {
213 *error = errors::kInvalidExportPermissions;
214 return false;
216 return true;
219 const std::vector<std::string> SharedModuleHandler::Keys() const {
220 static const char* keys[] = {
221 keys::kExport,
222 keys::kImport
224 return std::vector<std::string>(keys, keys + arraysize(keys));
227 } // namespace extensions