Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: media/remoting/renderer_controller.cc

Issue 2643253003: Media Remoting Clean-up: Less-redundant naming, style consistency, etc. (Closed)
Patch Set: REBASE Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/remoting/renderer_controller.h ('k') | media/remoting/renderer_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/remoting/remoting_renderer_controller.h" 5 #include "media/remoting/renderer_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/threading/thread_checker.h" 9 #include "base/threading/thread_checker.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "media/remoting/remoting_cdm.h"
11 #include "media/remoting/remoting_cdm_context.h" 12 #include "media/remoting/remoting_cdm_context.h"
12 13
13 namespace media { 14 namespace media {
15 namespace remoting {
14 16
15 RemotingRendererController::RemotingRendererController( 17 RendererController::RendererController(scoped_refptr<SharedSession> session)
16 scoped_refptr<RemotingSourceImpl> remoting_source) 18 : session_(std::move(session)), weak_factory_(this) {
17 : remoting_source_(remoting_source), weak_factory_(this) { 19 session_->AddClient(this);
18 remoting_source_->AddClient(this);
19 } 20 }
20 21
21 RemotingRendererController::~RemotingRendererController() { 22 RendererController::~RendererController() {
22 DCHECK(thread_checker_.CalledOnValidThread()); 23 DCHECK(thread_checker_.CalledOnValidThread());
23 metrics_recorder_.WillStopSession(remoting::MEDIA_ELEMENT_DESTROYED); 24 metrics_recorder_.WillStopSession(MEDIA_ELEMENT_DESTROYED);
24 remoting_source_->RemoveClient(this); 25 session_->RemoveClient(this);
25 } 26 }
26 27
27 void RemotingRendererController::OnStarted(bool success) { 28 void RendererController::OnStarted(bool success) {
28 DCHECK(thread_checker_.CalledOnValidThread()); 29 DCHECK(thread_checker_.CalledOnValidThread());
29 30
30 if (success) { 31 if (success) {
31 VLOG(1) << "Remoting started successively."; 32 VLOG(1) << "Remoting started successively.";
32 if (remote_rendering_started_) { 33 if (remote_rendering_started_) {
33 metrics_recorder_.DidStartSession(); 34 metrics_recorder_.DidStartSession();
34 DCHECK(!switch_renderer_cb_.is_null()); 35 DCHECK(!switch_renderer_cb_.is_null());
35 switch_renderer_cb_.Run(); 36 switch_renderer_cb_.Run();
36 } else { 37 } else {
37 remoting_source_->StopRemoting(this); 38 session_->StopRemoting(this);
38 } 39 }
39 } else { 40 } else {
40 VLOG(1) << "Failed to start remoting."; 41 VLOG(1) << "Failed to start remoting.";
41 remote_rendering_started_ = false; 42 remote_rendering_started_ = false;
42 metrics_recorder_.WillStopSession(remoting::START_RACE); 43 metrics_recorder_.WillStopSession(START_RACE);
43 } 44 }
44 } 45 }
45 46
46 void RemotingRendererController::OnSessionStateChanged() { 47 void RendererController::OnSessionStateChanged() {
47 DCHECK(thread_checker_.CalledOnValidThread()); 48 DCHECK(thread_checker_.CalledOnValidThread());
48 UpdateFromSessionState(remoting::SINK_AVAILABLE, remoting::ROUTE_TERMINATED); 49 UpdateFromSessionState(SINK_AVAILABLE, ROUTE_TERMINATED);
49 } 50 }
50 51
51 void RemotingRendererController::UpdateFromSessionState( 52 void RendererController::UpdateFromSessionState(StartTrigger start_trigger,
52 remoting::StartTrigger start_trigger, 53 StopTrigger stop_trigger) {
53 remoting::StopTrigger stop_trigger) { 54 VLOG(1) << "UpdateFromSessionState: " << session_->state();
54 VLOG(1) << "UpdateFromSessionState: " << remoting_source_->state();
55 if (!sink_available_changed_cb_.is_null()) 55 if (!sink_available_changed_cb_.is_null())
56 sink_available_changed_cb_.Run(IsRemoteSinkAvailable()); 56 sink_available_changed_cb_.Run(IsRemoteSinkAvailable());
57 57
58 UpdateInterstitial(base::nullopt); 58 UpdateInterstitial(base::nullopt);
59 UpdateAndMaybeSwitch(start_trigger, stop_trigger); 59 UpdateAndMaybeSwitch(start_trigger, stop_trigger);
60 } 60 }
61 61
62 bool RemotingRendererController::IsRemoteSinkAvailable() { 62 bool RendererController::IsRemoteSinkAvailable() {
63 DCHECK(thread_checker_.CalledOnValidThread()); 63 DCHECK(thread_checker_.CalledOnValidThread());
64 64
65 switch (remoting_source_->state()) { 65 switch (session_->state()) {
66 case SESSION_CAN_START: 66 case SharedSession::SESSION_CAN_START:
67 case SESSION_STARTING: 67 case SharedSession::SESSION_STARTING:
68 case SESSION_STARTED: 68 case SharedSession::SESSION_STARTED:
69 return true; 69 return true;
70 case SESSION_UNAVAILABLE: 70 case SharedSession::SESSION_UNAVAILABLE:
71 case SESSION_STOPPING: 71 case SharedSession::SESSION_STOPPING:
72 case SESSION_PERMANENTLY_STOPPED: 72 case SharedSession::SESSION_PERMANENTLY_STOPPED:
73 return false; 73 return false;
74 } 74 }
75 75
76 return false; // To suppress compile warning. 76 NOTREACHED();
77 return false; // To suppress compiler warning on Windows.
77 } 78 }
78 79
79 void RemotingRendererController::OnEnteredFullscreen() { 80 void RendererController::OnEnteredFullscreen() {
80 DCHECK(thread_checker_.CalledOnValidThread()); 81 DCHECK(thread_checker_.CalledOnValidThread());
81 82
82 is_fullscreen_ = true; 83 is_fullscreen_ = true;
83 // See notes in OnBecameDominantVisibleContent() for why this is forced: 84 // See notes in OnBecameDominantVisibleContent() for why this is forced:
84 is_dominant_content_ = true; 85 is_dominant_content_ = true;
85 UpdateAndMaybeSwitch(remoting::ENTERED_FULLSCREEN, 86 UpdateAndMaybeSwitch(ENTERED_FULLSCREEN, UNKNOWN_STOP_TRIGGER);
86 remoting::UNKNOWN_STOP_TRIGGER);
87 } 87 }
88 88
89 void RemotingRendererController::OnExitedFullscreen() { 89 void RendererController::OnExitedFullscreen() {
90 DCHECK(thread_checker_.CalledOnValidThread()); 90 DCHECK(thread_checker_.CalledOnValidThread());
91 91
92 is_fullscreen_ = false; 92 is_fullscreen_ = false;
93 // See notes in OnBecameDominantVisibleContent() for why this is forced: 93 // See notes in OnBecameDominantVisibleContent() for why this is forced:
94 is_dominant_content_ = false; 94 is_dominant_content_ = false;
95 UpdateAndMaybeSwitch(remoting::UNKNOWN_START_TRIGGER, 95 UpdateAndMaybeSwitch(UNKNOWN_START_TRIGGER, EXITED_FULLSCREEN);
96 remoting::EXITED_FULLSCREEN);
97 } 96 }
98 97
99 void RemotingRendererController::OnBecameDominantVisibleContent( 98 void RendererController::OnBecameDominantVisibleContent(bool is_dominant) {
100 bool is_dominant) {
101 DCHECK(thread_checker_.CalledOnValidThread()); 99 DCHECK(thread_checker_.CalledOnValidThread());
102 100
103 // Two scenarios where "dominance" status mixes with fullscreen transitions: 101 // Two scenarios where "dominance" status mixes with fullscreen transitions:
104 // 102 //
105 // 1. Just before/after entering fullscreen, the element will, of course, 103 // 1. Just before/after entering fullscreen, the element will, of course,
106 // become the dominant on-screen content via automatic page layout. 104 // become the dominant on-screen content via automatic page layout.
107 // 2. Just before/after exiting fullscreen, the element may or may not 105 // 2. Just before/after exiting fullscreen, the element may or may not
108 // shrink in size enough to become non-dominant. However, exiting 106 // shrink in size enough to become non-dominant. However, exiting
109 // fullscreen was caused by a user action that explicitly indicates a 107 // fullscreen was caused by a user action that explicitly indicates a
110 // desire to exit remoting, so even if the element is still dominant, 108 // desire to exit remoting, so even if the element is still dominant,
111 // remoting should be shut down. 109 // remoting should be shut down.
112 // 110 //
113 // Thus, to achieve the desired behaviors, |is_dominant_content_| is force-set 111 // Thus, to achieve the desired behaviors, |is_dominant_content_| is force-set
114 // in OnEnteredFullscreen() and OnExitedFullscreen(), and changes to it here 112 // in OnEnteredFullscreen() and OnExitedFullscreen(), and changes to it here
115 // are ignored while in fullscreen. 113 // are ignored while in fullscreen.
116 if (is_fullscreen_) 114 if (is_fullscreen_)
117 return; 115 return;
118 116
119 is_dominant_content_ = is_dominant; 117 is_dominant_content_ = is_dominant;
120 UpdateAndMaybeSwitch(remoting::BECAME_DOMINANT_CONTENT, 118 UpdateAndMaybeSwitch(BECAME_DOMINANT_CONTENT, BECAME_AUXILIARY_CONTENT);
121 remoting::BECAME_AUXILIARY_CONTENT);
122 } 119 }
123 120
124 void RemotingRendererController::OnSetCdm(CdmContext* cdm_context) { 121 void RendererController::OnSetCdm(CdmContext* cdm_context) {
125 DCHECK(thread_checker_.CalledOnValidThread()); 122 DCHECK(thread_checker_.CalledOnValidThread());
126 123
127 auto* remoting_cdm_context = RemotingCdmContext::From(cdm_context); 124 auto* remoting_cdm_context = RemotingCdmContext::From(cdm_context);
128 if (!remoting_cdm_context) 125 if (!remoting_cdm_context)
129 return; 126 return;
130 127
131 remoting_source_->RemoveClient(this); 128 session_->RemoveClient(this);
132 remoting_source_ = remoting_cdm_context->GetRemotingSource(); 129 session_ = remoting_cdm_context->GetSharedSession();
133 remoting_source_->AddClient(this); 130 session_->AddClient(this);
134 UpdateFromSessionState(remoting::CDM_READY, remoting::DECRYPTION_ERROR); 131 UpdateFromSessionState(CDM_READY, DECRYPTION_ERROR);
135 } 132 }
136 133
137 void RemotingRendererController::OnRemotePlaybackDisabled(bool disabled) { 134 void RendererController::OnRemotePlaybackDisabled(bool disabled) {
138 DCHECK(thread_checker_.CalledOnValidThread()); 135 DCHECK(thread_checker_.CalledOnValidThread());
139 136
140 is_remote_playback_disabled_ = disabled; 137 is_remote_playback_disabled_ = disabled;
141 metrics_recorder_.OnRemotePlaybackDisabled(disabled); 138 metrics_recorder_.OnRemotePlaybackDisabled(disabled);
142 UpdateAndMaybeSwitch(remoting::ENABLED_BY_PAGE, remoting::DISABLED_BY_PAGE); 139 UpdateAndMaybeSwitch(ENABLED_BY_PAGE, DISABLED_BY_PAGE);
143 } 140 }
144 141
145 void RemotingRendererController::OnSetPoster(const GURL& poster_url) { 142 void RendererController::OnSetPoster(const GURL& poster_url) {
146 DCHECK(thread_checker_.CalledOnValidThread()); 143 DCHECK(thread_checker_.CalledOnValidThread());
147 144
148 if (poster_url != poster_url_) { 145 if (poster_url != poster_url_) {
149 poster_url_ = poster_url; 146 poster_url_ = poster_url;
150 if (poster_url_.is_empty()) 147 if (poster_url_.is_empty())
151 UpdateInterstitial(SkBitmap()); 148 UpdateInterstitial(SkBitmap());
152 else 149 else
153 DownloadPosterImage(); 150 DownloadPosterImage();
154 } 151 }
155 } 152 }
156 153
157 void RemotingRendererController::SetSwitchRendererCallback( 154 void RendererController::SetSwitchRendererCallback(const base::Closure& cb) {
158 const base::Closure& cb) {
159 DCHECK(thread_checker_.CalledOnValidThread()); 155 DCHECK(thread_checker_.CalledOnValidThread());
160 DCHECK(!cb.is_null()); 156 DCHECK(!cb.is_null());
161 157
162 switch_renderer_cb_ = cb; 158 switch_renderer_cb_ = cb;
163 // Note: Not calling UpdateAndMaybeSwitch() here since this method should be 159 // Note: Not calling UpdateAndMaybeSwitch() here since this method should be
164 // called during the initialization phase of this RemotingRendererController; 160 // called during the initialization phase of this RendererController;
165 // and definitely before a whole lot of other things that are needed to 161 // and definitely before a whole lot of other things that are needed to
166 // trigger a switch. 162 // trigger a switch.
167 } 163 }
168 164
169 void RemotingRendererController::SetRemoteSinkAvailableChangedCallback( 165 void RendererController::SetRemoteSinkAvailableChangedCallback(
170 const base::Callback<void(bool)>& cb) { 166 const base::Callback<void(bool)>& cb) {
171 DCHECK(thread_checker_.CalledOnValidThread()); 167 DCHECK(thread_checker_.CalledOnValidThread());
172 168
173 sink_available_changed_cb_ = cb; 169 sink_available_changed_cb_ = cb;
174 if (!sink_available_changed_cb_.is_null()) 170 if (!sink_available_changed_cb_.is_null())
175 sink_available_changed_cb_.Run(IsRemoteSinkAvailable()); 171 sink_available_changed_cb_.Run(IsRemoteSinkAvailable());
176 } 172 }
177 173
178 base::WeakPtr<remoting::RpcBroker> RemotingRendererController::GetRpcBroker() 174 base::WeakPtr<RpcBroker> RendererController::GetRpcBroker() const {
179 const {
180 DCHECK(thread_checker_.CalledOnValidThread()); 175 DCHECK(thread_checker_.CalledOnValidThread());
181 176
182 return remoting_source_->GetRpcBroker()->GetWeakPtr(); 177 return session_->rpc_broker()->GetWeakPtr();
183 } 178 }
184 179
185 void RemotingRendererController::StartDataPipe( 180 void RendererController::StartDataPipe(
186 std::unique_ptr<mojo::DataPipe> audio_data_pipe, 181 std::unique_ptr<mojo::DataPipe> audio_data_pipe,
187 std::unique_ptr<mojo::DataPipe> video_data_pipe, 182 std::unique_ptr<mojo::DataPipe> video_data_pipe,
188 const RemotingSourceImpl::DataPipeStartCallback& done_callback) { 183 const SharedSession::DataPipeStartCallback& done_callback) {
189 DCHECK(thread_checker_.CalledOnValidThread()); 184 DCHECK(thread_checker_.CalledOnValidThread());
190 185
191 remoting_source_->StartDataPipe(std::move(audio_data_pipe), 186 session_->StartDataPipe(std::move(audio_data_pipe),
192 std::move(video_data_pipe), done_callback); 187 std::move(video_data_pipe), done_callback);
193 } 188 }
194 189
195 void RemotingRendererController::OnMetadataChanged( 190 void RendererController::OnMetadataChanged(const PipelineMetadata& metadata) {
196 const PipelineMetadata& metadata) {
197 DCHECK(thread_checker_.CalledOnValidThread()); 191 DCHECK(thread_checker_.CalledOnValidThread());
198 192
199 const gfx::Size old_size = pipeline_metadata_.natural_size; 193 const gfx::Size old_size = pipeline_metadata_.natural_size;
200 const bool was_audio_codec_supported = has_audio() && IsAudioCodecSupported(); 194 const bool was_audio_codec_supported = has_audio() && IsAudioCodecSupported();
201 const bool was_video_codec_supported = has_video() && IsVideoCodecSupported(); 195 const bool was_video_codec_supported = has_video() && IsVideoCodecSupported();
202 pipeline_metadata_ = metadata; 196 pipeline_metadata_ = metadata;
203 const bool is_audio_codec_supported = has_audio() && IsAudioCodecSupported(); 197 const bool is_audio_codec_supported = has_audio() && IsAudioCodecSupported();
204 const bool is_video_codec_supported = has_video() && IsVideoCodecSupported(); 198 const bool is_video_codec_supported = has_video() && IsVideoCodecSupported();
205 metrics_recorder_.OnPipelineMetadataChanged(metadata); 199 metrics_recorder_.OnPipelineMetadataChanged(metadata);
206 200
207 is_encrypted_ = false; 201 is_encrypted_ = false;
208 if (has_video()) 202 if (has_video())
209 is_encrypted_ |= metadata.video_decoder_config.is_encrypted(); 203 is_encrypted_ |= metadata.video_decoder_config.is_encrypted();
210 if (has_audio()) 204 if (has_audio())
211 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted(); 205 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted();
212 206
213 if (pipeline_metadata_.natural_size != old_size) 207 if (pipeline_metadata_.natural_size != old_size)
214 UpdateInterstitial(base::nullopt); 208 UpdateInterstitial(base::nullopt);
215 209
216 remoting::StartTrigger start_trigger = remoting::UNKNOWN_START_TRIGGER; 210 StartTrigger start_trigger = UNKNOWN_START_TRIGGER;
217 if (!was_audio_codec_supported && is_audio_codec_supported) 211 if (!was_audio_codec_supported && is_audio_codec_supported)
218 start_trigger = remoting::SUPPORTED_AUDIO_CODEC; 212 start_trigger = SUPPORTED_AUDIO_CODEC;
219 if (!was_video_codec_supported && is_video_codec_supported) { 213 if (!was_video_codec_supported && is_video_codec_supported) {
220 start_trigger = start_trigger == remoting::SUPPORTED_AUDIO_CODEC 214 start_trigger = start_trigger == SUPPORTED_AUDIO_CODEC
221 ? remoting::SUPPORTED_AUDIO_AND_VIDEO_CODECS 215 ? SUPPORTED_AUDIO_AND_VIDEO_CODECS
222 : remoting::SUPPORTED_VIDEO_CODEC; 216 : SUPPORTED_VIDEO_CODEC;
223 } 217 }
224 remoting::StopTrigger stop_trigger = remoting::UNKNOWN_STOP_TRIGGER; 218 StopTrigger stop_trigger = UNKNOWN_STOP_TRIGGER;
225 if (was_audio_codec_supported && !is_audio_codec_supported) 219 if (was_audio_codec_supported && !is_audio_codec_supported)
226 stop_trigger = remoting::UNSUPPORTED_AUDIO_CODEC; 220 stop_trigger = UNSUPPORTED_AUDIO_CODEC;
227 if (was_video_codec_supported && !is_video_codec_supported) { 221 if (was_video_codec_supported && !is_video_codec_supported) {
228 stop_trigger = stop_trigger == remoting::UNSUPPORTED_AUDIO_CODEC 222 stop_trigger = stop_trigger == UNSUPPORTED_AUDIO_CODEC
229 ? remoting::UNSUPPORTED_AUDIO_AND_VIDEO_CODECS 223 ? UNSUPPORTED_AUDIO_AND_VIDEO_CODECS
230 : remoting::UNSUPPORTED_VIDEO_CODEC; 224 : UNSUPPORTED_VIDEO_CODEC;
231 } 225 }
232 UpdateAndMaybeSwitch(start_trigger, stop_trigger); 226 UpdateAndMaybeSwitch(start_trigger, stop_trigger);
233 } 227 }
234 228
235 bool RemotingRendererController::IsVideoCodecSupported() { 229 bool RendererController::IsVideoCodecSupported() {
236 DCHECK(thread_checker_.CalledOnValidThread()); 230 DCHECK(thread_checker_.CalledOnValidThread());
237 DCHECK(has_video()); 231 DCHECK(has_video());
238 232
239 switch (pipeline_metadata_.video_decoder_config.codec()) { 233 switch (pipeline_metadata_.video_decoder_config.codec()) {
240 case VideoCodec::kCodecH264: 234 case VideoCodec::kCodecH264:
241 case VideoCodec::kCodecVP8: 235 case VideoCodec::kCodecVP8:
242 return true; 236 return true;
243 default: 237 default:
244 VLOG(2) << "Remoting does not support video codec: " 238 VLOG(2) << "Remoting does not support video codec: "
245 << pipeline_metadata_.video_decoder_config.codec(); 239 << pipeline_metadata_.video_decoder_config.codec();
246 return false; 240 return false;
247 } 241 }
248 } 242 }
249 243
250 bool RemotingRendererController::IsAudioCodecSupported() { 244 bool RendererController::IsAudioCodecSupported() {
251 DCHECK(thread_checker_.CalledOnValidThread()); 245 DCHECK(thread_checker_.CalledOnValidThread());
252 DCHECK(has_audio()); 246 DCHECK(has_audio());
253 247
254 switch (pipeline_metadata_.audio_decoder_config.codec()) { 248 switch (pipeline_metadata_.audio_decoder_config.codec()) {
255 case AudioCodec::kCodecAAC: 249 case AudioCodec::kCodecAAC:
256 case AudioCodec::kCodecMP3: 250 case AudioCodec::kCodecMP3:
257 case AudioCodec::kCodecPCM: 251 case AudioCodec::kCodecPCM:
258 case AudioCodec::kCodecVorbis: 252 case AudioCodec::kCodecVorbis:
259 case AudioCodec::kCodecFLAC: 253 case AudioCodec::kCodecFLAC:
260 case AudioCodec::kCodecAMR_NB: 254 case AudioCodec::kCodecAMR_NB:
261 case AudioCodec::kCodecAMR_WB: 255 case AudioCodec::kCodecAMR_WB:
262 case AudioCodec::kCodecPCM_MULAW: 256 case AudioCodec::kCodecPCM_MULAW:
263 case AudioCodec::kCodecGSM_MS: 257 case AudioCodec::kCodecGSM_MS:
264 case AudioCodec::kCodecPCM_S16BE: 258 case AudioCodec::kCodecPCM_S16BE:
265 case AudioCodec::kCodecPCM_S24BE: 259 case AudioCodec::kCodecPCM_S24BE:
266 case AudioCodec::kCodecOpus: 260 case AudioCodec::kCodecOpus:
267 case AudioCodec::kCodecEAC3: 261 case AudioCodec::kCodecEAC3:
268 case AudioCodec::kCodecPCM_ALAW: 262 case AudioCodec::kCodecPCM_ALAW:
269 case AudioCodec::kCodecALAC: 263 case AudioCodec::kCodecALAC:
270 case AudioCodec::kCodecAC3: 264 case AudioCodec::kCodecAC3:
271 return true; 265 return true;
272 default: 266 default:
273 VLOG(2) << "Remoting does not support audio codec: " 267 VLOG(2) << "Remoting does not support audio codec: "
274 << pipeline_metadata_.audio_decoder_config.codec(); 268 << pipeline_metadata_.audio_decoder_config.codec();
275 return false; 269 return false;
276 } 270 }
277 } 271 }
278 272
279 void RemotingRendererController::OnPlaying() { 273 void RendererController::OnPlaying() {
280 DCHECK(thread_checker_.CalledOnValidThread()); 274 DCHECK(thread_checker_.CalledOnValidThread());
281 275
282 is_paused_ = false; 276 is_paused_ = false;
283 UpdateAndMaybeSwitch(remoting::PLAY_COMMAND, remoting::UNKNOWN_STOP_TRIGGER); 277 UpdateAndMaybeSwitch(PLAY_COMMAND, UNKNOWN_STOP_TRIGGER);
284 } 278 }
285 279
286 void RemotingRendererController::OnPaused() { 280 void RendererController::OnPaused() {
287 DCHECK(thread_checker_.CalledOnValidThread()); 281 DCHECK(thread_checker_.CalledOnValidThread());
288 282
289 is_paused_ = true; 283 is_paused_ = true;
290 } 284 }
291 285
292 bool RemotingRendererController::ShouldBeRemoting() { 286 bool RendererController::ShouldBeRemoting() {
293 DCHECK(thread_checker_.CalledOnValidThread()); 287 DCHECK(thread_checker_.CalledOnValidThread());
294 288
295 if (switch_renderer_cb_.is_null()) { 289 if (switch_renderer_cb_.is_null()) {
296 DCHECK(!remote_rendering_started_); 290 DCHECK(!remote_rendering_started_);
297 return false; // No way to switch to a RemotingRenderImpl. 291 return false; // No way to switch to the remoting renderer.
298 } 292 }
299 293
300 const RemotingSessionState state = remoting_source_->state(); 294 const SharedSession::SessionState state = session_->state();
301 if (is_encrypted_) { 295 if (is_encrypted_) {
302 // Due to technical limitations when playing encrypted content, once a 296 // Due to technical limitations when playing encrypted content, once a
303 // remoting session has been started, always return true here to indicate 297 // remoting session has been started, always return true here to indicate
304 // that the RemotingRendererImpl should be used. In the stopped states, 298 // that the CourierRenderer should continue to be used. In the stopped
305 // RemotingRendererImpl will display an interstitial to notify the user that 299 // states, CourierRenderer will display an interstitial to notify the user
306 // local rendering cannot be resumed. 300 // that local rendering cannot be resumed.
307 // 301 //
308 // TODO(miu): Revisit this once more of the encrypted-remoting impl is 302 // TODO(miu): Revisit this once more of the encrypted-remoting impl is
309 // in-place. For example, this will prevent metrics from recording session 303 // in-place. For example, this will prevent metrics from recording session
310 // stop reasons. 304 // stop reasons.
311 return state == RemotingSessionState::SESSION_STARTED || 305 return state == SharedSession::SESSION_STARTED ||
312 state == RemotingSessionState::SESSION_STOPPING || 306 state == SharedSession::SESSION_STOPPING ||
313 state == RemotingSessionState::SESSION_PERMANENTLY_STOPPED; 307 state == SharedSession::SESSION_PERMANENTLY_STOPPED;
314 } 308 }
315 309
316 if (encountered_renderer_fatal_error_) 310 if (encountered_renderer_fatal_error_)
317 return false; 311 return false;
318 312
319 switch (state) { 313 switch (state) {
320 case SESSION_UNAVAILABLE: 314 case SharedSession::SESSION_UNAVAILABLE:
321 return false; // Cannot remote media without a remote sink. 315 return false; // Cannot remote media without a remote sink.
322 case SESSION_CAN_START: 316 case SharedSession::SESSION_CAN_START:
323 case SESSION_STARTING: 317 case SharedSession::SESSION_STARTING:
324 case SESSION_STARTED: 318 case SharedSession::SESSION_STARTED:
325 break; // Media remoting is possible, assuming other requirments are met. 319 break; // Media remoting is possible, assuming other requirments are met.
326 case SESSION_STOPPING: 320 case SharedSession::SESSION_STOPPING:
327 case SESSION_PERMANENTLY_STOPPED: 321 case SharedSession::SESSION_PERMANENTLY_STOPPED:
328 return false; // Use local rendering after stopping remoting. 322 return false; // Use local rendering after stopping remoting.
329 } 323 }
330 324
331 switch (remoting_source_->sink_capabilities()) { 325 switch (session_->sink_capabilities()) {
332 case mojom::RemotingSinkCapabilities::NONE: 326 case mojom::RemotingSinkCapabilities::NONE:
333 return false; 327 return false;
334 case mojom::RemotingSinkCapabilities::RENDERING_ONLY: 328 case mojom::RemotingSinkCapabilities::RENDERING_ONLY:
335 case mojom::RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING: 329 case mojom::RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING:
336 break; // The sink is capable of remote rendering. 330 break; // The sink is capable of remote rendering.
337 } 331 }
338 332
339 if ((!has_audio() && !has_video()) || 333 if ((!has_audio() && !has_video()) ||
340 (has_video() && !IsVideoCodecSupported()) || 334 (has_video() && !IsVideoCodecSupported()) ||
341 (has_audio() && !IsAudioCodecSupported())) { 335 (has_audio() && !IsAudioCodecSupported())) {
342 return false; 336 return false;
343 } 337 }
344 338
345 if (is_remote_playback_disabled_) 339 if (is_remote_playback_disabled_)
346 return false; 340 return false;
347 341
348 // Normally, entering fullscreen or being the dominant visible content is the 342 // Normally, entering fullscreen or being the dominant visible content is the
349 // signal that starts remote rendering. However, current technical limitations 343 // signal that starts remote rendering. However, current technical limitations
350 // require encrypted content be remoted without waiting for a user signal. 344 // require encrypted content be remoted without waiting for a user signal.
351 return is_fullscreen_ || is_dominant_content_; 345 return is_fullscreen_ || is_dominant_content_;
352 } 346 }
353 347
354 void RemotingRendererController::UpdateAndMaybeSwitch( 348 void RendererController::UpdateAndMaybeSwitch(StartTrigger start_trigger,
355 remoting::StartTrigger start_trigger, 349 StopTrigger stop_trigger) {
356 remoting::StopTrigger stop_trigger) {
357 DCHECK(thread_checker_.CalledOnValidThread()); 350 DCHECK(thread_checker_.CalledOnValidThread());
358 351
359 bool should_be_remoting = ShouldBeRemoting(); 352 bool should_be_remoting = ShouldBeRemoting();
360 353
361 if (remote_rendering_started_ == should_be_remoting) 354 if (remote_rendering_started_ == should_be_remoting)
362 return; 355 return;
363 356
364 // Only switch to remoting when media is playing. Since the renderer is 357 // Only switch to remoting when media is playing. Since the renderer is
365 // created when video starts loading/playing, receiver will display a black 358 // created when video starts loading/playing, receiver will display a black
366 // screen before video starts playing if switching to remoting when paused. 359 // screen before video starts playing if switching to remoting when paused.
367 // Thus, the user experience is improved by not starting remoting until 360 // Thus, the user experience is improved by not starting remoting until
368 // playback resumes. 361 // playback resumes.
369 if (should_be_remoting && is_paused_) 362 if (should_be_remoting && is_paused_)
370 return; 363 return;
371 364
372 // Switch between local renderer and remoting renderer. 365 // Switch between local renderer and remoting renderer.
373 remote_rendering_started_ = should_be_remoting; 366 remote_rendering_started_ = should_be_remoting;
374 367
375 if (remote_rendering_started_) { 368 if (remote_rendering_started_) {
376 DCHECK(!switch_renderer_cb_.is_null()); 369 DCHECK(!switch_renderer_cb_.is_null());
377 if (remoting_source_->state() == 370 if (session_->state() == SharedSession::SESSION_PERMANENTLY_STOPPED) {
378 RemotingSessionState::SESSION_PERMANENTLY_STOPPED) {
379 switch_renderer_cb_.Run(); 371 switch_renderer_cb_.Run();
380 return; 372 return;
381 } 373 }
382 DCHECK_NE(start_trigger, remoting::UNKNOWN_START_TRIGGER); 374 DCHECK_NE(start_trigger, UNKNOWN_START_TRIGGER);
383 metrics_recorder_.WillStartSession(start_trigger); 375 metrics_recorder_.WillStartSession(start_trigger);
384 // |switch_renderer_cb_.Run()| will be called after remoting is started 376 // |switch_renderer_cb_.Run()| will be called after remoting is started
385 // successfully. 377 // successfully.
386 remoting_source_->StartRemoting(this); 378 session_->StartRemoting(this);
387 } else { 379 } else {
388 // For encrypted content, it's only valid to switch to remoting renderer, 380 // For encrypted content, it's only valid to switch to remoting renderer,
389 // and never back to the local renderer. The RemotingCdmController will 381 // and never back to the local renderer. The RemotingCdmController will
390 // force-stop the session when remoting has ended; so no need to call 382 // force-stop the session when remoting has ended; so no need to call
391 // StopRemoting() from here. 383 // StopRemoting() from here.
392 DCHECK(!is_encrypted_); 384 DCHECK(!is_encrypted_);
393 DCHECK_NE(stop_trigger, remoting::UNKNOWN_STOP_TRIGGER); 385 DCHECK_NE(stop_trigger, UNKNOWN_STOP_TRIGGER);
394 metrics_recorder_.WillStopSession(stop_trigger); 386 metrics_recorder_.WillStopSession(stop_trigger);
395 switch_renderer_cb_.Run(); 387 switch_renderer_cb_.Run();
396 remoting_source_->StopRemoting(this); 388 session_->StopRemoting(this);
397 } 389 }
398 } 390 }
399 391
400 void RemotingRendererController::SetShowInterstitialCallback( 392 void RendererController::SetShowInterstitialCallback(
401 const ShowInterstitialCallback& cb) { 393 const ShowInterstitialCallback& cb) {
402 DCHECK(thread_checker_.CalledOnValidThread()); 394 DCHECK(thread_checker_.CalledOnValidThread());
403 show_interstitial_cb_ = cb; 395 show_interstitial_cb_ = cb;
404 UpdateInterstitial(SkBitmap()); 396 UpdateInterstitial(SkBitmap());
405 if (!poster_url_.is_empty()) 397 if (!poster_url_.is_empty())
406 DownloadPosterImage(); 398 DownloadPosterImage();
407 } 399 }
408 400
409 void RemotingRendererController::SetDownloadPosterCallback( 401 void RendererController::SetDownloadPosterCallback(
410 const DownloadPosterCallback& cb) { 402 const DownloadPosterCallback& cb) {
411 DCHECK(thread_checker_.CalledOnValidThread()); 403 DCHECK(thread_checker_.CalledOnValidThread());
412 DCHECK(download_poster_cb_.is_null()); 404 DCHECK(download_poster_cb_.is_null());
413 download_poster_cb_ = cb; 405 download_poster_cb_ = cb;
414 if (!poster_url_.is_empty()) 406 if (!poster_url_.is_empty())
415 DownloadPosterImage(); 407 DownloadPosterImage();
416 } 408 }
417 409
418 void RemotingRendererController::UpdateInterstitial( 410 void RendererController::UpdateInterstitial(
419 const base::Optional<SkBitmap>& image) { 411 const base::Optional<SkBitmap>& image) {
420 DCHECK(thread_checker_.CalledOnValidThread()); 412 DCHECK(thread_checker_.CalledOnValidThread());
421 if (show_interstitial_cb_.is_null() || 413 if (show_interstitial_cb_.is_null() ||
422 pipeline_metadata_.natural_size.IsEmpty()) 414 pipeline_metadata_.natural_size.IsEmpty())
423 return; 415 return;
424 416
425 RemotingInterstitialType type = RemotingInterstitialType::BETWEEN_SESSIONS; 417 InterstitialType type = InterstitialType::BETWEEN_SESSIONS;
426 switch (remoting_source_->state()) { 418 switch (session_->state()) {
427 case SESSION_STARTED: 419 case SharedSession::SESSION_STARTED:
428 type = RemotingInterstitialType::IN_SESSION; 420 type = InterstitialType::IN_SESSION;
429 break; 421 break;
430 case SESSION_PERMANENTLY_STOPPED: 422 case SharedSession::SESSION_PERMANENTLY_STOPPED:
431 type = RemotingInterstitialType::ENCRYPTED_MEDIA_FATAL_ERROR; 423 type = InterstitialType::ENCRYPTED_MEDIA_FATAL_ERROR;
432 break; 424 break;
433 case SESSION_UNAVAILABLE: 425 case SharedSession::SESSION_UNAVAILABLE:
434 case SESSION_CAN_START: 426 case SharedSession::SESSION_CAN_START:
435 case SESSION_STARTING: 427 case SharedSession::SESSION_STARTING:
436 case SESSION_STOPPING: 428 case SharedSession::SESSION_STOPPING:
437 break; 429 break;
438 } 430 }
439 431
440 show_interstitial_cb_.Run(image, pipeline_metadata_.natural_size, type); 432 show_interstitial_cb_.Run(image, pipeline_metadata_.natural_size, type);
441 } 433 }
442 434
443 void RemotingRendererController::DownloadPosterImage() { 435 void RendererController::DownloadPosterImage() {
444 if (download_poster_cb_.is_null() || show_interstitial_cb_.is_null()) 436 if (download_poster_cb_.is_null() || show_interstitial_cb_.is_null())
445 return; 437 return;
446 DCHECK(!poster_url_.is_empty()); 438 DCHECK(!poster_url_.is_empty());
447 439
448 const base::TimeTicks download_start_time = base::TimeTicks::Now(); 440 const base::TimeTicks download_start_time = base::TimeTicks::Now();
449 download_poster_cb_.Run( 441 download_poster_cb_.Run(
450 poster_url_, 442 poster_url_,
451 base::Bind(&RemotingRendererController::OnPosterImageDownloaded, 443 base::Bind(&RendererController::OnPosterImageDownloaded,
452 weak_factory_.GetWeakPtr(), poster_url_, download_start_time)); 444 weak_factory_.GetWeakPtr(), poster_url_, download_start_time));
453 } 445 }
454 446
455 void RemotingRendererController::OnPosterImageDownloaded( 447 void RendererController::OnPosterImageDownloaded(
456 const GURL& download_url, 448 const GURL& download_url,
457 base::TimeTicks download_start_time, 449 base::TimeTicks download_start_time,
458 const SkBitmap& image) { 450 const SkBitmap& image) {
459 DCHECK(thread_checker_.CalledOnValidThread()); 451 DCHECK(thread_checker_.CalledOnValidThread());
460 452
461 metrics_recorder_.OnPosterImageDownloaded( 453 metrics_recorder_.OnPosterImageDownloaded(
462 base::TimeTicks::Now() - download_start_time, !image.drawsNothing()); 454 base::TimeTicks::Now() - download_start_time, !image.drawsNothing());
463 if (download_url != poster_url_) 455 if (download_url != poster_url_)
464 return; // The poster image URL has changed during the download. 456 return; // The poster image URL has changed during the download.
465 UpdateInterstitial(image); 457 UpdateInterstitial(image);
466 } 458 }
467 459
468 void RemotingRendererController::OnRendererFatalError( 460 void RendererController::OnRendererFatalError(StopTrigger stop_trigger) {
469 remoting::StopTrigger stop_trigger) {
470 DCHECK(thread_checker_.CalledOnValidThread()); 461 DCHECK(thread_checker_.CalledOnValidThread());
471 462
472 // Do not act on errors caused by things like Mojo pipes being closed during 463 // Do not act on errors caused by things like Mojo pipes being closed during
473 // shutdown. 464 // shutdown.
474 if (!remote_rendering_started_) 465 if (!remote_rendering_started_)
475 return; 466 return;
476 467
477 encountered_renderer_fatal_error_ = true; 468 encountered_renderer_fatal_error_ = true;
478 UpdateAndMaybeSwitch(remoting::UNKNOWN_START_TRIGGER, stop_trigger); 469 UpdateAndMaybeSwitch(UNKNOWN_START_TRIGGER, stop_trigger);
479 } 470 }
480 471
472 } // namespace remoting
481 } // namespace media 473 } // namespace media
OLDNEW
« no previous file with comments | « media/remoting/renderer_controller.h ('k') | media/remoting/renderer_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698