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 CONTENT_BROWSER_MEDIA_FLINGING_RENDERER_H_
6 #define CONTENT_BROWSER_MEDIA_FLINGING_RENDERER_H_
7 
8 #include "base/callback.h"
9 #include "content/common/content_export.h"
10 #include "media/base/flinging_controller.h"
11 #include "media/base/media_resource.h"
12 #include "media/base/media_status_observer.h"
13 #include "media/base/renderer.h"
14 #include "media/base/renderer_client.h"
15 #include "media/mojo/mojom/renderer_extensions.mojom.h"
16 #include "mojo/public/cpp/bindings/pending_remote.h"
17 #include "mojo/public/cpp/bindings/remote.h"
18 #include "url/gurl.h"
19 
20 namespace content {
21 
22 class FlingingRendererTest;
23 class RenderFrameHost;
24 
25 // FlingingRenderer adapts from the media::Renderer interface to the
26 // MediaController interface. The MediaController is used to issue simple media
27 // playback commands. In this case, the media we are controlling should be an
28 // already existing RemotingCastSession, which should have been initiated by a
29 // blink::RemotePlayback object, using the PresentationService.
30 class CONTENT_EXPORT FlingingRenderer : public media::Renderer,
31                                         media::MediaStatusObserver {
32  public:
33   using ClientExtension = media::mojom::FlingingRendererClientExtension;
34 
35   // Helper method to create a FlingingRenderer from an already existing
36   // presentation ID.
37   // Returns nullptr if there was an error getting the MediaControllor for the
38   // given presentation ID.
39   static std::unique_ptr<FlingingRenderer> Create(
40       RenderFrameHost* render_frame_host,
41       const std::string& presentation_id,
42       mojo::PendingRemote<ClientExtension> client_extension);
43 
44   ~FlingingRenderer() override;
45 
46   // media::Renderer implementation
47   void Initialize(media::MediaResource* media_resource,
48                   media::RendererClient* client,
49                   media::PipelineStatusCallback init_cb) override;
50   void SetCdm(media::CdmContext* cdm_context,
51               media::CdmAttachedCB cdm_attached_cb) override;
52   void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) override;
53   void Flush(base::OnceClosure flush_cb) override;
54   void StartPlayingFrom(base::TimeDelta time) override;
55   void SetPlaybackRate(double playback_rate) override;
56   void SetVolume(float volume) override;
57   base::TimeDelta GetMediaTime() override;
58 
59   // media::MediaStatusObserver implementation.
60   void OnMediaStatusUpdated(const media::MediaStatus& status) override;
61 
62  private:
63   friend class FlingingRendererTest;
64   using PlayState = media::MediaStatus::State;
65 
66   explicit FlingingRenderer(
67       std::unique_ptr<media::FlingingController> controller,
68       mojo::PendingRemote<ClientExtension> client_extension);
69 
70   void SetExpectedPlayState(PlayState state);
71 
72   // The play state that we expect the remote device to reach.
73   // Updated whenever WMPI sends play/pause commands.
74   PlayState expected_play_state_ = PlayState::UNKNOWN;
75 
76   // True when the remote device has reached the expected play state.
77   // False when it is transitioning.
78   bool play_state_is_stable_ = false;
79 
80   // The last "stable" play state received from the cast device.
81   // Only updated when |play_state_is_stable_| is true.
82   PlayState last_play_state_received_ = PlayState::UNKNOWN;
83 
84   media::RendererClient* client_;
85 
86   mojo::Remote<ClientExtension> client_extension_;
87 
88   std::unique_ptr<media::FlingingController> controller_;
89 
90   DISALLOW_COPY_AND_ASSIGN(FlingingRenderer);
91 };
92 
93 }  // namespace content
94 
95 #endif  // CONTENT_BROWSER_MEDIA_FLINGING_RENDERER_H_
96