Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1294)

Unified Diff: chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc

Issue 288043004: Bootstrapping device lister plus tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@wifi_lib1
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..1123e341ebc7f1aa0efe3c5461151b8b59d1e5b9
--- /dev/null
+++ b/chrome/browser/local_discovery/wifi/bootstrapping_device_lister.cc
@@ -0,0 +1,173 @@
+// 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 <algorithm>
+#include <iterator>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/strings/string_util.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* const short_name;
+ const char* const long_name;
+} kPrivetShortNames[] = {{"cam", "camera"}, {"pri", "printer"}};
+
+const struct {
+ char signifier;
+ BootstrappingDeviceDescription::ConnectionStatus status;
+} kPrivetConnectionStatuses[] = {
+ {'C', BootstrappingDeviceDescription::CONNECTING},
+ {'F', BootstrappingDeviceDescription::OFFLINE},
+ {'L', BootstrappingDeviceDescription::LOCAL_ONLY},
+ {'N', BootstrappingDeviceDescription::NOT_CONFIGURED},
+ {'O', BootstrappingDeviceDescription::ONLINE},
+};
+
+const char kPrivetDeviceLongName[] = "device";
+
+std::string ExpandDeviceKind(const std::string& device_kind_short) {
+ for (size_t i = 0; i < arraysize(kPrivetShortNames); i++) {
+ if (device_kind_short == kPrivetShortNames[i].short_name) {
+ return kPrivetShortNames[i].long_name;
+ }
+ }
+ return kPrivetDeviceLongName;
+}
+
+BootstrappingDeviceDescription::ConnectionStatus GetConnectionStatus(
+ char signifier) {
+ for (size_t i = 0; i < arraysize(kPrivetConnectionStatuses); i++) {
+ if (signifier == kPrivetConnectionStatuses[i].signifier) {
+ return kPrivetConnectionStatuses[i].status;
+ }
+ }
+
+ LOG(WARNING) << "Unknown WiFi connection state signifier " << signifier;
+ return BootstrappingDeviceDescription::NOT_CONFIGURED;
+}
+
+// Return true if the SSID is a privet ssid and fills |description| with its
+// attributes.
+bool ParsePrivetSSID(const std::string& internal_id,
+ const std::string& ssid,
+ BootstrappingDeviceDescription* description) {
+ if (!EndsWith(ssid, kPrivetSuffix, true))
+ return false;
+
+ size_t at_pos = ssid.length() - kPrivetCharactersAfterSeparator - 1;
+
+ if (ssid[at_pos] != '@' || ssid.find('@', at_pos + 1) != std::string::npos)
+ return false;
+
+ description->device_network_id = internal_id;
+ description->device_ssid = ssid;
+
+ 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));
+
+ return true;
+}
+
+} // namespace
+
+BootstrappingDeviceDescription::BootstrappingDeviceDescription()
+ : connection_status(NOT_CONFIGURED) {
+}
+
+BootstrappingDeviceDescription::~BootstrappingDeviceDescription() {
+}
+
+BootstrappingDeviceLister::BootstrappingDeviceLister(
+ WifiManager* wifi_manager,
+ const UpdateCallback& update_callback)
+ : wifi_manager_(wifi_manager),
+ update_callback_(update_callback),
+ started_(false),
+ weak_factory_(this) {
+}
+
+BootstrappingDeviceLister::~BootstrappingDeviceLister() {
+ if (started_)
+ wifi_manager_->RemoveNetworkListObserver(this);
+}
+
+void BootstrappingDeviceLister::Start() {
+ DCHECK(!started_);
+
+ started_ = true;
+
+ wifi_manager_->AddNetworkListObserver(this);
+
+ wifi_manager_->GetSSIDList(
+ base::Bind(&BootstrappingDeviceLister::OnNetworkListChanged,
+ weak_factory_.GetWeakPtr()));
+}
+
+void BootstrappingDeviceLister::OnNetworkListChanged(
+ const std::vector<NetworkProperties>& ssids) {
+ ActiveDeviceList new_devices;
+
+ for (size_t i = 0; i < ssids.size(); i++) {
+ new_devices.push_back(make_pair(ssids[i].ssid, ssids[i].guid));
+ }
+
+ std::sort(new_devices.begin(), new_devices.end());
+
+ base::WeakPtr<BootstrappingDeviceLister> weak_this =
+ weak_factory_.GetWeakPtr();
+ // Find new or changed SSIDs
+ UpdateChangedSSIDs(true, new_devices, active_devices_);
+ if (!weak_this)
+ return;
+
+ // Find removed SSIDs
+ UpdateChangedSSIDs(false, active_devices_, new_devices);
+ if (!weak_this)
+ return;
+
+ active_devices_.swap(new_devices);
+}
+
+void BootstrappingDeviceLister::UpdateChangedSSIDs(
+ bool available,
+ const ActiveDeviceList& changed,
+ const ActiveDeviceList& original) {
+ base::WeakPtr<BootstrappingDeviceLister> weak_this =
+ weak_factory_.GetWeakPtr();
+
+ ActiveDeviceList changed_devices;
+ std::set_difference(changed.begin(),
+ changed.end(),
+ original.begin(),
+ original.end(),
+ std::back_inserter(changed_devices));
+
+ for (ActiveDeviceList::iterator i = changed_devices.begin();
+ weak_this && i != changed_devices.end();
+ i++) {
+ BootstrappingDeviceDescription description;
+ if (ParsePrivetSSID(i->second, i->first, &description)) {
+ update_callback_.Run(available, description);
+ }
+ }
+}
+
+} // namespace wifi
+
+} // namespace local_discovery

Powered by Google App Engine
This is Rietveld 408576698