Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / networking_config / networking_config_service.cc
blob7b4e5eca8af2e50762238e7efc4f7ddc5d6fc4ac
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <algorithm>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/lazy_instance.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "chromeos/network/managed_network_configuration_handler.h"
13 #include "chromeos/network/network_handler.h"
14 #include "chromeos/network/network_state.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "extensions/browser/api/networking_config/networking_config_service.h"
17 #include "extensions/common/api/networking_config.h"
19 namespace extensions {
21 namespace {
23 bool IsValidNonEmptyHexString(const std::string& input) {
24 size_t count = input.size();
25 if (count == 0 || (count % 2) != 0)
26 return false;
27 for (const char& c : input)
28 if (!base::IsHexDigit<char>(c))
29 return false;
30 return true;
33 } // namespace
35 NetworkingConfigService::AuthenticationResult::AuthenticationResult()
36 : authentication_state(NetworkingConfigService::NOTRY) {
39 NetworkingConfigService::AuthenticationResult::AuthenticationResult(
40 ExtensionId extension_id,
41 std::string guid,
42 AuthenticationState authentication_state)
43 : extension_id(extension_id),
44 guid(guid),
45 authentication_state(authentication_state) {
48 NetworkingConfigService::NetworkingConfigService(
49 content::BrowserContext* browser_context,
50 scoped_ptr<EventDelegate> event_delegate,
51 ExtensionRegistry* extension_registry)
52 : browser_context_(browser_context),
53 registry_observer_(this),
54 event_delegate_(event_delegate.Pass()),
55 weak_factory_(this) {
56 registry_observer_.Add(extension_registry);
59 NetworkingConfigService::~NetworkingConfigService() {
62 void NetworkingConfigService::OnExtensionUnloaded(
63 content::BrowserContext* browser_context,
64 const Extension* extension,
65 UnloadedExtensionInfo::Reason reason) {
66 UnregisterExtension(extension->id());
69 std::string NetworkingConfigService::LookupExtensionIdForHexSsid(
70 std::string hex_ssid) const {
71 // Transform hex_ssid to uppercase.
72 transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
74 const auto it = hex_ssid_to_extension_id_.find(hex_ssid);
75 if (it == hex_ssid_to_extension_id_.end())
76 return std::string();
77 return it->second;
80 bool NetworkingConfigService::IsRegisteredForCaptivePortalEvent(
81 std::string extension_id) const {
82 return event_delegate_->HasExtensionRegisteredForEvent(extension_id);
85 bool NetworkingConfigService::RegisterHexSsid(std::string hex_ssid,
86 const std::string& extension_id) {
87 if (!IsValidNonEmptyHexString(hex_ssid)) {
88 LOG(ERROR) << "\'" << hex_ssid << "\' is not a valid hex encoded string.";
89 return false;
92 // Transform hex_ssid to uppercase.
93 transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
95 return hex_ssid_to_extension_id_.insert(make_pair(hex_ssid, extension_id))
96 .second;
99 void NetworkingConfigService::UnregisterExtension(
100 const std::string& extension_id) {
101 for (auto it = hex_ssid_to_extension_id_.begin();
102 it != hex_ssid_to_extension_id_.end();) {
103 if (it->second == extension_id)
104 hex_ssid_to_extension_id_.erase(it++);
105 else
106 ++it;
110 const NetworkingConfigService::AuthenticationResult&
111 NetworkingConfigService::GetAuthenticationResult() const {
112 return authentication_result_;
115 void NetworkingConfigService::ResetAuthenticationResult() {
116 authentication_result_ = AuthenticationResult();
117 authentication_callback_.Reset();
120 void NetworkingConfigService::SetAuthenticationResult(
121 const AuthenticationResult& authentication_result) {
122 authentication_result_ = authentication_result;
123 if (authentication_result.authentication_state != SUCCESS) {
124 LOG(WARNING) << "Captive Portal Authentication failed.";
125 return;
128 if (!authentication_callback_.is_null()) {
129 authentication_callback_.Run();
130 authentication_callback_.Reset();
134 void NetworkingConfigService::OnGotProperties(
135 const std::string& extension_id,
136 const std::string& guid,
137 const base::Closure& authentication_callback,
138 const std::string& service_path,
139 const base::DictionaryValue& onc_network_config) {
140 authentication_result_ = NetworkingConfigService::AuthenticationResult(
141 std::string(), guid, NetworkingConfigService::NOTRY);
142 authentication_callback_ = authentication_callback;
144 // Try to extract |bssid| field.
145 const base::DictionaryValue* wifi_with_state = nullptr;
146 std::string bssid;
147 scoped_ptr<Event> event;
148 if (onc_network_config.GetDictionaryWithoutPathExpansion(
149 ::onc::network_config::kWiFi, &wifi_with_state) &&
150 wifi_with_state->GetStringWithoutPathExpansion(::onc::wifi::kBSSID,
151 &bssid)) {
152 event = CreatePortalDetectedEventAndDispatch(extension_id, guid, &bssid);
153 } else {
154 event = CreatePortalDetectedEventAndDispatch(extension_id, guid, nullptr);
157 EventRouter::Get(browser_context_)
158 ->DispatchEventToExtension(extension_id, event.Pass());
161 void NetworkingConfigService::OnGetPropertiesFailed(
162 const std::string& extension_id,
163 const std::string& guid,
164 const std::string& error_name,
165 scoped_ptr<base::DictionaryValue> error_data) {
166 LOG(WARNING) << "Failed to determine BSSID for network with guid " << guid
167 << ": " << error_name;
168 scoped_ptr<Event> event =
169 CreatePortalDetectedEventAndDispatch(extension_id, guid, nullptr);
170 EventRouter::Get(browser_context_)
171 ->DispatchEventToExtension(extension_id, event.Pass());
174 scoped_ptr<Event> NetworkingConfigService::CreatePortalDetectedEventAndDispatch(
175 const std::string& extension_id,
176 const std::string& guid,
177 const std::string* bssid) {
178 const chromeos::NetworkState* network = chromeos::NetworkHandler::Get()
179 ->network_state_handler()
180 ->GetNetworkStateFromGuid(guid);
181 if (!network)
182 return nullptr;
184 // Populate the NetworkInfo object.
185 api::networking_config::NetworkInfo network_info;
186 network_info.type = api::networking_config::NETWORK_TYPE_WIFI;
187 const std::vector<uint8_t>& raw_ssid = network->raw_ssid();
188 std::string hex_ssid =
189 base::HexEncode(vector_as_array(&raw_ssid), raw_ssid.size());
190 network_info.hex_ssid = make_scoped_ptr(new std::string(hex_ssid));
191 network_info.ssid = make_scoped_ptr(new std::string(network->name()));
192 network_info.guid = make_scoped_ptr(new std::string(network->guid()));
193 if (bssid)
194 network_info.bssid.reset(new std::string(*bssid));
195 scoped_ptr<base::ListValue> results =
196 api::networking_config::OnCaptivePortalDetected::Create(network_info);
197 scoped_ptr<Event> event(
198 new Event(events::NETWORKING_CONFIG_ON_CAPTIVE_PORTAL_DETECTED,
199 api::networking_config::OnCaptivePortalDetected::kEventName,
200 results.Pass()));
201 return event.Pass();
204 void NetworkingConfigService::DispatchPortalDetectedEvent(
205 const std::string& extension_id,
206 const std::string& guid,
207 const base::Closure& authentication_callback) {
208 // This dispatch starts a new cycle of portal detection and authentication.
209 // Ensure that any old |authentication_callback_| is dropped.
210 authentication_callback_.Reset();
212 // Determine |service_path| of network identified by |guid|.
213 chromeos::NetworkHandler* network_handler = chromeos::NetworkHandler::Get();
214 const chromeos::NetworkState* network =
215 network_handler->network_state_handler()->GetNetworkStateFromGuid(guid);
216 if (!network)
217 return;
218 const std::string service_path = network->path();
220 network_handler->managed_network_configuration_handler()->GetProperties(
221 service_path, base::Bind(&NetworkingConfigService::OnGotProperties,
222 weak_factory_.GetWeakPtr(), extension_id, guid,
223 authentication_callback),
224 base::Bind(&NetworkingConfigService::OnGetPropertiesFailed,
225 weak_factory_.GetWeakPtr(), extension_id, guid));
228 } // namespace extensions