| 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); |
| 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, |
| 167 // TODO(imcheng): These callbacks may be dropped. http://crbug.com/468575 |
| 149 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, | 168 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, |
| 150 weak_factory_.GetWeakPtr(), false, callback), | 169 weak_factory_.GetWeakPtr(), false, callback), |
| 151 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, | 170 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, |
| 152 weak_factory_.GetWeakPtr(), false, callback)); | 171 weak_factory_.GetWeakPtr(), false, callback)); |
| 153 } | 172 } |
| 154 | 173 |
| 155 void PresentationServiceImpl::HandleQueuedStartSessionRequests() { | 174 void PresentationServiceImpl::HandleQueuedStartSessionRequests() { |
| 156 DCHECK(!queued_start_session_requests_.empty()); | 175 DCHECK(!queued_start_session_requests_.empty()); |
| 157 queued_start_session_requests_.pop_front(); | 176 queued_start_session_requests_.pop_front(); |
| 158 if (!queued_start_session_requests_.empty()) { | 177 if (!queued_start_session_requests_.empty()) { |
| 159 const linked_ptr<StartSessionRequest>& request = | 178 const linked_ptr<StartSessionRequest>& request = |
| 160 queued_start_session_requests_.front(); | 179 queued_start_session_requests_.front(); |
| 161 DoStartSession(request->presentation_url, | 180 DoStartSession(request->presentation_url, |
| 162 request->presentation_id, | 181 request->presentation_id, |
| 163 request->callback); | 182 request->callback); |
| 164 } | 183 } |
| 165 } | 184 } |
| 166 | 185 |
| 167 void PresentationServiceImpl::DoStartSession( | 186 void PresentationServiceImpl::DoStartSession( |
| 168 const std::string& presentation_url, | 187 const std::string& presentation_url, |
| 169 const std::string& presentation_id, | 188 const std::string& presentation_id, |
| 170 const NewSessionMojoCallback& callback) { | 189 const NewSessionMojoCallback& callback) { |
| 171 delegate_->StartSession( | 190 delegate_->StartSession( |
| 172 render_frame_host_->GetProcess()->GetID(), | 191 render_frame_host_->GetProcess()->GetID(), |
| 173 render_frame_host_->GetRoutingID(), | 192 render_frame_host_->GetRoutingID(), |
| 174 presentation_url, | 193 presentation_url, |
| 175 presentation_id, | 194 presentation_id, |
| 195 // TODO(imcheng): These callbacks may be dropped. http://crbug.com/468575 |
| 176 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, | 196 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded, |
| 177 weak_factory_.GetWeakPtr(), true, callback), | 197 weak_factory_.GetWeakPtr(), true, callback), |
| 178 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, | 198 base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionError, |
| 179 weak_factory_.GetWeakPtr(), true, callback)); | 199 weak_factory_.GetWeakPtr(), true, callback)); |
| 180 } | 200 } |
| 181 | 201 |
| 182 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded( | 202 void PresentationServiceImpl::OnStartOrJoinSessionSucceeded( |
| 183 bool is_start_session, | 203 bool is_start_session, |
| 184 const NewSessionMojoCallback& callback, | 204 const NewSessionMojoCallback& callback, |
| 185 const PresentationSessionInfo& session_info) { | 205 const PresentationSessionInfo& session_info) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 } | 251 } |
| 232 | 252 |
| 233 auto old_it = availability_contexts_.find(old_default_url); | 253 auto old_it = availability_contexts_.find(old_default_url); |
| 234 // Haven't started listening yet. | 254 // Haven't started listening yet. |
| 235 if (old_it == availability_contexts_.end()) { | 255 if (old_it == availability_contexts_.end()) { |
| 236 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 256 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); |
| 237 return; | 257 return; |
| 238 } | 258 } |
| 239 | 259 |
| 240 // Have already started listening. Create a listener for the new URL and | 260 // Have already started listening. Create a listener for the new URL and |
| 241 // transfer the callback from the old listener, if any. | 261 // transfer the callbacks from the old listener, if any. |
| 242 // This is done so that a listener added before default URL is changed | 262 // This is done so that a listener added before default URL is changed |
| 243 // will continue to work. | 263 // will continue to work. |
| 244 ScreenAvailabilityMojoCallback* old_callback = old_it->second->GetCallback(); | |
| 245 ScreenAvailabilityContext* context = | 264 ScreenAvailabilityContext* context = |
| 246 GetOrCreateAvailabilityContext(new_default_url); | 265 GetOrCreateAvailabilityContext(new_default_url); |
| 247 if (old_callback) | 266 old_it->second->PassPendingCallbacks(context); |
| 248 context->CallbackReceived(*old_callback); | |
| 249 | 267 |
| 250 // Remove listener for old default presentation URL. | 268 // Remove listener for old default presentation URL. |
| 251 delegate_->RemoveScreenAvailabilityListener( | 269 delegate_->RemoveScreenAvailabilityListener( |
| 252 render_frame_host_->GetProcess()->GetID(), | 270 render_frame_host_->GetProcess()->GetID(), |
| 253 render_frame_host_->GetRoutingID(), | 271 render_frame_host_->GetRoutingID(), |
| 254 old_it->second.get()); | 272 old_it->second.get()); |
| 255 availability_contexts_.erase(old_it); | 273 availability_contexts_.erase(old_it); |
| 256 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 274 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); |
| 257 } | 275 } |
| 258 | 276 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 void PresentationServiceImpl::Reset() { | 314 void PresentationServiceImpl::Reset() { |
| 297 DVLOG(2) << "PresentationServiceImpl::Reset"; | 315 DVLOG(2) << "PresentationServiceImpl::Reset"; |
| 298 if (delegate_) { | 316 if (delegate_) { |
| 299 delegate_->Reset( | 317 delegate_->Reset( |
| 300 render_frame_host_->GetProcess()->GetID(), | 318 render_frame_host_->GetProcess()->GetID(), |
| 301 render_frame_host_->GetRoutingID()); | 319 render_frame_host_->GetRoutingID()); |
| 302 } | 320 } |
| 303 | 321 |
| 304 default_presentation_url_.clear(); | 322 default_presentation_url_.clear(); |
| 305 default_presentation_id_.clear(); | 323 default_presentation_id_.clear(); |
| 324 for (const auto& context : availability_contexts_) { |
| 325 context.second->OnScreenAvailabilityChanged(false); |
| 326 } |
| 306 availability_contexts_.clear(); | 327 availability_contexts_.clear(); |
| 328 // TODO(imcheng): This may drop callbacks. See http://crbug.com/468575. |
| 307 queued_start_session_requests_.clear(); | 329 queued_start_session_requests_.clear(); |
| 308 } | 330 } |
| 309 | 331 |
| 310 void PresentationServiceImpl::OnDelegateDestroyed() { | 332 void PresentationServiceImpl::OnDelegateDestroyed() { |
| 311 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed"; | 333 DVLOG(2) << "PresentationServiceImpl::OnDelegateDestroyed"; |
| 312 delegate_ = nullptr; | 334 delegate_ = nullptr; |
| 313 Reset(); | 335 Reset(); |
| 314 } | 336 } |
| 315 | 337 |
| 316 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( | 338 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( |
| 317 const std::string& presentation_url) | 339 const std::string& presentation_url) |
| 318 : presentation_url_(presentation_url) { | 340 : presentation_url_(presentation_url) { |
| 319 } | 341 } |
| 320 | 342 |
| 321 PresentationServiceImpl::ScreenAvailabilityContext:: | 343 PresentationServiceImpl::ScreenAvailabilityContext:: |
| 322 ~ScreenAvailabilityContext() { | 344 ~ScreenAvailabilityContext() { |
| 323 } | 345 } |
| 324 | 346 |
| 325 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( | 347 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( |
| 326 const ScreenAvailabilityMojoCallback& callback) { | 348 const ScreenAvailabilityMojoCallback& callback) { |
| 327 // NOTE: This will overwrite previously registered callback if any. | 349 // NOTE: This will overwrite previously registered callback if any. |
| 328 if (!available_ptr_) { | 350 if (!available_ptr_) { |
| 329 // No results yet, store callback for later invocation. | 351 // No results yet, store callback for later invocation. |
| 330 callback_ptr_.reset(new ScreenAvailabilityMojoCallback(callback)); | 352 callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback)); |
| 331 } else { | 353 } else { |
| 332 // Run callback now, reset result. | 354 // Run callback now, reset result. |
| 333 // There shouldn't be any callbacks stored in this scenario. | 355 // There shouldn't be any callbacks stored in this scenario. |
| 334 DCHECK(!callback_ptr_); | 356 DCHECK(!HasPendingCallbacks()); |
| 335 callback.Run(presentation_url_, *available_ptr_); | 357 callback.Run(presentation_url_, *available_ptr_); |
| 336 Reset(); | 358 available_ptr_.reset(); |
| 337 } | 359 } |
| 338 } | 360 } |
| 339 | 361 |
| 340 void PresentationServiceImpl::ScreenAvailabilityContext::Reset() { | |
| 341 callback_ptr_.reset(); | |
| 342 available_ptr_.reset(); | |
| 343 } | |
| 344 | |
| 345 std::string PresentationServiceImpl::ScreenAvailabilityContext | 362 std::string PresentationServiceImpl::ScreenAvailabilityContext |
| 346 ::GetPresentationUrl() const { | 363 ::GetPresentationUrl() const { |
| 347 return presentation_url_; | 364 return presentation_url_; |
| 348 } | 365 } |
| 349 | 366 |
| 350 void PresentationServiceImpl::ScreenAvailabilityContext | 367 void PresentationServiceImpl::ScreenAvailabilityContext |
| 351 ::OnScreenAvailabilityChanged(bool available) { | 368 ::OnScreenAvailabilityChanged(bool available) { |
| 352 if (!callback_ptr_) { | 369 if (!HasPendingCallbacks()) { |
| 353 // No callback, stash the result for now. | 370 // No callback, stash the result for now. |
| 354 available_ptr_.reset(new bool(available)); | 371 available_ptr_.reset(new bool(available)); |
| 355 } else { | 372 } else { |
| 356 // Invoke callback and erase it. | 373 // Invoke callbacks and erase them. |
| 357 // There shouldn't be any result stored in this scenario. | 374 // There shouldn't be any result stored in this scenario. |
| 358 DCHECK(!available_ptr_); | 375 DCHECK(!available_ptr_); |
| 359 callback_ptr_->Run(presentation_url_, available); | 376 ScopedVector<ScreenAvailabilityMojoCallback> callbacks; |
| 360 Reset(); | 377 callbacks.swap(callbacks_); |
| 378 for (const auto& callback : callbacks) |
| 379 callback->Run(presentation_url_, available); |
| 361 } | 380 } |
| 362 } | 381 } |
| 363 | 382 |
| 364 PresentationServiceImpl::ScreenAvailabilityMojoCallback* | 383 void PresentationServiceImpl::ScreenAvailabilityContext |
| 365 PresentationServiceImpl::ScreenAvailabilityContext::GetCallback() const { | 384 ::PassPendingCallbacks( |
| 366 return callback_ptr_.get(); | 385 PresentationServiceImpl::ScreenAvailabilityContext* other) { |
| 386 std::vector<ScreenAvailabilityMojoCallback*> callbacks; |
| 387 callbacks_.release(&callbacks); |
| 388 std::copy(callbacks.begin(), callbacks.end(), |
| 389 std::back_inserter(other->callbacks_)); |
| 390 } |
| 391 |
| 392 bool PresentationServiceImpl::ScreenAvailabilityContext |
| 393 ::HasPendingCallbacks() const { |
| 394 return !callbacks_.empty(); |
| 367 } | 395 } |
| 368 | 396 |
| 369 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( | 397 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( |
| 370 const std::string& presentation_url, | 398 const std::string& presentation_url, |
| 371 const std::string& presentation_id, | 399 const std::string& presentation_id, |
| 372 const NewSessionMojoCallback& callback) | 400 const NewSessionMojoCallback& callback) |
| 373 : presentation_url(presentation_url), | 401 : presentation_url(presentation_url), |
| 374 presentation_id(presentation_id), | 402 presentation_id(presentation_id), |
| 375 callback(callback) { | 403 callback(callback) { |
| 376 } | 404 } |
| 377 | 405 |
| 378 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() { | 406 PresentationServiceImpl::StartSessionRequest::~StartSessionRequest() { |
| 379 } | 407 } |
| 380 | 408 |
| 381 } // namespace content | 409 } // namespace content |
| 410 |
| OLD | NEW |