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