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 "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/one_ua_presentation_router.h" | |
| 12 #include "chrome/browser/media/router/one_ua_presentation_router_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()), |
| 193 one_ua_presentation_router_( | |
|
miu
2015/09/17 00:09:20
IMO, you should not store a pointer to the router
imcheng
2015/09/26 01:21:56
Done.
| |
| 194 media_router::OneUAPresentationRouterFactory:: | |
| 195 GetOrCreateForBrowserContext(owner_->extension_web_contents() | |
| 196 ->GetBrowserContext())), | |
| 189 capture_poll_timer_(false, false), | 197 capture_poll_timer_(false, false), |
| 190 content_capture_was_detected_(false) { | 198 content_capture_was_detected_(false) { |
| 191 DCHECK(profile_); | 199 DCHECK(profile_); |
| 200 DCHECK(one_ua_presentation_router_); | |
| 192 } | 201 } |
| 193 | 202 |
| 194 OffscreenPresentation::~OffscreenPresentation() { | 203 OffscreenPresentation::~OffscreenPresentation() { |
| 195 DVLOG(1) << "Destroying OffscreenPresentation for start_url=" | 204 DVLOG(1) << "Destroying OffscreenPresentation for start_url=" |
| 196 << start_url_.spec(); | 205 << start_url_.spec(); |
| 197 } | 206 } |
| 198 | 207 |
| 199 void OffscreenPresentation::Start(const gfx::Size& initial_size) { | 208 void OffscreenPresentation::Start(const gfx::Size& initial_size) { |
| 200 DCHECK(start_time_.is_null()); | 209 DCHECK(start_time_.is_null()); |
| 201 DVLOG(1) << "Starting OffscreenPresentation with initial size of " | 210 DVLOG(1) << "Starting OffscreenPresentation with initial size of " |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 218 // Mute audio output. When tab capture starts, the audio will be | 227 // Mute audio output. When tab capture starts, the audio will be |
| 219 // automatically unmuted, but will be captured into the MediaStream. | 228 // automatically unmuted, but will be captured into the MediaStream. |
| 220 presentation_web_contents_->SetAudioMuted(true); | 229 presentation_web_contents_->SetAudioMuted(true); |
| 221 | 230 |
| 222 // Navigate to the initial URL of the presentation. | 231 // Navigate to the initial URL of the presentation. |
| 223 content::NavigationController::LoadURLParams load_params(start_url_); | 232 content::NavigationController::LoadURLParams load_params(start_url_); |
| 224 load_params.should_replace_current_entry = true; | 233 load_params.should_replace_current_entry = true; |
| 225 load_params.should_clear_history_list = true; | 234 load_params.should_clear_history_list = true; |
| 226 presentation_web_contents_->GetController().LoadURLWithParams(load_params); | 235 presentation_web_contents_->GetController().LoadURLWithParams(load_params); |
| 227 | 236 |
| 237 // If the offscreen tab is for a 1-UA presentation, register the tab's main | |
| 238 // frame as a presenter frame in OneUAPresentationRouter. | |
| 239 // Use the OneUAPresentationRouter keyed off the owner's BrowserContext. | |
| 240 // We assume that the presentation's potential controllers will be using the | |
| 241 // same OneUAPresentationRouter instance to connect with the presenter. | |
| 242 content::RenderFrameHost* render_frame_host = | |
| 243 presentation_web_contents_->GetMainFrame(); | |
| 244 DCHECK(render_frame_host); | |
| 245 std::pair<int, int> rfh_id(render_frame_host->GetProcess()->GetID(), | |
| 246 render_frame_host->GetRoutingID()); | |
| 247 | |
| 248 one_ua_presentation_router_->RegisterPresenter(presentation_id(), rfh_id); | |
|
mark a. foltz
2015/09/11 23:24:20
Can RegisterPresenter() just take the (id, WebCont
miu
2015/09/17 00:09:20
+1 to mfoltz's comment.
Also, is registering the
imcheng
2015/09/26 01:21:56
Ok, looks like main frame should be initialized wh
imcheng
2015/09/26 01:21:56
Done.
miu
2015/09/27 00:22:08
Probably not, but there are multiple processes and
imcheng
2015/09/30 01:13:41
Acknowledged. Now I call ReceiverPresentationServi
| |
| 249 | |
| 228 start_time_ = base::TimeTicks::Now(); | 250 start_time_ = base::TimeTicks::Now(); |
| 229 DieIfContentCaptureEnded(); | 251 DieIfContentCaptureEnded(); |
| 230 } | 252 } |
| 231 | 253 |
| 232 void OffscreenPresentation::CloseContents(WebContents* source) { | 254 void OffscreenPresentation::CloseContents(WebContents* source) { |
| 233 DCHECK_EQ(presentation_web_contents_.get(), source); | 255 DCHECK_EQ(presentation_web_contents_.get(), source); |
| 234 // Javascript in the page called window.close(). | 256 // Javascript in the page called window.close(). |
| 235 DVLOG(1) << "OffscreenPresentation will die at renderer's request for " | 257 DVLOG(1) << "OffscreenPresentation will die at renderer's request for " |
| 236 "start_url=" << start_url_.spec(); | 258 "start_url=" << start_url_.spec(); |
| 237 owner_->ClosePresentation(this); | 259 Close(); |
| 238 } | 260 } |
| 239 | 261 |
| 240 bool OffscreenPresentation::ShouldSuppressDialogs(WebContents* source) { | 262 bool OffscreenPresentation::ShouldSuppressDialogs(WebContents* source) { |
| 241 DCHECK_EQ(presentation_web_contents_.get(), source); | 263 DCHECK_EQ(presentation_web_contents_.get(), source); |
| 242 // Suppress all because there is no possible direct user interaction with | 264 // Suppress all because there is no possible direct user interaction with |
| 243 // dialogs. | 265 // dialogs. |
| 244 return true; | 266 return true; |
| 245 } | 267 } |
| 246 | 268 |
| 247 bool OffscreenPresentation::ShouldFocusLocationBarByDefault( | 269 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()); | 459 current_fs_view->SetSize(presentation_web_contents_->GetPreferredSize()); |
| 438 } | 460 } |
| 439 | 461 |
| 440 void OffscreenPresentation::DieIfContentCaptureEnded() { | 462 void OffscreenPresentation::DieIfContentCaptureEnded() { |
| 441 DCHECK(presentation_web_contents_.get()); | 463 DCHECK(presentation_web_contents_.get()); |
| 442 | 464 |
| 443 if (content_capture_was_detected_) { | 465 if (content_capture_was_detected_) { |
| 444 if (presentation_web_contents_->GetCapturerCount() == 0) { | 466 if (presentation_web_contents_->GetCapturerCount() == 0) { |
| 445 DVLOG(2) << "Capture of OffscreenPresentation content has stopped for " | 467 DVLOG(2) << "Capture of OffscreenPresentation content has stopped for " |
| 446 "start_url=" << start_url_.spec(); | 468 "start_url=" << start_url_.spec(); |
| 447 owner_->ClosePresentation(this); | 469 Close(); |
| 448 return; | 470 return; |
| 449 } else { | 471 } else { |
| 450 DVLOG(3) << "Capture of OffscreenPresentation content continues for " | 472 DVLOG(3) << "Capture of OffscreenPresentation content continues for " |
| 451 "start_url=" << start_url_.spec(); | 473 "start_url=" << start_url_.spec(); |
| 452 } | 474 } |
| 453 } else if (presentation_web_contents_->GetCapturerCount() > 0) { | 475 } else if (presentation_web_contents_->GetCapturerCount() > 0) { |
| 454 DVLOG(2) << "Capture of OffscreenPresentation content has started for " | 476 DVLOG(2) << "Capture of OffscreenPresentation content has started for " |
| 455 "start_url=" << start_url_.spec(); | 477 "start_url=" << start_url_.spec(); |
| 456 content_capture_was_detected_ = true; | 478 content_capture_was_detected_ = true; |
| 457 } else if (base::TimeTicks::Now() - start_time_ > | 479 } else if (base::TimeTicks::Now() - start_time_ > |
| 458 base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { | 480 base::TimeDelta::FromSeconds(kMaxSecondsToWaitForCapture)) { |
| 459 // More than a minute has elapsed since this OffscreenPresentation was | 481 // More than a minute has elapsed since this OffscreenPresentation was |
| 460 // started and content capture still hasn't started. As a safety | 482 // started and content capture still hasn't started. As a safety |
| 461 // precaution, assume that content capture is never going to start and die | 483 // precaution, assume that content capture is never going to start and die |
| 462 // to free up resources. | 484 // to free up resources. |
| 463 LOG(WARNING) << "Capture of OffscreenPresentation content did not start " | 485 LOG(WARNING) << "Capture of OffscreenPresentation content did not start " |
| 464 "within timeout for start_url=" << start_url_.spec(); | 486 "within timeout for start_url=" << start_url_.spec(); |
| 465 owner_->ClosePresentation(this); | 487 Close(); |
| 466 return; | 488 return; |
| 467 } | 489 } |
| 468 | 490 |
| 469 // Schedule the timer to check again in a second. | 491 // Schedule the timer to check again in a second. |
| 470 capture_poll_timer_.Start( | 492 capture_poll_timer_.Start( |
| 471 FROM_HERE, | 493 FROM_HERE, |
| 472 base::TimeDelta::FromSeconds(kPollIntervalInSeconds), | 494 base::TimeDelta::FromSeconds(kPollIntervalInSeconds), |
| 473 base::Bind(&OffscreenPresentation::DieIfContentCaptureEnded, | 495 base::Bind(&OffscreenPresentation::DieIfContentCaptureEnded, |
| 474 base::Unretained(this))); | 496 base::Unretained(this))); |
| 475 } | 497 } |
| 476 | 498 |
| 499 void OffscreenPresentation::Close() { | |
| 500 content::RenderFrameHost* render_frame_host = | |
| 501 presentation_web_contents_->GetMainFrame(); | |
| 502 DCHECK(render_frame_host); | |
| 503 std::pair<int, int> rfh_id(render_frame_host->GetProcess()->GetID(), | |
| 504 render_frame_host->GetRoutingID()); | |
| 505 one_ua_presentation_router_->UnregisterPresenter(rfh_id); | |
|
mark a. foltz
2015/09/11 23:24:20
UnregisterPresentation(WebContents*)
imcheng
2015/09/26 01:21:56
Done.
| |
| 506 owner_->ClosePresentation(this); | |
| 507 } | |
| 508 | |
| 477 } // namespace extensions | 509 } // namespace extensions |
| OLD | NEW |