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

Side by Side Diff: content/browser/presentation/presentation_service_impl.cc

Issue 996173006: [Presentation API] Fix potential callback leaks in PSImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Anton's comments Created 5 years, 9 months 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
« no previous file with comments | « content/browser/presentation/presentation_service_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/presentation/presentation_service_impl.h" 5 #include "content/browser/presentation/presentation_service_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "content/browser/presentation/presentation_type_converters.h" 10 #include "content/browser/presentation/presentation_type_converters.h"
11 #include "content/public/browser/content_browser_client.h" 11 #include "content/public/browser/content_browser_client.h"
12 #include "content/public/browser/navigation_details.h" 12 #include "content/public/browser/navigation_details.h"
13 #include "content/public/browser/render_frame_host.h" 13 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/browser/render_process_host.h" 14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_client.h" 16 #include "content/public/common/content_client.h"
17 #include "content/public/common/frame_navigate_params.h" 17 #include "content/public/common/frame_navigate_params.h"
18 18
19 namespace content { 19 namespace content {
20 20
21 PresentationServiceImpl::PresentationServiceImpl( 21 PresentationServiceImpl::PresentationServiceImpl(
22 RenderFrameHost* render_frame_host, 22 RenderFrameHost* render_frame_host,
23 WebContents* web_contents, 23 WebContents* web_contents,
24 PresentationServiceDelegate* delegate) 24 PresentationServiceDelegate* delegate)
25 : WebContentsObserver(web_contents), 25 : WebContentsObserver(web_contents),
26 render_frame_host_(render_frame_host), 26 render_frame_host_(render_frame_host),
27 delegate_(delegate), 27 delegate_(delegate),
28 next_request_session_id_(0),
28 weak_factory_(this) { 29 weak_factory_(this) {
29 DCHECK(render_frame_host_); 30 DCHECK(render_frame_host_);
30 DCHECK(web_contents); 31 DCHECK(web_contents);
31 DVLOG(2) << "PresentationServiceImpl: " 32 DVLOG(2) << "PresentationServiceImpl: "
32 << render_frame_host_->GetProcess()->GetID() << ", " 33 << render_frame_host_->GetProcess()->GetID() << ", "
33 << render_frame_host_->GetRoutingID(); 34 << render_frame_host_->GetRoutingID();
34 if (delegate_) 35 if (delegate_)
35 delegate_->AddObserver(this); 36 delegate_->AddObserver(this);
36 } 37 }
37 38
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 const DefaultSessionMojoCallback& callback) { 127 const DefaultSessionMojoCallback& callback) {
127 NOTIMPLEMENTED(); 128 NOTIMPLEMENTED();
128 } 129 }
129 130
130 void PresentationServiceImpl::StartSession( 131 void PresentationServiceImpl::StartSession(
131 const mojo::String& presentation_url, 132 const mojo::String& presentation_url,
132 const mojo::String& presentation_id, 133 const mojo::String& presentation_id,
133 const NewSessionMojoCallback& callback) { 134 const NewSessionMojoCallback& callback) {
134 DVLOG(2) << "StartSession"; 135 DVLOG(2) << "StartSession";
135 if (!delegate_) { 136 if (!delegate_) {
136 callback.Run( 137 InvokeNewSessionMojoCallbackWithError(callback);
137 presentation::PresentationSessionInfoPtr(),
138 presentation::PresentationError::From(
139 PresentationError(PRESENTATION_ERROR_UNKNOWN, "")));
140 return; 138 return;
141 } 139 }
142 140
143 queued_start_session_requests_.push_back(make_linked_ptr( 141 queued_start_session_requests_.push_back(make_linked_ptr(
144 new StartSessionRequest(presentation_url, presentation_id, callback))); 142 new StartSessionRequest(presentation_url, presentation_id, callback)));
145 if (queued_start_session_requests_.size() == 1) 143 if (queued_start_session_requests_.size() == 1)
146 DoStartSession(presentation_url, presentation_id, callback); 144 DoStartSession(presentation_url, presentation_id, callback);
147 } 145 }
148 146
149 void PresentationServiceImpl::JoinSession( 147 void PresentationServiceImpl::JoinSession(
150 const mojo::String& presentation_url, 148 const mojo::String& presentation_url,
151 const mojo::String& presentation_id, 149 const mojo::String& presentation_id,
152 const NewSessionMojoCallback& callback) { 150 const NewSessionMojoCallback& callback) {
153 DVLOG(2) << "JoinSession"; 151 DVLOG(2) << "JoinSession";
154 if (!delegate_) { 152 if (!delegate_) {
155 callback.Run( 153 InvokeNewSessionMojoCallbackWithError(callback);
156 presentation::PresentationSessionInfoPtr(),
157 presentation::PresentationError::From(
158 PresentationError(PRESENTATION_ERROR_UNKNOWN, "")));
159 return; 154 return;
160 } 155 }
161 156
157 int request_session_id = RegisterNewSessionCallback(callback);
162 delegate_->JoinSession( 158 delegate_->JoinSession(
163 render_frame_host_->GetProcess()->GetID(), 159 render_frame_host_->GetProcess()->GetID(),
164 render_frame_host_->GetRoutingID(), 160 render_frame_host_->GetRoutingID(),
165 presentation_url, 161 presentation_url,
166 presentation_id, 162 presentation_id,
167 // TODO(imcheng): These callbacks may be dropped. http://crbug.com/468575
168 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, 163 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded,
169 weak_factory_.GetWeakPtr(), false, callback), 164 weak_factory_.GetWeakPtr(), false, request_session_id),
170 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, 165 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError,
171 weak_factory_.GetWeakPtr(), false, callback)); 166 weak_factory_.GetWeakPtr(), false, request_session_id));
172 } 167 }
173 168
174 void PresentationServiceImpl::HandleQueuedStartSessionRequests() { 169 void PresentationServiceImpl::HandleQueuedStartSessionRequests() {
175 DCHECK(!queued_start_session_requests_.empty()); 170 DCHECK(!queued_start_session_requests_.empty());
176 queued_start_session_requests_.pop_front(); 171 queued_start_session_requests_.pop_front();
177 if (!queued_start_session_requests_.empty()) { 172 if (!queued_start_session_requests_.empty()) {
178 const linked_ptr<StartSessionRequest>& request = 173 const linked_ptr<StartSessionRequest>& request =
179 queued_start_session_requests_.front(); 174 queued_start_session_requests_.front();
180 DoStartSession(request->presentation_url, 175 DoStartSession(request->presentation_url,
181 request->presentation_id, 176 request->presentation_id,
182 request->callback); 177 request->callback);
183 } 178 }
184 } 179 }
185 180
181 int PresentationServiceImpl::RegisterNewSessionCallback(
182 const NewSessionMojoCallback& callback) {
183 ++next_request_session_id_;
184 pending_session_cbs_[next_request_session_id_].reset(
185 new NewSessionMojoCallback(callback));
186 return next_request_session_id_;
187 }
188
186 void PresentationServiceImpl::DoStartSession( 189 void PresentationServiceImpl::DoStartSession(
187 const std::string& presentation_url, 190 const std::string& presentation_url,
188 const std::string& presentation_id, 191 const std::string& presentation_id,
189 const NewSessionMojoCallback& callback) { 192 const NewSessionMojoCallback& callback) {
193 int request_session_id = RegisterNewSessionCallback(callback);
190 delegate_->StartSession( 194 delegate_->StartSession(
191 render_frame_host_->GetProcess()->GetID(), 195 render_frame_host_->GetProcess()->GetID(),
192 render_frame_host_->GetRoutingID(), 196 render_frame_host_->GetRoutingID(),
193 presentation_url, 197 presentation_url,
194 presentation_id, 198 presentation_id,
195 // TODO(imcheng): These callbacks may be dropped. http://crbug.com/468575
196 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, 199 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded,
197 weak_factory_.GetWeakPtr(), true, callback), 200 weak_factory_.GetWeakPtr(), true, request_session_id),
198 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, 201 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError,
199 weak_factory_.GetWeakPtr(), true, callback)); 202 weak_factory_.GetWeakPtr(), true, request_session_id));
200 } 203 }
201 204
202 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded( 205 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded(
203 bool is_start_session, 206 bool is_start_session,
204 const NewSessionMojoCallback& callback, 207 int request_session_id,
205 const PresentationSessionInfo& session_info) { 208 const PresentationSessionInfo& session_info) {
206 callback.Run( 209 RunAndEraseNewSessionMojoCallback(
210 request_session_id,
207 presentation::PresentationSessionInfo::From(session_info), 211 presentation::PresentationSessionInfo::From(session_info),
208 presentation::PresentationErrorPtr()); 212 presentation::PresentationErrorPtr());
209 if (is_start_session) 213 if (is_start_session)
210 HandleQueuedStartSessionRequests(); 214 HandleQueuedStartSessionRequests();
211 } 215 }
212 216
213 void PresentationServiceImpl::OnStartOrJoinSessionError( 217 void PresentationServiceImpl::OnStartOrJoinSessionError(
214 bool is_start_session, 218 bool is_start_session,
215 const NewSessionMojoCallback& callback, 219 int request_session_id,
216 const PresentationError& error) { 220 const PresentationError& error) {
217 callback.Run( 221 RunAndEraseNewSessionMojoCallback(
222 request_session_id,
218 presentation::PresentationSessionInfoPtr(), 223 presentation::PresentationSessionInfoPtr(),
219 presentation::PresentationError::From(error)); 224 presentation::PresentationError::From(error));
220 if (is_start_session) 225 if (is_start_session)
221 HandleQueuedStartSessionRequests(); 226 HandleQueuedStartSessionRequests();
222 } 227 }
223 228
229 void PresentationServiceImpl::RunAndEraseNewSessionMojoCallback(
230 int request_session_id,
231 presentation::PresentationSessionInfoPtr session,
232 presentation::PresentationErrorPtr error) {
233 auto it = pending_session_cbs_.find(request_session_id);
234 if (it == pending_session_cbs_.end())
235 return;
236
237 DCHECK(it->second.get());
238 it->second->Run(session.Pass(), error.Pass());
239 pending_session_cbs_.erase(it);
240 }
241
224 void PresentationServiceImpl::DoSetDefaultPresentationUrl( 242 void PresentationServiceImpl::DoSetDefaultPresentationUrl(
225 const std::string& default_presentation_url, 243 const std::string& default_presentation_url,
226 const std::string& default_presentation_id) { 244 const std::string& default_presentation_id) {
227 DCHECK(delegate_); 245 DCHECK(delegate_);
228 delegate_->SetDefaultPresentationUrl( 246 delegate_->SetDefaultPresentationUrl(
229 render_frame_host_->GetProcess()->GetID(), 247 render_frame_host_->GetProcess()->GetID(),
230 render_frame_host_->GetRoutingID(), 248 render_frame_host_->GetRoutingID(),
231 default_presentation_url, 249 default_presentation_url,
232 default_presentation_id); 250 default_presentation_id);
233 default_presentation_url_ = default_presentation_url; 251 default_presentation_url_ = default_presentation_url;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 void PresentationServiceImpl::Reset() { 338 void PresentationServiceImpl::Reset() {
321 DVLOG(2) << "PresentationServiceImpl::Reset"; 339 DVLOG(2) << "PresentationServiceImpl::Reset";
322 if (delegate_) { 340 if (delegate_) {
323 delegate_->Reset( 341 delegate_->Reset(
324 render_frame_host_->GetProcess()->GetID(), 342 render_frame_host_->GetProcess()->GetID(),
325 render_frame_host_->GetRoutingID()); 343 render_frame_host_->GetRoutingID());
326 } 344 }
327 345
328 default_presentation_url_.clear(); 346 default_presentation_url_.clear();
329 default_presentation_id_.clear(); 347 default_presentation_id_.clear();
330 for (const auto& context : availability_contexts_) { 348 for (const auto& context_entry : availability_contexts_) {
331 context.second->OnScreenAvailabilityChanged(false); 349 context_entry.second->OnScreenAvailabilityChanged(false);
332 } 350 }
333 availability_contexts_.clear(); 351 availability_contexts_.clear();
334 // TODO(imcheng): This may drop callbacks. See http://crbug.com/468575. 352 for (auto& request_ptr : queued_start_session_requests_) {
353 InvokeNewSessionMojoCallbackWithError(request_ptr->callback);
354 }
335 queued_start_session_requests_.clear(); 355 queued_start_session_requests_.clear();
356 for (auto& pending_entry : pending_session_cbs_) {
357 InvokeNewSessionMojoCallbackWithError(*pending_entry.second);
358 }
359 pending_session_cbs_.clear();
360 }
361
362 void PresentationServiceImpl::InvokeNewSessionMojoCallbackWithError(
363 const NewSessionMojoCallback& callback) {
364 callback.Run(
365 presentation::PresentationSessionInfoPtr(),
366 presentation::PresentationError::From(
367 PresentationError(PRESENTATION_ERROR_UNKNOWN, "Internal error")));
336 } 368 }
337 369
338 void PresentationServiceImpl::OnDelegateDestroyed() { 370 void PresentationServiceImpl::OnDelegateDestroyed() {
339 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed"; 371 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed";
340 delegate_ = nullptr; 372 delegate_ = nullptr;
341 Reset(); 373 Reset();
342 } 374 }
343 375
344 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( 376 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext(
345 const std::string& presentation_url) 377 const std::string& presentation_url)
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 : presentation_url(presentation_url), 439 : presentation_url(presentation_url),
408 presentation_id(presentation_id), 440 presentation_id(presentation_id),
409 callback(callback) { 441 callback(callback) {
410 } 442 }
411 443
412 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() { 444 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() {
413 } 445 }
414 446
415 } // namespace content 447 } // namespace content
416 448
OLDNEW
« no previous file with comments | « content/browser/presentation/presentation_service_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698