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/simple_feature.h" | 5 #include "extensions/common/features/simple_feature.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 return "dev"; | 119 return "dev"; |
120 case version_info::Channel::BETA: | 120 case version_info::Channel::BETA: |
121 return "beta"; | 121 return "beta"; |
122 case version_info::Channel::STABLE: | 122 case version_info::Channel::STABLE: |
123 return "stable"; | 123 return "stable"; |
124 } | 124 } |
125 NOTREACHED(); | 125 NOTREACHED(); |
126 return ""; | 126 return ""; |
127 } | 127 } |
128 | 128 |
| 129 std::string GetDisplayName(FeatureSessionType session_type) { |
| 130 switch (session_type) { |
| 131 case FeatureSessionType::INITIAL: |
| 132 return "user-less"; |
| 133 case FeatureSessionType::UNKNOWN: |
| 134 return "unknown"; |
| 135 case FeatureSessionType::KIOSK: |
| 136 return "kiosk app"; |
| 137 case FeatureSessionType::REGULAR: |
| 138 return "regular user"; |
| 139 } |
| 140 return ""; |
| 141 } |
| 142 |
129 // Gets a human-readable list of the display names (pluralized, comma separated | 143 // Gets a human-readable list of the display names (pluralized, comma separated |
130 // with the "and" in the correct place) for each of |enum_types|. | 144 // with the "and" in the correct place) for each of |enum_types|. |
131 template <typename EnumType> | 145 template <typename EnumType> |
132 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { | 146 std::string ListDisplayNames(const std::vector<EnumType>& enum_types) { |
133 std::string display_name_list; | 147 std::string display_name_list; |
134 for (size_t i = 0; i < enum_types.size(); ++i) { | 148 for (size_t i = 0; i < enum_types.size(); ++i) { |
135 // Pluralize type name. | 149 // Pluralize type name. |
136 display_name_list += GetDisplayName(enum_types[i]) + "s"; | 150 display_name_list += GetDisplayName(enum_types[i]) + "s"; |
137 // Comma-separate entries, with an Oxford comma if there is more than 2 | 151 // Comma-separate entries, with an Oxford comma if there is more than 2 |
138 // total entries. | 152 // total entries. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); | 252 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); |
239 | 253 |
240 if (!command_line_switch_.empty() && | 254 if (!command_line_switch_.empty() && |
241 !IsCommandLineSwitchEnabled(command_line_switch_)) { | 255 !IsCommandLineSwitchEnabled(command_line_switch_)) { |
242 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); | 256 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); |
243 } | 257 } |
244 | 258 |
245 if (channel_ && *channel_ < GetCurrentChannel()) | 259 if (channel_ && *channel_ < GetCurrentChannel()) |
246 return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_); | 260 return CreateAvailability(UNSUPPORTED_CHANNEL, *channel_); |
247 | 261 |
| 262 FeatureSessionType session = GetCurrentFeatureSessionType(); |
| 263 if (!session_types_.empty() && |
| 264 !base::ContainsValue(session_types_, session)) { |
| 265 return CreateAvailability(INVALID_SESSION_TYPE, session); |
| 266 } |
| 267 |
248 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, | 268 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, |
249 extension_id, | 269 extension_id, |
250 type, | 270 type, |
251 location, | 271 location, |
252 manifest_version, | 272 manifest_version, |
253 platform)); | 273 platform)); |
254 } | 274 } |
255 | 275 |
256 Feature::Availability SimpleFeature::IsAvailableToContext( | 276 Feature::Availability SimpleFeature::IsAvailableToContext( |
257 const Extension* extension, | 277 const Extension* extension, |
258 SimpleFeature::Context context, | 278 Feature::Context context, |
259 const GURL& url, | 279 const GURL& url, |
260 SimpleFeature::Platform platform) const { | 280 SimpleFeature::Platform platform) const { |
261 if (extension) { | 281 if (extension) { |
262 Availability result = IsAvailableToManifest(extension->id(), | 282 Availability result = IsAvailableToManifest(extension->id(), |
263 extension->GetType(), | 283 extension->GetType(), |
264 extension->location(), | 284 extension->location(), |
265 extension->manifest_version(), | 285 extension->manifest_version(), |
266 platform); | 286 platform); |
267 if (!result.is_available()) | 287 if (!result.is_available()) |
268 return result; | 288 return result; |
269 } | 289 } |
270 | 290 |
271 // TODO(lazyboy): This isn't quite right for Extension Service Worker | 291 // TODO(lazyboy): This isn't quite right for Extension Service Worker |
272 // extension API calls, since there's no guarantee that the extension is | 292 // extension API calls, since there's no guarantee that the extension is |
273 // "active" in current renderer process when the API permission check is | 293 // "active" in current renderer process when the API permission check is |
274 // done. | 294 // done. |
275 if (!contexts_.empty() && !base::ContainsValue(contexts_, context)) | 295 if (!contexts_.empty() && !base::ContainsValue(contexts_, context)) |
276 return CreateAvailability(INVALID_CONTEXT, context); | 296 return CreateAvailability(INVALID_CONTEXT, context); |
277 | 297 |
278 // TODO(kalman): Consider checking |matches_| regardless of context type. | 298 // TODO(kalman): Consider checking |matches_| regardless of context type. |
279 // Fewer surprises, and if the feature configuration wants to isolate | 299 // Fewer surprises, and if the feature configuration wants to isolate |
280 // "matches" from say "blessed_extension" then they can use complex features. | 300 // "matches" from say "blessed_extension" then they can use complex features. |
281 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && | 301 if ((context == WEB_PAGE_CONTEXT || context == WEBUI_CONTEXT) && |
282 !matches_.MatchesURL(url)) { | 302 !matches_.MatchesURL(url)) { |
283 return CreateAvailability(INVALID_URL, url); | 303 return CreateAvailability(INVALID_URL, url); |
284 } | 304 } |
285 | 305 |
| 306 FeatureSessionType session = GetCurrentFeatureSessionType(); |
| 307 if (!session_types_.empty() && |
| 308 !base::ContainsValue(session_types_, session)) { |
| 309 return CreateAvailability(INVALID_SESSION_TYPE, session); |
| 310 } |
| 311 |
286 // TODO(kalman): Assert that if the context was a webpage or WebUI context | 312 // TODO(kalman): Assert that if the context was a webpage or WebUI context |
287 // then at some point a "matches" restriction was checked. | 313 // then at some point a "matches" restriction was checked. |
288 return CheckDependencies(base::Bind( | 314 return CheckDependencies(base::Bind(&IsAvailableToContextForBind, extension, |
289 &IsAvailableToContextForBind, extension, context, url, platform)); | 315 context, url, platform)); |
290 } | 316 } |
291 | 317 |
292 std::string SimpleFeature::GetAvailabilityMessage( | 318 std::string SimpleFeature::GetAvailabilityMessage( |
293 AvailabilityResult result, | 319 AvailabilityResult result, |
294 Manifest::Type type, | 320 Manifest::Type type, |
295 const GURL& url, | 321 const GURL& url, |
296 Context context, | 322 Context context, |
297 version_info::Channel channel) const { | 323 version_info::Channel channel, |
| 324 FeatureSessionType session_type) const { |
298 switch (result) { | 325 switch (result) { |
299 case IS_AVAILABLE: | 326 case IS_AVAILABLE: |
300 return std::string(); | 327 return std::string(); |
301 case NOT_FOUND_IN_WHITELIST: | 328 case NOT_FOUND_IN_WHITELIST: |
302 case FOUND_IN_BLACKLIST: | 329 case FOUND_IN_BLACKLIST: |
303 return base::StringPrintf( | 330 return base::StringPrintf( |
304 "'%s' is not allowed for specified extension ID.", | 331 "'%s' is not allowed for specified extension ID.", |
305 name().c_str()); | 332 name().c_str()); |
306 case INVALID_URL: | 333 case INVALID_URL: |
307 return base::StringPrintf("'%s' is not allowed on %s.", | 334 return base::StringPrintf("'%s' is not allowed on %s.", |
(...skipping 23 matching lines...) Expand all Loading... |
331 case INVALID_MIN_MANIFEST_VERSION: | 358 case INVALID_MIN_MANIFEST_VERSION: |
332 return base::StringPrintf( | 359 return base::StringPrintf( |
333 "'%s' requires manifest version of at least %d.", | 360 "'%s' requires manifest version of at least %d.", |
334 name().c_str(), | 361 name().c_str(), |
335 min_manifest_version_); | 362 min_manifest_version_); |
336 case INVALID_MAX_MANIFEST_VERSION: | 363 case INVALID_MAX_MANIFEST_VERSION: |
337 return base::StringPrintf( | 364 return base::StringPrintf( |
338 "'%s' requires manifest version of %d or lower.", | 365 "'%s' requires manifest version of %d or lower.", |
339 name().c_str(), | 366 name().c_str(), |
340 max_manifest_version_); | 367 max_manifest_version_); |
| 368 case INVALID_SESSION_TYPE: |
| 369 return base::StringPrintf( |
| 370 "'%s' is only allowed to run in %s sessions, but this is %s session.", |
| 371 name().c_str(), |
| 372 ListDisplayNames(std::vector<FeatureSessionType>( |
| 373 session_types_.begin(), session_types_.end())) |
| 374 .c_str(), |
| 375 GetDisplayName(session_type).c_str()); |
341 case NOT_PRESENT: | 376 case NOT_PRESENT: |
342 return base::StringPrintf( | 377 return base::StringPrintf( |
343 "'%s' requires a different Feature that is not present.", | 378 "'%s' requires a different Feature that is not present.", |
344 name().c_str()); | 379 name().c_str()); |
345 case UNSUPPORTED_CHANNEL: | 380 case UNSUPPORTED_CHANNEL: |
346 return base::StringPrintf( | 381 return base::StringPrintf( |
347 "'%s' requires %s channel or newer, but this is the %s channel.", | 382 "'%s' requires %s channel or newer, but this is the %s channel.", |
348 name().c_str(), GetDisplayName(channel).c_str(), | 383 name().c_str(), GetDisplayName(channel).c_str(), |
349 GetDisplayName(GetCurrentChannel()).c_str()); | 384 GetDisplayName(GetCurrentChannel()).c_str()); |
350 case MISSING_COMMAND_LINE_SWITCH: | 385 case MISSING_COMMAND_LINE_SWITCH: |
351 return base::StringPrintf( | 386 return base::StringPrintf( |
352 "'%s' requires the '%s' command line switch to be enabled.", | 387 "'%s' requires the '%s' command line switch to be enabled.", |
353 name().c_str(), command_line_switch_.c_str()); | 388 name().c_str(), command_line_switch_.c_str()); |
354 } | 389 } |
355 | 390 |
356 NOTREACHED(); | 391 NOTREACHED(); |
357 return std::string(); | 392 return std::string(); |
358 } | 393 } |
359 | 394 |
360 Feature::Availability SimpleFeature::CreateAvailability( | 395 Feature::Availability SimpleFeature::CreateAvailability( |
361 AvailabilityResult result) const { | 396 AvailabilityResult result) const { |
362 return Availability( | 397 return Availability( |
363 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 398 result, GetAvailabilityMessage( |
364 UNSPECIFIED_CONTEXT, | 399 result, Manifest::TYPE_UNKNOWN, GURL(), UNSPECIFIED_CONTEXT, |
365 version_info::Channel::UNKNOWN)); | 400 version_info::Channel::UNKNOWN, FeatureSessionType::UNKNOWN)); |
366 } | 401 } |
367 | 402 |
368 Feature::Availability SimpleFeature::CreateAvailability( | 403 Feature::Availability SimpleFeature::CreateAvailability( |
369 AvailabilityResult result, Manifest::Type type) const { | 404 AvailabilityResult result, Manifest::Type type) const { |
370 return Availability( | 405 return Availability( |
371 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, | 406 result, GetAvailabilityMessage(result, type, GURL(), UNSPECIFIED_CONTEXT, |
372 version_info::Channel::UNKNOWN)); | 407 version_info::Channel::UNKNOWN, |
| 408 FeatureSessionType::UNKNOWN)); |
373 } | 409 } |
374 | 410 |
375 Feature::Availability SimpleFeature::CreateAvailability( | 411 Feature::Availability SimpleFeature::CreateAvailability( |
376 AvailabilityResult result, | 412 AvailabilityResult result, |
377 const GURL& url) const { | 413 const GURL& url) const { |
378 return Availability( | 414 return Availability( |
379 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, url, | 415 result, GetAvailabilityMessage( |
380 UNSPECIFIED_CONTEXT, | 416 result, Manifest::TYPE_UNKNOWN, url, UNSPECIFIED_CONTEXT, |
381 version_info::Channel::UNKNOWN)); | 417 version_info::Channel::UNKNOWN, FeatureSessionType::UNKNOWN)); |
382 } | 418 } |
383 | 419 |
384 Feature::Availability SimpleFeature::CreateAvailability( | 420 Feature::Availability SimpleFeature::CreateAvailability( |
385 AvailabilityResult result, | 421 AvailabilityResult result, |
386 Context context) const { | 422 Context context) const { |
387 return Availability( | 423 return Availability( |
388 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 424 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
389 context, version_info::Channel::UNKNOWN)); | 425 context, version_info::Channel::UNKNOWN, |
| 426 FeatureSessionType::UNKNOWN)); |
390 } | 427 } |
391 | 428 |
392 Feature::Availability SimpleFeature::CreateAvailability( | 429 Feature::Availability SimpleFeature::CreateAvailability( |
393 AvailabilityResult result, | 430 AvailabilityResult result, |
394 version_info::Channel channel) const { | 431 version_info::Channel channel) const { |
395 return Availability( | 432 return Availability( |
396 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), | 433 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), |
397 UNSPECIFIED_CONTEXT, channel)); | 434 UNSPECIFIED_CONTEXT, channel, |
| 435 FeatureSessionType::UNKNOWN)); |
| 436 } |
| 437 |
| 438 Feature::Availability SimpleFeature::CreateAvailability( |
| 439 AvailabilityResult result, |
| 440 FeatureSessionType session_type) const { |
| 441 return Availability( |
| 442 result, GetAvailabilityMessage( |
| 443 result, Manifest::TYPE_UNKNOWN, GURL(), UNSPECIFIED_CONTEXT, |
| 444 version_info::Channel::UNKNOWN, session_type)); |
398 } | 445 } |
399 | 446 |
400 bool SimpleFeature::IsInternal() const { | 447 bool SimpleFeature::IsInternal() const { |
401 return is_internal_; | 448 return is_internal_; |
402 } | 449 } |
403 | 450 |
404 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { | 451 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { |
405 return IsIdInList(extension_id, blacklist_); | 452 return IsIdInList(extension_id, blacklist_); |
406 } | 453 } |
407 | 454 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 void SimpleFeature::set_dependencies( | 538 void SimpleFeature::set_dependencies( |
492 std::initializer_list<const char* const> dependencies) { | 539 std::initializer_list<const char* const> dependencies) { |
493 dependencies_.assign(dependencies.begin(), dependencies.end()); | 540 dependencies_.assign(dependencies.begin(), dependencies.end()); |
494 } | 541 } |
495 | 542 |
496 void SimpleFeature::set_extension_types( | 543 void SimpleFeature::set_extension_types( |
497 std::initializer_list<Manifest::Type> types) { | 544 std::initializer_list<Manifest::Type> types) { |
498 extension_types_ = types; | 545 extension_types_ = types; |
499 } | 546 } |
500 | 547 |
| 548 void SimpleFeature::set_session_types( |
| 549 std::initializer_list<FeatureSessionType> types) { |
| 550 session_types_ = types; |
| 551 } |
| 552 |
501 void SimpleFeature::set_matches( | 553 void SimpleFeature::set_matches( |
502 std::initializer_list<const char* const> matches) { | 554 std::initializer_list<const char* const> matches) { |
503 matches_.ClearPatterns(); | 555 matches_.ClearPatterns(); |
504 for (const auto* pattern : matches) | 556 for (const auto* pattern : matches) |
505 matches_.AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); | 557 matches_.AddPattern(URLPattern(URLPattern::SCHEME_ALL, pattern)); |
506 } | 558 } |
507 | 559 |
508 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) { | 560 void SimpleFeature::set_platforms(std::initializer_list<Platform> platforms) { |
509 platforms_ = platforms; | 561 platforms_ = platforms; |
510 } | 562 } |
511 | 563 |
512 void SimpleFeature::set_whitelist( | 564 void SimpleFeature::set_whitelist( |
513 std::initializer_list<const char* const> whitelist) { | 565 std::initializer_list<const char* const> whitelist) { |
514 whitelist_.assign(whitelist.begin(), whitelist.end()); | 566 whitelist_.assign(whitelist.begin(), whitelist.end()); |
515 } | 567 } |
516 | 568 |
517 } // namespace extensions | 569 } // namespace extensions |
OLD | NEW |