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