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 
5 #ifndef SERVICES_MEDIA_SESSION_MEDIA_CONTROLLER_H_
6 #define SERVICES_MEDIA_SESSION_MEDIA_CONTROLLER_H_
7 
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/containers/flat_map.h"
13 #include "base/optional.h"
14 #include "base/sequence_checker.h"
15 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
16 #include "mojo/public/cpp/bindings/receiver.h"
17 #include "mojo/public/cpp/bindings/receiver_set.h"
18 #include "mojo/public/cpp/bindings/remote_set.h"
19 #include "services/media_session/public/cpp/media_metadata.h"
20 #include "services/media_session/public/mojom/media_controller.mojom.h"
21 #include "services/media_session/public/mojom/media_session.mojom.h"
22 
23 namespace media_session {
24 
25 class AudioFocusRequest;
26 
27 // MediaController provides a control surface over Mojo for controlling a
28 // specific MediaSession. If |session_| is nullptr then all commands will be
29 // dropped. MediaController is also a MediaSessionObserver and will forward
30 // events to added observers.
31 class MediaController : public mojom::MediaController,
32                         public mojom::MediaSessionObserver {
33  public:
34   MediaController();
35   ~MediaController() override;
36 
37   // mojom::MediaController overrides.
38   void Suspend() override;
39   void Resume() override;
40   void Stop() override;
41   void ToggleSuspendResume() override;
42   void AddObserver(
43       mojo::PendingRemote<mojom::MediaControllerObserver> observer) override;
44   void PreviousTrack() override;
45   void NextTrack() override;
46   void Seek(base::TimeDelta seek_time) override;
47   void ObserveImages(mojom::MediaSessionImageType type,
48                      int minimum_size_px,
49                      int desired_size_px,
50                      mojo::PendingRemote<mojom::MediaControllerImageObserver>
51                          observer) override;
52   void SeekTo(base::TimeDelta seek_time) override;
53   void ScrubTo(base::TimeDelta seek_time) override;
54   void EnterPictureInPicture() override;
55   void ExitPictureInPicture() override;
56 
57   // mojom::MediaSessionObserver overrides.
58   void MediaSessionInfoChanged(
59       mojom::MediaSessionInfoPtr session_info) override;
60   void MediaSessionMetadataChanged(
61       const base::Optional<MediaMetadata>&) override;
62   void MediaSessionActionsChanged(
63       const std::vector<mojom::MediaSessionAction>& action) override;
64   void MediaSessionImagesChanged(
65       const base::flat_map<mojom::MediaSessionImageType,
66                            std::vector<MediaImage>>& images) override;
67   void MediaSessionPositionChanged(
68       const base::Optional<media_session::MediaPosition>& position) override;
69 
70   void SetMediaSession(AudioFocusRequest* session);
71   void ClearMediaSession();
72 
73   void BindToInterface(mojo::PendingReceiver<mojom::MediaController> receiver);
74   void FlushForTesting();
75 
76  private:
77   friend class MediaControllerTest;
78 
79   class ImageObserverHolder;
80 
81   // Removes unbound or faulty image observers.
82   void CleanupImageObservers();
83 
84   void Reset();
85 
86   // Holds mojo bindings for mojom::MediaController.
87   mojo::ReceiverSet<mojom::MediaController> receivers_;
88 
89   // The current info for the |session_|.
90   mojom::MediaSessionInfoPtr session_info_;
91 
92   // The current metadata for |session_|.
93   base::Optional<MediaMetadata> session_metadata_;
94 
95   // The current actions for |session_|.
96   std::vector<mojom::MediaSessionAction> session_actions_;
97 
98   // The current position for |session_|.
99   base::Optional<MediaPosition> session_position_;
100 
101   // The current images for |session_|.
102   base::flat_map<mojom::MediaSessionImageType, std::vector<MediaImage>>
103       session_images_;
104 
105   // Raw pointer to the media session we are controlling.
106   AudioFocusRequest* session_ = nullptr;
107 
108   // Observers that are observing |this|.
109   mojo::RemoteSet<mojom::MediaControllerObserver> observers_;
110 
111   // Binding for |this| to act as an observer to |session_|.
112   mojo::Receiver<mojom::MediaSessionObserver> session_receiver_{this};
113 
114   // Manages individual image observers.
115   std::vector<std::unique_ptr<ImageObserverHolder>> image_observers_;
116 
117   // Protects |session_| as it is not thread safe.
118   SEQUENCE_CHECKER(sequence_checker_);
119 
120   DISALLOW_COPY_AND_ASSIGN(MediaController);
121 };
122 
123 }  // namespace media_session
124 
125 #endif  // SERVICES_MEDIA_SESSION_MEDIA_CONTROLLER_H_
126