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 "chrome/browser/extensions/api/tab_capture/offscreen_presentation.h" | 5 #include "chrome/browser/extensions/api/tab_capture/offscreen_presentation.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" | 10 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 11 #include "chrome/browser/media/router/offscreen_presentation_manager.h" |
| 12 #include "chrome/browser/media/router/offscreen_presentation_manager_factory.h" |
11 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/web_contents_sizer.h" | 14 #include "chrome/browser/ui/web_contents_sizer.h" |
| 15 #include "content/public/browser/render_frame_host.h" |
| 16 #include "content/public/browser/render_process_host.h" |
13 #include "content/public/browser/render_widget_host_view.h" | 17 #include "content/public/browser/render_widget_host_view.h" |
14 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
15 #include "extensions/browser/extension_host.h" | 19 #include "extensions/browser/extension_host.h" |
16 #include "extensions/browser/process_manager.h" | 20 #include "extensions/browser/process_manager.h" |
17 | 21 |
18 #if defined(USE_AURA) | 22 #if defined(USE_AURA) |
19 #include "base/memory/weak_ptr.h" | 23 #include "base/memory/weak_ptr.h" |
20 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
21 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
22 #include "chrome/browser/ui/browser_list.h" | 26 #include "chrome/browser/ui/browser_list.h" |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 } | 180 } |
177 return nullptr; | 181 return nullptr; |
178 } | 182 } |
179 | 183 |
180 OffscreenPresentation::OffscreenPresentation(OffscreenPresentationsOwner* owner, | 184 OffscreenPresentation::OffscreenPresentation(OffscreenPresentationsOwner* owner, |
181 const GURL& start_url, | 185 const GURL& start_url, |
182 const std::string& id) | 186 const std::string& id) |
183 : owner_(owner), | 187 : owner_(owner), |
184 start_url_(start_url), | 188 start_url_(start_url), |
185 presentation_id_(id), | 189 presentation_id_(id), |
186 profile_(Profile::FromBrowserContext( | 190 profile_(Profile::FromBrowserContext(owner->extension_web_contents() |
187 owner->extension_web_contents()->GetBrowserContext()) | 191 ->GetBrowserContext()) |
188 ->CreateOffTheRecordProfile()), | 192 ->CreateOffTheRecordProfile()), |
189 capture_poll_timer_(false, false), | 193 capture_poll_timer_(false, false), |
190 content_capture_was_detected_(false) { | 194 content_capture_was_detected_(false) { |
191 DCHECK(profile_); | 195 DCHECK(profile_); |
192 } | 196 } |
193 | 197 |
194 OffscreenPresentation::~OffscreenPresentation() { | 198 OffscreenPresentation::~OffscreenPresentation() { |
195 DVLOG(1) << "Destroying OffscreenPresentation for start_url=" | 199 DVLOG(1) << "Destroying OffscreenPresentation for start_url=" |
196 << start_url_.spec(); | 200 << start_url_.spec(); |
197 } | 201 } |
198 | 202 |
(...skipping 13 matching lines...) Expand all Loading... |
212 #endif | 216 #endif |
213 | 217 |
214 // Set initial size, if specified. | 218 // Set initial size, if specified. |
215 if (!initial_size.IsEmpty()) | 219 if (!initial_size.IsEmpty()) |
216 ResizeWebContents(presentation_web_contents_.get(), initial_size); | 220 ResizeWebContents(presentation_web_contents_.get(), initial_size); |
217 | 221 |
218 // Mute audio output. When tab capture starts, the audio will be | 222 // Mute audio output. When tab capture starts, the audio will be |
219 // automatically unmuted, but will be captured into the MediaStream. | 223 // automatically unmuted, but will be captured into the MediaStream. |
220 presentation_web_contents_->SetAudioMuted(true); | 224 presentation_web_contents_->SetAudioMuted(true); |
221 | 225 |
| 226 // If the tab is for an offscreen presentation, register the tab as a |
| 227 // presenter in OffscreenPresentationManager. |
| 228 // Use the OffscreenPresentationManager keyed off the owner's BrowserContext. |
| 229 // We assume that the presentation's potential controllers will be using the |
| 230 // same OffscreenPresentationManager instance to connect with the presenter. |
| 231 GetOffscreenPresentationManager()->RegisterPresenterTab( |
| 232 presentation_id(), presentation_web_contents_.get()); |
| 233 |
222 // Navigate to the initial URL of the presentation. | 234 // Navigate to the initial URL of the presentation. |
223 content::NavigationController::LoadURLParams load_params(start_url_); | 235 content::NavigationController::LoadURLParams load_params(start_url_); |
224 load_params.should_replace_current_entry = true; | 236 load_params.should_replace_current_entry = true; |
225 load_params.should_clear_history_list = true; | 237 load_params.should_clear_history_list = true; |
226 presentation_web_contents_->GetController().LoadURLWithParams(load_params); | 238 presentation_web_contents_->GetController().LoadURLWithParams(load_params); |
227 | 239 |
228 start_time_ = base::TimeTicks::Now(); | 240 start_time_ = base::TimeTicks::Now(); |
229 DieIfContentCaptureEnded(); | 241 DieIfContentCaptureEnded(); |
230 } | 242 } |
231 | 243 |
232 void OffscreenPresentation::CloseContents(WebContents* source) { | 244 void OffscreenPresentation::CloseContents(WebContents* source) { |
233 DCHECK_EQ(presentation_web_contents_.get(), source); | 245 DCHECK_EQ(presentation_web_contents_.get(), source); |
234 // Javascript in the page called window.close(). | 246 // Javascript in the page called window.close(). |
235 DVLOG(1) << "OffscreenPresentation will die at renderer's request for " | 247 DVLOG(1) << "OffscreenPresentation will die at renderer's request for " |
236 "start_url=" << start_url_.spec(); | 248 "start_url=" << start_url_.spec(); |
237 owner_->ClosePresentation(this); | 249 Destroy(); |
238 } | 250 } |
239 | 251 |
240 bool OffscreenPresentation::ShouldSuppressDialogs(WebContents* source) { | 252 bool OffscreenPresentation::ShouldSuppressDialogs(WebContents* source) { |
241 DCHECK_EQ(presentation_web_contents_.get(), source); | 253 DCHECK_EQ(presentation_web_contents_.get(), source); |
242 // Suppress all because there is no possible direct user interaction with | 254 // Suppress all because there is no possible direct user interaction with |
243 // dialogs. | 255 // dialogs. |
244 return true; | 256 return true; |
245 } | 257 } |
246 | 258 |
247 bool OffscreenPresentation::ShouldFocusLocationBarByDefault( | 259 bool OffscreenPresentation::ShouldFocusLocationBarByDefault( |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 current_fs_view->SetSize(presentation_web_contents_->GetPreferredSize()); | 449 current_fs_view->SetSize(presentation_web_contents_->GetPreferredSize()); |
438 } | 450 } |
439 | 451 |
440 void OffscreenPresentation::DieIfContentCaptureEnded() { | 452 void OffscreenPresentation::DieIfContentCaptureEnded() { |
441 DCHECK(presentation_web_contents_.get()); | 453 DCHECK(presentation_web_contents_.get()); |
442 | 454 |
443 if (content_capture_was_detected_) { | 455 if (content_capture_was_detected_) { |
444 if (presentation_web_contents_->GetCapturerCount() == 0) { | 456 if (presentation_web_contents_->GetCapturerCount() == 0) { |
445 DVLOG(2) << "Capture of OffscreenPresentation content has stopped for " | 457 DVLOG(2) << "Capture of OffscreenPresentation content has stopped for " |
446 "start_url=" << start_url_.spec(); | 458 "start_url=" << start_url_.spec(); |
447 owner_->ClosePresentation(this); | 459 Destroy(); |
448 return; | 460 return; |
449 } else { | 461 } else { |
450 DVLOG(3) << "Capture of OffscreenPresentation content continues for " | 462 DVLOG(3) << "Capture of OffscreenPresentation content continues for " |
451 "start_url=" << start_url_.spec(); | 463 "start_url=" << start_url_.spec(); |
452 } | 464 } |
453 } else if (presentation_web_contents_->GetCapturerCount() > 0) { | 465 } else if (presentation_web_contents_->GetCapturerCount() > 0) { |
454 DVLOG(2) << "Capture of OffscreenPresentation content has started for " | 466 DVLOG(2) << "Capture of OffscreenPresentation content has started for " |
455 "start_url=" << start_url_.spec(); | 467 "start_url=" << start_url_.spec(); |
456 content_capture_was_detected_ = true; | 468 content_capture_was_detected_ = true; |
457 } else if (base::TimeTicks::Now() - start_time_ > | 469 } else if (base::TimeTicks::Now() - start_time_ > |
458 base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { | 470 base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { |
459 // More than a minute has elapsed since this OffscreenPresentation was | 471 // More than a minute has elapsed since this OffscreenPresentation was |
460 // started and content capture still hasn't started. As a safety | 472 // started and content capture still hasn't started. As a safety |
461 // precaution, assume that content capture is never going to start and die | 473 // precaution, assume that content capture is never going to start and die |
462 // to free up resources. | 474 // to free up resources. |
463 LOG(WARNING) << "Capture of OffscreenPresentation content did not start " | 475 LOG(WARNING) << "Capture of OffscreenPresentation content did not start " |
464 "within timeout for start_url=" << start_url_.spec(); | 476 "within timeout for start_url=" << start_url_.spec(); |
465 owner_->ClosePresentation(this); | 477 Destroy(); |
466 return; | 478 return; |
467 } | 479 } |
468 | 480 |
469 // Schedule the timer to check again in a second. | 481 // Schedule the timer to check again in a second. |
470 capture_poll_timer_.Start( | 482 capture_poll_timer_.Start( |
471 FROM_HERE, | 483 FROM_HERE, |
472 base::TimeDelta::FromSeconds(kPollIntervalInSeconds), | 484 base::TimeDelta::FromSeconds(kPollIntervalInSeconds), |
473 base::Bind(&OffscreenPresentation::DieIfContentCaptureEnded, | 485 base::Bind(&OffscreenPresentation::DieIfContentCaptureEnded, |
474 base::Unretained(this))); | 486 base::Unretained(this))); |
475 } | 487 } |
476 | 488 |
| 489 void OffscreenPresentation::Destroy() { |
| 490 GetOffscreenPresentationManager()->UnregisterPresenterTab( |
| 491 presentation_web_contents_.get()); |
| 492 owner_->ClosePresentation(this); |
| 493 } |
| 494 |
| 495 media_router::OffscreenPresentationManager* |
| 496 OffscreenPresentation::GetOffscreenPresentationManager() { |
| 497 auto* manager = media_router::OffscreenPresentationManagerFactory:: |
| 498 GetOrCreateForBrowserContext( |
| 499 owner_->extension_web_contents()->GetBrowserContext()); |
| 500 DCHECK(manager); |
| 501 return manager; |
| 502 } |
| 503 |
477 } // namespace extensions | 504 } // namespace extensions |
OLD | NEW |