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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/policy/device_status_location_helper.h"
6
7 #include "base/string_number_conversions.h"
8 #include "base/time.h"
9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/common/pref_names.h"
11 #include "content/browser/geolocation/geolocation_provider.h"
12 #include "content/public/browser/browser_thread.h"
13
14 namespace policy {
15
16 DeviceStatusLocationHelper::DeviceStatusLocationHelper(
17 PrefService* local_state)
18 : local_state_(local_state),
19 timer_(NULL),
20 provider_(NULL),
21 observing_(false) {
22 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
23 Geoposition position;
24 std::string timestamp_str;
Joao da Silva 2012/04/20 14:21:09 #include <string>
bartfab (slow) 2012/04/23 09:48:54 Done.
25 int64 timestamp;
26 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.
27 local_state_->GetDictionary(prefs::kDeviceLocation);
28 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.
29 location->GetDouble("longitude", &position.longitude) &&
30 location->GetDouble("altitude", &position.altitude) &&
31 location->GetDouble("accuracy", &position.accuracy) &&
32 location->GetDouble("altitude_accuracy",
33 &position.altitude_accuracy) &&
34 location->GetDouble("heading", &position.heading) &&
35 location->GetDouble("speed", &position.speed) &&
36 location->GetString("timestamp", &timestamp_str) &&
37 base::StringToInt64(timestamp_str, &timestamp)) {
38 position.timestamp = base::Time::FromInternalValue(timestamp);
39 position_ = position;
40 }
41 content::BrowserThread::PostTask(
42 content::BrowserThread::IO,
43 FROM_HERE,
44 base::Bind(&DeviceStatusLocationHelper::Init,
45 base::Unretained(this),
46 position_));
47 }
48
49 void DeviceStatusLocationHelper::Destruct() {
50 // This class has a specific shutdown sequence that ensures all classes it
51 // interfaces with are notified on the appropriate threads and any tasks
52 // posted to it are processed before destruction.
53 //
54 // The shutdown sequence is initiated by calling Destruct() on the UI thread:
55 //
56 // 1. Destruct() makes the UI thread ignore any further updates it receives,
57 // then posts DestructInternal() to the IO thread.
58 // 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.
59 // it have been processed. This function destroys the poll timer and
60 // detaches from the GeolocationProvider so that no further updates can be
61 // received by the IO thread. Then, it posts DeleteSoon() back to the UI
62 // thread.
63 // 3. DeleteSoon() reaches the UI thread after any updates queued for it have
64 // been processed. At this point, there are no more tasks queued up for
65 // either of the threads and it is safe for the object to be deleted.
66 // 4. ~DeviceStatusLocationHelper() is run by DeleteSoon() and the object RIP.
67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
68 local_state_ = NULL;
69 content::BrowserThread::PostTask(
70 content::BrowserThread::IO,
71 FROM_HERE,
72 base::Bind(&DeviceStatusLocationHelper::DestructInternal,
73 base::Unretained(this)));
74 }
75
76 const Geoposition& DeviceStatusLocationHelper::GetPosition() const {
77 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
78 return position_;
79 }
80
81 // static
82 void DeviceStatusLocationHelper::RegisterPrefs(PrefService* local_state) {
83 local_state->RegisterDictionaryPref(prefs::kDeviceLocation,
84 new DictionaryValue);
85 }
86
87 void DeviceStatusLocationHelper::OnLocationUpdate(const Geoposition& position) {
88 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
89 if (!position.IsValidFix())
90 return;
91 content::BrowserThread::PostTask(
92 content::BrowserThread::UI,
93 FROM_HERE,
94 base::Bind(&DeviceStatusLocationHelper::ReceiveUpdate,
95 base::Unretained(this), position));
96 StopObserving();
97 ScheduleUpdate(position);
98 }
99
100 void DeviceStatusLocationHelper::SetGeolocationProviderForTest(
101 GeolocationProvider* provider) {
102 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
103 DCHECK(!provider_);
104 provider_ = provider;
105 }
106
107 DeviceStatusLocationHelper::~DeviceStatusLocationHelper() {
108 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
109 DCHECK(local_state_ == NULL);
110 DCHECK(timer_ == NULL);
111 }
112
113 void DeviceStatusLocationHelper::Init(const Geoposition& position) {
114 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
115 if (!provider_)
116 provider_ = GeolocationProvider::GetInstance();
117 timer_ = new base::OneShotTimer<DeviceStatusLocationHelper>();
118 provider_->OnPermissionGranted();
119 ScheduleUpdate(position);
120 }
121
122 void DeviceStatusLocationHelper::DestructInternal() {
123 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
124 delete timer_;
125 timer_ = 0;
126 StopObserving();
127 content::BrowserThread::DeleteSoon(content::BrowserThread::UI,
128 FROM_HERE,
129 this);
130 }
131
132 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.
133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
134 if (position.IsValidFix()) {
135 base::TimeDelta elapsed = base::Time::Now() - position.timestamp;
136 base::TimeDelta interval =
137 base::TimeDelta::FromSeconds(kPollIntervalSeconds);
138 if (elapsed > interval) {
139 StartObserving();
140 } else {
141 timer_->Start(FROM_HERE, interval - elapsed, this,
142 &DeviceStatusLocationHelper::StartObserving);
143 }
144 } else {
145 StartObserving();
146 }
147 }
148
149 void DeviceStatusLocationHelper::StartObserving() {
150 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
151 timer_->Stop();
152 provider_->AddObserver(this, GeolocationObserverOptions(true));
153 observing_ = true;
154 }
155
156 void DeviceStatusLocationHelper::StopObserving() {
157 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
158 if (!observing_)
159 return;
160 provider_->RemoveObserver(this);
161 observing_ = false;
162 }
163
164 void DeviceStatusLocationHelper::ReceiveUpdate(const Geoposition& position) {
165 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
166 if (!local_state_)
167 return;
168 position_ = position;
169 DictionaryValue location;
170 location.SetDouble("latitude", position.latitude);
171 location.SetDouble("longitude", position.longitude);
172 location.SetDouble("altitude", position.altitude);
173 location.SetDouble("accuracy", position.accuracy);
174 location.SetDouble("altitude_accuracy", position.altitude_accuracy);
175 location.SetDouble("heading", position.heading);
176 location.SetDouble("speed", position.speed);
177 location.SetString("timestamp",
178 base::Int64ToString(position.timestamp.ToInternalValue()));
179 local_state_->Set(prefs::kDeviceLocation, location);
180 }
181
182 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698