audio_focus_manager.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright 2018 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. #ifndef SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
  5. #define SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
  6. #include <list>
  7. #include <string>
  8. #include <vector>
  9. #include "base/memory/weak_ptr.h"
  10. #include "base/threading/thread_checker.h"
  11. #include "mojo/public/cpp/bindings/pending_receiver.h"
  12. #include "mojo/public/cpp/bindings/receiver_set.h"
  13. #include "mojo/public/cpp/bindings/remote_set.h"
  14. #include "services/media_session/media_controller.h"
  15. #include "services/media_session/public/mojom/audio_focus.mojom.h"
  16. #include "services/media_session/public/mojom/media_controller.mojom.h"
  17. namespace base {
  18. class UnguessableToken;
  19. } // namespace base
  20. namespace media_session {
  21. namespace test {
  22. class MockMediaSession;
  23. } // namespace test
  24. class AudioFocusRequest;
  25. class MediaController;
  26. class MediaPowerDelegate;
  27. struct EnforcementState {
  28. bool should_duck = false;
  29. bool should_stop = false;
  30. bool should_suspend = false;
  31. };
  32. class AudioFocusManager : public mojom::AudioFocusManager,
  33. public mojom::AudioFocusManagerDebug,
  34. public mojom::MediaControllerManager {
  35. public:
  36. AudioFocusManager();
  37. AudioFocusManager(const AudioFocusManager&) = delete;
  38. AudioFocusManager& operator=(const AudioFocusManager&) = delete;
  39. ~AudioFocusManager() override;
  40. // TODO(beccahughes): Remove this.
  41. using RequestId = base::UnguessableToken;
  42. // mojom::AudioFocusManager.
  43. void RequestAudioFocus(
  44. mojo::PendingReceiver<mojom::AudioFocusRequestClient> receiver,
  45. mojo::PendingRemote<mojom::MediaSession> session,
  46. mojom::MediaSessionInfoPtr session_info,
  47. mojom::AudioFocusType type,
  48. RequestAudioFocusCallback callback) override;
  49. void RequestGroupedAudioFocus(
  50. const base::UnguessableToken& request_id,
  51. mojo::PendingReceiver<mojom::AudioFocusRequestClient> receiver,
  52. mojo::PendingRemote<mojom::MediaSession> session,
  53. mojom::MediaSessionInfoPtr session_info,
  54. mojom::AudioFocusType type,
  55. const base::UnguessableToken& group_id,
  56. RequestGroupedAudioFocusCallback callback) override;
  57. void GetFocusRequests(GetFocusRequestsCallback callback) override;
  58. void AddObserver(
  59. mojo::PendingRemote<mojom::AudioFocusObserver> observer) override;
  60. void SetSource(const base::UnguessableToken& identity,
  61. const std::string& name) override;
  62. void SetEnforcementMode(mojom::EnforcementMode mode) override;
  63. void AddSourceObserver(
  64. const base::UnguessableToken& source_id,
  65. mojo::PendingRemote<mojom::AudioFocusObserver> observer) override;
  66. void GetSourceFocusRequests(const base::UnguessableToken& source_id,
  67. GetFocusRequestsCallback callback) override;
  68. void RequestIdReleased(const base::UnguessableToken& request_id) override;
  69. // mojom::AudioFocusManagerDebug.
  70. void GetDebugInfoForRequest(const RequestId& request_id,
  71. GetDebugInfoForRequestCallback callback) override;
  72. // mojom::MediaControllerManager.
  73. void CreateActiveMediaController(
  74. mojo::PendingReceiver<mojom::MediaController> receiver) override;
  75. void CreateMediaControllerForSession(
  76. mojo::PendingReceiver<mojom::MediaController> receiver,
  77. const base::UnguessableToken& receiver_id) override;
  78. void SuspendAllSessions() override;
  79. // Bind to a receiver of mojom::AudioFocusManager.
  80. void BindToInterface(
  81. mojo::PendingReceiver<mojom::AudioFocusManager> receiver);
  82. // Bind to a receiver of mojom::AudioFocusManagerDebug.
  83. void BindToDebugInterface(
  84. mojo::PendingReceiver<mojom::AudioFocusManagerDebug> receiver);
  85. // Bind to a receiver of mojom::MediaControllerManager.
  86. void BindToControllerManagerInterface(
  87. mojo::PendingReceiver<mojom::MediaControllerManager> receiver);
  88. private:
  89. friend class AudioFocusManagerTest;
  90. friend class AudioFocusRequest;
  91. friend class MediaControllerTest;
  92. friend class test::MockMediaSession;
  93. class SourceObserverHolder;
  94. // ReceiverContext stores associated metadata for mojo binding.
  95. struct ReceiverContext {
  96. // The source name is associated with a binding when a client calls
  97. // |SetSourceName|. It is used to provide extra granularity for metrics and
  98. // for identifying where an audio focus request originated from.
  99. std::string source_name;
  100. // The identity associated with the binding when it was created.
  101. base::UnguessableToken identity;
  102. };
  103. void RequestAudioFocusInternal(std::unique_ptr<AudioFocusRequest>,
  104. mojom::AudioFocusType);
  105. void AbandonAudioFocusInternal(RequestId);
  106. void EnforceAudioFocus();
  107. void MaybeUpdateActiveSession();
  108. std::unique_ptr<AudioFocusRequest> RemoveFocusEntryIfPresent(RequestId id);
  109. bool IsFocusEntryPresent(const base::UnguessableToken& id) const;
  110. // Returns the source name of the binding currently accessing the Audio
  111. // Focus Manager API over mojo.
  112. const std::string& GetBindingSourceName() const;
  113. // Returns the identity of the binding currently accessing the Audio Focus
  114. // Manager API over mojo.
  115. const base::UnguessableToken& GetBindingIdentity() const;
  116. bool IsSessionOnTopOfAudioFocusStack(RequestId id,
  117. mojom::AudioFocusType type) const;
  118. bool ShouldSessionBeSuspended(const AudioFocusRequest* session,
  119. const EnforcementState& state) const;
  120. bool ShouldSessionBeDucked(const AudioFocusRequest* session,
  121. const EnforcementState& state) const;
  122. void EnforceSingleSession(AudioFocusRequest* session,
  123. const EnforcementState& state);
  124. // Removes unbound or faulty source observers.
  125. void CleanupSourceObservers();
  126. // This |MediaController| acts as a proxy for controlling the active
  127. // |MediaSession| over mojo.
  128. MediaController active_media_controller_;
  129. // Holds mojo receivers for the Audio Focus Manager API.
  130. mojo::ReceiverSet<mojom::AudioFocusManager, std::unique_ptr<ReceiverContext>>
  131. receivers_;
  132. // Holds mojo receivers for the Audio Focus Manager Debug API.
  133. mojo::ReceiverSet<mojom::AudioFocusManagerDebug> debug_receivers_;
  134. // Holds mojo receivers for the Media Controller Manager API.
  135. mojo::ReceiverSet<mojom::MediaControllerManager> controller_receivers_;
  136. // Weak reference of managed observers. Observers are expected to remove
  137. // themselves before being destroyed.
  138. mojo::RemoteSet<mojom::AudioFocusObserver> observers_;
  139. // Manages individual source observers.
  140. std::vector<std::unique_ptr<SourceObserverHolder>> source_observers_;
  141. // A stack of Mojo interface pointers and their requested audio focus type.
  142. // A MediaSession must abandon audio focus before its destruction.
  143. std::list<std::unique_ptr<AudioFocusRequest>> audio_focus_stack_;
  144. // Controls media playback when device power events occur.
  145. std::unique_ptr<MediaPowerDelegate> power_delegate_;
  146. mojom::EnforcementMode enforcement_mode_;
  147. // Adding observers should happen on the same thread that the service is
  148. // running on.
  149. THREAD_CHECKER(thread_checker_);
  150. base::WeakPtrFactory<AudioFocusManager> weak_ptr_factory_{this};
  151. };
  152. } // namespace media_session
  153. #endif // SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_