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::RemoveLocationCallback));
55 content::BrowserThread::PostTask(
56 content::BrowserThread::IO,
58 base::Bind(&DoInstallLocationCallback, self->on_location_update_));
62 void LoginLocationMonitor::RemoveLocationCallback() {
63 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
65 LoginLocationMonitor* self = GetInstance();
66 self->request_timeout_.Stop();
67 content::BrowserThread::PostTask(
68 content::BrowserThread::IO,
70 base::Bind(&DoRemoveLocationCallback, self->on_location_update_));
73 LoginLocationMonitor::LoginLocationMonitor()
74 : weak_factory_(this),
76 base::Bind(&LoginLocationMonitor::OnLocationUpdatedIO)) {
77 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
81 void LoginLocationMonitor::DoInstallLocationCallback(
82 content::GeolocationProvider::LocationUpdateCallback callback) {
83 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
84 content::GeolocationProvider* provider =
85 content::GeolocationProvider::GetInstance();
87 provider->AddLocationUpdateCallback(callback, false);
88 provider->UserDidOptIntoLocationServices();
92 void LoginLocationMonitor::DoRemoveLocationCallback(
93 content::GeolocationProvider::LocationUpdateCallback callback) {
94 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
95 content::GeolocationProvider* provider =
96 content::GeolocationProvider::GetInstance();
97 provider->RemoveLocationUpdateCallback(callback);
100 void LoginLocationMonitor::OnLocationUpdatedIO(
101 const content::Geoposition& position) {
102 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
103 if (!position.Validate()) {
105 << "LoginLocationMonitor::OnLocationUpdatedIO(): invalid position: {"
106 << GeopositionToStringForDebug(position) << "}";
109 VLOG(1) << "LoginLocationMonitor::OnLocationUpdatedIO(): valid position: {"
110 << GeopositionToStringForDebug(position) << "}";
112 content::BrowserThread::PostTask(
113 content::BrowserThread::UI,
115 base::Bind(&LoginLocationMonitor::OnLocationUpdatedUI, position));
118 void LoginLocationMonitor::OnLocationUpdatedUI(
119 const content::Geoposition& position) {
120 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
121 DCHECK(position.Validate());
123 LoginLocationMonitor* self = GetInstance();
125 if (!self->request_timeout_.IsRunning()) {
127 << "LoginLocationMonitor::OnLocationUpdatedUI(): Service is stopped: {"
128 << GeopositionToStringForDebug(position) << "}";
132 RemoveLocationCallback();
134 // We need a cumulative timeout for timezone resolve, that is
135 // (location resolve + timezone resolve). This is used to measure
136 // timeout for the following timezone resolve.
137 const base::TimeDelta elapsed = base::Time::Now() - self->started_;
139 WizardController::OnLocationUpdated(position, elapsed);
142 } // namespace chromeos