OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/media/android/remote/remote_media_player_bridge.h" | 5 #include "chrome/browser/media/android/remote/remote_media_player_bridge.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 // Create a Java String for the URL. | 71 // Create a Java String for the URL. |
72 j_url_string = ConvertUTF8ToJavaString(env, escaped_url); | 72 j_url_string = ConvertUTF8ToJavaString(env, escaped_url); |
73 } | 73 } |
74 ScopedJavaLocalRef<jstring> j_frame_url_string; | 74 ScopedJavaLocalRef<jstring> j_frame_url_string; |
75 GURL frameUrl = GetLocalPlayer()->frame_url(); | 75 GURL frameUrl = GetLocalPlayer()->frame_url(); |
76 if (frameUrl.is_valid()) { | 76 if (frameUrl.is_valid()) { |
77 // Create a Java String for the URL. | 77 // Create a Java String for the URL. |
78 j_frame_url_string = ConvertUTF8ToJavaString(env, frameUrl.spec()); | 78 j_frame_url_string = ConvertUTF8ToJavaString(env, frameUrl.spec()); |
79 } | 79 } |
80 java_bridge_.Reset(Java_RemoteMediaPlayerBridge_create( | 80 java_bridge_.Reset(Java_RemoteMediaPlayerBridge_create( |
81 env, reinterpret_cast<intptr_t>(this), j_url_string.obj(), | 81 env, reinterpret_cast<intptr_t>(this), j_url_string, j_frame_url_string, |
82 j_frame_url_string.obj(), | 82 ConvertUTF8ToJavaString(env, user_agent))); |
83 ConvertUTF8ToJavaString(env, user_agent).obj())); | |
84 } | 83 } |
85 | 84 |
86 RemoteMediaPlayerBridge::~RemoteMediaPlayerBridge() { | 85 RemoteMediaPlayerBridge::~RemoteMediaPlayerBridge() { |
87 JNIEnv* env = base::android::AttachCurrentThread(); | 86 JNIEnv* env = base::android::AttachCurrentThread(); |
88 CHECK(env); | 87 CHECK(env); |
89 Java_RemoteMediaPlayerBridge_destroy(env, java_bridge_.obj()); | 88 Java_RemoteMediaPlayerBridge_destroy(env, java_bridge_); |
90 Release(); | 89 Release(); |
91 } | 90 } |
92 | 91 |
93 bool RemoteMediaPlayerBridge::HasVideo() const { | 92 bool RemoteMediaPlayerBridge::HasVideo() const { |
94 NOTIMPLEMENTED(); | 93 NOTIMPLEMENTED(); |
95 return true; | 94 return true; |
96 } | 95 } |
97 | 96 |
98 bool RemoteMediaPlayerBridge::HasAudio() const { | 97 bool RemoteMediaPlayerBridge::HasAudio() const { |
99 NOTIMPLEMENTED(); | 98 NOTIMPLEMENTED(); |
(...skipping 23 matching lines...) Expand all Loading... |
123 void RemoteMediaPlayerBridge::OnPlaybackComplete() { | 122 void RemoteMediaPlayerBridge::OnPlaybackComplete() { |
124 time_update_timer_.Stop(); | 123 time_update_timer_.Stop(); |
125 MediaPlayerAndroid::OnPlaybackComplete(); | 124 MediaPlayerAndroid::OnPlaybackComplete(); |
126 } | 125 } |
127 | 126 |
128 void RemoteMediaPlayerBridge::OnMediaInterrupted() {} | 127 void RemoteMediaPlayerBridge::OnMediaInterrupted() {} |
129 | 128 |
130 void RemoteMediaPlayerBridge::StartInternal() { | 129 void RemoteMediaPlayerBridge::StartInternal() { |
131 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 130 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
132 JNIEnv* env = AttachCurrentThread(); | 131 JNIEnv* env = AttachCurrentThread(); |
133 Java_RemoteMediaPlayerBridge_start(env, java_bridge_.obj()); | 132 Java_RemoteMediaPlayerBridge_start(env, java_bridge_); |
134 if (!time_update_timer_.IsRunning()) { | 133 if (!time_update_timer_.IsRunning()) { |
135 time_update_timer_.Start( | 134 time_update_timer_.Start( |
136 FROM_HERE, | 135 FROM_HERE, |
137 base::TimeDelta::FromMilliseconds(media::kTimeUpdateInterval), | 136 base::TimeDelta::FromMilliseconds(media::kTimeUpdateInterval), |
138 this, &RemoteMediaPlayerBridge::OnTimeUpdateTimerFired); | 137 this, &RemoteMediaPlayerBridge::OnTimeUpdateTimerFired); |
139 } | 138 } |
140 } | 139 } |
141 | 140 |
142 void RemoteMediaPlayerBridge::PauseInternal() { | 141 void RemoteMediaPlayerBridge::PauseInternal() { |
143 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 142 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
144 JNIEnv* env = AttachCurrentThread(); | 143 JNIEnv* env = AttachCurrentThread(); |
145 Java_RemoteMediaPlayerBridge_pause(env, java_bridge_.obj()); | 144 Java_RemoteMediaPlayerBridge_pause(env, java_bridge_); |
146 time_update_timer_.Stop(); | 145 time_update_timer_.Stop(); |
147 } | 146 } |
148 | 147 |
149 void RemoteMediaPlayerBridge::OnTimeUpdateTimerFired() { | 148 void RemoteMediaPlayerBridge::OnTimeUpdateTimerFired() { |
150 manager()->OnTimeUpdate( | 149 manager()->OnTimeUpdate( |
151 player_id(), GetCurrentTime(), base::TimeTicks::Now()); | 150 player_id(), GetCurrentTime(), base::TimeTicks::Now()); |
152 } | 151 } |
153 | 152 |
154 void RemoteMediaPlayerBridge::PauseLocal(JNIEnv* env, | 153 void RemoteMediaPlayerBridge::PauseLocal(JNIEnv* env, |
155 const JavaParamRef<jobject>& obj) { | 154 const JavaParamRef<jobject>& obj) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 197 } |
199 | 198 |
200 void RemoteMediaPlayerBridge::Pause(bool is_media_related_action) { | 199 void RemoteMediaPlayerBridge::Pause(bool is_media_related_action) { |
201 // Ignore the pause if it's not from an event that is explicitly telling | 200 // Ignore the pause if it's not from an event that is explicitly telling |
202 // the video to pause. It's possible for Pause() to be called for other | 201 // the video to pause. It's possible for Pause() to be called for other |
203 // reasons, such as freeing resources, etc. and during those times, the | 202 // reasons, such as freeing resources, etc. and during those times, the |
204 // remote video playback should not be paused. | 203 // remote video playback should not be paused. |
205 if (is_media_related_action) { | 204 if (is_media_related_action) { |
206 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 205 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
207 JNIEnv* env = AttachCurrentThread(); | 206 JNIEnv* env = AttachCurrentThread(); |
208 Java_RemoteMediaPlayerBridge_pause(env, java_bridge_.obj()); | 207 Java_RemoteMediaPlayerBridge_pause(env, java_bridge_); |
209 time_update_timer_.Stop(); | 208 time_update_timer_.Stop(); |
210 } | 209 } |
211 } | 210 } |
212 | 211 |
213 void RemoteMediaPlayerBridge::SetVideoSurface(gl::ScopedJavaSurface surface) { | 212 void RemoteMediaPlayerBridge::SetVideoSurface(gl::ScopedJavaSurface surface) { |
214 // The surface is reset whenever the fullscreen view is destroyed or created. | 213 // The surface is reset whenever the fullscreen view is destroyed or created. |
215 // Since the remote player doesn't use it, we forward it to the local player | 214 // Since the remote player doesn't use it, we forward it to the local player |
216 // for the time when user disconnects and resumes local playback | 215 // for the time when user disconnects and resumes local playback |
217 // (see crbug.com/420690). | 216 // (see crbug.com/420690). |
218 MediaPlayerAndroid* local_player = GetLocalPlayer(); | 217 MediaPlayerAndroid* local_player = GetLocalPlayer(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 | 262 |
264 void RemoteMediaPlayerBridge::RequestRemotePlayback() { | 263 void RemoteMediaPlayerBridge::RequestRemotePlayback() { |
265 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 264 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
266 MediaPlayerAndroid* local_player = GetLocalPlayer(); | 265 MediaPlayerAndroid* local_player = GetLocalPlayer(); |
267 if (!local_player) | 266 if (!local_player) |
268 return; | 267 return; |
269 JNIEnv* env = AttachCurrentThread(); | 268 JNIEnv* env = AttachCurrentThread(); |
270 CHECK(env); | 269 CHECK(env); |
271 | 270 |
272 Java_RemoteMediaPlayerBridge_requestRemotePlayback( | 271 Java_RemoteMediaPlayerBridge_requestRemotePlayback( |
273 env, java_bridge_.obj(), local_player->GetCurrentTime().InMilliseconds()); | 272 env, java_bridge_, local_player->GetCurrentTime().InMilliseconds()); |
274 } | 273 } |
275 | 274 |
276 void RemoteMediaPlayerBridge::RequestRemotePlaybackControl() { | 275 void RemoteMediaPlayerBridge::RequestRemotePlaybackControl() { |
277 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 276 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
278 JNIEnv* env = AttachCurrentThread(); | 277 JNIEnv* env = AttachCurrentThread(); |
279 CHECK(env); | 278 CHECK(env); |
280 | 279 |
281 Java_RemoteMediaPlayerBridge_requestRemotePlaybackControl( | 280 Java_RemoteMediaPlayerBridge_requestRemotePlaybackControl(env, java_bridge_); |
282 env, java_bridge_.obj()); | |
283 } | 281 } |
284 | 282 |
285 void RemoteMediaPlayerBridge::SetNativePlayer() { | 283 void RemoteMediaPlayerBridge::SetNativePlayer() { |
286 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 284 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
287 JNIEnv* env = AttachCurrentThread(); | 285 JNIEnv* env = AttachCurrentThread(); |
288 CHECK(env); | 286 CHECK(env); |
289 | 287 |
290 Java_RemoteMediaPlayerBridge_setNativePlayer( | 288 Java_RemoteMediaPlayerBridge_setNativePlayer(env, java_bridge_); |
291 env, java_bridge_.obj()); | |
292 } | 289 } |
293 | 290 |
294 void RemoteMediaPlayerBridge::OnPlayerCreated() { | 291 void RemoteMediaPlayerBridge::OnPlayerCreated() { |
295 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 292 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
296 JNIEnv* env = AttachCurrentThread(); | 293 JNIEnv* env = AttachCurrentThread(); |
297 CHECK(env); | 294 CHECK(env); |
298 | 295 |
299 Java_RemoteMediaPlayerBridge_onPlayerCreated( | 296 Java_RemoteMediaPlayerBridge_onPlayerCreated(env, java_bridge_); |
300 env, java_bridge_.obj()); | |
301 } | 297 } |
302 | 298 |
303 void RemoteMediaPlayerBridge::OnPlayerDestroyed() { | 299 void RemoteMediaPlayerBridge::OnPlayerDestroyed() { |
304 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 300 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
305 JNIEnv* env = AttachCurrentThread(); | 301 JNIEnv* env = AttachCurrentThread(); |
306 CHECK(env); | 302 CHECK(env); |
307 | 303 |
308 Java_RemoteMediaPlayerBridge_onPlayerDestroyed( | 304 Java_RemoteMediaPlayerBridge_onPlayerDestroyed(env, java_bridge_); |
309 env, java_bridge_.obj()); | |
310 } | 305 } |
311 | 306 |
312 std::string RemoteMediaPlayerBridge::GetCastingMessage() { | 307 std::string RemoteMediaPlayerBridge::GetCastingMessage() { |
313 return casting_message_ ? | 308 return casting_message_ ? |
314 *casting_message_ : std::string(); | 309 *casting_message_ : std::string(); |
315 } | 310 } |
316 | 311 |
317 void RemoteMediaPlayerBridge::SetPosterBitmap( | 312 void RemoteMediaPlayerBridge::SetPosterBitmap( |
318 const std::vector<SkBitmap>& bitmaps) { | 313 const std::vector<SkBitmap>& bitmaps) { |
319 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 314 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
320 JNIEnv* env = AttachCurrentThread(); | 315 JNIEnv* env = AttachCurrentThread(); |
321 CHECK(env); | 316 CHECK(env); |
322 | 317 |
323 if (bitmaps.empty()) { | 318 if (bitmaps.empty()) { |
324 Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_.obj(), | 319 Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_, nullptr); |
325 nullptr); | |
326 } else { | 320 } else { |
327 ScopedJavaLocalRef<jobject> j_poster_bitmap; | 321 ScopedJavaLocalRef<jobject> j_poster_bitmap; |
328 j_poster_bitmap = gfx::ConvertToJavaBitmap(&(bitmaps[0])); | 322 j_poster_bitmap = gfx::ConvertToJavaBitmap(&(bitmaps[0])); |
329 | 323 |
330 Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_.obj(), | 324 Java_RemoteMediaPlayerBridge_setPosterBitmap(env, java_bridge_, |
331 j_poster_bitmap.obj()); | 325 j_poster_bitmap); |
332 } | 326 } |
333 } | 327 } |
334 | 328 |
335 void RemoteMediaPlayerBridge::Start() { | 329 void RemoteMediaPlayerBridge::Start() { |
336 StartInternal(); | 330 StartInternal(); |
337 } | 331 } |
338 | 332 |
339 void RemoteMediaPlayerBridge::SeekTo(base::TimeDelta time) { | 333 void RemoteMediaPlayerBridge::SeekTo(base::TimeDelta time) { |
340 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 334 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
341 // TODO(aberent) Move the checks to the Java side. | 335 // TODO(aberent) Move the checks to the Java side. |
342 base::TimeDelta duration = GetDuration(); | 336 base::TimeDelta duration = GetDuration(); |
343 | 337 |
344 if (time > duration) | 338 if (time > duration) |
345 time = duration; | 339 time = duration; |
346 | 340 |
347 // Seeking to an invalid position may cause media player to stuck in an | 341 // Seeking to an invalid position may cause media player to stuck in an |
348 // error state. | 342 // error state. |
349 if (time < base::TimeDelta()) { | 343 if (time < base::TimeDelta()) { |
350 DCHECK_EQ(-1.0, time.InMillisecondsF()); | 344 DCHECK_EQ(-1.0, time.InMillisecondsF()); |
351 return; | 345 return; |
352 } | 346 } |
353 | 347 |
354 JNIEnv* env = AttachCurrentThread(); | 348 JNIEnv* env = AttachCurrentThread(); |
355 CHECK(env); | 349 CHECK(env); |
356 int time_msec = static_cast<int>(time.InMilliseconds()); | 350 int time_msec = static_cast<int>(time.InMilliseconds()); |
357 Java_RemoteMediaPlayerBridge_seekTo(env, java_bridge_.obj(), time_msec); | 351 Java_RemoteMediaPlayerBridge_seekTo(env, java_bridge_, time_msec); |
358 } | 352 } |
359 | 353 |
360 void RemoteMediaPlayerBridge::Release() { | 354 void RemoteMediaPlayerBridge::Release() { |
361 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 355 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
362 time_update_timer_.Stop(); | 356 time_update_timer_.Stop(); |
363 JNIEnv* env = AttachCurrentThread(); | 357 JNIEnv* env = AttachCurrentThread(); |
364 Java_RemoteMediaPlayerBridge_release(env, java_bridge_.obj()); | 358 Java_RemoteMediaPlayerBridge_release(env, java_bridge_); |
365 DetachListener(); | 359 DetachListener(); |
366 } | 360 } |
367 | 361 |
368 void RemoteMediaPlayerBridge::UpdateEffectiveVolumeInternal( | 362 void RemoteMediaPlayerBridge::UpdateEffectiveVolumeInternal( |
369 double effective_volume) { | 363 double effective_volume) { |
370 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 364 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
371 JNIEnv* env = AttachCurrentThread(); | 365 JNIEnv* env = AttachCurrentThread(); |
372 CHECK(env); | 366 CHECK(env); |
373 Java_RemoteMediaPlayerBridge_setVolume( | 367 Java_RemoteMediaPlayerBridge_setVolume(env, java_bridge_, |
374 env, java_bridge_.obj(), GetEffectiveVolume()); | 368 GetEffectiveVolume()); |
375 } | 369 } |
376 | 370 |
377 base::TimeDelta RemoteMediaPlayerBridge::GetCurrentTime() { | 371 base::TimeDelta RemoteMediaPlayerBridge::GetCurrentTime() { |
378 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 372 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
379 JNIEnv* env = AttachCurrentThread(); | 373 JNIEnv* env = AttachCurrentThread(); |
380 return base::TimeDelta::FromMilliseconds( | 374 return base::TimeDelta::FromMilliseconds( |
381 Java_RemoteMediaPlayerBridge_getCurrentPosition( | 375 Java_RemoteMediaPlayerBridge_getCurrentPosition(env, java_bridge_)); |
382 env, java_bridge_.obj())); | |
383 } | 376 } |
384 | 377 |
385 base::TimeDelta RemoteMediaPlayerBridge::GetDuration() { | 378 base::TimeDelta RemoteMediaPlayerBridge::GetDuration() { |
386 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 379 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
387 JNIEnv* env = AttachCurrentThread(); | 380 JNIEnv* env = AttachCurrentThread(); |
388 const int duration_ms = | 381 const int duration_ms = |
389 Java_RemoteMediaPlayerBridge_getDuration(env, java_bridge_.obj()); | 382 Java_RemoteMediaPlayerBridge_getDuration(env, java_bridge_); |
390 // Sometimes we can't get the duration remotely, but the local media player | 383 // Sometimes we can't get the duration remotely, but the local media player |
391 // knows it. | 384 // knows it. |
392 // TODO (aberent) This is for YouTube. Remove it when the YouTube receiver is | 385 // TODO (aberent) This is for YouTube. Remove it when the YouTube receiver is |
393 // fixed. | 386 // fixed. |
394 if (duration_ms == 0) { | 387 if (duration_ms == 0) { |
395 MediaPlayerAndroid* local_player = GetLocalPlayer(); | 388 MediaPlayerAndroid* local_player = GetLocalPlayer(); |
396 if (!local_player) | 389 if (!local_player) |
397 return media::kInfiniteDuration; | 390 return media::kInfiniteDuration; |
398 return local_player->GetDuration(); | 391 return local_player->GetDuration(); |
399 } | 392 } |
400 return duration_ms < 0 ? media::kInfiniteDuration | 393 return duration_ms < 0 ? media::kInfiniteDuration |
401 : base::TimeDelta::FromMilliseconds(duration_ms); | 394 : base::TimeDelta::FromMilliseconds(duration_ms); |
402 } | 395 } |
403 | 396 |
404 bool RemoteMediaPlayerBridge::IsPlaying() { | 397 bool RemoteMediaPlayerBridge::IsPlaying() { |
405 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 398 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
406 JNIEnv* env = AttachCurrentThread(); | 399 JNIEnv* env = AttachCurrentThread(); |
407 CHECK(env); | 400 CHECK(env); |
408 jboolean result = Java_RemoteMediaPlayerBridge_isPlaying( | 401 jboolean result = Java_RemoteMediaPlayerBridge_isPlaying(env, java_bridge_); |
409 env, java_bridge_.obj()); | |
410 return result; | 402 return result; |
411 } | 403 } |
412 | 404 |
413 bool RemoteMediaPlayerBridge::CanPause() { | 405 bool RemoteMediaPlayerBridge::CanPause() { |
414 return true; | 406 return true; |
415 } | 407 } |
416 | 408 |
417 bool RemoteMediaPlayerBridge::CanSeekForward() { | 409 bool RemoteMediaPlayerBridge::CanSeekForward() { |
418 return true; | 410 return true; |
419 } | 411 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 | 467 |
476 | 468 |
477 void RemoteMediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) { | 469 void RemoteMediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) { |
478 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 470 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
479 // TODO(aberent) Do we need to retrieve auth credentials for basic | 471 // TODO(aberent) Do we need to retrieve auth credentials for basic |
480 // authentication? MediaPlayerBridge does. | 472 // authentication? MediaPlayerBridge does. |
481 cookies_ = cookies; | 473 cookies_ = cookies; |
482 JNIEnv* env = AttachCurrentThread(); | 474 JNIEnv* env = AttachCurrentThread(); |
483 CHECK(env); | 475 CHECK(env); |
484 Java_RemoteMediaPlayerBridge_setCookies( | 476 Java_RemoteMediaPlayerBridge_setCookies( |
485 env, java_bridge_.obj(), ConvertUTF8ToJavaString(env, cookies).obj()); | 477 env, java_bridge_, ConvertUTF8ToJavaString(env, cookies)); |
486 } | 478 } |
487 | 479 |
488 MediaPlayerAndroid* RemoteMediaPlayerBridge::GetLocalPlayer() { | 480 MediaPlayerAndroid* RemoteMediaPlayerBridge::GetLocalPlayer() { |
489 return static_cast<RemoteMediaPlayerManager*>(manager())->GetLocalPlayer( | 481 return static_cast<RemoteMediaPlayerManager*>(manager())->GetLocalPlayer( |
490 player_id()); | 482 player_id()); |
491 } | 483 } |
492 | 484 |
493 } // namespace remote_media | 485 } // namespace remote_media |
OLD | NEW |