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

Unified Diff: chromeos/network/geolocation_handler.cc

Issue 11887008: Deprecate ShillNetworkClient and add GeolocationHandler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittest Created 7 years, 11 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: chromeos/network/geolocation_handler.cc
diff --git a/chromeos/network/geolocation_handler.cc b/chromeos/network/geolocation_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c08ea141d2fb874e0ca136c88bb74ce768bf6aab
--- /dev/null
+++ b/chromeos/network/geolocation_handler.cc
@@ -0,0 +1,174 @@
+// Copyright (c) 2013 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 "chromeos/network/geolocation_handler.h"
+
+#include "base/bind.h"
+#include "base/string_number_conversions.h"
+#include "base/values.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/shill_manager_client.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+static GeolocationHandler* g_geolocation_handler = NULL;
+
+GeolocationHandler::GeolocationHandler()
+ : wifi_enabled_(false),
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+}
+
+GeolocationHandler::~GeolocationHandler() {
+ ShillManagerClient* manager_client =
+ DBusThreadManager::Get()->GetShillManagerClient();
+ if (manager_client)
+ manager_client->RemovePropertyChangedObserver(this);
+}
+
+void GeolocationHandler::Init() {
+ ShillManagerClient* manager_client =
+ DBusThreadManager::Get()->GetShillManagerClient();
+ manager_client->GetProperties(
+ base::Bind(&GeolocationHandler::ManagerPropertiesCallback,
+ weak_ptr_factory_.GetWeakPtr()));
+ manager_client->AddPropertyChangedObserver(this);
+}
+
+// static
+void GeolocationHandler::Initialize() {
+ CHECK(!g_geolocation_handler);
+ g_geolocation_handler = new GeolocationHandler();
+ g_geolocation_handler->Init();
+}
+
+// static
+void GeolocationHandler::Shutdown() {
+ CHECK(g_geolocation_handler);
+ delete g_geolocation_handler;
+ g_geolocation_handler = NULL;
+}
+
+// static
+GeolocationHandler* GeolocationHandler::Get() {
+ CHECK(g_geolocation_handler)
+ << "GeolocationHandler::Get() called before Initialize()";
+ return g_geolocation_handler;
+}
+
+bool GeolocationHandler::GetWifiAccessPoints(
+ WifiAccessPointVector* access_points, int64* age_ms) {
+ if (!wifi_enabled_)
+ return false;
+ // Always request updated access points.
+ RequestWifiAccessPoints();
+ // If no data has been received, return false.
+ if (geolocation_received_time_.is_null())
+ return false;
+ if (access_points)
+ *access_points = wifi_access_points_;
+ if (age_ms) {
+ base::TimeDelta dtime = base::Time::Now() - geolocation_received_time_;
+ *age_ms = dtime.InMilliseconds();
+ }
+ return true;
+}
+
+void GeolocationHandler::OnPropertyChanged(const std::string& key,
+ const base::Value& value) {
+ HandlePropertyChanged(key, value);
+}
+
+//------------------------------------------------------------------------------
+// Private methods
+
+void GeolocationHandler::ManagerPropertiesCallback(
+ DBusMethodCallStatus call_status,
+ const base::DictionaryValue& properties) {
+ const base::Value* value = NULL;
+ if (properties.Get(flimflam::kEnabledTechnologiesProperty, &value) && value)
+ HandlePropertyChanged(flimflam::kEnabledTechnologiesProperty, *value);
+}
+
+void GeolocationHandler::HandlePropertyChanged(const std::string& key,
+ const base::Value& value) {
+ if (key != flimflam::kEnabledTechnologiesProperty)
+ return;
+ const base::ListValue* technologies = NULL;
+ if (!value.GetAsList(&technologies) || !technologies)
+ return;
+ bool wifi_was_enabled = wifi_enabled_;
+ wifi_enabled_ = false;
+ for (base::ListValue::const_iterator iter = technologies->begin();
+ iter != technologies->end(); ++iter) {
+ std::string technology;
+ (*iter)->GetAsString(&technology);
+ if (technology == flimflam::kTypeWifi) {
+ wifi_enabled_ = true;
+ break;
+ }
+ }
+ if (!wifi_was_enabled && wifi_enabled_)
+ RequestWifiAccessPoints(); // Request initial location data.
+}
+
+void GeolocationHandler::RequestWifiAccessPoints() {
+ DBusThreadManager::Get()->GetShillManagerClient()->GetNetworksForGeolocation(
+ base::Bind(&GeolocationHandler::GeolocationCallback,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void GeolocationHandler::GeolocationCallback(
+ DBusMethodCallStatus call_status,
+ const base::DictionaryValue& properties) {
+ if (call_status != DBUS_METHOD_CALL_SUCCESS) {
+ LOG(ERROR) << "Failed to get Geolocation data: " << call_status;
+ return;
+ }
+ wifi_access_points_.clear();
+ if (properties.empty())
+ return; // No enabled devices, don't update received time.
+
+ // Dictionary<device_type, entry_list>
+ for (base::DictionaryValue::Iterator iter(properties);
+ iter.HasNext(); iter.Advance()) {
+ const base::ListValue* entry_list = NULL;
+ if (!iter.value().GetAsList(&entry_list)) {
+ LOG(WARNING) << "Geolocation dictionary value not a List: " << iter.key();
+ continue;
+ }
+ // List[Dictionary<key, value_str>]
+ for (size_t i = 0; i < entry_list->GetSize(); ++i) {
+ const base::DictionaryValue* entry = NULL;
+ if (!entry_list->GetDictionary(i, &entry) || !entry) {
+ LOG(WARNING) << "Geolocation list value not a Dictionary: " << i;
+ continue;
+ }
+ // Docs: developers.google.com/maps/documentation/business/geolocation
+ WifiAccessPoint wap;
+ entry->GetString(shill::kGeoMacAddressProperty, &wap.mac_address);
+ std::string age_str;
+ if (entry->GetString(shill::kGeoAgeProperty, &age_str)) {
+ int64 age_ms;
+ if (base::StringToInt64(age_str, &age_ms)) {
+ wap.timestamp =
+ base::Time::Now() - base::TimeDelta::FromMilliseconds(age_ms);
+ }
+ }
+ std::string strength_str;
+ if (entry->GetString(shill::kGeoSignalStrengthProperty, &strength_str))
+ base::StringToInt(strength_str, &wap.signal_strength);
+ std::string signal_str;
+ if (entry->GetString(shill::kGeoSignalToNoiseRatioProperty, &signal_str))
+ base::StringToInt(signal_str, &wap.signal_to_noise);
+ std::string channel_str;
+ if (entry->GetString(shill::kGeoChannelProperty, &channel_str))
+ base::StringToInt(channel_str, &wap.channel);
+ wifi_access_points_.push_back(wap);
+ }
+ }
+ geolocation_received_time_ = base::Time::Now();
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698