content_video_view.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 3// found in the LICENSE file. 4 5#include "content/browser/android/content_video_view.h" 6 7#include "base/command_line.h" 8#include "base/logging.h" 9#include "base/message_loop/message_loop.h" 10#include "content/browser/android/content_view_core_impl.h" 11#include "content/browser/media/android/browser_media_player_manager.h" 12#include "content/browser/power_save_blocker_impl.h" 13#include "content/common/android/surface_texture_peer.h" 14#include "content/public/common/content_switches.h" 15#include "jni/ContentVideoView_jni.h" 16 17using base::android::AttachCurrentThread; 18using base::android::CheckException; 19using base::android::ScopedJavaGlobalRef; 20 21namespace content { 22 23namespace { 24// There can only be one content video view at a time, this holds onto that 25// singleton instance. 26ContentVideoView* g_content_video_view = NULL; 27 28} // namespace 29 30static jobject GetSingletonJavaContentVideoView(JNIEnv*env, jclass) { 31 if (g_content_video_view) 32 return g_content_video_view->GetJavaObject(env).Release(); 33 else 34 return NULL; 35} 36 37bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) { 38 return RegisterNativesImpl(env); 39} 40 41ContentVideoView* ContentVideoView::GetInstance() { 42 return g_content_video_view; 43} 44 45ContentVideoView::ContentVideoView( 46 BrowserMediaPlayerManager* manager) 47 : manager_(manager), 48 weak_factory_(this) { 49 DCHECK(!g_content_video_view); 50 j_content_video_view_ = CreateJavaObject(); 51 g_content_video_view = this; 52 CreatePowerSaveBlocker(); 53} 54 55ContentVideoView::~ContentVideoView() { 56 DCHECK(g_content_video_view); 57 DestroyContentVideoView(true); 58 g_content_video_view = NULL; 59} 60 61void ContentVideoView::OpenVideo() { 62 JNIEnv* env = AttachCurrentThread(); 63 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 64 if (!content_video_view.is_null()) { 65 CreatePowerSaveBlocker(); 66 Java_ContentVideoView_openVideo(env, content_video_view.obj()); 67 } 68} 69 70void ContentVideoView::OnMediaPlayerError(int error_type) { 71 JNIEnv* env = AttachCurrentThread(); 72 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 73 if (!content_video_view.is_null()) { 74 power_save_blocker_.reset(); 75 Java_ContentVideoView_onMediaPlayerError(env, content_video_view.obj(), 76 error_type); 77 } 78} 79 80void ContentVideoView::OnVideoSizeChanged(int width, int height) { 81 JNIEnv* env = AttachCurrentThread(); 82 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 83 if (!content_video_view.is_null()) { 84 Java_ContentVideoView_onVideoSizeChanged(env, content_video_view.obj(), 85 width, height); 86 } 87} 88 89void ContentVideoView::OnBufferingUpdate(int percent) { 90 JNIEnv* env = AttachCurrentThread(); 91 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 92 if (!content_video_view.is_null()) { 93 Java_ContentVideoView_onBufferingUpdate(env, content_video_view.obj(), 94 percent); 95 } 96} 97 98void ContentVideoView::OnPlaybackComplete() { 99 JNIEnv* env = AttachCurrentThread(); 100 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 101 if (!content_video_view.is_null()) { 102 power_save_blocker_.reset(); 103 Java_ContentVideoView_onPlaybackComplete(env, content_video_view.obj()); 104 } 105} 106 107void ContentVideoView::OnExitFullscreen() { 108 JNIEnv* env = AttachCurrentThread(); 109 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 110 if (!content_video_view.is_null()) { 111 Java_ContentVideoView_onExitFullscreen(env, content_video_view.obj()); 112 j_content_video_view_.reset(); 113 } 114} 115 116void ContentVideoView::UpdateMediaMetadata() { 117 JNIEnv* env = AttachCurrentThread(); 118 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 119 if (content_video_view.is_null()) 120 return; 121 122 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 123 if (player && player->IsPlayerReady()) { 124 Java_ContentVideoView_onUpdateMediaMetadata( 125 env, content_video_view.obj(), player->GetVideoWidth(), 126 player->GetVideoHeight(), player->GetDuration().InMilliseconds(), 127 player->CanPause(),player->CanSeekForward(), player->CanSeekBackward()); 128 } 129} 130 131int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const { 132 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 133 return player ? player->GetVideoWidth() : 0; 134} 135 136int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const { 137 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 138 return player ? player->GetVideoHeight() : 0; 139} 140 141int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const { 142 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 143 return player ? player->GetDuration().InMilliseconds() : -1; 144} 145 146int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const { 147 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 148 return player ? player->GetCurrentTime().InMilliseconds() : 0; 149} 150 151bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) { 152 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer(); 153 return player ? player->IsPlaying() : false; 154} 155 156void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) { 157 manager_->FullscreenPlayerSeek(msec); 158} 159 160void ContentVideoView::Play(JNIEnv*, jobject obj) { 161 CreatePowerSaveBlocker(); 162 manager_->FullscreenPlayerPlay(); 163} 164 165void ContentVideoView::Pause(JNIEnv*, jobject obj) { 166 power_save_blocker_.reset(); 167 manager_->FullscreenPlayerPause(); 168} 169 170void ContentVideoView::ExitFullscreen( 171 JNIEnv*, jobject, jboolean release_media_player) { 172 power_save_blocker_.reset(); 173 j_content_video_view_.reset(); 174 manager_->ExitFullscreen(release_media_player); 175} 176 177void ContentVideoView::SetSurface(JNIEnv* env, jobject obj, 178 jobject surface) { 179 manager_->SetVideoSurface( 180 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); 181} 182 183void ContentVideoView::RequestMediaMetadata(JNIEnv* env, jobject obj) { 184 base::MessageLoop::current()->PostTask( 185 FROM_HERE, 186 base::Bind(&ContentVideoView::UpdateMediaMetadata, 187 weak_factory_.GetWeakPtr())); 188} 189 190ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) { 191 return j_content_video_view_.get(env); 192} 193 194gfx::NativeView ContentVideoView::GetNativeView() { 195 JNIEnv* env = AttachCurrentThread(); 196 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 197 if (content_video_view.is_null()) 198 return NULL; 199 200 return reinterpret_cast<gfx::NativeView>( 201 Java_ContentVideoView_getNativeViewAndroid(env, 202 content_video_view.obj())); 203 204} 205 206JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject() { 207 ContentViewCoreImpl* content_view_core = manager_->GetContentViewCore(); 208 JNIEnv* env = AttachCurrentThread(); 209 bool legacyMode = CommandLine::ForCurrentProcess()->HasSwitch( 210 switches::kDisableOverlayFullscreenVideoSubtitle); 211 return JavaObjectWeakGlobalRef( 212 env, 213 Java_ContentVideoView_createContentVideoView( 214 env, 215 content_view_core->GetContext().obj(), 216 reinterpret_cast<intptr_t>(this), 217 content_view_core->GetContentVideoViewClient().obj(), 218 legacyMode).obj()); 219} 220 221void ContentVideoView::CreatePowerSaveBlocker() { 222 if (power_save_blocker_) return; 223 224 power_save_blocker_ = PowerSaveBlocker::Create( 225 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep, 226 "Playing video").Pass(); 227 static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())-> 228 InitDisplaySleepBlocker(GetNativeView()); 229} 230 231void ContentVideoView::DestroyContentVideoView(bool native_view_destroyed) { 232 JNIEnv* env = AttachCurrentThread(); 233 ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env); 234 if (!content_video_view.is_null()) { 235 Java_ContentVideoView_destroyContentVideoView(env, 236 content_video_view.obj(), native_view_destroyed); 237 j_content_video_view_.reset(); 238 } 239} 240} // namespace content 241