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

Unified Diff: chrome/browser/policy/device_status_location_helper.cc

Issue 10103029: Add device location reporting (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Comments addressed. Created 8 years, 8 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/policy/device_status_location_helper.cc
diff --git a/chrome/browser/policy/device_status_location_helper.cc b/chrome/browser/policy/device_status_location_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..99fac1098a7224a7daa5585dbb4d08a2fa1c9821
--- /dev/null
+++ b/chrome/browser/policy/device_status_location_helper.cc
@@ -0,0 +1,182 @@
+// Copyright (c) 2012 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/policy/device_status_location_helper.h"
+
+#include "base/string_number_conversions.h"
+#include "base/time.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
+#include "content/browser/geolocation/geolocation_provider.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace policy {
+
+DeviceStatusLocationHelper::DeviceStatusLocationHelper(
+ PrefService* local_state)
+ : local_state_(local_state),
+ timer_(NULL),
+ provider_(NULL),
+ observing_(false) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ Geoposition position;
+ std::string timestamp_str;
Joao da Silva 2012/04/20 14:21:09 #include <string>
bartfab (slow) 2012/04/23 09:48:54 Done.
+ int64 timestamp;
+ const base::DictionaryValue* location =
Joao da Silva 2012/04/20 14:21:09 #include "base/values.h"
bartfab (slow) 2012/04/23 09:48:54 Done.
+ local_state_->GetDictionary(prefs::kDeviceLocation);
+ if (location->GetDouble("latitude", &position.latitude) &&
joth 2012/04/23 10:05:14 a comment would be useful - explaining why the loc
bartfab (slow) 2012/04/23 12:21:28 Done.
+ location->GetDouble("longitude", &position.longitude) &&
+ location->GetDouble("altitude", &position.altitude) &&
+ location->GetDouble("accuracy", &position.accuracy) &&
+ location->GetDouble("altitude_accuracy",
+ &position.altitude_accuracy) &&
+ location->GetDouble("heading", &position.heading) &&
+ location->GetDouble("speed", &position.speed) &&
+ location->GetString("timestamp", &timestamp_str) &&
+ base::StringToInt64(timestamp_str, &timestamp)) {
+ position.timestamp = base::Time::FromInternalValue(timestamp);
+ position_ = position;
+ }
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&DeviceStatusLocationHelper::Init,
+ base::Unretained(this),
+ position_));
+}
+
+void DeviceStatusLocationHelper::Destruct() {
+ // This class has a specific shutdown sequence that ensures all classes it
+ // interfaces with are notified on the appropriate threads and any tasks
+ // posted to it are processed before destruction.
+ //
+ // The shutdown sequence is initiated by calling Destruct() on the UI thread:
+ //
+ // 1. Destruct() makes the UI thread ignore any further updates it receives,
+ // then posts DestructInternal() to the IO thread.
+ // 2. DestructInteral() reaches the IO thread after any updates queued up for
Joao da Silva 2012/04/20 14:21:09 nit: DestructInteral -> DestructInternal
bartfab (slow) 2012/04/23 09:48:54 Done.
+ // it have been processed. This function destroys the poll timer and
+ // detaches from the GeolocationProvider so that no further updates can be
+ // received by the IO thread. Then, it posts DeleteSoon() back to the UI
+ // thread.
+ // 3. DeleteSoon() reaches the UI thread after any updates queued for it have
+ // been processed. At this point, there are no more tasks queued up for
+ // either of the threads and it is safe for the object to be deleted.
+ // 4. ~DeviceStatusLocationHelper() is run by DeleteSoon() and the object RIP.
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ local_state_ = NULL;
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&DeviceStatusLocationHelper::DestructInternal,
+ base::Unretained(this)));
+}
+
+const Geoposition& DeviceStatusLocationHelper::GetPosition() const {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ return position_;
+}
+
+// static
+void DeviceStatusLocationHelper::RegisterPrefs(PrefService* local_state) {
+ local_state->RegisterDictionaryPref(prefs::kDeviceLocation,
+ new DictionaryValue);
+}
+
+void DeviceStatusLocationHelper::OnLocationUpdate(const Geoposition& position) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!position.IsValidFix())
+ return;
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&DeviceStatusLocationHelper::ReceiveUpdate,
+ base::Unretained(this), position));
+ StopObserving();
+ ScheduleUpdate(position);
+}
+
+void DeviceStatusLocationHelper::SetGeolocationProviderForTest(
+ GeolocationProvider* provider) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ DCHECK(!provider_);
+ provider_ = provider;
+}
+
+DeviceStatusLocationHelper::~DeviceStatusLocationHelper() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ DCHECK(local_state_ == NULL);
+ DCHECK(timer_ == NULL);
+}
+
+void DeviceStatusLocationHelper::Init(const Geoposition& position) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!provider_)
+ provider_ = GeolocationProvider::GetInstance();
+ timer_ = new base::OneShotTimer<DeviceStatusLocationHelper>();
+ provider_->OnPermissionGranted();
+ ScheduleUpdate(position);
+}
+
+void DeviceStatusLocationHelper::DestructInternal() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ delete timer_;
+ timer_ = 0;
+ StopObserving();
+ content::BrowserThread::DeleteSoon(content::BrowserThread::UI,
+ FROM_HERE,
+ this);
+}
+
+void DeviceStatusLocationHelper::ScheduleUpdate(const Geoposition& position) {
joth 2012/04/23 10:05:14 comment explaining why the timer is needed here wo
bartfab (slow) 2012/04/23 12:21:28 Done.
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (position.IsValidFix()) {
+ base::TimeDelta elapsed = base::Time::Now() - position.timestamp;
+ base::TimeDelta interval =
+ base::TimeDelta::FromSeconds(kPollIntervalSeconds);
+ if (elapsed > interval) {
+ StartObserving();
+ } else {
+ timer_->Start(FROM_HERE, interval - elapsed, this,
+ &DeviceStatusLocationHelper::StartObserving);
+ }
+ } else {
+ StartObserving();
+ }
+}
+
+void DeviceStatusLocationHelper::StartObserving() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ timer_->Stop();
+ provider_->AddObserver(this, GeolocationObserverOptions(true));
+ observing_ = true;
+}
+
+void DeviceStatusLocationHelper::StopObserving() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!observing_)
+ return;
+ provider_->RemoveObserver(this);
+ observing_ = false;
+}
+
+void DeviceStatusLocationHelper::ReceiveUpdate(const Geoposition& position) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!local_state_)
+ return;
+ position_ = position;
+ DictionaryValue location;
+ location.SetDouble("latitude", position.latitude);
+ location.SetDouble("longitude", position.longitude);
+ location.SetDouble("altitude", position.altitude);
+ location.SetDouble("accuracy", position.accuracy);
+ location.SetDouble("altitude_accuracy", position.altitude_accuracy);
+ location.SetDouble("heading", position.heading);
+ location.SetDouble("speed", position.speed);
+ location.SetString("timestamp",
+ base::Int64ToString(position.timestamp.ToInternalValue()));
+ local_state_->Set(prefs::kDeviceLocation, location);
+}
+
+} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698