| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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 MEDIA_REMOTING_REMOTING_RENDERER_CONTROLLER_H_ | |
| 6 #define MEDIA_REMOTING_REMOTING_RENDERER_CONTROLLER_H_ | |
| 7 | |
| 8 #include "base/callback.h" | |
| 9 #include "base/memory/weak_ptr.h" | |
| 10 #include "base/optional.h" | |
| 11 #include "media/base/media_observer.h" | |
| 12 #include "media/remoting/metrics.h" | |
| 13 #include "media/remoting/remoting_interstitial_ui.h" | |
| 14 #include "media/remoting/remoting_source_impl.h" | |
| 15 #include "third_party/skia/include/core/SkBitmap.h" | |
| 16 | |
| 17 namespace media { | |
| 18 | |
| 19 namespace remoting { | |
| 20 class RpcBroker; | |
| 21 } | |
| 22 | |
| 23 // This class: | |
| 24 // 1) Implements the RemotingSourceImpl::Client; | |
| 25 // 2) Monitors player events as a MediaObserver; | |
| 26 // 3) May trigger the switch of the media renderer between local playback | |
| 27 // and remoting. | |
| 28 class RemotingRendererController final : public RemotingSourceImpl::Client, | |
| 29 public MediaObserver { | |
| 30 public: | |
| 31 explicit RemotingRendererController( | |
| 32 scoped_refptr<RemotingSourceImpl> remoting_source); | |
| 33 ~RemotingRendererController() override; | |
| 34 | |
| 35 // RemotingSourceImpl::Client implemenations. | |
| 36 void OnStarted(bool success) override; | |
| 37 void OnSessionStateChanged() override; | |
| 38 | |
| 39 // MediaObserver implementations. | |
| 40 void OnEnteredFullscreen() override; | |
| 41 void OnExitedFullscreen() override; | |
| 42 void OnBecameDominantVisibleContent(bool is_dominant) override; | |
| 43 void OnSetCdm(CdmContext* cdm_context) override; | |
| 44 void OnMetadataChanged(const PipelineMetadata& metadata) override; | |
| 45 void OnRemotePlaybackDisabled(bool disabled) override; | |
| 46 void OnPlaying() override; | |
| 47 void OnPaused() override; | |
| 48 void OnSetPoster(const GURL& poster) override; | |
| 49 | |
| 50 void SetSwitchRendererCallback(const base::Closure& cb); | |
| 51 void SetRemoteSinkAvailableChangedCallback( | |
| 52 const base::Callback<void(bool)>& cb); | |
| 53 | |
| 54 using ShowInterstitialCallback = | |
| 55 base::Callback<void(const base::Optional<SkBitmap>&, | |
| 56 const gfx::Size&, | |
| 57 RemotingInterstitialType type)>; | |
| 58 // Called by RemoteRendererImpl constructor to set the callback to draw and | |
| 59 // show remoting interstial. | |
| 60 void SetShowInterstitialCallback(const ShowInterstitialCallback& cb); | |
| 61 using DownloadPosterCallback = | |
| 62 base::Callback<void(const GURL&, | |
| 63 const base::Callback<void(const SkBitmap&)>&)>; | |
| 64 // Set the callback to download poster image. | |
| 65 void SetDownloadPosterCallback(const DownloadPosterCallback& cb); | |
| 66 | |
| 67 base::WeakPtr<RemotingRendererController> GetWeakPtr() { | |
| 68 return weak_factory_.GetWeakPtr(); | |
| 69 } | |
| 70 | |
| 71 // Used by RemotingRendererFactory to query whether to create Media Remoting | |
| 72 // Renderer. | |
| 73 bool remote_rendering_started() const { | |
| 74 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 75 return remote_rendering_started_; | |
| 76 } | |
| 77 | |
| 78 void StartDataPipe( | |
| 79 std::unique_ptr<mojo::DataPipe> audio_data_pipe, | |
| 80 std::unique_ptr<mojo::DataPipe> video_data_pipe, | |
| 81 const RemotingSourceImpl::DataPipeStartCallback& done_callback); | |
| 82 | |
| 83 // Used by RemotingRendererImpl to query the session state. | |
| 84 RemotingSourceImpl* remoting_source() const { | |
| 85 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 86 return remoting_source_.get(); | |
| 87 } | |
| 88 | |
| 89 base::WeakPtr<remoting::RpcBroker> GetRpcBroker() const; | |
| 90 | |
| 91 // Called by RemoteRendererImpl when it encountered a fatal error. This will | |
| 92 // cause remoting to shut down and never start back up for the lifetime of | |
| 93 // this controller. | |
| 94 void OnRendererFatalError(remoting::StopTrigger stop_trigger); | |
| 95 | |
| 96 private: | |
| 97 bool has_audio() const { | |
| 98 return pipeline_metadata_.has_audio && | |
| 99 pipeline_metadata_.audio_decoder_config.IsValidConfig(); | |
| 100 } | |
| 101 | |
| 102 bool has_video() const { | |
| 103 return pipeline_metadata_.has_video && | |
| 104 pipeline_metadata_.video_decoder_config.IsValidConfig(); | |
| 105 } | |
| 106 | |
| 107 // Called when the session availability state may have changed. Each call to | |
| 108 // this method could cause a remoting session to be started or stopped; and if | |
| 109 // that happens, the |start_trigger| or |stop_trigger| must be the reason. | |
| 110 void UpdateFromSessionState(remoting::StartTrigger start_trigger, | |
| 111 remoting::StopTrigger stop_trigger); | |
| 112 | |
| 113 bool IsVideoCodecSupported(); | |
| 114 bool IsAudioCodecSupported(); | |
| 115 bool IsRemoteSinkAvailable(); | |
| 116 | |
| 117 // Helper to decide whether to enter or leave Remoting mode. | |
| 118 bool ShouldBeRemoting(); | |
| 119 | |
| 120 // Determines whether to enter or leave Remoting mode and switches if | |
| 121 // necessary. Each call to this method could cause a remoting session to be | |
| 122 // started or stopped; and if that happens, the |start_trigger| or | |
| 123 // |stop_trigger| must be the reason. | |
| 124 void UpdateAndMaybeSwitch(remoting::StartTrigger start_trigger, | |
| 125 remoting::StopTrigger stop_trigger); | |
| 126 | |
| 127 // Called to download the poster image. Called when: | |
| 128 // 1. Poster URL changes. | |
| 129 // 2. ShowInterstitialCallback is set. | |
| 130 // 3. DownloadPosterCallback is set. | |
| 131 void DownloadPosterImage(); | |
| 132 | |
| 133 // Called when poster image is downloaded. | |
| 134 void OnPosterImageDownloaded(const GURL& download_url, | |
| 135 base::TimeTicks download_start_time, | |
| 136 const SkBitmap& image); | |
| 137 | |
| 138 // Update remoting interstitial with |image|. When |image| is not set, | |
| 139 // interstitial will be drawn on previously downloaded poster image (in | |
| 140 // RemoteRendererImpl) or black background if none was downloaded before. | |
| 141 // Call this when: | |
| 142 // 1. SetShowInterstitialCallback() is called (RemoteRendererImpl is created). | |
| 143 // 2. The remoting session is shut down (to update the status message in the | |
| 144 // interstitial). | |
| 145 // 3. The size of the canvas is changed (to update the background image and | |
| 146 // the position of the status message). | |
| 147 // 4. Poster image is downloaded (to update the background image). | |
| 148 void UpdateInterstitial(const base::Optional<SkBitmap>& image); | |
| 149 | |
| 150 // Indicates whether this media element is in full screen. | |
| 151 bool is_fullscreen_ = false; | |
| 152 | |
| 153 // Indicates whether remoting is started. | |
| 154 bool remote_rendering_started_ = false; | |
| 155 | |
| 156 // Indicates whether audio or video is encrypted. | |
| 157 bool is_encrypted_ = false; | |
| 158 | |
| 159 // Indicates whether remote playback is currently disabled. This starts out as | |
| 160 // true, and should be updated at least once via a call to | |
| 161 // OnRemotePlaybackDisabled() at some point in the future. A web page | |
| 162 // typically sets/removes the disableRemotePlayback attribute on a | |
| 163 // HTMLMediaElement to disable/enable remoting of its content. Please see the | |
| 164 // Remote Playback API spec for more details: | |
| 165 // https://w3c.github.io/remote-playback | |
| 166 bool is_remote_playback_disabled_ = true; | |
| 167 | |
| 168 // Indicates whether video is the dominant visible content in the tab. | |
| 169 bool is_dominant_content_ = false; | |
| 170 | |
| 171 // Indicates whether video is paused. | |
| 172 bool is_paused_ = true; | |
| 173 | |
| 174 // Indicates whether OnRendererFatalError() has been called. This indicates | |
| 175 // one of several possible problems: 1) An environmental problem such as | |
| 176 // out-of-memory, insufficient network bandwidth, etc. 2) The receiver may | |
| 177 // have been unable to play-out the content correctly (e.g., not capable of a | |
| 178 // high frame rate at a high resolution). 3) An implementation bug. In any | |
| 179 // case, once a renderer encounters a fatal error, remoting will be shut down | |
| 180 // and never start again for the lifetime of this controller. | |
| 181 bool encountered_renderer_fatal_error_ = false; | |
| 182 | |
| 183 // The callback to switch the media renderer. | |
| 184 base::Closure switch_renderer_cb_; | |
| 185 | |
| 186 // Called when remoting sink availability is changed. | |
| 187 base::Callback<void(bool)> sink_available_changed_cb_; | |
| 188 | |
| 189 // This is initially the RemotingSourceImpl passed to the ctor, and might be | |
| 190 // replaced with a different instance later if OnSetCdm() is called. | |
| 191 scoped_refptr<RemotingSourceImpl> remoting_source_; | |
| 192 | |
| 193 // This is used to check all the methods are called on the current thread in | |
| 194 // debug builds. | |
| 195 base::ThreadChecker thread_checker_; | |
| 196 | |
| 197 // Current pipeline metadata. | |
| 198 PipelineMetadata pipeline_metadata_; | |
| 199 | |
| 200 // The callback to show remoting interstitial. It is set when entering the | |
| 201 // remoting mode (RemotingRendererImpl is constructed) by calling | |
| 202 // SetShowInterstitialCallback(), and is reset when leaving the remoting mode. | |
| 203 ShowInterstitialCallback show_interstitial_cb_; | |
| 204 | |
| 205 // Current poster URL, whose image will feed into the local UI. | |
| 206 GURL poster_url_; | |
| 207 | |
| 208 // The callback to download the poster image. Called when |poster_url_| | |
| 209 // changes during a remoting session or the show interstial callback is set. | |
| 210 // OnPosterImageDownloaded() will be called when download completes. | |
| 211 DownloadPosterCallback download_poster_cb_; | |
| 212 | |
| 213 // Records session events of interest. | |
| 214 remoting::SessionMetricsRecorder metrics_recorder_; | |
| 215 | |
| 216 base::WeakPtrFactory<RemotingRendererController> weak_factory_; | |
| 217 | |
| 218 DISALLOW_COPY_AND_ASSIGN(RemotingRendererController); | |
| 219 }; | |
| 220 | |
| 221 } // namespace media | |
| 222 | |
| 223 #endif // MEDIA_REMOTING_REMOTING_RENDERER_CONTROLLER_H_ | |
| OLD | NEW |