| 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 |