| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/android/content_video_view.h" | 5 #include "content/browser/android/content_video_view.h" |
| 6 | 6 |
| 7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 10 #include "content/browser/android/media_player_manager_android.h" |
| 11 #include "content/browser/media/media_player_delegate_android.h" | |
| 12 #endif | |
| 13 #include "content/common/android/surface_callback.h" | 11 #include "content/common/android/surface_callback.h" |
| 14 #include "content/common/android/surface_texture_peer.h" | 12 #include "content/common/android/surface_texture_peer.h" |
| 15 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 16 #include "content/public/common/content_switches.h" | 14 #include "content/public/common/content_switches.h" |
| 17 #include "jni/ContentVideoView_jni.h" | 15 #include "jni/ContentVideoView_jni.h" |
| 18 #include "webkit/media/android/media_metadata_android.h" | |
| 19 | 16 |
| 20 using base::android::AttachCurrentThread; | 17 using base::android::AttachCurrentThread; |
| 21 using base::android::CheckException; | 18 using base::android::CheckException; |
| 22 using base::android::ScopedJavaGlobalRef; | 19 using base::android::ScopedJavaGlobalRef; |
| 23 | 20 |
| 24 // The timeout value we should wait after user click the back button on the | |
| 25 // fullscreen view. | |
| 26 static const int kTimeoutMillseconds = 1000; | |
| 27 | |
| 28 // ---------------------------------------------------------------------------- | |
| 29 // Methods that call to Java via JNI | |
| 30 // ---------------------------------------------------------------------------- | |
| 31 | |
| 32 namespace content { | 21 namespace content { |
| 33 | 22 |
| 34 // static | |
| 35 bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) { | 23 bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) { |
| 36 return RegisterNativesImpl(env); | 24 return RegisterNativesImpl(env); |
| 37 } | 25 } |
| 38 | 26 |
| 39 void ContentVideoView::CreateContentVideoView( | 27 ContentVideoView::ContentVideoView(MediaPlayerManagerAndroid* manager) |
| 40 MediaPlayerDelegateAndroid* player) { | 28 : manager_(manager) { |
| 41 player_ = player; | 29 } |
| 30 |
| 31 ContentVideoView::~ContentVideoView() { |
| 32 DestroyContentVideoView(); |
| 33 } |
| 34 |
| 35 void ContentVideoView::CreateContentVideoView() { |
| 42 if (j_content_video_view_.is_null()) { | 36 if (j_content_video_view_.is_null()) { |
| 43 JNIEnv* env = AttachCurrentThread(); | 37 JNIEnv* env = AttachCurrentThread(); |
| 44 j_content_video_view_.Reset(Java_ContentVideoView_createContentVideoView( | 38 j_content_video_view_.Reset(Java_ContentVideoView_createContentVideoView( |
| 45 env, reinterpret_cast<jint>(this))); | 39 env, reinterpret_cast<jint>(this))); |
| 46 } else { | 40 } else { |
| 47 // Just ask video view to reopen the video. | 41 // Just ask video view to reopen the video. |
| 48 Java_ContentVideoView_openVideo(AttachCurrentThread(), | 42 Java_ContentVideoView_openVideo(AttachCurrentThread(), |
| 49 j_content_video_view_.obj()); | 43 j_content_video_view_.obj()); |
| 50 } | 44 } |
| 51 } | 45 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 Java_ContentVideoView_onPlaybackComplete(AttachCurrentThread(), | 81 Java_ContentVideoView_onPlaybackComplete(AttachCurrentThread(), |
| 88 j_content_video_view_.obj()); | 82 j_content_video_view_.obj()); |
| 89 } | 83 } |
| 90 } | 84 } |
| 91 | 85 |
| 92 void ContentVideoView::UpdateMediaMetadata() { | 86 void ContentVideoView::UpdateMediaMetadata() { |
| 93 if (!j_content_video_view_.is_null()) | 87 if (!j_content_video_view_.is_null()) |
| 94 UpdateMediaMetadata(AttachCurrentThread(), j_content_video_view_.obj()); | 88 UpdateMediaMetadata(AttachCurrentThread(), j_content_video_view_.obj()); |
| 95 } | 89 } |
| 96 | 90 |
| 97 // ---------------------------------------------------------------------------- | |
| 98 | |
| 99 ContentVideoView::ContentVideoView() : player_(NULL) { | |
| 100 } | |
| 101 | |
| 102 ContentVideoView::~ContentVideoView() { | |
| 103 player_ = NULL; | |
| 104 | |
| 105 // If the browser process crashed, just kill the fullscreen view. | |
| 106 DestroyContentVideoView(); | |
| 107 } | |
| 108 | |
| 109 // ---------------------------------------------------------------------------- | |
| 110 // All these functions are called on UI thread | |
| 111 | |
| 112 int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const { | 91 int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const { |
| 113 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 92 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 93 return player ? player->GetVideoWidth() : 0; |
| 115 return player_ ? player_->GetVideoWidth() : 0; | |
| 116 #else | |
| 117 return 0; | |
| 118 #endif | |
| 119 } | 94 } |
| 120 | 95 |
| 121 int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const { | 96 int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const { |
| 122 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 97 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 98 return player ? player->GetVideoHeight() : 0; |
| 124 return player_ ? player_->GetVideoHeight() : 0; | |
| 125 #else | |
| 126 return 0; | |
| 127 #endif | |
| 128 } | 99 } |
| 129 | 100 |
| 130 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const { | 101 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const { |
| 131 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 102 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 103 return player ? player->GetDuration().InMilliseconds() : -1; |
| 133 return player_ ? ConvertSecondsToMilliSeconds(player_->Duration()) : -1; | |
| 134 #else | |
| 135 return -1; | |
| 136 #endif | |
| 137 } | 104 } |
| 138 | 105 |
| 139 int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const { | 106 int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const { |
| 140 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 107 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 108 return player ? player->GetCurrentTime().InMilliseconds() : 0; |
| 142 return player_ ? ConvertSecondsToMilliSeconds(player_->CurrentTime()) : 0; | |
| 143 #else | |
| 144 return 0; | |
| 145 #endif | |
| 146 } | 109 } |
| 147 | 110 |
| 148 bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) { | 111 bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) { |
| 149 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 112 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 113 return player ? player->IsPlaying() : false; |
| 151 return player_ ? player_->IsPlaying() : false; | |
| 152 #else | |
| 153 return false; | |
| 154 #endif | |
| 155 } | 114 } |
| 156 | 115 |
| 157 void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) { | 116 void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) { |
| 158 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 117 manager_->FullscreenPlayerSeek(msec); |
| 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 160 if (player_) | |
| 161 player_->Seek(static_cast<float>(msec / 1000.0)); | |
| 162 #endif | |
| 163 } | |
| 164 | |
| 165 webkit_media::MediaMetadataAndroid* ContentVideoView::GetMediaMetadata() { | |
| 166 #if !defined(ANDROID_UPSTREAM_BRINGUP) | |
| 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 168 if (!player_) | |
| 169 return NULL; | |
| 170 | |
| 171 return new webkit_media::MediaMetadataAndroid(player_->GetVideoWidth(), | |
| 172 player_->GetVideoHeight(), | |
| 173 base::TimeDelta::FromSeconds( | |
| 174 player_->Duration()), | |
| 175 base::TimeDelta::FromSeconds( | |
| 176 player_->CurrentTime()), | |
| 177 !player_->IsPlaying(), | |
| 178 player_->CanPause(), | |
| 179 player_->CanSeekForward(), | |
| 180 player_->CanSeekForward()); | |
| 181 #else | |
| 182 return NULL; | |
| 183 #endif | |
| 184 } | |
| 185 | |
| 186 int ContentVideoView::GetPlayerId(JNIEnv*, jobject obj) const { | |
| 187 #if !defined(ANDROID_UPSTREAM_BRINGUP) | |
| 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 189 return player_ ? player_->player_id() : -1; | |
| 190 #else | |
| 191 return -1; | |
| 192 #endif | |
| 193 } | |
| 194 | |
| 195 int ContentVideoView::GetRouteId(JNIEnv*, jobject obj) const { | |
| 196 #if !defined(ANDROID_UPSTREAM_BRINGUP) | |
| 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 198 return player_ ? player_->route_id() : -1; | |
| 199 #else | |
| 200 return -1; | |
| 201 #endif | |
| 202 } | |
| 203 | |
| 204 int ContentVideoView::GetRenderHandle(JNIEnv*, jobject obj) const { | |
| 205 #if !defined(ANDROID_UPSTREAM_BRINGUP) | |
| 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 207 static bool single_process = | |
| 208 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); | |
| 209 if (!player_) | |
| 210 return -1; | |
| 211 | |
| 212 if (single_process) | |
| 213 return 0; | |
| 214 return player_->render_handle(); | |
| 215 #else | |
| 216 return -1; | |
| 217 #endif | |
| 218 } | 118 } |
| 219 | 119 |
| 220 void ContentVideoView::Play(JNIEnv*, jobject obj) { | 120 void ContentVideoView::Play(JNIEnv*, jobject obj) { |
| 221 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 121 manager_->FullscreenPlayerPlay(); |
| 222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 223 if (player_) | |
| 224 player_->Play(); | |
| 225 #endif | |
| 226 } | 122 } |
| 227 | 123 |
| 228 void ContentVideoView::Pause(JNIEnv*, jobject obj) { | 124 void ContentVideoView::Pause(JNIEnv*, jobject obj) { |
| 229 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 125 manager_->FullscreenPlayerPause(); |
| 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 231 if (player_) | |
| 232 player_->Pause(); | |
| 233 #endif | |
| 234 } | 126 } |
| 235 | 127 |
| 236 void ContentVideoView::OnTimeout() { | 128 void ContentVideoView::ExitFullscreen( |
| 237 #if !defined(ANDROID_UPSTREAM_BRINGUP) | 129 JNIEnv*, jobject, jboolean release_media_player) { |
| 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 130 manager_->ExitFullscreen(release_media_player); |
| 239 #endif | 131 j_content_video_view_.Reset(); |
| 240 timeout_timer_.Stop(); | |
| 241 DestroyContentVideoView(); | |
| 242 } | |
| 243 | |
| 244 int ContentVideoView::ConvertSecondsToMilliSeconds(float seconds) const { | |
| 245 return static_cast<int>(seconds * 1000); | |
| 246 } | |
| 247 | |
| 248 // ---------------------------------------------------------------------------- | |
| 249 // Methods called from Java via JNI | |
| 250 // ---------------------------------------------------------------------------- | |
| 251 | |
| 252 void ContentVideoView::DestroyContentVideoView(JNIEnv*, jobject, | |
| 253 jboolean release_media_player) { | |
| 254 #if !defined(ANDROID_UPSTREAM_BRINGUP) | |
| 255 if (player_) { | |
| 256 player_->ExitFullscreen(release_media_player); | |
| 257 | |
| 258 // Fire off a timer so that we will close the fullscreen view in case the | |
| 259 // renderer crashes. | |
| 260 timeout_timer_.Start(FROM_HERE, | |
| 261 base::TimeDelta::FromMilliseconds(kTimeoutMillseconds), | |
| 262 this, &ContentVideoView::OnTimeout); | |
| 263 } | |
| 264 #endif | |
| 265 } | 132 } |
| 266 | 133 |
| 267 void ContentVideoView::SetSurface(JNIEnv* env, jobject obj, | 134 void ContentVideoView::SetSurface(JNIEnv* env, jobject obj, |
| 268 jobject surface, | 135 jobject surface) { |
| 269 jint route_id, | 136 manager_->SetVideoSurface(surface); |
| 270 jint player_id) { | 137 ReleaseSurface(surface); |
| 271 SetSurfaceAsync(env, | |
| 272 surface, | |
| 273 SurfaceTexturePeer::SET_VIDEO_SURFACE_TEXTURE, | |
| 274 route_id, | |
| 275 player_id, | |
| 276 NULL); | |
| 277 } | 138 } |
| 278 | 139 |
| 279 void ContentVideoView::UpdateMediaMetadata(JNIEnv* env, jobject obj) { | 140 void ContentVideoView::UpdateMediaMetadata(JNIEnv* env, jobject obj) { |
| 280 scoped_ptr<webkit_media::MediaMetadataAndroid> metadata(GetMediaMetadata()); | 141 media::MediaPlayerBridge* player = manager_->GetFullscreenPlayer(); |
| 281 Java_ContentVideoView_updateMediaMetadata(env, | 142 if (player) |
| 282 obj, | 143 Java_ContentVideoView_updateMediaMetadata( |
| 283 metadata->width, | 144 env, obj, player->GetVideoWidth(), player->GetVideoHeight(), |
| 284 metadata->height, | 145 player->GetDuration().InMilliseconds(), player->can_pause(), |
| 285 metadata->duration.InMilliseconds(), | 146 player->can_seek_forward(), player->can_seek_backward()); |
| 286 metadata->can_pause, | |
| 287 metadata->can_seek_forward, | |
| 288 metadata->can_seek_backward); | |
| 289 } | 147 } |
| 290 | 148 |
| 291 } // namespace content | 149 } // namespace content |
| OLD | NEW |