Upstream version 7.35.139.0
[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::RemoveLocationCallback));
54
55   content::BrowserThread::PostTask(
56       content::BrowserThread::IO,
57       FROM_HERE,
58       base::Bind(&DoInstallLocationCallback, self->on_location_update_));
59 }
60
61 // static
62 void LoginLocationMonitor::RemoveLocationCallback() {
63   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
64
65   LoginLocationMonitor* self = GetInstance();
66   self->request_timeout_.Stop();
67   content::BrowserThread::PostTask(
68       content::BrowserThread::IO,
69       FROM_HERE,
70       base::Bind(&DoRemoveLocationCallback, self->on_location_update_));
71 }
72
73 LoginLocationMonitor::LoginLocationMonitor()
74     : weak_factory_(this),
75       on_location_update_(
76           base::Bind(&LoginLocationMonitor::OnLocationUpdatedIO)) {
77   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
78 }
79
80 // static
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();
86
87   provider->AddLocationUpdateCallback(callback, false);
88   provider->UserDidOptIntoLocationServices();
89 }
90
91 // static
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);
98 }
99
100 void LoginLocationMonitor::OnLocationUpdatedIO(
101     const content::Geoposition& position) {
102   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
103   if (!position.Validate()) {
104     VLOG(1)
105         << "LoginLocationMonitor::OnLocationUpdatedIO(): invalid position: {"
106         << GeopositionToStringForDebug(position) << "}";
107     return;
108   }
109   VLOG(1) << "LoginLocationMonitor::OnLocationUpdatedIO(): valid position: {"
110           << GeopositionToStringForDebug(position) << "}";
111
112   content::BrowserThread::PostTask(
113       content::BrowserThread::UI,
114       FROM_HERE,
115       base::Bind(&LoginLocationMonitor::OnLocationUpdatedUI, position));
116 }
117
118 void LoginLocationMonitor::OnLocationUpdatedUI(
119     const content::Geoposition& position) {
120   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
121   DCHECK(position.Validate());
122
123   LoginLocationMonitor* self = GetInstance();
124
125   if (!self->request_timeout_.IsRunning()) {
126     VLOG(1)
127         << "LoginLocationMonitor::OnLocationUpdatedUI(): Service is stopped: {"
128         << GeopositionToStringForDebug(position) << "}";
129     return;
130   }
131
132   RemoveLocationCallback();
133
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_;
138
139   WizardController::OnLocationUpdated(position, elapsed);
140 }
141
142 }  // namespace chromeos