OLD | NEW |
---|---|
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" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 binding_.reset(new mojo::Binding<presentation::PresentationService>( | 94 binding_.reset(new mojo::Binding<presentation::PresentationService>( |
95 this, request.Pass())); | 95 this, request.Pass())); |
96 binding_->set_error_handler(this); | 96 binding_->set_error_handler(this); |
97 } | 97 } |
98 | 98 |
99 void PresentationServiceImpl::OnConnectionError() { | 99 void PresentationServiceImpl::OnConnectionError() { |
100 DVLOG(1) << "OnConnectionError"; | 100 DVLOG(1) << "OnConnectionError"; |
101 delete this; | 101 delete this; |
102 } | 102 } |
103 | 103 |
104 PresentationServiceImpl::ScreenAvailabilityContext* | 104 void PresentationServiceImpl::SetClient( |
105 PresentationServiceImpl::GetOrCreateAvailabilityContext( | 105 presentation::PresentationServiceClientPtr client) { |
106 const std::string& presentation_url) { | 106 DCHECK(client_.is_null()); |
107 auto it = availability_contexts_.find(presentation_url); | 107 client_ = client.Pass(); |
108 if (it == availability_contexts_.end()) { | |
109 linked_ptr<ScreenAvailabilityContext> context( | |
110 new ScreenAvailabilityContext(presentation_url)); | |
111 if (!delegate_->AddScreenAvailabilityListener( | |
112 render_process_id_, render_frame_id_, context.get())) { | |
113 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; | |
114 return nullptr; | |
115 } | |
116 it = availability_contexts_.insert( | |
117 std::make_pair(context->GetPresentationUrl(), context)).first; | |
118 } | |
119 return it->second.get(); | |
120 } | 108 } |
121 | 109 |
122 void PresentationServiceImpl::ListenForScreenAvailability( | 110 void PresentationServiceImpl::ListenForScreenAvailability() { |
123 const mojo::String& presentation_url, | |
124 const ScreenAvailabilityMojoCallback& callback) { | |
125 DVLOG(2) << "ListenForScreenAvailability"; | 111 DVLOG(2) << "ListenForScreenAvailability"; |
126 if (!delegate_) { | 112 if (!delegate_) |
127 callback.Run(presentation_url, false); | 113 return; |
114 | |
115 if (screen_availability_listener_.get() && | |
mark a. foltz
2015/05/11 23:48:38
ISTM this check should go into ResetScreenAvailabi
imcheng (use chromium acct)
2015/05/12 00:14:03
In the two cases where ResetScreenAvailabilityList
| |
116 screen_availability_listener_->GetPresentationUrl() == | |
117 default_presentation_url_) { | |
128 return; | 118 return; |
129 } | 119 } |
130 | 120 |
131 ScreenAvailabilityContext* context = | 121 ResetScreenAvailabilityListener(default_presentation_url_); |
132 GetOrCreateAvailabilityContext(presentation_url.get()); | |
133 if (!context) { | |
134 callback.Run(presentation_url, false); | |
135 return; | |
136 } | |
137 context->CallbackReceived(callback); | |
138 } | 122 } |
139 | 123 |
140 void PresentationServiceImpl::RemoveScreenAvailabilityListener( | 124 void PresentationServiceImpl::ResetScreenAvailabilityListener( |
141 const mojo::String& presentation_url) { | 125 const std::string& presentation_url) { |
142 DVLOG(2) << "RemoveScreenAvailabilityListener"; | 126 DCHECK(delegate_); |
127 | |
128 // (1) Unregister old listener with delegate | |
129 StopListeningForScreenAvailability(); | |
130 | |
131 // (2) Replace old listener with new listener | |
132 screen_availability_listener_.reset(new ScreenAvailabilityListenerImpl( | |
133 presentation_url, this)); | |
134 | |
135 // (3) Register new listener with delegate | |
136 if (!delegate_->AddScreenAvailabilityListener( | |
137 render_process_id_, | |
138 render_frame_id_, | |
139 screen_availability_listener_.get())) { | |
140 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; | |
141 screen_availability_listener_.reset(); | |
142 } | |
143 } | |
144 | |
145 void PresentationServiceImpl::StopListeningForScreenAvailability() { | |
146 DVLOG(2) << "StopListeningForScreenAvailability"; | |
143 if (!delegate_) | 147 if (!delegate_) |
144 return; | 148 return; |
145 | 149 |
146 const std::string& presentation_url_str = presentation_url.get(); | 150 if (screen_availability_listener_.get()) { |
147 auto it = availability_contexts_.find(presentation_url_str); | 151 delegate_->RemoveScreenAvailabilityListener( |
148 if (it == availability_contexts_.end()) | 152 render_process_id_, |
149 return; | 153 render_frame_id_, |
150 | 154 screen_availability_listener_.get()); |
151 delegate_->RemoveScreenAvailabilityListener( | 155 screen_availability_listener_.reset(); |
152 render_process_id_, render_frame_id_, it->second.get()); | 156 } |
153 // Resolve the context's pending callbacks before removing it. | |
154 it->second->OnScreenAvailabilityChanged(false); | |
155 availability_contexts_.erase(it); | |
156 } | 157 } |
157 | 158 |
158 void PresentationServiceImpl::ListenForDefaultSessionStart( | 159 void PresentationServiceImpl::ListenForDefaultSessionStart( |
159 const DefaultSessionMojoCallback& callback) { | 160 const DefaultSessionMojoCallback& callback) { |
160 if (!default_session_start_context_.get()) | 161 if (!default_session_start_context_.get()) |
161 default_session_start_context_.reset(new DefaultSessionStartContext); | 162 default_session_start_context_.reset(new DefaultSessionStartContext); |
162 default_session_start_context_->AddCallback(callback); | 163 default_session_start_context_->AddCallback(callback); |
163 } | 164 } |
164 | 165 |
165 void PresentationServiceImpl::StartSession( | 166 void PresentationServiceImpl::StartSession( |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 presentation::PresentationErrorPtr error) { | 279 presentation::PresentationErrorPtr error) { |
279 auto it = pending_session_cbs_.find(request_session_id); | 280 auto it = pending_session_cbs_.find(request_session_id); |
280 if (it == pending_session_cbs_.end()) | 281 if (it == pending_session_cbs_.end()) |
281 return; | 282 return; |
282 | 283 |
283 DCHECK(it->second.get()); | 284 DCHECK(it->second.get()); |
284 it->second->Run(session.Pass(), error.Pass()); | 285 it->second->Run(session.Pass(), error.Pass()); |
285 pending_session_cbs_.erase(it); | 286 pending_session_cbs_.erase(it); |
286 } | 287 } |
287 | 288 |
288 void PresentationServiceImpl::DoSetDefaultPresentationUrl( | |
289 const std::string& default_presentation_url, | |
290 const std::string& default_presentation_id) { | |
291 DCHECK(delegate_); | |
292 delegate_->SetDefaultPresentationUrl( | |
293 render_process_id_, | |
294 render_frame_id_, | |
295 default_presentation_url, | |
296 default_presentation_id); | |
297 default_presentation_url_ = default_presentation_url; | |
298 default_presentation_id_ = default_presentation_id; | |
299 } | |
300 | |
301 void PresentationServiceImpl::SetDefaultPresentationURL( | 289 void PresentationServiceImpl::SetDefaultPresentationURL( |
302 const mojo::String& default_presentation_url, | 290 const mojo::String& default_presentation_url, |
303 const mojo::String& default_presentation_id) { | 291 const mojo::String& default_presentation_id) { |
304 DVLOG(2) << "SetDefaultPresentationURL"; | 292 DVLOG(2) << "SetDefaultPresentationURL"; |
305 if (!delegate_) | 293 if (!delegate_) |
306 return; | 294 return; |
307 | 295 |
308 const std::string& old_default_url = default_presentation_url_; | 296 const std::string& old_default_url = default_presentation_url_; |
309 const std::string& new_default_url = default_presentation_url.get(); | 297 const std::string& new_default_url = default_presentation_url.get(); |
310 | 298 |
311 // Don't call delegate if nothing changed. | 299 // Don't call delegate if nothing changed. |
312 if (old_default_url == new_default_url && | 300 if (old_default_url == new_default_url && |
313 default_presentation_id_ == default_presentation_id) { | 301 default_presentation_id_ == default_presentation_id) { |
314 return; | 302 return; |
315 } | 303 } |
316 | 304 |
317 auto old_it = availability_contexts_.find(old_default_url); | 305 if (old_default_url != new_default_url) { |
318 // Haven't started listening yet. | 306 // If DPU changed, replace screen availability listeners if any. |
319 if (old_it == availability_contexts_.end()) { | 307 if (screen_availability_listener_.get()) |
320 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 308 ResetScreenAvailabilityListener(new_default_url); |
321 return; | |
322 } | 309 } |
323 | 310 |
324 // Have already started listening. Create a listener for the new URL and | 311 delegate_->SetDefaultPresentationUrl( |
325 // transfer the callbacks from the old listener, if any. | |
326 // This is done so that a listener added before default URL is changed | |
327 // will continue to work. | |
328 ScreenAvailabilityContext* context = | |
329 GetOrCreateAvailabilityContext(new_default_url); | |
330 old_it->second->PassPendingCallbacks(context); | |
331 | |
332 // Remove listener for old default presentation URL. | |
333 delegate_->RemoveScreenAvailabilityListener( | |
334 render_process_id_, | 312 render_process_id_, |
335 render_frame_id_, | 313 render_frame_id_, |
336 old_it->second.get()); | 314 default_presentation_url, |
337 availability_contexts_.erase(old_it); | 315 default_presentation_id); |
338 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 316 default_presentation_url_ = default_presentation_url; |
317 default_presentation_id_ = default_presentation_id; | |
339 } | 318 } |
340 | 319 |
341 void PresentationServiceImpl::CloseSession( | 320 void PresentationServiceImpl::CloseSession( |
342 const mojo::String& presentation_url, | 321 const mojo::String& presentation_url, |
343 const mojo::String& presentation_id) { | 322 const mojo::String& presentation_id) { |
344 NOTIMPLEMENTED(); | 323 NOTIMPLEMENTED(); |
345 } | 324 } |
346 | 325 |
347 void PresentationServiceImpl::ListenForSessionStateChange( | 326 void PresentationServiceImpl::ListenForSessionStateChange( |
348 const SessionStateCallback& callback) { | 327 const SessionStateCallback& callback) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 delete this; | 411 delete this; |
433 } | 412 } |
434 | 413 |
435 void PresentationServiceImpl::Reset() { | 414 void PresentationServiceImpl::Reset() { |
436 DVLOG(2) << "PresentationServiceImpl::Reset"; | 415 DVLOG(2) << "PresentationServiceImpl::Reset"; |
437 if (delegate_) | 416 if (delegate_) |
438 delegate_->Reset(render_process_id_, render_frame_id_); | 417 delegate_->Reset(render_process_id_, render_frame_id_); |
439 | 418 |
440 default_presentation_url_.clear(); | 419 default_presentation_url_.clear(); |
441 default_presentation_id_.clear(); | 420 default_presentation_id_.clear(); |
442 availability_contexts_.clear(); | 421 screen_availability_listener_.reset(); |
443 queued_start_session_requests_.clear(); | 422 queued_start_session_requests_.clear(); |
444 FlushNewSessionCallbacks(); | 423 FlushNewSessionCallbacks(); |
445 default_session_start_context_.reset(); | 424 default_session_start_context_.reset(); |
446 if (on_session_messages_callback_.get()) { | 425 if (on_session_messages_callback_.get()) { |
447 on_session_messages_callback_->Run( | 426 on_session_messages_callback_->Run( |
448 mojo::Array<presentation::SessionMessagePtr>()); | 427 mojo::Array<presentation::SessionMessagePtr>()); |
449 on_session_messages_callback_.reset(); | 428 on_session_messages_callback_.reset(); |
450 } | 429 } |
451 } | 430 } |
452 | 431 |
(...skipping 11 matching lines...) Expand all Loading... | |
464 delegate_ = nullptr; | 443 delegate_ = nullptr; |
465 Reset(); | 444 Reset(); |
466 } | 445 } |
467 | 446 |
468 void PresentationServiceImpl::OnDefaultPresentationStarted( | 447 void PresentationServiceImpl::OnDefaultPresentationStarted( |
469 const PresentationSessionInfo& session) { | 448 const PresentationSessionInfo& session) { |
470 if (default_session_start_context_.get()) | 449 if (default_session_start_context_.get()) |
471 default_session_start_context_->set_session(session); | 450 default_session_start_context_->set_session(session); |
472 } | 451 } |
473 | 452 |
474 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( | 453 PresentationServiceImpl::ScreenAvailabilityListenerImpl |
475 const std::string& presentation_url) | 454 ::ScreenAvailabilityListenerImpl( |
476 : presentation_url_(presentation_url) { | 455 const std::string& presentation_url, |
456 PresentationServiceImpl* service) | |
457 : presentation_url_(presentation_url), | |
458 service_(service) { | |
459 DCHECK(service_); | |
460 DCHECK(!service_->client_.is_null()); | |
477 } | 461 } |
478 | 462 |
479 PresentationServiceImpl::ScreenAvailabilityContext:: | 463 PresentationServiceImpl::ScreenAvailabilityListenerImpl:: |
480 ~ScreenAvailabilityContext() { | 464 ~ScreenAvailabilityListenerImpl() { |
481 // Ensure that pending callbacks are flushed. | |
482 OnScreenAvailabilityChanged(false); | |
483 } | 465 } |
484 | 466 |
485 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( | 467 std::string PresentationServiceImpl::ScreenAvailabilityListenerImpl |
486 const ScreenAvailabilityMojoCallback& callback) { | |
487 // NOTE: This will overwrite previously registered callback if any. | |
488 if (!available_ptr_) { | |
489 // No results yet, store callback for later invocation. | |
490 callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback)); | |
491 } else { | |
492 // Run callback now, reset result. | |
493 // There shouldn't be any callbacks stored in this scenario. | |
494 DCHECK(!HasPendingCallbacks()); | |
495 callback.Run(presentation_url_, *available_ptr_); | |
496 available_ptr_.reset(); | |
497 } | |
498 } | |
499 | |
500 std::string PresentationServiceImpl::ScreenAvailabilityContext | |
501 ::GetPresentationUrl() const { | 468 ::GetPresentationUrl() const { |
502 return presentation_url_; | 469 return presentation_url_; |
503 } | 470 } |
504 | 471 |
505 void PresentationServiceImpl::ScreenAvailabilityContext | 472 void PresentationServiceImpl::ScreenAvailabilityListenerImpl |
506 ::OnScreenAvailabilityChanged(bool available) { | 473 ::OnScreenAvailabilityChanged(bool available) { |
507 if (!HasPendingCallbacks()) { | 474 service_->client_->OnScreenAvailabilityUpdated(available); |
508 // No callback, stash the result for now. | |
509 available_ptr_.reset(new bool(available)); | |
510 } else { | |
511 // Invoke callbacks and erase them. | |
512 // There shouldn't be any result stored in this scenario. | |
513 DCHECK(!available_ptr_); | |
514 ScopedVector<ScreenAvailabilityMojoCallback> callbacks; | |
515 callbacks.swap(callbacks_); | |
516 for (const auto& callback : callbacks) | |
517 callback->Run(presentation_url_, available); | |
518 } | |
519 } | |
520 | |
521 void PresentationServiceImpl::ScreenAvailabilityContext | |
522 ::PassPendingCallbacks( | |
523 PresentationServiceImpl::ScreenAvailabilityContext* other) { | |
524 std::vector<ScreenAvailabilityMojoCallback*> callbacks; | |
525 callbacks_.release(&callbacks); | |
526 std::copy(callbacks.begin(), callbacks.end(), | |
527 std::back_inserter(other->callbacks_)); | |
528 } | |
529 | |
530 bool PresentationServiceImpl::ScreenAvailabilityContext | |
531 ::HasPendingCallbacks() const { | |
532 return !callbacks_.empty(); | |
533 } | 475 } |
534 | 476 |
535 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( | 477 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( |
536 const std::string& presentation_url, | 478 const std::string& presentation_url, |
537 const std::string& presentation_id, | 479 const std::string& presentation_id, |
538 const NewSessionMojoCallback& callback) | 480 const NewSessionMojoCallback& callback) |
539 : presentation_url_(presentation_url), | 481 : presentation_url_(presentation_url), |
540 presentation_id_(presentation_id), | 482 presentation_id_(presentation_id), |
541 callback_(callback) { | 483 callback_(callback) { |
542 } | 484 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { | 532 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { |
591 ScopedVector<DefaultSessionMojoCallback> callbacks; | 533 ScopedVector<DefaultSessionMojoCallback> callbacks; |
592 callbacks.swap(callbacks_); | 534 callbacks.swap(callbacks_); |
593 for (const auto& callback : callbacks) | 535 for (const auto& callback : callbacks) |
594 callback->Run(presentation::PresentationSessionInfoPtr()); | 536 callback->Run(presentation::PresentationSessionInfoPtr()); |
595 session_.reset(); | 537 session_.reset(); |
596 } | 538 } |
597 | 539 |
598 } // namespace content | 540 } // namespace content |
599 | 541 |
OLD | NEW |