summaryrefslogtreecommitdiffstats
path: root/extensions/browser/api/networking_config
diff options
context:
space:
mode:
authorcschuet <cschuet@chromium.org>2015-02-03 02:23:39 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-03 10:24:31 +0000
commitb34ff556a7902fe52fe17e63c2e05faa616c8380 (patch)
treedb8ba3ebd46ba7198e7387a943207dc20a8cd594 /extensions/browser/api/networking_config
parent6bc9a331e82e4f94ca9e0f24eb0efa45ffc1e472 (diff)
downloadchromium_src-b34ff556a7902fe52fe17e63c2e05faa616c8380.zip
chromium_src-b34ff556a7902fe52fe17e63c2e05faa616c8380.tar.gz
chromium_src-b34ff556a7902fe52fe17e63c2e05faa616c8380.tar.bz2
Implementation of the NetworkingConfigService
Implementation of the NetworkingConfigService and boiler plate code for the networking.config API. Reviewers: Please see 1) https://docs.google.com/document/d/1V8YGouKC477iC11L4PL8H_HU1Ru3R5kMhXppuoIVNeo for the design document. 2) https://docs.google.com/drawings/d/12Hai1LdaPzwtkrQUdCjSpt1s7InRNNBDeWiW5ujfIRg for a flow diagram. Review URL: https://codereview.chromium.org/880073002 Cr-Commit-Position: refs/heads/master@{#314303}
Diffstat (limited to 'extensions/browser/api/networking_config')
-rw-r--r--extensions/browser/api/networking_config/OWNERS3
-rw-r--r--extensions/browser/api/networking_config/networking_config_api.cc128
-rw-r--r--extensions/browser/api/networking_config/networking_config_api.h55
-rw-r--r--extensions/browser/api/networking_config/networking_config_service.cc112
-rw-r--r--extensions/browser/api/networking_config/networking_config_service.h107
-rw-r--r--extensions/browser/api/networking_config/networking_config_service_chromeos_unittest.cc71
-rw-r--r--extensions/browser/api/networking_config/networking_config_service_factory.cc83
-rw-r--r--extensions/browser/api/networking_config/networking_config_service_factory.h41
8 files changed, 600 insertions, 0 deletions
diff --git a/extensions/browser/api/networking_config/OWNERS b/extensions/browser/api/networking_config/OWNERS
new file mode 100644
index 0000000..5dc3191
--- /dev/null
+++ b/extensions/browser/api/networking_config/OWNERS
@@ -0,0 +1,3 @@
+cschuet@chromium.org
+pneubeck@chromium.org
+stevenjb@chromium.org
diff --git a/extensions/browser/api/networking_config/networking_config_api.cc b/extensions/browser/api/networking_config/networking_config_api.cc
new file mode 100644
index 0000000..bf37436
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_api.cc
@@ -0,0 +1,128 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "extensions/browser/api/networking_config/networking_config_api.h"
+#include "extensions/browser/api/networking_config/networking_config_service.h"
+#include "extensions/browser/api/networking_config/networking_config_service_factory.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace extensions {
+
+namespace {
+
+const char kAuthenticationResultFailed[] =
+ "Failed to set AuthenticationResult.";
+const char kMalformedFilterDescription[] = "Malformed filter description.";
+const char kMalformedFilterDescriptionWithSSID[] =
+ "Malformed filter description. Failed to register network with SSID "
+ "(hex): *";
+const char kUnsupportedNetworkType[] = "Unsupported network type.";
+
+} // namespace
+
+NetworkingConfigSetNetworkFilterFunction::
+ NetworkingConfigSetNetworkFilterFunction() {
+}
+
+ExtensionFunction::ResponseAction
+NetworkingConfigSetNetworkFilterFunction::Run() {
+ parameters_ =
+ core_api::networking_config::SetNetworkFilter::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+
+ NetworkingConfigService* service =
+ NetworkingConfigServiceFactory::GetForBrowserContext(browser_context());
+ DCHECK(service);
+
+ // Remove previously registered networks.
+ service->UnregisterExtension(extension_id());
+
+ for (linked_ptr<core_api::networking_config::NetworkInfo>& ni :
+ parameters_->networks) {
+ // |Type| field must be set to |WiFi|
+ if (ni->type != core_api::networking_config::NETWORK_TYPE_WIFI)
+ return RespondNow(Error(kUnsupportedNetworkType));
+
+ // Either |ssid| or |hex_ssid| must be set.
+ if (!ni->ssid.get() && !ni->hex_ssid.get())
+ return RespondNow(Error(kMalformedFilterDescription));
+
+ std::string hex_ssid;
+ if (ni->ssid.get()) {
+ auto ssid_field = ni->ssid.get();
+ hex_ssid = base::HexEncode(ssid_field->c_str(), ssid_field->size());
+ }
+ if (ni->hex_ssid.get())
+ hex_ssid = *ni->hex_ssid.get();
+
+ if (!service->RegisterHexSsid(hex_ssid, extension_id()))
+ return RespondNow(Error(kMalformedFilterDescriptionWithSSID, hex_ssid));
+ }
+
+ return RespondNow(NoArguments());
+}
+
+NetworkingConfigSetNetworkFilterFunction::
+ ~NetworkingConfigSetNetworkFilterFunction() {
+}
+
+NetworkingConfigFinishAuthenticationFunction::
+ NetworkingConfigFinishAuthenticationFunction() {
+}
+
+ExtensionFunction::ResponseAction
+NetworkingConfigFinishAuthenticationFunction::Run() {
+ parameters_ =
+ core_api::networking_config::FinishAuthentication::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(parameters_.get());
+
+ NetworkingConfigService* service =
+ NetworkingConfigServiceFactory::GetForBrowserContext(browser_context());
+ DCHECK(service);
+
+ const NetworkingConfigService::AuthenticationResult& last_result =
+ service->GetAuthenticationResult();
+ if (last_result.authentication_state != NetworkingConfigService::NOTRY ||
+ last_result.guid != parameters_->guid) {
+ RespondNow(Error(kAuthenticationResultFailed));
+ }
+
+ // Populate NetworkingCaptivePortalAPI::AuthenticationResult.
+ NetworkingConfigService::AuthenticationResult authentication_result = {
+ extension_id(), parameters_->guid, NetworkingConfigService::FAILED,
+ };
+ switch (parameters_->result) {
+ case core_api::networking_config::AUTHENTICATION_RESULT_NONE:
+ NOTREACHED();
+ break;
+ case core_api::networking_config::AUTHENTICATION_RESULT_UNHANDLED:
+ authentication_result.authentication_state =
+ NetworkingConfigService::FAILED;
+ break;
+ case core_api::networking_config::AUTHENTICATION_RESULT_REJECTED:
+ authentication_result.authentication_state =
+ NetworkingConfigService::REJECTED;
+ break;
+ case core_api::networking_config::AUTHENTICATION_RESULT_FAILED:
+ authentication_result.authentication_state =
+ NetworkingConfigService::FAILED;
+ break;
+ case core_api::networking_config::AUTHENTICATION_RESULT_SUCCEEDED:
+ authentication_result.authentication_state =
+ NetworkingConfigService::SUCCESS;
+ break;
+ }
+ service->SetAuthenticationResult(authentication_result);
+ return RespondNow(NoArguments());
+}
+
+NetworkingConfigFinishAuthenticationFunction::
+ ~NetworkingConfigFinishAuthenticationFunction() {
+}
+
+} // namespace extensions
diff --git a/extensions/browser/api/networking_config/networking_config_api.h b/extensions/browser/api/networking_config/networking_config_api.h
new file mode 100644
index 0000000..863fb08
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_api.h
@@ -0,0 +1,55 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_API_H_
+#define EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_API_H_
+
+#include "extensions/common/api/networking_config.h"
+#include "extensions/browser/extension_function.h"
+
+namespace extensions {
+
+class NetworkingConfigSetNetworkFilterFunction
+ : public UIThreadExtensionFunction {
+ public:
+ NetworkingConfigSetNetworkFilterFunction();
+
+ ResponseAction Run() override;
+
+ DECLARE_EXTENSION_FUNCTION("networking.config.setNetworkFilter",
+ NETWORKING_CONFIG_SETNETWORKFILTER);
+
+ protected:
+ ~NetworkingConfigSetNetworkFilterFunction() override;
+
+ scoped_ptr<core_api::networking_config::SetNetworkFilter::Params>
+ parameters_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkingConfigSetNetworkFilterFunction);
+};
+
+class NetworkingConfigFinishAuthenticationFunction
+ : public UIThreadExtensionFunction {
+ public:
+ NetworkingConfigFinishAuthenticationFunction();
+
+ ResponseAction Run() override;
+
+ DECLARE_EXTENSION_FUNCTION("networking.config.finishAuthenticationFunction",
+ NETWORKING_CONFIG_FINISHAUTHENTICATION);
+
+ protected:
+ ~NetworkingConfigFinishAuthenticationFunction() override;
+
+ scoped_ptr<core_api::networking_config::FinishAuthentication::Params>
+ parameters_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NetworkingConfigFinishAuthenticationFunction);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_API_H_
diff --git a/extensions/browser/api/networking_config/networking_config_service.cc b/extensions/browser/api/networking_config/networking_config_service.cc
new file mode 100644
index 0000000..54a8ecd
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_service.cc
@@ -0,0 +1,112 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+
+#include "base/lazy_instance.h"
+#include "base/strings/string_util.h"
+#include "extensions/browser/api/networking_config/networking_config_service.h"
+
+namespace extensions {
+
+namespace {
+
+bool IsValidNonEmptyHexString(const std::string& input) {
+ size_t count = input.size();
+ if (count == 0 || (count % 2) != 0)
+ return false;
+ for (const char& c : input)
+ if (!IsHexDigit<char>(c))
+ return false;
+ return true;
+}
+
+} // namespace
+
+NetworkingConfigService::AuthenticationResult::AuthenticationResult()
+ : authentication_state(NetworkingConfigService::NOTRY) {
+}
+
+NetworkingConfigService::AuthenticationResult::AuthenticationResult(
+ ExtensionId extension_id,
+ std::string guid,
+ AuthenticationState authentication_state)
+ : extension_id(extension_id),
+ guid(guid),
+ authentication_state(authentication_state) {
+}
+
+NetworkingConfigService::NetworkingConfigService(
+ scoped_ptr<EventDelegate> event_delegate,
+ ExtensionRegistry* extension_registry)
+ : registry_observer_(this), event_delegate_(event_delegate.Pass()) {
+ registry_observer_.Add(extension_registry);
+}
+
+NetworkingConfigService::~NetworkingConfigService() {
+}
+
+void NetworkingConfigService::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ UnregisterExtension(extension->id());
+}
+
+std::string NetworkingConfigService::LookupExtensionIdForHexSsid(
+ std::string hex_ssid) const {
+ // Transform hex_ssid to uppercase.
+ transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
+
+ const auto it = hex_ssid_to_extension_id_.find(hex_ssid);
+ if (it == hex_ssid_to_extension_id_.end())
+ return std::string();
+ return it->second;
+}
+
+bool NetworkingConfigService::IsRegisteredForCaptivePortalEvent(
+ std::string extension_id) const {
+ return event_delegate_->HasExtensionRegisteredForEvent(extension_id);
+}
+
+bool NetworkingConfigService::RegisterHexSsid(std::string hex_ssid,
+ const std::string& extension_id) {
+ if (!IsValidNonEmptyHexString(hex_ssid)) {
+ LOG(ERROR) << "\'" << hex_ssid << "\' is not a valid hex encoded string.";
+ return false;
+ }
+
+ // Transform hex_ssid to uppercase.
+ transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
+
+ return hex_ssid_to_extension_id_.insert(make_pair(hex_ssid, extension_id))
+ .second;
+}
+
+void NetworkingConfigService::UnregisterExtension(
+ const std::string& extension_id) {
+ for (auto it = hex_ssid_to_extension_id_.begin();
+ it != hex_ssid_to_extension_id_.end();) {
+ if (it->second == extension_id)
+ hex_ssid_to_extension_id_.erase(it++);
+ else
+ ++it;
+ }
+}
+
+const NetworkingConfigService::AuthenticationResult&
+NetworkingConfigService::GetAuthenticationResult() const {
+ return authentication_result_;
+}
+
+void NetworkingConfigService::ResetAuthenticationResult() {
+ authentication_result_ = AuthenticationResult();
+}
+
+void NetworkingConfigService::SetAuthenticationResult(
+ const AuthenticationResult& authentication_result) {
+ authentication_result_ = authentication_result;
+}
+
+} // namespace extensions
diff --git a/extensions/browser/api/networking_config/networking_config_service.h b/extensions/browser/api/networking_config/networking_config_service.h
new file mode 100644
index 0000000..236b992
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_service.h
@@ -0,0 +1,107 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_H_
+#define EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_H_
+
+#include <map>
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/scoped_observer.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_registry_observer.h"
+
+namespace extensions {
+
+// This class provides the session-scoped storage backing the networking config
+// extension API. Currently only the parts relevant for captive portal handling
+// are implemented.
+class NetworkingConfigService : public ExtensionRegistryObserver,
+ public KeyedService {
+ public:
+ class EventDelegate {
+ public:
+ EventDelegate() {}
+ virtual ~EventDelegate() {}
+ virtual bool HasExtensionRegisteredForEvent(
+ const std::string& extension_id) const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EventDelegate);
+ };
+
+ // Indicates the authentication state of the portal.
+ enum AuthenticationState { NOTRY, TRYING, SUCCESS, REJECTED, FAILED };
+
+ // Provides information about the current authentication state of the portal.
+ struct AuthenticationResult {
+ AuthenticationResult();
+ AuthenticationResult(ExtensionId extension_id,
+ std::string guid,
+ AuthenticationState authentication_state);
+ ExtensionId extension_id;
+ std::string guid;
+ AuthenticationState authentication_state;
+ };
+
+ // Note: |extension_registry| must outlive this class.
+ NetworkingConfigService(scoped_ptr<EventDelegate> event_delegate,
+ ExtensionRegistry* extension_registry);
+ ~NetworkingConfigService() override;
+
+ // ExtensionRegistryObserver
+ void OnExtensionUnloaded(content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) override;
+
+ // Returns the extension id registered for |hex_ssid|. If no extension is
+ // registered for this |hex_ssid|, the function returns an empty string.
+ // |hex_ssid|: SSID in hex encoding.
+ std::string LookupExtensionIdForHexSsid(std::string hex_ssid) const;
+
+ // Returns true if the extension with id |extension_id| registered for
+ // |onCaptivePortalDetected| events, otherwise false.
+ bool IsRegisteredForCaptivePortalEvent(std::string extension_id) const;
+
+ // Registers |hex_ssid| as being handled by the extension with extension ID
+ // |extension_id|. Returns true on success and false if another extension
+ // already registered for |hex_ssid|.
+ // |hex_ssid|: SSID in hex encoding of the network to be registered.
+ // |extension_id|: Extension ID of the extension handling the network
+ // configuration for this network.
+ bool RegisterHexSsid(std::string hex_ssid, const std::string& extension_id);
+
+ // Unregisters extension with the ID |extension_id| removing all associated
+ // HexSSIDs from the map.
+ // |extension_id|: ID identifying the extenion to be removed
+ void UnregisterExtension(const std::string& extensionId);
+
+ // Returns the current AuthenticationResult.
+ const AuthenticationResult& GetAuthenticationResult() const;
+
+ // Sets the authentication_state to NOTRY and clears all other fields.
+ void ResetAuthenticationResult();
+
+ // Sets the current AuthenticationResult.
+ void SetAuthenticationResult(
+ const AuthenticationResult& authentication_result);
+
+ private:
+ AuthenticationResult authentication_result_;
+
+ ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
+ registry_observer_;
+
+ scoped_ptr<EventDelegate> event_delegate_;
+
+ // This map associates a given hex encoded SSID to an extension entry.
+ std::map<std::string, std::string> hex_ssid_to_extension_id_;
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_H_
diff --git a/extensions/browser/api/networking_config/networking_config_service_chromeos_unittest.cc b/extensions/browser/api/networking_config/networking_config_service_chromeos_unittest.cc
new file mode 100644
index 0000000..9990d74
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_service_chromeos_unittest.cc
@@ -0,0 +1,71 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/api/networking_config/networking_config_service.h"
+#include "extensions/browser/api_unittest.h"
+#include "extensions/browser/extension_registry.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace {
+
+const char kExtensionId[] = "necdpnkfgondfageiompbacibhgmfebg";
+const char kHexSsid[] = "54657374535349445F5A5A5A5A";
+const char kHexSsidLower[] = "54657374535349445f5a5a5a5a";
+
+class MockEventDelegate : public NetworkingConfigService::EventDelegate {
+ public:
+ MockEventDelegate() : extension_registered_(false) {}
+ ~MockEventDelegate() override {}
+
+ bool HasExtensionRegisteredForEvent(
+ const std::string& extension_id) const override {
+ return extension_registered_;
+ }
+
+ void SetExtensionRegisteredForEvent(bool extension_registered) {
+ extension_registered_ = extension_registered;
+ }
+
+ private:
+ bool extension_registered_;
+};
+
+} // namespace
+
+class NetworkingConfigServiceTest : public ApiUnitTest {
+ public:
+ NetworkingConfigServiceTest() {}
+ ~NetworkingConfigServiceTest() override {}
+
+ void SetUp() override {
+ ApiUnitTest::SetUp();
+ extension_registry_ = scoped_ptr<ExtensionRegistry>(
+ new ExtensionRegistry(browser_context()));
+ scoped_ptr<MockEventDelegate> mock_event_delegate =
+ scoped_ptr<MockEventDelegate>(new MockEventDelegate());
+ service_ = scoped_ptr<NetworkingConfigService>(new NetworkingConfigService(
+ mock_event_delegate.Pass(), extension_registry_.get()));
+ DCHECK(service_);
+ }
+
+ protected:
+ scoped_ptr<ExtensionRegistry> extension_registry_;
+ scoped_ptr<NetworkingConfigService> service_;
+};
+
+TEST_F(NetworkingConfigServiceTest, BasicRegisterHexSsid) {
+ EXPECT_TRUE(service_->RegisterHexSsid(kHexSsid, kExtensionId));
+ EXPECT_EQ(kExtensionId, service_->LookupExtensionIdForHexSsid(kHexSsid));
+ EXPECT_EQ(kExtensionId, service_->LookupExtensionIdForHexSsid(kHexSsidLower));
+}
+
+TEST_F(NetworkingConfigServiceTest, BasicRegisterHexSsidLower) {
+ EXPECT_TRUE(service_->RegisterHexSsid(kHexSsidLower, kExtensionId));
+ EXPECT_EQ(kExtensionId, service_->LookupExtensionIdForHexSsid(kHexSsid));
+ EXPECT_EQ(kExtensionId, service_->LookupExtensionIdForHexSsid(kHexSsidLower));
+}
+
+} // namespace extensions
diff --git a/extensions/browser/api/networking_config/networking_config_service_factory.cc b/extensions/browser/api/networking_config/networking_config_service_factory.cc
new file mode 100644
index 0000000..62bc8f1
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_service_factory.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/api/networking_config/networking_config_service_factory.h"
+
+#include <string>
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "extensions/browser/api/networking_config/networking_config_service.h"
+#include "extensions/browser/extension_registry_factory.h"
+#include "extensions/browser/extension_system_provider.h"
+#include "extensions/browser/extensions_browser_client.h"
+#include "extensions/common/api/networking_config.h"
+
+namespace extensions {
+
+namespace {
+
+class DefaultEventDelegate : public NetworkingConfigService::EventDelegate {
+ public:
+ explicit DefaultEventDelegate(content::BrowserContext* context);
+ ~DefaultEventDelegate() override;
+
+ bool HasExtensionRegisteredForEvent(
+ const std::string& extension_id) const override;
+
+ private:
+ content::BrowserContext* const context_;
+};
+
+DefaultEventDelegate::DefaultEventDelegate(content::BrowserContext* context)
+ : context_(context) {
+}
+
+DefaultEventDelegate::~DefaultEventDelegate() {
+}
+
+bool DefaultEventDelegate::HasExtensionRegisteredForEvent(
+ const std::string& extension_id) const {
+ return EventRouter::Get(context_)->ExtensionHasEventListener(
+ extension_id,
+ core_api::networking_config::OnCaptivePortalDetected::kEventName);
+}
+
+} // namespace
+
+// static
+NetworkingConfigService* NetworkingConfigServiceFactory::GetForBrowserContext(
+ content::BrowserContext* context) {
+ return static_cast<NetworkingConfigService*>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+NetworkingConfigServiceFactory* NetworkingConfigServiceFactory::GetInstance() {
+ return Singleton<NetworkingConfigServiceFactory>::get();
+}
+
+NetworkingConfigServiceFactory::NetworkingConfigServiceFactory()
+ : BrowserContextKeyedServiceFactory(
+ "NetworkingConfigService",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
+ DependsOn(extensions::ExtensionRegistryFactory::GetInstance());
+}
+
+NetworkingConfigServiceFactory::~NetworkingConfigServiceFactory() {
+}
+
+KeyedService* NetworkingConfigServiceFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new NetworkingConfigService(
+ make_scoped_ptr(new DefaultEventDelegate(context)),
+ ExtensionRegistry::Get(context));
+}
+
+content::BrowserContext* NetworkingConfigServiceFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
+}
+
+} // namespace extensions
diff --git a/extensions/browser/api/networking_config/networking_config_service_factory.h b/extensions/browser/api/networking_config/networking_config_service_factory.h
new file mode 100644
index 0000000..58e5632
--- /dev/null
+++ b/extensions/browser/api/networking_config/networking_config_service_factory.h
@@ -0,0 +1,41 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_FACTORY_H_
+#define EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace content {
+class BrowserContext;
+} // namespace content
+
+namespace extensions {
+class NetworkingConfigService;
+
+class NetworkingConfigServiceFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ static NetworkingConfigService* GetForBrowserContext(
+ content::BrowserContext* context);
+
+ static NetworkingConfigServiceFactory* GetInstance();
+
+ private:
+ friend struct DefaultSingletonTraits<NetworkingConfigServiceFactory>;
+
+ NetworkingConfigServiceFactory();
+ ~NetworkingConfigServiceFactory() override;
+
+ // BrowserContextKeyedBaseFactory
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_NETWORKING_CONFIG_NETWORKING_CONFIG_SERVICE_FACTORY_H_