Chromium Code Reviews| Index: chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc |
| diff --git a/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc b/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1d0ab3b2f9627b4fc18342533e258c22e4e22255 |
| --- /dev/null |
| +++ b/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc |
| @@ -0,0 +1,178 @@ |
| +// 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 "chrome/browser/local_discovery/wifi/bootstrapping_device_lister.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/location.h" |
| +#include "base/message_loop/message_loop_proxy.h" |
| + |
| +namespace local_discovery { |
| + |
| +namespace wifi { |
| + |
| +namespace { |
| + |
| +const char kPrivetSuffix[] = "prv"; |
| +// 3 for prv, 3 for type, one for connection status. |
| +const size_t kPrivetCharactersAfterSeparator = 7; |
| + |
| +const struct { |
| + const char* short_name; |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
const char* const
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + const char* long_name; |
| +} kPrivetShortNames[] = { |
| + {"cam", "camera"}, |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
I thing it should be 2 spaces
Noam Samuel
2014/05/22 18:43:59
I'd be reluctant to make any changes clang-format
|
| + {"pri", "printer"}, |
| + {NULL, NULL} // Sentinel value |
| +}; |
| + |
| +const char* kPrivetDeviceLongName = "device"; |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
const char kPrivetDeviceLongName[]
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + |
| +std::string ExpandDeviceKind(const std::string& device_kind_short) { |
| + int i = 0; |
| + |
| + while (kPrivetShortNames[i].short_name) { |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
for loop is better
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + if (device_kind_short == kPrivetShortNames[i].short_name) { |
| + return kPrivetShortNames[i].long_name; |
| + } |
| + |
| + i++; |
| + } |
| + return kPrivetDeviceLongName; |
| +} |
| + |
| +BootstrappingDeviceDescription::ConnectionStatus GetConnectionStatus( |
| + char signifier) { |
| + if (signifier == 'O') |
| + return BootstrappingDeviceDescription::ONLINE; |
| + if (signifier == 'F') |
| + return BootstrappingDeviceDescription::OFFLINE; |
| + if (signifier == 'C') |
| + return BootstrappingDeviceDescription::CONNECTING; |
| + if (signifier == 'N') |
| + return BootstrappingDeviceDescription::NOT_CONFIGURED; |
| + if (signifier == 'L') |
| + return BootstrappingDeviceDescription::LOCAL_ONLY; |
| + |
| + LOG(WARNING) << "Unknown WiFi connection state signifier " << signifier; |
| + return BootstrappingDeviceDescription::NOT_CONFIGURED; |
| +} |
| + |
| +// Return whether or not the ssid ends with ".privet" and has two periods |
| +bool IsPrivetSSID(const std::string& ssid) { |
| + bool ends_with_privet = |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
EndsWith()
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + (ssid.length() >= sizeof(kPrivetSuffix) - 1 && |
| + ssid.rfind(kPrivetSuffix) == ssid.length() - sizeof(kPrivetSuffix) + 1); |
| + |
| + if (!ends_with_privet) |
| + return false; |
| + |
| + size_t at_pos = ssid.rfind('@'); |
| + |
| + if (at_pos == std::string::npos) |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
if (ssid[ssid.length() - kPrivetCharactersAfterSep
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + return false; |
| + |
| + if (ssid.length() - at_pos != kPrivetCharactersAfterSeparator + 1) |
| + return false; |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
or maybe just use base::SplitString
Noam Samuel
2014/05/22 18:43:59
Did the first one.
|
| + |
| + return true; |
| +} |
| + |
| +void FillBootstrappingDeviceDescription( |
| + const std::string internal_id, |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
string&
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + const std::string ssid, |
| + BootstrappingDeviceDescription* description) { |
| + description->device_network_id = internal_id; |
| + description->device_ssid = ssid; |
| + |
| + size_t at_pos = ssid.rfind('@'); |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
base::SplitString ?
Noam Samuel
2014/05/22 18:43:59
We don't really use the split strings directly, so
|
| + |
| + description->device_name = ssid.substr(0, at_pos); |
| + description->device_kind = ExpandDeviceKind(ssid.substr(at_pos + 1, 3)); |
| + description->connection_status = GetConnectionStatus(ssid.at(at_pos + 4)); |
| +} |
| + |
| +} // namespace |
| + |
| +BootstrappingDeviceDescription::BootstrappingDeviceDescription() { |
| +} |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
: connection_status(SOMETHING)
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + |
| +BootstrappingDeviceDescription::~BootstrappingDeviceDescription() { |
| +} |
| + |
| +BootstrappingDeviceLister::BootstrappingDeviceLister( |
| + WifiManager* wifi_manager, |
| + const UpdateCallback& update_callback) |
| + : wifi_manager_(wifi_manager), |
| + update_callback_(update_callback), |
| + started_(false), |
| + weak_factory_(this) { |
| +} |
| + |
| +void BootstrappingDeviceLister::Start() { |
| + DCHECK(!started_); |
| + |
| + started_ = true; |
| + |
| + network_watcher_ = wifi_manager_->CreateNetworkListWatcher(base::Bind( |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
break before base::Bind
Noam Samuel
2014/05/22 18:43:59
Again, clang-format reverts this change when I run
|
| + &BootstrappingDeviceLister::OnGotSSIDList, base::Unretained(this))); |
| + |
| + network_watcher_->Start(); |
| + |
| + wifi_manager_->GetSSIDList(base::Bind( |
| + &BootstrappingDeviceLister::OnGotSSIDList, weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +void BootstrappingDeviceLister::OnGotSSIDList( |
| + const std::vector<NetworkProperties>& ssids) { |
| + ActiveDeviceMap active_devices; |
| + |
| + for (std::vector<NetworkProperties>::const_iterator i = ssids.begin(); |
| + i != ssids.end(); |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
usually size_t i = 0 ... for are shorter
Noam Samuel
2014/05/22 18:43:59
Done.
|
| + i++) { |
| + if (IsPrivetSSID(i->ssid)) { |
| + active_devices[i->ssid] = i->internal_id; |
| + } |
| + } |
| + |
| + base::WeakPtr<BootstrappingDeviceLister> weak_this = |
| + weak_factory_.GetWeakPtr(); |
| + |
| + // Find new or changed SSIDs |
| + for (ActiveDeviceMap::iterator i = active_devices.begin(); |
| + weak_this && i != active_devices.end(); |
|
Vitaly Buka (NO REVIEWS)
2014/05/22 05:51:36
same
Noam Samuel
2014/05/22 18:43:59
This is iteration over a map.
|
| + i++) { |
| + ActiveDeviceMap::iterator found = active_devices_.find(i->first); |
| + // Send an update if the network was not last available, or if its internal |
| + // ID has changed. |
| + if (found == active_devices_.end() || found->second != i->second) { |
| + BootstrappingDeviceDescription description; |
| + FillBootstrappingDeviceDescription(i->second, i->first, &description); |
| + update_callback_.Run(true, description); |
| + } |
| + } |
| + |
| + // Swap active_devices_ and active_devices now so we're not iterating over and |
| + // instance variable when the object may be deleted. Also, because we need to |
| + // swap them at some point. |
| + active_devices_.swap(active_devices); |
| + |
| + // Find removed SSIDs |
| + for (ActiveDeviceMap::iterator i = active_devices.begin(); |
| + weak_this && i != active_devices.end(); |
| + i++) { |
| + if (active_devices_.find(i->first) == active_devices_.end()) { |
| + BootstrappingDeviceDescription description; |
| + FillBootstrappingDeviceDescription(i->second, i->first, &description); |
| + update_callback_.Run(false, description); |
| + } |
| + } |
| +} |
| + |
| +BootstrappingDeviceLister::~BootstrappingDeviceLister() { |
| +} |
| + |
| +} // namespace wifi |
| + |
| +} // namespace local_discovery |