c1c528a35695a8a769fa08d80d75a1d4f2a0588f
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / login_location_monitor.cc
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.
4
5 #include "chrome/browser/chromeos/login/login_location_monitor.h"
6
7 #include "base/bind.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"
13
14 namespace chromeos {
15
16 namespace {
17
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",
22       pos.latitude,
23       pos.longitude,
24       pos.altitude,
25       pos.accuracy,
26       pos.altitude_accuracy,
27       pos.heading,
28       pos.speed);
29 }
30
31 }  // namespace
32
33 LoginLocationMonitor::~LoginLocationMonitor() {
34 }
35
36 // static
37 LoginLocationMonitor* LoginLocationMonitor::GetInstance() {
38   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
39   return Singleton<LoginLocationMonitor>::get();
40 }
41
42 // static
43 void LoginLocationMonitor::InstallLocationCallback(
44     const base::TimeDelta timeout) {
45   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
46
47   LoginLocationMonitor* self = GetInstance();
48
49   self->started_ = base::Time::Now();
50   self->request_timeout_.Start(
51       FROM_HERE,
52       timeout,
53       base::Bind(&LoginLocationMonitor::DoRemoveLocationCallback,
54                  self->on_location_update_));
55
56   content::BrowserThread::PostTask(
57       content::BrowserThread::IO,
58       FROM_HERE,
59       base::Bind(&DoInstallLocationCallback, self->on_location_update_));
60 }
61
62 // static
63 void LoginLocationMonitor::RemoveLocationCallback() {
64   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
65
66   LoginLocationMonitor* self = GetInstance();
67   self->request_timeout_.Stop();
68   content::BrowserThread::PostTask(
69       content::BrowserThread::IO,
70       FROM_HERE,
71       base::Bind(&DoRemoveLocationCallback, self->on_location_update_));
72 }
73
74 LoginLocationMonitor::LoginLocationMonitor()
75     : weak_factory_(this),
76       on_location_update_(
77           base::Bind(&LoginLocationMonitor::OnLocationUpdatedIO)) {
78   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
79 }
80
81 // static
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();
87
88   provider->AddLocationUpdateCallback(callback, false);
89   provider->UserDidOptIntoLocationServices();
90 }
91
92 // static
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);
99 }
100
101 void LoginLocationMonitor::OnLocationUpdatedIO(
102     const content::Geoposition& position) {
103   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
104   if (!position.Validate()) {
105     VLOG(1)
106         << "LoginLocationMonitor::OnLocationUpdatedIO(): invalid position: {"
107         << GeopositionToStringForDebug(position) << "}";
108     return;
109   }
110   VLOG(1) << "LoginLocationMonitor::OnLocationUpdatedIO(): valid position: {"
111           << GeopositionToStringForDebug(position) << "}";
112
113   content::BrowserThread::PostTask(
114       content::BrowserThread::UI,
115       FROM_HERE,
116       base::Bind(&LoginLocationMonitor::OnLocationUpdatedUI, position));
117 }
118
119 void LoginLocationMonitor::OnLocationUpdatedUI(
120     const content::Geoposition& position) {
121   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
122   DCHECK(position.Validate());
123
124   LoginLocationMonitor* self = GetInstance();
125
126   if (!self->request_timeout_.IsRunning()) {
127     VLOG(1)
128         << "LoginLocationMonitor::OnLocationUpdatedUI(): Service is stopped: {"
129         << GeopositionToStringForDebug(position) << "}";
130     return;
131   }
132
133   RemoveLocationCallback();
134
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_;
139
140   WizardController::OnLocationUpdated(position, elapsed);
141 }
142
143 }  // namespace chromeos