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

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

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

Powered by Google App Engine
This is Rietveld 408576698