OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/geolocation/geolocation_provider.h" | 5 #include "content/browser/geolocation/geolocation_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" |
| 10 #include "base/location.h" |
| 11 #include "base/logging.h" |
9 #include "base/memory/singleton.h" | 12 #include "base/memory/singleton.h" |
10 #include "base/threading/thread_restrictions.h" | 13 #include "base/message_loop.h" |
11 #include "content/browser/geolocation/location_arbitrator.h" | 14 #include "content/browser/geolocation/location_arbitrator.h" |
| 15 #include "content/public/browser/browser_thread.h" |
| 16 |
| 17 using content::BrowserThread; |
12 | 18 |
13 GeolocationProvider* GeolocationProvider::GetInstance() { | 19 GeolocationProvider* GeolocationProvider::GetInstance() { |
| 20 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
14 return Singleton<GeolocationProvider>::get(); | 21 return Singleton<GeolocationProvider>::get(); |
15 } | 22 } |
16 | 23 |
17 GeolocationProvider::GeolocationProvider() | 24 GeolocationProvider::GeolocationProvider() |
18 : base::Thread("Geolocation"), | 25 : base::Thread("Geolocation"), |
19 client_loop_(base::MessageLoopProxy::current()), | |
20 is_permission_granted_(false), | 26 is_permission_granted_(false), |
21 arbitrator_(NULL) { | 27 arbitrator_(NULL) { |
| 28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
22 } | 29 } |
23 | 30 |
24 GeolocationProvider::~GeolocationProvider() { | 31 GeolocationProvider::~GeolocationProvider() { |
25 DCHECK(observers_.empty()); // observers must unregister. | 32 DCHECK(observers_.empty()); // observers must unregister. |
26 Stop(); | 33 Stop(); |
27 DCHECK(!arbitrator_); | 34 DCHECK(!arbitrator_); |
28 } | 35 } |
29 | 36 |
30 void GeolocationProvider::AddObserver(GeolocationObserver* observer, | 37 void GeolocationProvider::AddObserver(GeolocationObserver* observer, |
31 const GeolocationObserverOptions& update_options) { | 38 const GeolocationObserverOptions& update_options) { |
32 DCHECK(OnClientThread()); | 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
33 observers_[observer] = update_options; | 40 observers_[observer] = update_options; |
34 OnObserversChanged(); | 41 OnObserversChanged(); |
35 if (position_.IsInitialized()) | 42 if (position_.IsInitialized()) |
36 observer->OnLocationUpdate(position_); | 43 observer->OnLocationUpdate(position_); |
37 } | 44 } |
38 | 45 |
39 bool GeolocationProvider::RemoveObserver(GeolocationObserver* observer) { | 46 bool GeolocationProvider::RemoveObserver(GeolocationObserver* observer) { |
40 DCHECK(OnClientThread()); | 47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
41 size_t remove = observers_.erase(observer); | 48 size_t remove = observers_.erase(observer); |
42 OnObserversChanged(); | 49 OnObserversChanged(); |
43 return remove > 0; | 50 return remove > 0; |
44 } | 51 } |
45 | 52 |
46 void GeolocationProvider::OnObserversChanged() { | 53 void GeolocationProvider::OnObserversChanged() { |
47 DCHECK(OnClientThread()); | 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
48 base::Closure task; | 55 base::Closure task; |
49 if (observers_.empty()) { | 56 if (observers_.empty()) { |
50 DCHECK(IsRunning()); | 57 DCHECK(IsRunning()); |
51 task = base::Bind(&GeolocationProvider::StopProviders, | 58 task = base::Bind(&GeolocationProvider::StopProviders, |
52 base::Unretained(this)); | 59 base::Unretained(this)); |
53 } else { | 60 } else { |
54 if (!IsRunning()) { | 61 if (!IsRunning()) { |
55 Start(); | 62 Start(); |
56 if (HasPermissionBeenGranted()) | 63 if (HasPermissionBeenGranted()) |
57 InformProvidersPermissionGranted(); | 64 InformProvidersPermissionGranted(); |
58 } | 65 } |
59 | 66 |
60 // The high accuracy requirement may have changed. | 67 // The high accuracy requirement may have changed. |
61 task = base::Bind(&GeolocationProvider::StartProviders, | 68 task = base::Bind(&GeolocationProvider::StartProviders, |
62 base::Unretained(this), | 69 base::Unretained(this), |
63 GeolocationObserverOptions::Collapse(observers_)); | 70 GeolocationObserverOptions::Collapse(observers_)); |
64 } | 71 } |
65 | 72 |
66 message_loop()->PostTask(FROM_HERE, task); | 73 message_loop()->PostTask(FROM_HERE, task); |
67 } | 74 } |
68 | 75 |
69 void GeolocationProvider::NotifyObservers(const Geoposition& position) { | 76 void GeolocationProvider::NotifyObservers(const Geoposition& position) { |
70 DCHECK(OnClientThread()); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
71 DCHECK(position.IsInitialized()); | 78 DCHECK(position.IsInitialized()); |
72 position_ = position; | 79 position_ = position; |
73 ObserverMap::const_iterator it = observers_.begin(); | 80 ObserverMap::const_iterator it = observers_.begin(); |
74 while (it != observers_.end()) { | 81 while (it != observers_.end()) { |
75 // Advance iterator before callback to guard against synchronous unregister. | 82 // Advance iterator before callback to guard against synchronous unregister. |
76 GeolocationObserver* observer = it->first; | 83 GeolocationObserver* observer = it->first; |
77 ++it; | 84 ++it; |
78 observer->OnLocationUpdate(position_); | 85 observer->OnLocationUpdate(position_); |
79 } | 86 } |
80 } | 87 } |
81 | 88 |
82 void GeolocationProvider::StartProviders( | 89 void GeolocationProvider::StartProviders( |
83 const GeolocationObserverOptions& options) { | 90 const GeolocationObserverOptions& options) { |
84 DCHECK(OnGeolocationThread()); | 91 DCHECK(OnGeolocationThread()); |
85 DCHECK(arbitrator_); | 92 DCHECK(arbitrator_); |
86 arbitrator_->StartProviders(options); | 93 arbitrator_->StartProviders(options); |
87 } | 94 } |
88 | 95 |
89 void GeolocationProvider::StopProviders() { | 96 void GeolocationProvider::StopProviders() { |
90 DCHECK(OnGeolocationThread()); | 97 DCHECK(OnGeolocationThread()); |
91 DCHECK(arbitrator_); | 98 DCHECK(arbitrator_); |
92 arbitrator_->StopProviders(); | 99 arbitrator_->StopProviders(); |
93 } | 100 } |
94 | 101 |
95 void GeolocationProvider::OnPermissionGranted() { | 102 void GeolocationProvider::OnPermissionGranted() { |
96 DCHECK(OnClientThread()); | 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
97 is_permission_granted_ = true; | 104 is_permission_granted_ = true; |
98 if (IsRunning()) | 105 if (IsRunning()) |
99 InformProvidersPermissionGranted(); | 106 InformProvidersPermissionGranted(); |
100 } | 107 } |
101 | 108 |
102 void GeolocationProvider::InformProvidersPermissionGranted() { | 109 void GeolocationProvider::InformProvidersPermissionGranted() { |
103 DCHECK(IsRunning()); | 110 DCHECK(IsRunning()); |
104 if (!OnGeolocationThread()) { | 111 if (!OnGeolocationThread()) { |
105 message_loop()->PostTask( | 112 message_loop()->PostTask( |
106 FROM_HERE, | 113 FROM_HERE, |
(...skipping 13 matching lines...) Expand all Loading... |
120 } | 127 } |
121 | 128 |
122 void GeolocationProvider::CleanUp() { | 129 void GeolocationProvider::CleanUp() { |
123 DCHECK(OnGeolocationThread()); | 130 DCHECK(OnGeolocationThread()); |
124 delete arbitrator_; | 131 delete arbitrator_; |
125 arbitrator_ = NULL; | 132 arbitrator_ = NULL; |
126 } | 133 } |
127 | 134 |
128 void GeolocationProvider::OnLocationUpdate(const Geoposition& position) { | 135 void GeolocationProvider::OnLocationUpdate(const Geoposition& position) { |
129 DCHECK(OnGeolocationThread()); | 136 DCHECK(OnGeolocationThread()); |
130 client_loop_->PostTask( | 137 content::BrowserThread::PostTask( |
| 138 content::BrowserThread::IO, |
131 FROM_HERE, | 139 FROM_HERE, |
132 base::Bind(&GeolocationProvider::NotifyObservers, | 140 base::Bind(&GeolocationProvider::NotifyObservers, |
133 base::Unretained(this), position)); | 141 base::Unretained(this), position)); |
134 } | 142 } |
135 | 143 |
136 bool GeolocationProvider::HasPermissionBeenGranted() const { | 144 bool GeolocationProvider::HasPermissionBeenGranted() const { |
137 DCHECK(OnClientThread()); | 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
138 return is_permission_granted_; | 146 return is_permission_granted_; |
139 } | 147 } |
140 | 148 |
141 bool GeolocationProvider::OnClientThread() const { | |
142 return client_loop_->BelongsToCurrentThread(); | |
143 } | |
144 | |
145 bool GeolocationProvider::OnGeolocationThread() const { | 149 bool GeolocationProvider::OnGeolocationThread() const { |
146 return MessageLoop::current() == message_loop(); | 150 return MessageLoop::current() == message_loop(); |
147 } | 151 } |
OLD | NEW |