Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: content/browser/geolocation/geolocation_dispatcher_host.cc

Issue 65273002: Add a mechanism to pause and resume geolocation requests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: joth comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_dispatcher_host.h" 5 #include "content/browser/geolocation/geolocation_dispatcher_host.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 int bridge_id, 62 int bridge_id,
63 const GURL& requesting_frame); 63 const GURL& requesting_frame);
64 void OnCancelPermissionRequest(int render_view_id, 64 void OnCancelPermissionRequest(int render_view_id,
65 int bridge_id, 65 int bridge_id,
66 const GURL& requesting_frame); 66 const GURL& requesting_frame);
67 void OnStartUpdating(int render_view_id, 67 void OnStartUpdating(int render_view_id,
68 const GURL& requesting_frame, 68 const GURL& requesting_frame,
69 bool enable_high_accuracy); 69 bool enable_high_accuracy);
70 void OnStopUpdating(int render_view_id); 70 void OnStopUpdating(int render_view_id);
71 71
72 virtual void PauseOrResume(int render_view_id, bool should_pause) OVERRIDE;
73
72 // Updates the |geolocation_provider_| with the currently required update 74 // Updates the |geolocation_provider_| with the currently required update
73 // options, based on |renderer_high_accuracy_|. 75 // options.
74 void RefreshHighAccuracy(); 76 void RefreshGeolocationOptions();
75 77
76 void OnLocationUpdate(const Geoposition& position); 78 void OnLocationUpdate(const Geoposition& position);
77 79
78 int render_process_id_; 80 int render_process_id_;
79 scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_; 81 scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
80 82
81 // Iterated when sending location updates to renderer processes. The fan out 83 struct RendererGeolocationOptions {
82 // to individual bridge IDs happens renderer side, in order to minimize 84 bool high_accuracy;
83 // context switches. 85 bool is_paused;
86 };
87
88 // Used to keep track of the renderers in this process that are using
89 // geolocation and the options associated with them. The map is iterated
90 // when a location update is available and the fan out to individual bridge
91 // IDs happens renderer side, in order to minimize context switches.
84 // Only used on the IO thread. 92 // Only used on the IO thread.
85 std::set<int> geolocation_renderer_ids_; 93 std::map<int, RendererGeolocationOptions> geolocation_renderers_;
86 // Maps renderer_id to whether high accuracy is requested for this particular 94
87 // bridge.
88 std::map<int, bool> renderer_high_accuracy_;
89 // Only set whilst we are registered with the geolocation provider. 95 // Only set whilst we are registered with the geolocation provider.
90 GeolocationProviderImpl* geolocation_provider_; 96 GeolocationProviderImpl* geolocation_provider_;
91 97
92 GeolocationProviderImpl::LocationUpdateCallback callback_; 98 GeolocationProviderImpl::LocationUpdateCallback callback_;
93 99
94 DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHostImpl); 100 DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHostImpl);
95 }; 101 };
96 102
97 GeolocationDispatcherHostImpl::GeolocationDispatcherHostImpl( 103 GeolocationDispatcherHostImpl::GeolocationDispatcherHostImpl(
98 int render_process_id, 104 int render_process_id,
(...skipping 26 matching lines...) Expand all
125 IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating) 131 IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating)
126 IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating) 132 IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating)
127 IPC_MESSAGE_UNHANDLED(handled = false) 133 IPC_MESSAGE_UNHANDLED(handled = false)
128 IPC_END_MESSAGE_MAP() 134 IPC_END_MESSAGE_MAP()
129 return handled; 135 return handled;
130 } 136 }
131 137
132 void GeolocationDispatcherHostImpl::OnLocationUpdate( 138 void GeolocationDispatcherHostImpl::OnLocationUpdate(
133 const Geoposition& geoposition) { 139 const Geoposition& geoposition) {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
135 for (std::set<int>::iterator it = geolocation_renderer_ids_.begin(); 141 for (std::map<int, RendererGeolocationOptions>::iterator it =
136 it != geolocation_renderer_ids_.end(); ++it) { 142 geolocation_renderers_.begin();
137 Send(new GeolocationMsg_PositionUpdated(*it, geoposition)); 143 it != geolocation_renderers_.end(); ++it) {
144 Send(new GeolocationMsg_PositionUpdated(it->first, geoposition));
joth 2013/11/10 17:59:02 technically should only send if (!it->second.is_p
Michael van Ouwerkerk 2013/11/11 14:19:49 Agreed, I think that would be clearer. Otherwise t
benm (inactive) 2013/11/11 14:50:41 Right. Otherwise in this case as long as one rende
138 } 145 }
139 } 146 }
140 147
141 void GeolocationDispatcherHostImpl::OnRequestPermission( 148 void GeolocationDispatcherHostImpl::OnRequestPermission(
142 int render_view_id, 149 int render_view_id,
143 int bridge_id, 150 int bridge_id,
144 const GURL& requesting_frame) { 151 const GURL& requesting_frame) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
146 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" 153 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
147 << render_view_id << ":" << bridge_id; 154 << render_view_id << ":" << bridge_id;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 const GURL& requesting_frame, 188 const GURL& requesting_frame,
182 bool enable_high_accuracy) { 189 bool enable_high_accuracy) {
183 // StartUpdating() can be invoked as a result of high-accuracy mode 190 // StartUpdating() can be invoked as a result of high-accuracy mode
184 // being enabled / disabled. No need to record the dispatcher again. 191 // being enabled / disabled. No need to record the dispatcher again.
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
186 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" 193 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
187 << render_view_id; 194 << render_view_id;
188 UMA_HISTOGRAM_BOOLEAN( 195 UMA_HISTOGRAM_BOOLEAN(
189 "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy", 196 "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
190 enable_high_accuracy); 197 enable_high_accuracy);
191 if (!geolocation_renderer_ids_.count(render_view_id)) 198 RendererGeolocationOptions opts = { enable_high_accuracy, false };
192 geolocation_renderer_ids_.insert(render_view_id); 199 geolocation_renderers_[render_view_id] = opts;
193 200 RefreshGeolocationOptions();
194 renderer_high_accuracy_[render_view_id] = enable_high_accuracy;
195 RefreshHighAccuracy();
196 } 201 }
197 202
198 void GeolocationDispatcherHostImpl::OnStopUpdating(int render_view_id) { 203 void GeolocationDispatcherHostImpl::OnStopUpdating(int render_view_id) {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
200 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":" 205 DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
201 << render_view_id; 206 << render_view_id;
202 if (renderer_high_accuracy_.erase(render_view_id)) 207 DCHECK_EQ(1U, geolocation_renderers_.count(render_view_id));
203 RefreshHighAccuracy(); 208 geolocation_renderers_.erase(render_view_id);
204 209 RefreshGeolocationOptions();
205 DCHECK_EQ(1U, geolocation_renderer_ids_.count(render_view_id));
206 geolocation_renderer_ids_.erase(render_view_id);
207 } 210 }
208 211
209 void GeolocationDispatcherHostImpl::RefreshHighAccuracy() { 212 void GeolocationDispatcherHostImpl::PauseOrResume(int render_view_id,
213 bool should_pause) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
211 if (renderer_high_accuracy_.empty()) { 215 std::map<int, RendererGeolocationOptions>::iterator it =
212 if (geolocation_provider_) { 216 geolocation_renderers_.find(render_view_id);
213 geolocation_provider_->RemoveLocationUpdateCallback(callback_); 217 if (it == geolocation_renderers_.end())
214 geolocation_provider_ = NULL; 218 return;
215 } 219
216 } else { 220 RendererGeolocationOptions* opts = &(it->second);
221 if (opts->is_paused != should_pause) {
222 opts->is_paused = should_pause;
223 RefreshGeolocationOptions();
224 }
225 }
226
227 void GeolocationDispatcherHostImpl::RefreshGeolocationOptions() {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
229
230 bool needs_updates = false;
231 bool use_high_accuracy = false;
232 std::map<int, RendererGeolocationOptions>::const_iterator i =
233 geolocation_renderers_.begin();
234 for (; i != geolocation_renderers_.end(); ++i) {
235 needs_updates |= !(i->second.is_paused);
236 use_high_accuracy |= i->second.high_accuracy;
237 if (needs_updates && use_high_accuracy)
238 break;
239 }
240 if (needs_updates) {
217 if (!geolocation_provider_) 241 if (!geolocation_provider_)
218 geolocation_provider_ = GeolocationProviderImpl::GetInstance(); 242 geolocation_provider_ = GeolocationProviderImpl::GetInstance();
219 // Re-add to re-establish our options, in case they changed. 243 // Re-add to re-establish our options, in case they changed.
220 bool use_high_accuracy = false;
221 std::map<int, bool>::iterator i = renderer_high_accuracy_.begin();
222 for (; i != renderer_high_accuracy_.end(); ++i) {
223 if (i->second) {
224 use_high_accuracy = true;
225 break;
226 }
227 }
228 geolocation_provider_->AddLocationUpdateCallback( 244 geolocation_provider_->AddLocationUpdateCallback(
229 callback_, use_high_accuracy); 245 callback_, use_high_accuracy);
246 } else {
247 if (geolocation_provider_)
248 geolocation_provider_->RemoveLocationUpdateCallback(callback_);
249 geolocation_provider_ = NULL;
230 } 250 }
231 } 251 }
232 } // namespace 252 } // namespace
233 253
234 254
235 // GeolocationDispatcherHost -------------------------------------------------- 255 // GeolocationDispatcherHost --------------------------------------------------
236 256
237 // static 257 // static
238 GeolocationDispatcherHost* GeolocationDispatcherHost::New( 258 GeolocationDispatcherHost* GeolocationDispatcherHost::New(
239 int render_process_id, 259 int render_process_id,
240 GeolocationPermissionContext* geolocation_permission_context) { 260 GeolocationPermissionContext* geolocation_permission_context) {
241 return new GeolocationDispatcherHostImpl( 261 return new GeolocationDispatcherHostImpl(
242 render_process_id, 262 render_process_id,
243 geolocation_permission_context); 263 geolocation_permission_context);
244 } 264 }
245 265
246 GeolocationDispatcherHost::GeolocationDispatcherHost() { 266 GeolocationDispatcherHost::GeolocationDispatcherHost() {
247 } 267 }
248 268
249 GeolocationDispatcherHost::~GeolocationDispatcherHost() { 269 GeolocationDispatcherHost::~GeolocationDispatcherHost() {
250 } 270 }
251 271
252 } // namespace content 272 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698