| Index: chrome/common/extensions/api/common_extension_api_unittest.cc
 | 
| diff --git a/chrome/common/extensions/api/common_extension_api_unittest.cc b/chrome/common/extensions/api/common_extension_api_unittest.cc
 | 
| index 9ee5f56ee40aa04468cc6811e4a75edcad594458..8b6146b4334d87d9cfdea93b25d99ca8adeeecea 100644
 | 
| --- a/chrome/common/extensions/api/common_extension_api_unittest.cc
 | 
| +++ b/chrome/common/extensions/api/common_extension_api_unittest.cc
 | 
| @@ -39,6 +39,8 @@ const char* const kTestFeatures[] = {
 | 
|      "test6", "test7", "parent1", "parent2", "parent3",
 | 
|  };
 | 
|  
 | 
| +const char* const kAliasTestApis[] = {"alias_api_source"};
 | 
| +
 | 
|  const char* const kSessionTypeTestFeatures[] = {
 | 
|      "test1", "kiosk_only", "non_kiosk", "multiple_session_types"};
 | 
|  
 | 
| @@ -203,10 +205,8 @@ TEST(ExtensionAPITest, APIFeatures) {
 | 
|  
 | 
|      bool expected = test_data[i].expect_is_available;
 | 
|      Feature::Availability availability =
 | 
| -        api.IsAvailable(test_data[i].api_full_name,
 | 
| -                        NULL,
 | 
| -                        test_data[i].context,
 | 
| -                        test_data[i].url);
 | 
| +        api.IsAvailable(test_data[i].api_full_name, NULL, test_data[i].context,
 | 
| +                        test_data[i].url, false);
 | 
|      EXPECT_EQ(expected, availability.is_available())
 | 
|          << base::StringPrintf("Test %d: Feature '%s' was %s: %s",
 | 
|                                static_cast<int>(i),
 | 
| @@ -216,6 +216,50 @@ TEST(ExtensionAPITest, APIFeatures) {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +TEST(ExtensionAPITest, APIFeaturesAlias) {
 | 
| +  UnittestFeatureProvider api_feature_provider;
 | 
| +
 | 
| +  TestExtensionAPI api;
 | 
| +  api.RegisterDependencyProvider("api", &api_feature_provider);
 | 
| +  for (const auto& key : kAliasTestApis)
 | 
| +    api.add_fake_schema(key);
 | 
| +  ExtensionAPI::OverrideSharedInstanceForTest scope(&api);
 | 
| +
 | 
| +  ASSERT_FALSE(api.IsAvailable("alias_api_source", NULL,
 | 
| +                               Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                               false /* allow_alias */)
 | 
| +                   .is_available());
 | 
| +  ASSERT_TRUE(api.IsAvailable("alias_api_source", NULL,
 | 
| +                              Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                              true /* allow_alias */)
 | 
| +                  .is_available());
 | 
| +  ASSERT_TRUE(api.IsAvailable("alias_api_source.bar", NULL,
 | 
| +                              Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                              true /* allow_alias */)
 | 
| +                  .is_available());
 | 
| +  ASSERT_FALSE(api.IsAvailable("alias_api_source.foo", NULL,
 | 
| +                               Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                               true /* allow_alias */)
 | 
| +                   .is_available());
 | 
| +
 | 
| +  scoped_refptr<const Extension> extension =
 | 
| +      ExtensionBuilder()
 | 
| +          .SetManifest(DictionaryBuilder()
 | 
| +                           .Set("name", "extension")
 | 
| +                           .Set("version", "1")
 | 
| +                           .Set("manifest_version", 2)
 | 
| +                           .Build())
 | 
| +          .Build();
 | 
| +  Feature* test_feature = api_feature_provider.GetFeature("alias_api_source");
 | 
| +  ASSERT_TRUE(test_feature);
 | 
| +  ASSERT_FALSE(api.IsAnyFeatureAvailableToContext(
 | 
| +      *test_feature, extension.get(), Feature::UNBLESSED_EXTENSION_CONTEXT,
 | 
| +      GURL(), false /* alow_alias */));
 | 
| +  EXPECT_TRUE(api.IsAnyFeatureAvailableToContext(
 | 
| +      *test_feature, extension.get(), Feature::UNBLESSED_EXTENSION_CONTEXT,
 | 
| +      GURL(), true /* alow_alias */));
 | 
| +}
 | 
| +
 | 
|  TEST(ExtensionAPITest, IsAnyFeatureAvailableToContext) {
 | 
|    scoped_refptr<const Extension> app =
 | 
|        ExtensionBuilder()
 | 
| @@ -283,10 +327,9 @@ TEST(ExtensionAPITest, IsAnyFeatureAvailableToContext) {
 | 
|          api_feature_provider.GetFeature(test_data[i].api_full_name);
 | 
|      ASSERT_TRUE(test_feature);
 | 
|      EXPECT_EQ(test_data[i].expect_is_available,
 | 
| -              api.IsAnyFeatureAvailableToContext(*test_feature,
 | 
| -                                                 test_data[i].extension,
 | 
| -                                                 test_data[i].context,
 | 
| -                                                 test_data[i].url))
 | 
| +              api.IsAnyFeatureAvailableToContext(
 | 
| +                  *test_feature, test_data[i].extension, test_data[i].context,
 | 
| +                  test_data[i].url, false))
 | 
|          << i;
 | 
|    }
 | 
|  }
 | 
| @@ -319,7 +362,7 @@ TEST(ExtensionAPITest, SessionTypeFeature) {
 | 
|          ScopedCurrentFeatureSessionType(test.current_session_type));
 | 
|      EXPECT_EQ(test.expect_available,
 | 
|                api.IsAvailable(test.api_name, nullptr,
 | 
| -                              Feature::BLESSED_EXTENSION_CONTEXT, GURL())
 | 
| +                              Feature::BLESSED_EXTENSION_CONTEXT, GURL(), false)
 | 
|                    .is_available())
 | 
|          << "Test case (" << test.api_name << ", "
 | 
|          << static_cast<int>(test.current_session_type) << ").";
 | 
| @@ -395,59 +438,39 @@ TEST(ExtensionAPITest, ExtensionWithUnprivilegedAPIs) {
 | 
|  
 | 
|    // "storage" is completely unprivileged.
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("storage"),
 | 
| -      NULL,
 | 
| -      Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("storage"), NULL,
 | 
| +      Feature::BLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("storage"),
 | 
| -      NULL,
 | 
| -      Feature::UNBLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("storage"), NULL,
 | 
| +      Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("storage"),
 | 
| -      NULL,
 | 
| -      Feature::CONTENT_SCRIPT_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("storage"), NULL,
 | 
| +      Feature::CONTENT_SCRIPT_CONTEXT, GURL(), false));
 | 
|  
 | 
|    // "extension" is partially unprivileged.
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("extension"),
 | 
| -      NULL,
 | 
| -      Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("extension"), NULL,
 | 
| +      Feature::BLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("extension"),
 | 
| -      NULL,
 | 
| -      Feature::UNBLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("extension"), NULL,
 | 
| +      Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("extension"),
 | 
| -      NULL,
 | 
| -      Feature::CONTENT_SCRIPT_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("extension"), NULL,
 | 
| +      Feature::CONTENT_SCRIPT_CONTEXT, GURL(), false));
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("extension.getURL"),
 | 
| -      NULL,
 | 
| -      Feature::CONTENT_SCRIPT_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("extension.getURL"), NULL,
 | 
| +      Feature::CONTENT_SCRIPT_CONTEXT, GURL(), false));
 | 
|  
 | 
|    // "history" is entirely privileged.
 | 
|    EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("history"),
 | 
| -      NULL,
 | 
| -      Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("history"), NULL,
 | 
| +      Feature::BLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("history"),
 | 
| -      NULL,
 | 
| -      Feature::UNBLESSED_EXTENSION_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("history"), NULL,
 | 
| +      Feature::UNBLESSED_EXTENSION_CONTEXT, GURL(), false));
 | 
|    EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
 | 
| -      *api_features.GetFeature("history"),
 | 
| -      NULL,
 | 
| -      Feature::CONTENT_SCRIPT_CONTEXT,
 | 
| -      GURL()));
 | 
| +      *api_features.GetFeature("history"), NULL,
 | 
| +      Feature::CONTENT_SCRIPT_CONTEXT, GURL(), false));
 | 
|  }
 | 
|  
 | 
|  scoped_refptr<Extension> CreateHostedApp() {
 | 
| @@ -504,26 +527,31 @@ TEST(ExtensionAPITest, HostedAppPermissions) {
 | 
|        ExtensionAPI::CreateWithDefaultConfiguration());
 | 
|  
 | 
|    // "runtime" and "tabs" should not be available in hosted apps.
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("runtime",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("runtime.id",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("runtime.sendMessage",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("runtime.sendNativeMessage",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("tabs.create",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("runtime", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("runtime.id", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("runtime.sendMessage", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("runtime.sendNativeMessage", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("tabs.create", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
|  }
 | 
|  
 | 
|  TEST(ExtensionAPITest, AppAndFriendsAvailability) {
 | 
| @@ -538,21 +566,21 @@ TEST(ExtensionAPITest, AppAndFriendsAvailability) {
 | 
|      permissions.insert("app.window");
 | 
|      scoped_refptr<Extension> extension =
 | 
|          CreatePackagedAppWithPermissions(permissions);
 | 
| -    EXPECT_FALSE(extension_api->IsAvailable(
 | 
| -        "app",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| -    EXPECT_TRUE(extension_api->IsAvailable(
 | 
| -        "app.runtime",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| -    EXPECT_TRUE(extension_api->IsAvailable(
 | 
| -        "app.window",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| +    EXPECT_FALSE(extension_api
 | 
| +                     ->IsAvailable("app", extension.get(),
 | 
| +                                   Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                   GURL("http://foo.com"), false)
 | 
| +                     .is_available());
 | 
| +    EXPECT_TRUE(extension_api
 | 
| +                    ->IsAvailable("app.runtime", extension.get(),
 | 
| +                                  Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                  GURL("http://foo.com"), false)
 | 
| +                    .is_available());
 | 
| +    EXPECT_TRUE(extension_api
 | 
| +                    ->IsAvailable("app.window", extension.get(),
 | 
| +                                  Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                  GURL("http://foo.com"), false)
 | 
| +                    .is_available());
 | 
|    }
 | 
|    // Make sure chrome.app.runtime and chrome.app.window are not available to
 | 
|    // extensions, and chrome.app is.
 | 
| @@ -560,21 +588,21 @@ TEST(ExtensionAPITest, AppAndFriendsAvailability) {
 | 
|      std::set<std::string> permissions;
 | 
|      scoped_refptr<Extension> extension =
 | 
|          CreateExtensionWithPermissions(permissions);
 | 
| -    EXPECT_TRUE(extension_api->IsAvailable(
 | 
| -        "app",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| -    EXPECT_FALSE(extension_api->IsAvailable(
 | 
| -        "app.runtime",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| -    EXPECT_FALSE(extension_api->IsAvailable(
 | 
| -        "app.window",
 | 
| -        extension.get(),
 | 
| -        Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -        GURL("http://foo.com")).is_available());
 | 
| +    EXPECT_TRUE(extension_api
 | 
| +                    ->IsAvailable("app", extension.get(),
 | 
| +                                  Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                  GURL("http://foo.com"), false)
 | 
| +                    .is_available());
 | 
| +    EXPECT_FALSE(extension_api
 | 
| +                     ->IsAvailable("app.runtime", extension.get(),
 | 
| +                                   Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                   GURL("http://foo.com"), false)
 | 
| +                     .is_available());
 | 
| +    EXPECT_FALSE(extension_api
 | 
| +                     ->IsAvailable("app.window", extension.get(),
 | 
| +                                   Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| +                                   GURL("http://foo.com"), false)
 | 
| +                     .is_available());
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -586,14 +614,14 @@ TEST(ExtensionAPITest, ExtensionWithDependencies) {
 | 
|          CreateExtensionWithPermission("ttsEngine");
 | 
|      std::unique_ptr<ExtensionAPI> api(
 | 
|          ExtensionAPI::CreateWithDefaultConfiguration());
 | 
| -    EXPECT_TRUE(api->IsAvailable("ttsEngine",
 | 
| -                                 extension.get(),
 | 
| -                                 Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                 GURL()).is_available());
 | 
| -    EXPECT_FALSE(api->IsAvailable("tts",
 | 
| -                                  extension.get(),
 | 
| -                                  Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                  GURL()).is_available());
 | 
| +    EXPECT_TRUE(api->IsAvailable("ttsEngine", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                    .is_available());
 | 
| +    EXPECT_FALSE(api->IsAvailable("tts", extension.get(),
 | 
| +                                  Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                  false)
 | 
| +                     .is_available());
 | 
|    }
 | 
|  
 | 
|    // Conversely, extension with the "tts" permission but not the "ttsEngine"
 | 
| @@ -603,21 +631,22 @@ TEST(ExtensionAPITest, ExtensionWithDependencies) {
 | 
|          CreateExtensionWithPermission("tts");
 | 
|      std::unique_ptr<ExtensionAPI> api(
 | 
|          ExtensionAPI::CreateWithDefaultConfiguration());
 | 
| -    EXPECT_FALSE(api->IsAvailable("ttsEngine",
 | 
| -                                  extension.get(),
 | 
| -                                  Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                  GURL()).is_available());
 | 
| -    EXPECT_TRUE(api->IsAvailable("tts",
 | 
| -                                 extension.get(),
 | 
| -                                 Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                 GURL()).is_available());
 | 
| +    EXPECT_FALSE(api->IsAvailable("ttsEngine", extension.get(),
 | 
| +                                  Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                  false)
 | 
| +                     .is_available());
 | 
| +    EXPECT_TRUE(api->IsAvailable("tts", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                    .is_available());
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  bool MatchesURL(
 | 
|      ExtensionAPI* api, const std::string& api_name, const std::string& url) {
 | 
| -  return api->IsAvailable(
 | 
| -      api_name, NULL, Feature::WEB_PAGE_CONTEXT, GURL(url)).is_available();
 | 
| +  return api
 | 
| +      ->IsAvailable(api_name, NULL, Feature::WEB_PAGE_CONTEXT, GURL(url), false)
 | 
| +      .is_available();
 | 
|  }
 | 
|  
 | 
|  TEST(ExtensionAPITest, URLMatching) {
 | 
| @@ -849,11 +878,12 @@ TEST(ExtensionAPITest, NoPermissions) {
 | 
|        BuildExtension(ExtensionBuilder()).Build();
 | 
|  
 | 
|    for (size_t i = 0; i < arraysize(kTests); ++i) {
 | 
| -    EXPECT_EQ(kTests[i].expect_success,
 | 
| -              extension_api->IsAvailable(kTests[i].permission_name,
 | 
| -                                         extension.get(),
 | 
| -                                         Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                         GURL()).is_available())
 | 
| +    EXPECT_EQ(
 | 
| +        kTests[i].expect_success,
 | 
| +        extension_api
 | 
| +            ->IsAvailable(kTests[i].permission_name, extension.get(),
 | 
| +                          Feature::BLESSED_EXTENSION_CONTEXT, GURL(), false)
 | 
| +            .is_available())
 | 
|          << "Permission being tested: " << kTests[i].permission_name;
 | 
|    }
 | 
|  }
 | 
| @@ -871,14 +901,16 @@ TEST(ExtensionAPITest, ManifestKeys) {
 | 
|                               .Build())
 | 
|            .Build();
 | 
|  
 | 
| -  EXPECT_TRUE(extension_api->IsAvailable("browserAction",
 | 
| -                                         extension.get(),
 | 
| -                                         Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                         GURL()).is_available());
 | 
| -  EXPECT_FALSE(extension_api->IsAvailable("pageAction",
 | 
| -                                          extension.get(),
 | 
| -                                          Feature::BLESSED_EXTENSION_CONTEXT,
 | 
| -                                          GURL()).is_available());
 | 
| +  EXPECT_TRUE(extension_api
 | 
| +                  ->IsAvailable("browserAction", extension.get(),
 | 
| +                                Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                false)
 | 
| +                  .is_available());
 | 
| +  EXPECT_FALSE(extension_api
 | 
| +                   ->IsAvailable("pageAction", extension.get(),
 | 
| +                                 Feature::BLESSED_EXTENSION_CONTEXT, GURL(),
 | 
| +                                 false)
 | 
| +                   .is_available());
 | 
|  }
 | 
|  
 | 
|  }  // namespace extensions
 | 
| 
 |