Commit b34ff556 authored by cschuet's avatar cschuet Committed by Commit bot

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}
parent 6bc9a331
// 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 "chrome/browser/extensions/extension_apitest.h"
namespace {
class NetworkingConfigTest : public ExtensionApiTest {
public:
NetworkingConfigTest() {}
};
} // namespace
IN_PROC_BROWSER_TEST_F(NetworkingConfigTest, ApiAvailability) {
ASSERT_TRUE(RunExtensionSubtest("networking_config", "api_availability.html"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(NetworkingConfigTest, RegisterNetworks) {
ASSERT_TRUE(
RunExtensionSubtest("networking_config", "register_networks.html"))
<< message_;
}
...@@ -263,6 +263,7 @@ ...@@ -263,6 +263,7 @@
'browser/extensions/lazy_background_page_apitest.cc', 'browser/extensions/lazy_background_page_apitest.cc',
'browser/extensions/lazy_background_page_test_util.h', 'browser/extensions/lazy_background_page_test_util.h',
'browser/extensions/mutation_observers_apitest.cc', 'browser/extensions/mutation_observers_apitest.cc',
'browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc',
'browser/extensions/options_page_apitest.cc', 'browser/extensions/options_page_apitest.cc',
'browser/extensions/page_action_browsertest.cc', 'browser/extensions/page_action_browsertest.cc',
'browser/extensions/plugin_apitest.cc', 'browser/extensions/plugin_apitest.cc',
......
cschuet@chromium.org
pneubeck@chromium.org
stevenjb@chromium.org
<!--
* 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.
-->
<script src="api_availability.js"></script>
// 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.
chrome.test.assertFalse(!chrome.networking.config,
"No networking_config namespace.");
chrome.test.assertFalse(!chrome.networking.config.setNetworkFilter,
"No setNetworkFilter function.");
chrome.test.assertFalse(!chrome.networking.config.finishAuthentication,
"No finishAuthentication function.");
chrome.test.succeed();
{
"name": "networking.config browser tests",
"version": "0.1",
"manifest_version": 2,
"permissions": [
"networking.config"
]
}
<!--
* 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.
-->
<script src="register_networks.js"></script>
// 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.
'use strict';
var assertEq = chrome.test.assertEq;
var assertTrue = chrome.test.assertTrue;
var assertThrows = chrome.test.assertThrows;
var fail = chrome.test.fail;
var succeed = chrome.test.succeed;
var callbackPass = chrome.test.callbackPass;
var callbackFail = chrome.test.callbackFail;
var testCases = {
neitherHexSsidNorSsid:
{input: [{Type: 'WiFi'}], error: 'Malformed filter description.'},
ssid: {input: [{Type: 'WiFi', SSID: 'SSID1'}]},
hexSsid: {input: [{Type: 'WiFi', HexSSID: '5353494431'}]},
invalidHexSsid1: {
input: [{Type: 'WiFi', HexSSID: '5'}],
error:
'Malformed filter description. Failed to register network with SSID ' +
'(hex): 5'
},
invalidHexSsid2: {
input: [{Type: 'WiFi', HexSSID: 'ABCDEFGH'}],
error:
'Malformed filter description. Failed to register network with SSID ' +
'(hex): ABCDEFGH'
}
};
var runTests = function() {
for (var key in testCases) {
var testCase = testCases[key];
if (testCase.hasOwnProperty('error'))
var callback = callbackFail(testCase.error);
else
var callback = callbackPass();
chrome.networking.config.setNetworkFilter(testCase.input, callback);
}
};
runTests();
...@@ -580,6 +580,12 @@ source_set("browser") { ...@@ -580,6 +580,12 @@ source_set("browser") {
if (is_chromeos) { if (is_chromeos) {
sources += [ sources += [
"api/networking_config/networking_config_api.cc",
"api/networking_config/networking_config_api.h",
"api/networking_config/networking_config_service.cc",
"api/networking_config/networking_config_service.h",
"api/networking_config/networking_config_service_factory.cc",
"api/networking_config/networking_config_service_factory.h",
"api/vpn_provider/vpn_provider_api.cc", "api/vpn_provider/vpn_provider_api.cc",
"api/vpn_provider/vpn_provider_api.h", "api/vpn_provider/vpn_provider_api.h",
"api/vpn_provider/vpn_service.cc", "api/vpn_provider/vpn_service.cc",
......
cschuet@chromium.org
pneubeck@chromium.org
stevenjb@chromium.org
// 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
// 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_
// 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
// 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_
// 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
// 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
// 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_
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "extensions/browser/api/hid/hid_device_manager.h" #include "extensions/browser/api/hid/hid_device_manager.h"
#include "extensions/browser/api/idle/idle_manager_factory.h" #include "extensions/browser/api/idle/idle_manager_factory.h"
#include "extensions/browser/api/management/management_api.h" #include "extensions/browser/api/management/management_api.h"
#include "extensions/browser/api/networking_config/networking_config_service_factory.h"
#include "extensions/browser/api/networking_private/networking_private_event_router_factory.h" #include "extensions/browser/api/networking_private/networking_private_event_router_factory.h"
#include "extensions/browser/api/runtime/runtime_api.h" #include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/api/serial/serial_connection.h" #include "extensions/browser/api/serial/serial_connection.h"
...@@ -47,6 +48,9 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { ...@@ -47,6 +48,9 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
HidDeviceManager::GetFactoryInstance(); HidDeviceManager::GetFactoryInstance();
IdleManagerFactory::GetInstance(); IdleManagerFactory::GetInstance();
ManagementAPI::GetFactoryInstance(); ManagementAPI::GetFactoryInstance();
#if defined(OS_CHROMEOS)
NetworkingConfigServiceFactory::GetInstance();
#endif
#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MACOSX) #if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_MACOSX)
NetworkingPrivateEventRouterFactory::GetInstance(); NetworkingPrivateEventRouterFactory::GetInstance();
#endif #endif
......
...@@ -1013,6 +1013,8 @@ enum HistogramValue { ...@@ -1013,6 +1013,8 @@ enum HistogramValue {
FILEMANAGERPRIVATE_SEARCHFILESBYHASHES, FILEMANAGERPRIVATE_SEARCHFILESBYHASHES,
EASYUNLOCKPRIVATE_SHOWERRORBUBBLE, EASYUNLOCKPRIVATE_SHOWERRORBUBBLE,
EXTENSIONVIEWINTERNAL_NAVIGATE, EXTENSIONVIEWINTERNAL_NAVIGATE,
NETWORKING_CONFIG_SETNETWORKFILTER,
NETWORKING_CONFIG_FINISHAUTHENTICATION,
// Last entry: Add new entries above and ensure to update // Last entry: Add new entries above and ensure to update
// tools/metrics/histograms/histograms.xml. // tools/metrics/histograms/histograms.xml.
ENUM_BOUNDARY ENUM_BOUNDARY
......
...@@ -199,6 +199,10 @@ ...@@ -199,6 +199,10 @@
"63ED55E43214C211F82122ED56407FF1A807F2A3" // http://crbug.com/448569 "63ED55E43214C211F82122ED56407FF1A807F2A3" // http://crbug.com/448569
] ]
}, },
"networking.config": {
"dependencies": ["permission:networking.config"],
"contexts": ["blessed_extension"]
},
"networkingPrivate": { "networkingPrivate": {
"dependencies": ["permission:networkingPrivate"], "dependencies": ["permission:networkingPrivate"],
"contexts": ["blessed_extension"] "contexts": ["blessed_extension"]
......
...@@ -201,6 +201,11 @@ ...@@ -201,6 +201,11 @@
"channel": "stable", "channel": "stable",
"extension_types": ["extension", "legacy_packaged_app", "platform_app"] "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
}, },
"networking.config": {
"channel": "dev",
"platforms": ["chromeos"],
"extension_types": ["extension"]
},
"networkingPrivate": { "networkingPrivate": {
"channel": "stable", "channel": "stable",
"extension_types": ["extension", "legacy_packaged_app", "platform_app"], "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
......
...@@ -49,6 +49,13 @@ namespace networking.config { ...@@ -49,6 +49,13 @@ namespace networking.config {
failed failed
}; };
// Invoked by $(setNetworkFilter) when the respective operation is finished.
callback SetNetworkFilterCallback = void();
// Invoked by $(finishAuthentication) when the respective operation is
// finished.
callback FinishAuthenticationCallback = void();
interface Functions { interface Functions {
// Allows an extension to define network filters for the networks it can // Allows an extension to define network filters for the networks it can
// handle. A call to this function will remove all filters previously // handle. A call to this function will remove all filters previously
...@@ -56,16 +63,20 @@ namespace networking.config { ...@@ -56,16 +63,20 @@ namespace networking.config {
// |networks|: Network filters to set. Every <code>NetworkInfo</code> must // |networks|: Network filters to set. Every <code>NetworkInfo</code> must
// either have the <code>SSID</code> or <code>HexSSID</code> // either have the <code>SSID</code> or <code>HexSSID</code>
// set. Other fields will be ignored. // set. Other fields will be ignored.
void setNetworkFilter(NetworkInfo[] networks); // |callback|: Called back when this operation is finished.
void setNetworkFilter(NetworkInfo[] networks,
SetNetworkFilterCallback callback);
// Called by the extension to notify the network config API that it finished // Called by the extension to notify the network config API that it finished
// a captive portal authentication attempt and hand over the result of the // a captive portal authentication attempt and hand over the result of the
// attempt. This function must only be called with the GUID of the latest // attempt. This function must only be called with the GUID of the latest
// $(onCaptivePortalDetected) event. // $(onCaptivePortalDetected) event.
// |GUID|: unique network identifier obtained from // |GUID|: Unique network identifier obtained from
// $(onCaptivePortalDetected). // $(onCaptivePortalDetected).
// |result|: the result of the authentication attempt // |result|: The result of the authentication attempt.
void finishAuthentication(DOMString GUID, AuthenticationResult result); // |callback|: Called back when this operation is finished.
void finishAuthentication(DOMString GUID, AuthenticationResult result,
FinishAuthenticationCallback callback);
}; };
interface Events { interface Events {
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
], ],
# ChromeOS-specific schemas. # ChromeOS-specific schemas.
'chromeos_schema_files': [ 'chromeos_schema_files': [
'networking_config.idl',
'vpn_provider.idl', 'vpn_provider.idl',
'webcam_private.idl', 'webcam_private.idl',
], ],
......
...@@ -143,6 +143,7 @@ class APIPermission { ...@@ -143,6 +143,7 @@ class APIPermission {
kMDns, kMDns,
kMusicManagerPrivate, kMusicManagerPrivate,
kNativeMessaging, kNativeMessaging,
kNetworkingConfig,
kNetworkingPrivate, kNetworkingPrivate,
kNotificationProvider, kNotificationProvider,
kNotifications, kNotifications,
......
...@@ -73,6 +73,11 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions() ...@@ -73,6 +73,11 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions()
{APIPermission::kOverrideEscFullscreen, {APIPermission::kOverrideEscFullscreen,
"app.window.fullscreen.overrideEsc"}, "app.window.fullscreen.overrideEsc"},
{APIPermission::kIdle, "idle"}, {APIPermission::kIdle, "idle"},
{APIPermission::kNetworkingConfig,
"networking.config",
APIPermissionInfo::kFlagNone,
IDS_EXTENSION_PROMPT_WARNING_NETWORKING_CONFIG,
PermissionMessage::kNetworkingConfig},
{APIPermission::kNetworkingPrivate, {APIPermission::kNetworkingPrivate,
"networkingPrivate", "networkingPrivate",
APIPermissionInfo::kFlagCannotBeOptional, APIPermissionInfo::kFlagCannotBeOptional,
......
...@@ -100,6 +100,7 @@ class PermissionMessage { ...@@ -100,6 +100,7 @@ class PermissionMessage {
kHosts4OrMoreReadOnly, kHosts4OrMoreReadOnly,
kHostsAllReadOnly, kHostsAllReadOnly,
kInterceptAllKeys, kInterceptAllKeys,
kNetworkingConfig,
// Last entry: Add new entries above and ensure to update the // Last entry: Add new entries above and ensure to update the
// "ExtensionPermission2" enum in tools/metrics/histograms/histograms.xml. // "ExtensionPermission2" enum in tools/metrics/histograms/histograms.xml.
kEnumBoundary, kEnumBoundary,
......
...@@ -890,6 +890,12 @@ ...@@ -890,6 +890,12 @@
'../chromeos/chromeos.gyp:chromeos', '../chromeos/chromeos.gyp:chromeos',
], ],
'sources': [ 'sources': [
'browser/api/networking_config/networking_config_api.cc',
'browser/api/networking_config/networking_config_api.h',
'browser/api/networking_config/networking_config_service.cc',
'browser/api/networking_config/networking_config_service.h',
'browser/api/networking_config/networking_config_service_factory.cc',
'browser/api/networking_config/networking_config_service_factory.h',
'browser/api/vpn_provider/vpn_provider_api.cc', 'browser/api/vpn_provider/vpn_provider_api.cc',
'browser/api/vpn_provider/vpn_provider_api.h', 'browser/api/vpn_provider/vpn_provider_api.h',
'browser/api/vpn_provider/vpn_service.cc', 'browser/api/vpn_provider/vpn_service.cc',
......
...@@ -359,6 +359,9 @@ ...@@ -359,6 +359,9 @@
<message name="IDS_DEVICE_UNKNOWN_VENDOR" desc="String used when no human-readable vendor name is available for a device."> <message name="IDS_DEVICE_UNKNOWN_VENDOR" desc="String used when no human-readable vendor name is available for a device.">
Vendor <ph name="VENDOR_ID">$1<ex>0x1234</ex></ph> Vendor <ph name="VENDOR_ID">$1<ex>0x1234</ex></ph>
</message> </message>
<message name="IDS_EXTENSION_PROMPT_WARNING_NETWORKING_CONFIG" desc="Permission string for Networking Config API.">
Configure network connections
</message>
<message name="IDS_EXTENSION_PROMPT_WARNING_NETWORKING_PRIVATE" desc="Permission string for Networking Private API."> <message name="IDS_EXTENSION_PROMPT_WARNING_NETWORKING_PRIVATE" desc="Permission string for Networking Private API.">
Manage network connections Manage network connections
</message> </message>
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
'browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc', 'browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc',
'browser/api/idle/idle_api_unittest.cc', 'browser/api/idle/idle_api_unittest.cc',
'browser/api/mime_handler_private/mime_handler_private_unittest.cc', 'browser/api/mime_handler_private/mime_handler_private_unittest.cc',
'browser/api/networking_config/networking_config_service_chromeos_unittest.cc',
'browser/api/power/power_api_unittest.cc', 'browser/api/power/power_api_unittest.cc',
'browser/api/sockets_tcp/sockets_tcp_api_unittest.cc', 'browser/api/sockets_tcp/sockets_tcp_api_unittest.cc',
'browser/api/sockets_udp/sockets_udp_api_unittest.cc', 'browser/api/sockets_udp/sockets_udp_api_unittest.cc',
......
...@@ -47268,6 +47268,8 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -47268,6 +47268,8 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="952" label="FILEMANAGERPRIVATE_SEARCHFILESBYHASHES"/> <int value="952" label="FILEMANAGERPRIVATE_SEARCHFILESBYHASHES"/>
<int value="953" label="EASYUNLOCKPRIVATE_SHOWERRORBUBBLE"/> <int value="953" label="EASYUNLOCKPRIVATE_SHOWERRORBUBBLE"/>
<int value="954" label="EXTENSIONVIEWINTERNAL_NAVIGATE"/> <int value="954" label="EXTENSIONVIEWINTERNAL_NAVIGATE"/>
<int value="955" label="NETWORKING_CONFIG_SETNETWORKFILTER"/>
<int value="956" label="NETWORKING_CONFIG_FINISHAUTHENTICATION"/>
</enum> </enum>
<enum name="ExtensionInstallCause" type="int"> <enum name="ExtensionInstallCause" type="int">
...@@ -47455,6 +47457,7 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -47455,6 +47457,7 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="66" label="kTopSites"/> <int value="66" label="kTopSites"/>
<int value="67" label="kU2fDevices"/> <int value="67" label="kU2fDevices"/>
<int value="68" label="kDocumentScan"/> <int value="68" label="kDocumentScan"/>
<int value="69" label="kNetworkingConfig"/>
</enum> </enum>
<enum name="ExtensionServiceVerifyAllSuccess" type="int"> <enum name="ExtensionServiceVerifyAllSuccess" type="int">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment