#ifndef SERVICES_MEDIA_SESSION_MEDIA_CONTROLLER_H_
#define SERVICES_MEDIA_SESSION_MEDIA_CONTROLLER_H_
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/sequence_checker.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "services/media_session/public/cpp/media_metadata.h"
#include "services/media_session/public/mojom/media_controller.mojom.h"
#include "services/media_session/public/mojom/media_session.mojom.h"
namespace media_session {
class AudioFocusRequest;
class MediaController : public mojom::MediaController,
public mojom::MediaSessionObserver {
public:
MediaController();
MediaController(const MediaController&) = delete;
MediaController& operator=(const MediaController&) = delete;
~MediaController() override;
void Suspend() override;
void Resume() override;
void Stop() override;
void ToggleSuspendResume() override;
void AddObserver(
mojo::PendingRemote<mojom::MediaControllerObserver> observer) override;
void PreviousTrack() override;
void NextTrack() override;
void Seek(base::TimeDelta seek_time) override;
void SkipAd() override;
void ObserveImages(mojom::MediaSessionImageType type,
int minimum_size_px,
int desired_size_px,
mojo::PendingRemote<mojom::MediaControllerImageObserver>
observer) override;
void SeekTo(base::TimeDelta seek_time) override;
void ScrubTo(base::TimeDelta seek_time) override;
void EnterPictureInPicture() override;
void ExitPictureInPicture() override;
void SetAudioSinkId(const std::optional<std::string>& id) override;
void ToggleMicrophone() override;
void ToggleCamera() override;
void HangUp() override;
void Raise() override;
void SetMute(bool mute) override;
void RequestMediaRemoting() override;
void EnterAutoPictureInPicture() override;
void MediaSessionInfoChanged(
mojom::MediaSessionInfoPtr session_info) override;
void MediaSessionMetadataChanged(
const std::optional<MediaMetadata>&) override;
void MediaSessionActionsChanged(
const std::vector<mojom::MediaSessionAction>& action) override;
void MediaSessionImagesChanged(
const base::flat_map<mojom::MediaSessionImageType,
std::vector<MediaImage>>& images) override;
void MediaSessionPositionChanged(
const std::optional<media_session::MediaPosition>& position) override;
void SetMediaSession(AudioFocusRequest* session);
void ClearMediaSession();
void BindToInterface(mojo::PendingReceiver<mojom::MediaController> receiver);
void FlushForTesting();
private:
friend class MediaControllerTest;
class ImageObserverHolder;
void CleanupImageObservers();
void Reset();
mojo::ReceiverSet<mojom::MediaController> receivers_;
mojom::MediaSessionInfoPtr session_info_;
std::optional<MediaMetadata> session_metadata_;
std::vector<mojom::MediaSessionAction> session_actions_;
std::optional<MediaPosition> session_position_;
base::flat_map<mojom::MediaSessionImageType, std::vector<MediaImage>>
session_images_;
base::flat_map<int, std::vector<MediaImage>> chapter_images_;
raw_ptr<AudioFocusRequest> session_ = nullptr;
mojo::RemoteSet<mojom::MediaControllerObserver> observers_;
mojo::Receiver<mojom::MediaSessionObserver> session_receiver_{this};
std::vector<std::unique_ptr<ImageObserverHolder>> image_observers_;
SEQUENCE_CHECKER(sequence_checker_);
};
}
#endif