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

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

Issue 2801853002: Media Remoting: Remove old interstitial implementation. (Closed)
Patch Set: Rebase. Created 3 years, 8 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') | no next file » | 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/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"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 DCHECK(thread_checker_.CalledOnValidThread()); 48 DCHECK(thread_checker_.CalledOnValidThread());
49 UpdateFromSessionState(SINK_AVAILABLE, ROUTE_TERMINATED); 49 UpdateFromSessionState(SINK_AVAILABLE, ROUTE_TERMINATED);
50 } 50 }
51 51
52 void RendererController::UpdateFromSessionState(StartTrigger start_trigger, 52 void RendererController::UpdateFromSessionState(StartTrigger start_trigger,
53 StopTrigger stop_trigger) { 53 StopTrigger stop_trigger) {
54 VLOG(1) << "UpdateFromSessionState: " << session_->state(); 54 VLOG(1) << "UpdateFromSessionState: " << session_->state();
55 if (client_) 55 if (client_)
56 client_->ActivateViewportIntersectionMonitoring(IsRemoteSinkAvailable()); 56 client_->ActivateViewportIntersectionMonitoring(IsRemoteSinkAvailable());
57 57
58 UpdateInterstitial(base::nullopt);
59 UpdateAndMaybeSwitch(start_trigger, stop_trigger); 58 UpdateAndMaybeSwitch(start_trigger, stop_trigger);
60 } 59 }
61 60
62 bool RendererController::IsRemoteSinkAvailable() { 61 bool RendererController::IsRemoteSinkAvailable() {
63 DCHECK(thread_checker_.CalledOnValidThread()); 62 DCHECK(thread_checker_.CalledOnValidThread());
64 63
65 switch (session_->state()) { 64 switch (session_->state()) {
66 case SharedSession::SESSION_CAN_START: 65 case SharedSession::SESSION_CAN_START:
67 case SharedSession::SESSION_STARTING: 66 case SharedSession::SESSION_STARTING:
68 case SharedSession::SESSION_STARTED: 67 case SharedSession::SESSION_STARTED:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 } 131 }
133 132
134 void RendererController::OnRemotePlaybackDisabled(bool disabled) { 133 void RendererController::OnRemotePlaybackDisabled(bool disabled) {
135 DCHECK(thread_checker_.CalledOnValidThread()); 134 DCHECK(thread_checker_.CalledOnValidThread());
136 135
137 is_remote_playback_disabled_ = disabled; 136 is_remote_playback_disabled_ = disabled;
138 metrics_recorder_.OnRemotePlaybackDisabled(disabled); 137 metrics_recorder_.OnRemotePlaybackDisabled(disabled);
139 UpdateAndMaybeSwitch(ENABLED_BY_PAGE, DISABLED_BY_PAGE); 138 UpdateAndMaybeSwitch(ENABLED_BY_PAGE, DISABLED_BY_PAGE);
140 } 139 }
141 140
142 void RendererController::OnSetPoster(const GURL& poster_url) {
143 DCHECK(thread_checker_.CalledOnValidThread());
144
145 if (poster_url != poster_url_) {
146 poster_url_ = poster_url;
147 if (poster_url_.is_empty())
148 UpdateInterstitial(SkBitmap());
149 else
150 DownloadPosterImage();
151 }
152 }
153
154 base::WeakPtr<RpcBroker> RendererController::GetRpcBroker() const { 141 base::WeakPtr<RpcBroker> RendererController::GetRpcBroker() const {
155 DCHECK(thread_checker_.CalledOnValidThread()); 142 DCHECK(thread_checker_.CalledOnValidThread());
156 143
157 return session_->rpc_broker()->GetWeakPtr(); 144 return session_->rpc_broker()->GetWeakPtr();
158 } 145 }
159 146
160 void RendererController::StartDataPipe( 147 void RendererController::StartDataPipe(
161 std::unique_ptr<mojo::DataPipe> audio_data_pipe, 148 std::unique_ptr<mojo::DataPipe> audio_data_pipe,
162 std::unique_ptr<mojo::DataPipe> video_data_pipe, 149 std::unique_ptr<mojo::DataPipe> video_data_pipe,
163 const SharedSession::DataPipeStartCallback& done_callback) { 150 const SharedSession::DataPipeStartCallback& done_callback) {
164 DCHECK(thread_checker_.CalledOnValidThread()); 151 DCHECK(thread_checker_.CalledOnValidThread());
165 152
166 session_->StartDataPipe(std::move(audio_data_pipe), 153 session_->StartDataPipe(std::move(audio_data_pipe),
167 std::move(video_data_pipe), done_callback); 154 std::move(video_data_pipe), done_callback);
168 } 155 }
169 156
170 void RendererController::OnMetadataChanged(const PipelineMetadata& metadata) { 157 void RendererController::OnMetadataChanged(const PipelineMetadata& metadata) {
171 DCHECK(thread_checker_.CalledOnValidThread()); 158 DCHECK(thread_checker_.CalledOnValidThread());
172 159
173 const gfx::Size old_size = pipeline_metadata_.natural_size;
174 const bool was_audio_codec_supported = has_audio() && IsAudioCodecSupported(); 160 const bool was_audio_codec_supported = has_audio() && IsAudioCodecSupported();
175 const bool was_video_codec_supported = has_video() && IsVideoCodecSupported(); 161 const bool was_video_codec_supported = has_video() && IsVideoCodecSupported();
176 pipeline_metadata_ = metadata; 162 pipeline_metadata_ = metadata;
177 const bool is_audio_codec_supported = has_audio() && IsAudioCodecSupported(); 163 const bool is_audio_codec_supported = has_audio() && IsAudioCodecSupported();
178 const bool is_video_codec_supported = has_video() && IsVideoCodecSupported(); 164 const bool is_video_codec_supported = has_video() && IsVideoCodecSupported();
179 metrics_recorder_.OnPipelineMetadataChanged(metadata); 165 metrics_recorder_.OnPipelineMetadataChanged(metadata);
180 166
181 is_encrypted_ = false; 167 is_encrypted_ = false;
182 if (has_video()) 168 if (has_video())
183 is_encrypted_ |= metadata.video_decoder_config.is_encrypted(); 169 is_encrypted_ |= metadata.video_decoder_config.is_encrypted();
184 if (has_audio()) 170 if (has_audio())
185 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted(); 171 is_encrypted_ |= metadata.audio_decoder_config.is_encrypted();
186 172
187 if (pipeline_metadata_.natural_size != old_size)
188 UpdateInterstitial(base::nullopt);
189
190 StartTrigger start_trigger = UNKNOWN_START_TRIGGER; 173 StartTrigger start_trigger = UNKNOWN_START_TRIGGER;
191 if (!was_audio_codec_supported && is_audio_codec_supported) 174 if (!was_audio_codec_supported && is_audio_codec_supported)
192 start_trigger = SUPPORTED_AUDIO_CODEC; 175 start_trigger = SUPPORTED_AUDIO_CODEC;
193 if (!was_video_codec_supported && is_video_codec_supported) { 176 if (!was_video_codec_supported && is_video_codec_supported) {
194 start_trigger = start_trigger == SUPPORTED_AUDIO_CODEC 177 start_trigger = start_trigger == SUPPORTED_AUDIO_CODEC
195 ? SUPPORTED_AUDIO_AND_VIDEO_CODECS 178 ? SUPPORTED_AUDIO_AND_VIDEO_CODECS
196 : SUPPORTED_VIDEO_CODEC; 179 : SUPPORTED_VIDEO_CODEC;
197 } 180 }
198 StopTrigger stop_trigger = UNKNOWN_STOP_TRIGGER; 181 StopTrigger stop_trigger = UNKNOWN_STOP_TRIGGER;
199 if (was_audio_codec_supported && !is_audio_codec_supported) 182 if (was_audio_codec_supported && !is_audio_codec_supported)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 DCHECK(thread_checker_.CalledOnValidThread()); 250 DCHECK(thread_checker_.CalledOnValidThread());
268 251
269 if (!client_) { 252 if (!client_) {
270 DCHECK(!remote_rendering_started_); 253 DCHECK(!remote_rendering_started_);
271 return false; // No way to switch to the remoting renderer. 254 return false; // No way to switch to the remoting renderer.
272 } 255 }
273 256
274 const SharedSession::SessionState state = session_->state(); 257 const SharedSession::SessionState state = session_->state();
275 if (is_encrypted_) { 258 if (is_encrypted_) {
276 // Due to technical limitations when playing encrypted content, once a 259 // Due to technical limitations when playing encrypted content, once a
277 // remoting session has been started, always return true here to indicate 260 // remoting session has been started, playback cannot be resumed locally
278 // that the CourierRenderer should continue to be used. In the stopped 261 // without reloading the page, so leave the CourierRenderer in-place to
279 // states, CourierRenderer will display an interstitial to notify the user 262 // avoid having the default renderer attempt and fail to play the content.
280 // that local rendering cannot be resumed.
281 // 263 //
282 // TODO(miu): Revisit this once more of the encrypted-remoting impl is 264 // TODO(miu): Revisit this once more of the encrypted-remoting impl is
283 // in-place. For example, this will prevent metrics from recording session 265 // in-place. For example, this will prevent metrics from recording session
284 // stop reasons. 266 // stop reasons.
285 return state == SharedSession::SESSION_STARTED || 267 return state == SharedSession::SESSION_STARTED ||
286 state == SharedSession::SESSION_STOPPING || 268 state == SharedSession::SESSION_STOPPING ||
287 state == SharedSession::SESSION_PERMANENTLY_STOPPED; 269 state == SharedSession::SESSION_PERMANENTLY_STOPPED;
288 } 270 }
289 271
290 if (encountered_renderer_fatal_error_) 272 if (encountered_renderer_fatal_error_)
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // started successfully. 339 // started successfully.
358 session_->StartRemoting(this); 340 session_->StartRemoting(this);
359 } else { 341 } else {
360 // For encrypted content, it's only valid to switch to remoting renderer, 342 // For encrypted content, it's only valid to switch to remoting renderer,
361 // and never back to the local renderer. The RemotingCdmController will 343 // and never back to the local renderer. The RemotingCdmController will
362 // force-stop the session when remoting has ended; so no need to call 344 // force-stop the session when remoting has ended; so no need to call
363 // StopRemoting() from here. 345 // StopRemoting() from here.
364 DCHECK(!is_encrypted_); 346 DCHECK(!is_encrypted_);
365 DCHECK_NE(stop_trigger, UNKNOWN_STOP_TRIGGER); 347 DCHECK_NE(stop_trigger, UNKNOWN_STOP_TRIGGER);
366 metrics_recorder_.WillStopSession(stop_trigger); 348 metrics_recorder_.WillStopSession(stop_trigger);
367 // Update the interstitial one last time before switching back to the local
368 // Renderer.
369 UpdateInterstitial(base::nullopt);
370 client_->SwitchRenderer(false); 349 client_->SwitchRenderer(false);
371 session_->StopRemoting(this); 350 session_->StopRemoting(this);
372 } 351 }
373 } 352 }
374 353
375 void RendererController::SetShowInterstitialCallback(
376 const ShowInterstitialCallback& cb) {
377 DCHECK(thread_checker_.CalledOnValidThread());
378 show_interstitial_cb_ = cb;
379 UpdateInterstitial(SkBitmap());
380 if (!poster_url_.is_empty())
381 DownloadPosterImage();
382 }
383
384 void RendererController::SetDownloadPosterCallback(
385 const DownloadPosterCallback& cb) {
386 DCHECK(thread_checker_.CalledOnValidThread());
387 DCHECK(download_poster_cb_.is_null());
388 download_poster_cb_ = cb;
389 if (!poster_url_.is_empty())
390 DownloadPosterImage();
391 }
392
393 void RendererController::UpdateInterstitial(
394 const base::Optional<SkBitmap>& image) {
395 DCHECK(thread_checker_.CalledOnValidThread());
396 if (show_interstitial_cb_.is_null())
397 return;
398
399 InterstitialType type = InterstitialType::BETWEEN_SESSIONS;
400 switch (remote_rendering_started_ ? session_->state()
401 : SharedSession::SESSION_STOPPING) {
402 case SharedSession::SESSION_STARTED:
403 type = InterstitialType::IN_SESSION;
404 break;
405 case SharedSession::SESSION_PERMANENTLY_STOPPED:
406 type = InterstitialType::ENCRYPTED_MEDIA_FATAL_ERROR;
407 break;
408 case SharedSession::SESSION_UNAVAILABLE:
409 case SharedSession::SESSION_CAN_START:
410 case SharedSession::SESSION_STARTING:
411 case SharedSession::SESSION_STOPPING:
412 break;
413 }
414
415 bool needs_update = false;
416 if (image.has_value()) {
417 interstitial_background_ = image.value();
418 needs_update = true;
419 }
420 if (interstitial_natural_size_ != pipeline_metadata_.natural_size) {
421 interstitial_natural_size_ = pipeline_metadata_.natural_size;
422 needs_update = true;
423 }
424 if (interstitial_type_ != type) {
425 interstitial_type_ = type;
426 needs_update = true;
427 }
428 if (!needs_update)
429 return;
430
431 show_interstitial_cb_.Run(interstitial_background_,
432 interstitial_natural_size_, interstitial_type_);
433 }
434
435 void RendererController::DownloadPosterImage() {
436 if (download_poster_cb_.is_null() || show_interstitial_cb_.is_null())
437 return;
438 DCHECK(!poster_url_.is_empty());
439
440 const base::TimeTicks download_start_time = base::TimeTicks::Now();
441 download_poster_cb_.Run(
442 poster_url_,
443 base::Bind(&RendererController::OnPosterImageDownloaded,
444 weak_factory_.GetWeakPtr(), poster_url_, download_start_time));
445 }
446
447 void RendererController::OnPosterImageDownloaded(
448 const GURL& download_url,
449 base::TimeTicks download_start_time,
450 const SkBitmap& image) {
451 DCHECK(thread_checker_.CalledOnValidThread());
452
453 metrics_recorder_.OnPosterImageDownloaded(
454 base::TimeTicks::Now() - download_start_time, !image.drawsNothing());
455 if (download_url != poster_url_)
456 return; // The poster image URL has changed during the download.
457 UpdateInterstitial(image);
458 }
459
460 void RendererController::OnRendererFatalError(StopTrigger stop_trigger) { 354 void RendererController::OnRendererFatalError(StopTrigger stop_trigger) {
461 DCHECK(thread_checker_.CalledOnValidThread()); 355 DCHECK(thread_checker_.CalledOnValidThread());
462 356
463 // Do not act on errors caused by things like Mojo pipes being closed during 357 // Do not act on errors caused by things like Mojo pipes being closed during
464 // shutdown. 358 // shutdown.
465 if (!remote_rendering_started_) 359 if (!remote_rendering_started_)
466 return; 360 return;
467 361
468 encountered_renderer_fatal_error_ = true; 362 encountered_renderer_fatal_error_ = true;
469 UpdateAndMaybeSwitch(UNKNOWN_START_TRIGGER, stop_trigger); 363 UpdateAndMaybeSwitch(UNKNOWN_START_TRIGGER, stop_trigger);
470 } 364 }
471 365
472 void RendererController::SetClient(MediaObserverClient* client) { 366 void RendererController::SetClient(MediaObserverClient* client) {
473 DCHECK(thread_checker_.CalledOnValidThread()); 367 DCHECK(thread_checker_.CalledOnValidThread());
474 DCHECK(client); 368 DCHECK(client);
475 DCHECK(!client_); 369 DCHECK(!client_);
476 370
477 client_ = client; 371 client_ = client;
478 client_->ActivateViewportIntersectionMonitoring(IsRemoteSinkAvailable()); 372 client_->ActivateViewportIntersectionMonitoring(IsRemoteSinkAvailable());
479 } 373 }
480 374
481 } // namespace remoting 375 } // namespace remoting
482 } // namespace media 376 } // namespace media
OLDNEW
« no previous file with comments | « media/remoting/renderer_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698