video_detector.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/wm/video_detector.h"
  5. #include "ash/public/cpp/shell_window_ids.h"
  6. #include "ash/shell.h"
  7. #include "ash/wm/window_state.h"
  8. #include "base/bind.h"
  9. #include "components/viz/host/host_frame_sink_manager.h"
  10. #include "mojo/public/cpp/bindings/pending_remote.h"
  11. #include "ui/aura/env.h"
  12. #include "ui/aura/window_event_dispatcher.h"
  13. #include "ui/compositor/compositor.h"
  14. #include "ui/gfx/geometry/rect.h"
  15. #include "ui/wm/core/window_util.h"
  16. namespace ash {
  17. namespace {
  18. // How long to wait before attempting to re-establish a lost connection.
  19. constexpr base::TimeDelta kReEstablishConnectionDelay = base::Milliseconds(100);
  20. } // namespace
  21. VideoDetector::VideoDetector()
  22. : state_(State::NOT_PLAYING),
  23. video_is_playing_(false),
  24. is_shutting_down_(false) {
  25. aura::Env::GetInstance()->AddObserver(this);
  26. Shell::Get()->AddShellObserver(this);
  27. EstablishConnectionToViz();
  28. }
  29. VideoDetector::~VideoDetector() {
  30. Shell::Get()->RemoveShellObserver(this);
  31. aura::Env::GetInstance()->RemoveObserver(this);
  32. }
  33. void VideoDetector::AddObserver(Observer* observer) {
  34. observers_.AddObserver(observer);
  35. }
  36. void VideoDetector::RemoveObserver(Observer* observer) {
  37. observers_.RemoveObserver(observer);
  38. }
  39. void VideoDetector::OnWindowInitialized(aura::Window* window) {
  40. window_observations_manager_.AddObservation(window);
  41. }
  42. void VideoDetector::OnWindowDestroying(aura::Window* window) {
  43. if (fullscreen_desks_containers_.count(window)) {
  44. window_observations_manager_.RemoveObservation(window);
  45. fullscreen_desks_containers_.erase(window);
  46. UpdateState();
  47. }
  48. }
  49. void VideoDetector::OnWindowDestroyed(aura::Window* window) {
  50. window_observations_manager_.RemoveObservation(window);
  51. }
  52. void VideoDetector::OnChromeTerminating() {
  53. // Stop checking video activity once the shutdown
  54. // process starts. crbug.com/231696.
  55. is_shutting_down_ = true;
  56. }
  57. void VideoDetector::OnFullscreenStateChanged(bool is_fullscreen,
  58. aura::Window* container) {
  59. const bool has_fullscreen_in_container =
  60. fullscreen_desks_containers_.count(container);
  61. if (is_fullscreen && !has_fullscreen_in_container) {
  62. fullscreen_desks_containers_.insert(container);
  63. if (!window_observations_manager_.IsObservingSource(container))
  64. window_observations_manager_.AddObservation(container);
  65. UpdateState();
  66. } else if (!is_fullscreen && has_fullscreen_in_container) {
  67. fullscreen_desks_containers_.erase(container);
  68. window_observations_manager_.RemoveObservation(container);
  69. UpdateState();
  70. }
  71. }
  72. void VideoDetector::UpdateState() {
  73. State new_state = State::NOT_PLAYING;
  74. if (video_is_playing_) {
  75. new_state = fullscreen_desks_containers_.empty()
  76. ? State::PLAYING_WINDOWED
  77. : State::PLAYING_FULLSCREEN;
  78. }
  79. if (state_ != new_state) {
  80. state_ = new_state;
  81. for (auto& observer : observers_)
  82. observer.OnVideoStateChanged(state_);
  83. }
  84. }
  85. void VideoDetector::OnVideoActivityStarted() {
  86. if (is_shutting_down_)
  87. return;
  88. video_is_playing_ = true;
  89. UpdateState();
  90. }
  91. void VideoDetector::OnVideoActivityEnded() {
  92. video_is_playing_ = false;
  93. UpdateState();
  94. }
  95. void VideoDetector::EstablishConnectionToViz() {
  96. if (receiver_.is_bound())
  97. receiver_.reset();
  98. mojo::PendingRemote<viz::mojom::VideoDetectorObserver> observer =
  99. receiver_.BindNewPipeAndPassRemote();
  100. receiver_.set_disconnect_handler(base::BindOnce(
  101. &VideoDetector::OnConnectionError, base::Unretained(this)));
  102. aura::Env::GetInstance()
  103. ->context_factory()
  104. ->GetHostFrameSinkManager()
  105. ->AddVideoDetectorObserver(std::move(observer));
  106. }
  107. void VideoDetector::OnConnectionError() {
  108. if (video_is_playing_)
  109. OnVideoActivityEnded();
  110. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  111. FROM_HERE,
  112. base::BindOnce(&VideoDetector::EstablishConnectionToViz,
  113. weak_factory_.GetWeakPtr()),
  114. kReEstablishConnectionDelay);
  115. }
  116. } // namespace ash