1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
6 #define SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
12 #include "base/memory/weak_ptr.h"
13 #include "base/threading/thread_checker.h"
14 #include "mojo/public/cpp/bindings/pending_receiver.h"
15 #include "mojo/public/cpp/bindings/receiver_set.h"
16 #include "mojo/public/cpp/bindings/remote_set.h"
17 #include "services/media_session/media_controller.h"
18 #include "services/media_session/public/mojom/audio_focus.mojom.h"
19 #include "services/media_session/public/mojom/media_controller.mojom.h"
22 class UnguessableToken;
25 namespace media_session {
28 class MockMediaSession;
31 class AudioFocusRequest;
32 class MediaController;
33 class MediaPowerDelegate;
35 struct EnforcementState {
36 bool should_duck = false;
37 bool should_stop = false;
38 bool should_suspend = false;
41 class AudioFocusManager : public mojom::AudioFocusManager,
42 public mojom::AudioFocusManagerDebug,
43 public mojom::MediaControllerManager {
47 AudioFocusManager(const AudioFocusManager&) = delete;
48 AudioFocusManager& operator=(const AudioFocusManager&) = delete;
50 ~AudioFocusManager() override;
52 // TODO(beccahughes): Remove this.
53 using RequestId = base::UnguessableToken;
55 // mojom::AudioFocusManager.
56 void RequestAudioFocus(
57 mojo::PendingReceiver<mojom::AudioFocusRequestClient> receiver,
58 mojo::PendingRemote<mojom::MediaSession> session,
59 mojom::MediaSessionInfoPtr session_info,
60 mojom::AudioFocusType type,
61 RequestAudioFocusCallback callback) override;
62 void RequestGroupedAudioFocus(
63 const base::UnguessableToken& request_id,
64 mojo::PendingReceiver<mojom::AudioFocusRequestClient> receiver,
65 mojo::PendingRemote<mojom::MediaSession> session,
66 mojom::MediaSessionInfoPtr session_info,
67 mojom::AudioFocusType type,
68 const base::UnguessableToken& group_id,
69 RequestGroupedAudioFocusCallback callback) override;
70 void GetFocusRequests(GetFocusRequestsCallback callback) override;
72 mojo::PendingRemote<mojom::AudioFocusObserver> observer) override;
73 void SetSource(const base::UnguessableToken& identity,
74 const std::string& name) override;
75 void SetEnforcementMode(mojom::EnforcementMode mode) override;
76 void AddSourceObserver(
77 const base::UnguessableToken& source_id,
78 mojo::PendingRemote<mojom::AudioFocusObserver> observer) override;
79 void GetSourceFocusRequests(const base::UnguessableToken& source_id,
80 GetFocusRequestsCallback callback) override;
81 void RequestIdReleased(const base::UnguessableToken& request_id) override;
83 // mojom::AudioFocusManagerDebug.
84 void GetDebugInfoForRequest(const RequestId& request_id,
85 GetDebugInfoForRequestCallback callback) override;
87 // mojom::MediaControllerManager.
88 void CreateActiveMediaController(
89 mojo::PendingReceiver<mojom::MediaController> receiver) override;
90 void CreateMediaControllerForSession(
91 mojo::PendingReceiver<mojom::MediaController> receiver,
92 const base::UnguessableToken& receiver_id) override;
93 void SuspendAllSessions() override;
95 // Bind to a receiver of mojom::AudioFocusManager.
97 mojo::PendingReceiver<mojom::AudioFocusManager> receiver);
99 // Bind to a receiver of mojom::AudioFocusManagerDebug.
100 void BindToDebugInterface(
101 mojo::PendingReceiver<mojom::AudioFocusManagerDebug> receiver);
103 // Bind to a receiver of mojom::MediaControllerManager.
104 void BindToControllerManagerInterface(
105 mojo::PendingReceiver<mojom::MediaControllerManager> receiver);
108 friend class AudioFocusManagerTest;
109 friend class AudioFocusRequest;
110 friend class MediaControllerTest;
111 friend class test::MockMediaSession;
113 class SourceObserverHolder;
115 // ReceiverContext stores associated metadata for mojo binding.
116 struct ReceiverContext {
117 // The source name is associated with a binding when a client calls
118 // |SetSourceName|. It is used to provide extra granularity for metrics and
119 // for identifying where an audio focus request originated from.
120 std::string source_name;
122 // The identity associated with the binding when it was created.
123 base::UnguessableToken identity;
126 void RequestAudioFocusInternal(std::unique_ptr<AudioFocusRequest>,
127 mojom::AudioFocusType);
128 void AbandonAudioFocusInternal(RequestId);
130 void EnforceAudioFocus();
132 void MaybeUpdateActiveSession();
134 std::unique_ptr<AudioFocusRequest> RemoveFocusEntryIfPresent(RequestId id);
136 bool IsFocusEntryPresent(const base::UnguessableToken& id) const;
138 // Returns the source name of the binding currently accessing the Audio
139 // Focus Manager API over mojo.
140 const std::string& GetBindingSourceName() const;
142 // Returns the identity of the binding currently accessing the Audio Focus
143 // Manager API over mojo.
144 const base::UnguessableToken& GetBindingIdentity() const;
146 bool IsSessionOnTopOfAudioFocusStack(RequestId id,
147 mojom::AudioFocusType type) const;
149 bool ShouldSessionBeSuspended(const AudioFocusRequest* session,
150 const EnforcementState& state) const;
151 bool ShouldSessionBeDucked(const AudioFocusRequest* session,
152 const EnforcementState& state) const;
154 void EnforceSingleSession(AudioFocusRequest* session,
155 const EnforcementState& state);
157 // Removes unbound or faulty source observers.
158 void CleanupSourceObservers();
160 // This |MediaController| acts as a proxy for controlling the active
161 // |MediaSession| over mojo.
162 MediaController active_media_controller_;
164 // Holds mojo receivers for the Audio Focus Manager API.
165 mojo::ReceiverSet<mojom::AudioFocusManager, std::unique_ptr<ReceiverContext>>
168 // Holds mojo receivers for the Audio Focus Manager Debug API.
169 mojo::ReceiverSet<mojom::AudioFocusManagerDebug> debug_receivers_;
171 // Holds mojo receivers for the Media Controller Manager API.
172 mojo::ReceiverSet<mojom::MediaControllerManager> controller_receivers_;
174 // Weak reference of managed observers. Observers are expected to remove
175 // themselves before being destroyed.
176 mojo::RemoteSet<mojom::AudioFocusObserver> observers_;
178 // Manages individual source observers.
179 std::vector<std::unique_ptr<SourceObserverHolder>> source_observers_;
181 // A stack of Mojo interface pointers and their requested audio focus type.
182 // A MediaSession must abandon audio focus before its destruction.
183 std::list<std::unique_ptr<AudioFocusRequest>> audio_focus_stack_;
185 // Controls media playback when device power events occur.
186 std::unique_ptr<MediaPowerDelegate> power_delegate_;
188 mojom::EnforcementMode enforcement_mode_;
190 // Adding observers should happen on the same thread that the service is
192 THREAD_CHECKER(thread_checker_);
194 base::WeakPtrFactory<AudioFocusManager> weak_ptr_factory_{this};
197 } // namespace media_session
199 #endif // SERVICES_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_