Chromium Code Reviews| 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> | |
| 8 | |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 8 #include "content/browser/presentation/presentation_type_converters.h" | 10 #include "content/browser/presentation/presentation_type_converters.h" |
| 9 #include "content/public/browser/content_browser_client.h" | 11 #include "content/public/browser/content_browser_client.h" |
| 10 #include "content/public/browser/navigation_details.h" | 12 #include "content/public/browser/navigation_details.h" |
| 11 #include "content/public/browser/render_frame_host.h" | 13 #include "content/public/browser/render_frame_host.h" |
| 12 #include "content/public/browser/render_process_host.h" | 14 #include "content/public/browser/render_process_host.h" |
| 13 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
| 14 #include "content/public/common/content_client.h" | 16 #include "content/public/common/content_client.h" |
| 15 #include "content/public/common/frame_navigate_params.h" | 17 #include "content/public/common/frame_navigate_params.h" |
| 16 | 18 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 it = availability_contexts_.insert( | 81 it = availability_contexts_.insert( |
| 80 std::make_pair(context->GetPresentationUrl(), context)).first; | 82 std::make_pair(context->GetPresentationUrl(), context)).first; |
| 81 } | 83 } |
| 82 return it->second.get(); | 84 return it->second.get(); |
| 83 } | 85 } |
| 84 | 86 |
| 85 void PresentationServiceImpl::GetScreenAvailability( | 87 void PresentationServiceImpl::GetScreenAvailability( |
| 86 const mojo::String& presentation_url, | 88 const mojo::String& presentation_url, |
| 87 const ScreenAvailabilityMojoCallback& callback) { | 89 const ScreenAvailabilityMojoCallback& callback) { |
| 88 DVLOG(2) << "GetScreenAvailability"; | 90 DVLOG(2) << "GetScreenAvailability"; |
| 89 if (!delegate_) | 91 if (!delegate_) { |
| 92 callback.Run(presentation_url, false); | |
| 90 return; | 93 return; |
| 94 } | |
| 91 | 95 |
| 92 ScreenAvailabilityContext* context = | 96 ScreenAvailabilityContext* context = |
| 93 GetOrCreateAvailabilityContext(presentation_url.get()); | 97 GetOrCreateAvailabilityContext(presentation_url.get()); |
| 94 if (!context) | 98 if (!context) { |
| 99 callback.Run(presentation_url, false);; | |
|
imcheng
2015/03/19 01:21:14
extra semicolon
Ken Rockot(use gerrit already)
2015/03/19 16:16:39
Done.
| |
| 95 return; | 100 return; |
| 101 } | |
| 96 context->CallbackReceived(callback); | 102 context->CallbackReceived(callback); |
| 97 } | 103 } |
| 98 | 104 |
| 99 void PresentationServiceImpl::OnScreenAvailabilityListenerRemoved( | 105 void PresentationServiceImpl::OnScreenAvailabilityListenerRemoved( |
| 100 const mojo::String& presentation_url) { | 106 const mojo::String& presentation_url) { |
| 101 DVLOG(2) << "OnScreenAvailabilityListenerRemoved"; | 107 DVLOG(2) << "OnScreenAvailabilityListenerRemoved"; |
| 102 if (!delegate_) | 108 if (!delegate_) |
| 103 return; | 109 return; |
| 104 | 110 |
| 105 const std::string& presentation_url_str = presentation_url.get(); | 111 const std::string& presentation_url_str = presentation_url.get(); |
| 106 auto it = availability_contexts_.find(presentation_url_str); | 112 auto it = availability_contexts_.find(presentation_url_str); |
| 107 if (it == availability_contexts_.end()) | 113 if (it == availability_contexts_.end()) |
| 108 return; | 114 return; |
| 109 | 115 |
| 110 delegate_->RemoveScreenAvailabilityListener( | 116 delegate_->RemoveScreenAvailabilityListener( |
| 111 render_frame_host_->GetProcess()->GetID(), | 117 render_frame_host_->GetProcess()->GetID(), |
| 112 render_frame_host_->GetRoutingID(), | 118 render_frame_host_->GetRoutingID(), |
| 113 it->second.get()); | 119 it->second.get()); |
| 120 // Resolve the context's pending callbacks before removing it. | |
| 121 it->second->OnScreenAvailabilityChanged(false); | |
| 114 availability_contexts_.erase(it); | 122 availability_contexts_.erase(it); |
| 115 } | 123 } |
| 116 | 124 |
| 117 void PresentationServiceImpl::ListenForDefaultSessionStart( | 125 void PresentationServiceImpl::ListenForDefaultSessionStart( |
| 118 const DefaultSessionMojoCallback& callback) { | 126 const DefaultSessionMojoCallback& callback) { |
| 119 NOTIMPLEMENTED(); | 127 NOTIMPLEMENTED(); |
| 120 } | 128 } |
| 121 | 129 |
| 122 void PresentationServiceImpl::StartSession( | 130 void PresentationServiceImpl::StartSession( |
| 123 const mojo::String& presentation_url, | 131 const mojo::String& presentation_url, |
| 124 const mojo::String& presentation_id, | 132 const mojo::String& presentation_id, |
| 125 const NewSessionMojoCallback& callback) { | 133 const NewSessionMojoCallback& callback) { |
| 126 DVLOG(2) << "StartSession"; | 134 DVLOG(2) << "StartSession"; |
| 127 if (!delegate_) | 135 if (!delegate_) { |
| 136 callback.Run( | |
| 137 presentation::PresentationSessionInfoPtr(), | |
| 138 presentation::PresentationError::From( | |
| 139 PresentationError(PRESENTATION_ERROR_UNKNOWN, ""))); | |
| 128 return; | 140 return; |
| 141 } | |
| 129 | 142 |
| 130 queued_start_session_requests_.push_back(make_linked_ptr( | 143 queued_start_session_requests_.push_back(make_linked_ptr( |
| 131 new StartSessionRequest(presentation_url, presentation_id, callback))); | 144 new StartSessionRequest(presentation_url, presentation_id, callback))); |
| 132 if (queued_start_session_requests_.size() == 1) | 145 if (queued_start_session_requests_.size() == 1) |
| 133 DoStartSession(presentation_url, presentation_id, callback); | 146 DoStartSession(presentation_url, presentation_id, callback); |
| 134 } | 147 } |
| 135 | 148 |
| 136 void PresentationServiceImpl::JoinSession( | 149 void PresentationServiceImpl::JoinSession( |
| 137 const mojo::String& presentation_url, | 150 const mojo::String& presentation_url, |
| 138 const mojo::String& presentation_id, | 151 const mojo::String& presentation_id, |
| 139 const NewSessionMojoCallback& callback) { | 152 const NewSessionMojoCallback& callback) { |
| 140 DVLOG(2) << "JoinSession"; | 153 DVLOG(2) << "JoinSession"; |
| 141 if (!delegate_) | 154 if (!delegate_) { |
| 155 callback.Run( | |
| 156 presentation::PresentationSessionInfoPtr(), | |
| 157 presentation::PresentationError::From( | |
| 158 PresentationError(PRESENTATION_ERROR_UNKNOWN, ""))); | |
| 142 return; | 159 return; |
| 160 } | |
| 143 | 161 |
| 144 delegate_->JoinSession( | 162 delegate_->JoinSession( |
| 145 render_frame_host_->GetProcess()->GetID(), | 163 render_frame_host_->GetProcess()->GetID(), |
| 146 render_frame_host_->GetRoutingID(), | 164 render_frame_host_->GetRoutingID(), |
| 147 presentation_url, | 165 presentation_url, |
| 148 presentation_id, | 166 presentation_id, |
| 149 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, | 167 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, |
|
imcheng
2015/03/19 01:21:14
This is actually another potential place where cal
Ken Rockot(use gerrit already)
2015/03/19 16:16:39
Done.
| |
| 150 weak_factory_.GetWeakPtr(), false, callback), | 168 weak_factory_.GetWeakPtr(), false, callback), |
| 151 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, | 169 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, |
| 152 weak_factory_.GetWeakPtr(), false, callback)); | 170 weak_factory_.GetWeakPtr(), false, callback)); |
| 153 } | 171 } |
| 154 | 172 |
| 155 void PresentationServiceImpl::HandleQueuedStartSessionRequests() { | 173 void PresentationServiceImpl::HandleQueuedStartSessionRequests() { |
| 156 DCHECK(!queued_start_session_requests_.empty()); | 174 DCHECK(!queued_start_session_requests_.empty()); |
| 157 queued_start_session_requests_.pop_front(); | 175 queued_start_session_requests_.pop_front(); |
| 158 if (!queued_start_session_requests_.empty()) { | 176 if (!queued_start_session_requests_.empty()) { |
| 159 const linked_ptr<StartSessionRequest>& request = | 177 const linked_ptr<StartSessionRequest>& request = |
| 160 queued_start_session_requests_.front(); | 178 queued_start_session_requests_.front(); |
| 161 DoStartSession(request->presentation_url, | 179 DoStartSession(request->presentation_url, |
| 162 request->presentation_id, | 180 request->presentation_id, |
| 163 request->callback); | 181 request->callback); |
| 164 } | 182 } |
| 165 } | 183 } |
| 166 | 184 |
| 167 void PresentationServiceImpl::DoStartSession( | 185 void PresentationServiceImpl::DoStartSession( |
| 168 const std::string& presentation_url, | 186 const std::string& presentation_url, |
| 169 const std::string& presentation_id, | 187 const std::string& presentation_id, |
| 170 const NewSessionMojoCallback& callback) { | 188 const NewSessionMojoCallback& callback) { |
| 171 delegate_->StartSession( | 189 delegate_->StartSession( |
| 172 render_frame_host_->GetProcess()->GetID(), | 190 render_frame_host_->GetProcess()->GetID(), |
| 173 render_frame_host_->GetRoutingID(), | 191 render_frame_host_->GetRoutingID(), |
| 174 presentation_url, | 192 presentation_url, |
| 175 presentation_id, | 193 presentation_id, |
| 176 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, | 194 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, |
|
imcheng
2015/03/19 01:21:14
This is actually another potential place where cal
Ken Rockot(use gerrit already)
2015/03/19 16:16:39
Done.
| |
| 177 weak_factory_.GetWeakPtr(), true, callback), | 195 weak_factory_.GetWeakPtr(), true, callback), |
| 178 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, | 196 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, |
| 179 weak_factory_.GetWeakPtr(), true, callback)); | 197 weak_factory_.GetWeakPtr(), true, callback)); |
| 180 } | 198 } |
| 181 | 199 |
| 182 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded( | 200 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded( |
| 183 bool is_start_session, | 201 bool is_start_session, |
| 184 const NewSessionMojoCallback& callback, | 202 const NewSessionMojoCallback& callback, |
| 185 const PresentationSessionInfo& session_info) { | 203 const PresentationSessionInfo& session_info) { |
| 186 callback.Run( | 204 callback.Run( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 } | 249 } |
| 232 | 250 |
| 233 auto old_it = availability_contexts_.find(old_default_url); | 251 auto old_it = availability_contexts_.find(old_default_url); |
| 234 // Haven't started listening yet. | 252 // Haven't started listening yet. |
| 235 if (old_it == availability_contexts_.end()) { | 253 if (old_it == availability_contexts_.end()) { |
| 236 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 254 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); |
| 237 return; | 255 return; |
| 238 } | 256 } |
| 239 | 257 |
| 240 // Have already started listening. Create a listener for the new URL and | 258 // Have already started listening. Create a listener for the new URL and |
| 241 // transfer the callback from the old listener, if any. | 259 // transfer the callbacks from the old listener, if any. |
| 242 // This is done so that a listener added before default URL is changed | 260 // This is done so that a listener added before default URL is changed |
| 243 // will continue to work. | 261 // will continue to work. |
| 244 ScreenAvailabilityMojoCallback* old_callback = old_it->second->GetCallback(); | |
| 245 ScreenAvailabilityContext* context = | 262 ScreenAvailabilityContext* context = |
| 246 GetOrCreateAvailabilityContext(new_default_url); | 263 GetOrCreateAvailabilityContext(new_default_url); |
| 247 if (old_callback) | 264 old_it->second->PassPendingCallbacks(context); |
| 248 context->CallbackReceived(*old_callback); | |
| 249 | 265 |
| 250 // Remove listener for old default presentation URL. | 266 // Remove listener for old default presentation URL. |
| 251 delegate_->RemoveScreenAvailabilityListener( | 267 delegate_->RemoveScreenAvailabilityListener( |
| 252 render_frame_host_->GetProcess()->GetID(), | 268 render_frame_host_->GetProcess()->GetID(), |
| 253 render_frame_host_->GetRoutingID(), | 269 render_frame_host_->GetRoutingID(), |
| 254 old_it->second.get()); | 270 old_it->second.get()); |
| 255 availability_contexts_.erase(old_it); | 271 availability_contexts_.erase(old_it); |
| 256 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 272 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); |
| 257 } | 273 } |
| 258 | 274 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 void PresentationServiceImpl::Reset() { | 312 void PresentationServiceImpl::Reset() { |
| 297 DVLOG(2) << "PresentationServiceImpl::Reset"; | 313 DVLOG(2) << "PresentationServiceImpl::Reset"; |
| 298 if (delegate_) { | 314 if (delegate_) { |
| 299 delegate_->Reset( | 315 delegate_->Reset( |
| 300 render_frame_host_->GetProcess()->GetID(), | 316 render_frame_host_->GetProcess()->GetID(), |
| 301 render_frame_host_->GetRoutingID()); | 317 render_frame_host_->GetRoutingID()); |
| 302 } | 318 } |
| 303 | 319 |
| 304 default_presentation_url_.clear(); | 320 default_presentation_url_.clear(); |
| 305 default_presentation_id_.clear(); | 321 default_presentation_id_.clear(); |
| 306 availability_contexts_.clear(); | 322 availability_contexts_.clear(); |
|
imcheng
2015/03/19 01:21:14
This is actually another place where callbacks get
Ken Rockot(use gerrit already)
2015/03/19 16:16:39
Oops. I've changed this to signal the availability
| |
| 307 queued_start_session_requests_.clear(); | 323 queued_start_session_requests_.clear(); |
| 308 } | 324 } |
| 309 | 325 |
| 310 void PresentationServiceImpl::OnDelegateDestroyed() { | 326 void PresentationServiceImpl::OnDelegateDestroyed() { |
| 311 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed"; | 327 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed"; |
| 312 delegate_ = nullptr; | 328 delegate_ = nullptr; |
| 313 Reset(); | 329 Reset(); |
| 314 } | 330 } |
| 315 | 331 |
| 316 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( | 332 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( |
| 317 const std::string& presentation_url) | 333 const std::string& presentation_url) |
| 318 : presentation_url_(presentation_url) { | 334 : presentation_url_(presentation_url) { |
| 319 } | 335 } |
| 320 | 336 |
| 321 PresentationServiceImpl::ScreenAvailabilityContext:: | 337 PresentationServiceImpl::ScreenAvailabilityContext:: |
| 322 ~ScreenAvailabilityContext() { | 338 ~ScreenAvailabilityContext() { |
| 323 } | 339 } |
| 324 | 340 |
| 325 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( | 341 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( |
| 326 const ScreenAvailabilityMojoCallback& callback) { | 342 const ScreenAvailabilityMojoCallback& callback) { |
| 327 // NOTE: This will overwrite previously registered callback if any. | 343 // NOTE: This will overwrite previously registered callback if any. |
| 328 if (!available_ptr_) { | 344 if (!available_ptr_) { |
| 329 // No results yet, store callback for later invocation. | 345 // No results yet, store callback for later invocation. |
| 330 callback_ptr_.reset(new ScreenAvailabilityMojoCallback(callback)); | 346 callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback)); |
| 331 } else { | 347 } else { |
| 332 // Run callback now, reset result. | 348 // Run callback now, reset result. |
| 333 // There shouldn't be any callbacks stored in this scenario. | 349 // There shouldn't be any callbacks stored in this scenario. |
| 334 DCHECK(!callback_ptr_); | 350 DCHECK(!HasPendingCallbacks()); |
| 335 callback.Run(presentation_url_, *available_ptr_); | 351 callback.Run(presentation_url_, *available_ptr_); |
| 336 Reset(); | 352 available_ptr_.reset(); |
| 337 } | 353 } |
| 338 } | 354 } |
| 339 | 355 |
| 340 void PresentationServiceImpl::ScreenAvailabilityContext::Reset() { | |
| 341 callback_ptr_.reset(); | |
| 342 available_ptr_.reset(); | |
| 343 } | |
| 344 | |
| 345 std::string PresentationServiceImpl::ScreenAvailabilityContext | 356 std::string PresentationServiceImpl::ScreenAvailabilityContext |
| 346 ::GetPresentationUrl() const { | 357 ::GetPresentationUrl() const { |
| 347 return presentation_url_; | 358 return presentation_url_; |
| 348 } | 359 } |
| 349 | 360 |
| 350 void PresentationServiceImpl::ScreenAvailabilityContext | 361 void PresentationServiceImpl::ScreenAvailabilityContext |
| 351 ::OnScreenAvailabilityChanged(bool available) { | 362 ::OnScreenAvailabilityChanged(bool available) { |
| 352 if (!callback_ptr_) { | 363 if (!HasPendingCallbacks()) { |
| 353 // No callback, stash the result for now. | 364 // No callback, stash the result for now. |
| 354 available_ptr_.reset(new bool(available)); | 365 available_ptr_.reset(new bool(available)); |
| 355 } else { | 366 } else { |
| 356 // Invoke callback and erase it. | 367 // Invoke callbacks and erase them. |
| 357 // There shouldn't be any result stored in this scenario. | 368 // There shouldn't be any result stored in this scenario. |
| 358 DCHECK(!available_ptr_); | 369 DCHECK(!available_ptr_); |
| 359 callback_ptr_->Run(presentation_url_, available); | 370 ScopedVector<ScreenAvailabilityMojoCallback> callbacks; |
| 360 Reset(); | 371 callbacks.swap(callbacks_); |
| 372 for (const auto& callback : callbacks) | |
| 373 callback->Run(presentation_url_, available); | |
| 361 } | 374 } |
| 362 } | 375 } |
| 363 | 376 |
| 364 PresentationServiceImpl::ScreenAvailabilityMojoCallback* | 377 void PresentationServiceImpl::ScreenAvailabilityContext |
| 365 PresentationServiceImpl::ScreenAvailabilityContext::GetCallback() const { | 378 ::PassPendingCallbacks( |
| 366 return callback_ptr_.get(); | 379 PresentationServiceImpl::ScreenAvailabilityContext* other) { |
| 380 std::vector<ScreenAvailabilityMojoCallback*> callbacks; | |
| 381 callbacks_.release(&callbacks); | |
| 382 std::copy(callbacks.begin(), callbacks.end(), | |
| 383 std::back_inserter(other->callbacks_)); | |
| 384 } | |
| 385 | |
| 386 bool PresentationServiceImpl::ScreenAvailabilityContext | |
| 387 ::HasPendingCallbacks() const { | |
| 388 return !callbacks_.empty(); | |
| 367 } | 389 } |
| 368 | 390 |
| 369 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( | 391 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( |
| 370 const std::string& presentation_url, | 392 const std::string& presentation_url, |
| 371 const std::string& presentation_id, | 393 const std::string& presentation_id, |
| 372 const NewSessionMojoCallback& callback) | 394 const NewSessionMojoCallback& callback) |
| 373 : presentation_url(presentation_url), | 395 : presentation_url(presentation_url), |
| 374 presentation_id(presentation_id), | 396 presentation_id(presentation_id), |
| 375 callback(callback) { | 397 callback(callback) { |
| 376 } | 398 } |
| 377 | 399 |
| 378 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() { | 400 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() { |
| 379 } | 401 } |
| 380 | 402 |
| 381 } // namespace content | 403 } // namespace content |
| 404 | |
| OLD | NEW |