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 |