1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/login/login_location_monitor.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/chromeos/login/wizard_controller.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/geolocation_provider.h"
18 std::string GeopositionToStringForDebug(const content::Geoposition& pos) {
19 return base::StringPrintf(
20 "latitude=%f, longitude=%f, altitude=%f, accuracy=%f, "
21 "altitude_accuracy=%f, heading=%f, speed=%f",
26 pos.altitude_accuracy,
33 LoginLocationMonitor::~LoginLocationMonitor() {
37 LoginLocationMonitor* LoginLocationMonitor::GetInstance() {
38 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
39 return Singleton<LoginLocationMonitor>::get();
43 void LoginLocationMonitor::InstallLocationCallback(
44 const base::TimeDelta timeout) {
45 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
47 LoginLocationMonitor* self = GetInstance();
49 self->started_ = base::Time::Now();
50 self->request_timeout_.Start(
53 base::Bind(&LoginLocationMonitor::DoRemoveLocationCallback,
54 self->on_location_update_));
56 content::BrowserThread::PostTask(
57 content::BrowserThread::IO,
59 base::Bind(&DoInstallLocationCallback, self->on_location_update_));
63 void LoginLocationMonitor::RemoveLocationCallback() {
64 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
66 LoginLocationMonitor* self = GetInstance();
67 self->request_timeout_.Stop();
68 content::BrowserThread::PostTask(
69 content::BrowserThread::IO,
71 base::Bind(&DoRemoveLocationCallback, self->on_location_update_));
74 LoginLocationMonitor::LoginLocationMonitor()
75 : weak_factory_(this),
77 base::Bind(&LoginLocationMonitor::OnLocationUpdatedIO)) {
78 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
82 void LoginLocationMonitor::DoInstallLocationCallback(
83 content::GeolocationProvider::LocationUpdateCallback callback) {
84 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
85 content::GeolocationProvider* provider =
86 content::GeolocationProvider::GetInstance();
88 provider->AddLocationUpdateCallback(callback, false);
89 provider->UserDidOptIntoLocationServices();
93 void LoginLocationMonitor::DoRemoveLocationCallback(
94 content::GeolocationProvider::LocationUpdateCallback callback) {
95 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
96 content::GeolocationProvider* provider =
97 content::GeolocationProvider::GetInstance();
98 provider->RemoveLocationUpdateCallback(callback);
101 void LoginLocationMonitor::OnLocationUpdatedIO(
102 const content::Geoposition& position) {
103 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
104 if (!position.Validate()) {
106 << "LoginLocationMonitor::OnLocationUpdatedIO(): invalid position: {"
107 << GeopositionToStringForDebug(position) << "}";
110 VLOG(1) << "LoginLocationMonitor::OnLocationUpdatedIO(): valid position: {"
111 << GeopositionToStringForDebug(position) << "}";
113 content::BrowserThread::PostTask(
114 content::BrowserThread::UI,
116 base::Bind(&LoginLocationMonitor::OnLocationUpdatedUI, position));
119 void LoginLocationMonitor::OnLocationUpdatedUI(
120 const content::Geoposition& position) {
121 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
122 DCHECK(position.Validate());
124 LoginLocationMonitor* self = GetInstance();
126 if (!self->request_timeout_.IsRunning()) {
128 << "LoginLocationMonitor::OnLocationUpdatedUI(): Service is stopped: {"
129 << GeopositionToStringForDebug(position) << "}";
133 RemoveLocationCallback();
135 // We need a cumulative timeout for timezone resolve, that is
136 // (location resolve + timezone resolve). This is used to measure
137 // timeout for the following timezone resolve.
138 const base::TimeDelta elapsed = base::Time::Now() - self->started_;
140 WizardController::OnLocationUpdated(position, elapsed);
143 } // namespace chromeos