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.
5 #include "content/browser/android/content_video_view.h"
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"
17 using base::android::AttachCurrentThread
;
18 using base::android::CheckException
;
19 using base::android::ScopedJavaGlobalRef
;
24 // There can only be one content video view at a time, this holds onto that
25 // singleton instance.
26 ContentVideoView
* g_content_video_view
= NULL
;
30 static jobject
GetSingletonJavaContentVideoView(JNIEnv
*env
, jclass
) {
31 if (g_content_video_view
)
32 return g_content_video_view
->GetJavaObject(env
).Release();
37 bool ContentVideoView::RegisterContentVideoView(JNIEnv
* env
) {
38 return RegisterNativesImpl(env
);
41 ContentVideoView
* ContentVideoView::GetInstance() {
42 return g_content_video_view
;
45 ContentVideoView::ContentVideoView(
46 BrowserMediaPlayerManager
* manager
)
49 DCHECK(!g_content_video_view
);
50 j_content_video_view_
= CreateJavaObject();
51 g_content_video_view
= this;
52 CreatePowerSaveBlocker();
55 ContentVideoView::~ContentVideoView() {
56 DCHECK(g_content_video_view
);
57 JNIEnv
* env
= AttachCurrentThread();
58 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
59 if (!content_video_view
.is_null()) {
60 Java_ContentVideoView_destroyContentVideoView(env
,
61 content_video_view
.obj(), true);
62 j_content_video_view_
.reset();
64 g_content_video_view
= NULL
;
67 void ContentVideoView::OpenVideo() {
68 JNIEnv
* env
= AttachCurrentThread();
69 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
70 if (!content_video_view
.is_null()) {
71 CreatePowerSaveBlocker();
72 Java_ContentVideoView_openVideo(env
, content_video_view
.obj());
76 void ContentVideoView::OnMediaPlayerError(int error_type
) {
77 JNIEnv
* env
= AttachCurrentThread();
78 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
79 if (!content_video_view
.is_null()) {
80 power_save_blocker_
.reset();
81 Java_ContentVideoView_onMediaPlayerError(env
, content_video_view
.obj(),
86 void ContentVideoView::OnVideoSizeChanged(int width
, int height
) {
87 JNIEnv
* env
= AttachCurrentThread();
88 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
89 if (!content_video_view
.is_null()) {
90 Java_ContentVideoView_onVideoSizeChanged(env
, content_video_view
.obj(),
95 void ContentVideoView::OnBufferingUpdate(int percent
) {
96 JNIEnv
* env
= AttachCurrentThread();
97 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
98 if (!content_video_view
.is_null()) {
99 Java_ContentVideoView_onBufferingUpdate(env
, content_video_view
.obj(),
104 void ContentVideoView::OnPlaybackComplete() {
105 JNIEnv
* env
= AttachCurrentThread();
106 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
107 if (!content_video_view
.is_null()) {
108 power_save_blocker_
.reset();
109 Java_ContentVideoView_onPlaybackComplete(env
, content_video_view
.obj());
113 void ContentVideoView::OnExitFullscreen() {
114 JNIEnv
* env
= AttachCurrentThread();
115 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
116 if (!content_video_view
.is_null())
117 Java_ContentVideoView_onExitFullscreen(env
, content_video_view
.obj());
120 void ContentVideoView::UpdateMediaMetadata() {
121 JNIEnv
* env
= AttachCurrentThread();
122 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
123 if (content_video_view
.is_null())
126 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
127 if (player
&& player
->IsPlayerReady()) {
128 Java_ContentVideoView_onUpdateMediaMetadata(
129 env
, content_video_view
.obj(), player
->GetVideoWidth(),
130 player
->GetVideoHeight(),
131 static_cast<int>(player
->GetDuration().InMilliseconds()),
132 player
->CanPause(),player
->CanSeekForward(), player
->CanSeekBackward());
136 int ContentVideoView::GetVideoWidth(JNIEnv
*, jobject obj
) const {
137 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
138 return player
? player
->GetVideoWidth() : 0;
141 int ContentVideoView::GetVideoHeight(JNIEnv
*, jobject obj
) const {
142 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
143 return player
? player
->GetVideoHeight() : 0;
146 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv
*, jobject obj
) const {
147 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
148 return player
? player
->GetDuration().InMilliseconds() : -1;
151 int ContentVideoView::GetCurrentPosition(JNIEnv
*, jobject obj
) const {
152 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
153 return player
? player
->GetCurrentTime().InMilliseconds() : 0;
156 bool ContentVideoView::IsPlaying(JNIEnv
*, jobject obj
) {
157 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
158 return player
? player
->IsPlaying() : false;
161 void ContentVideoView::SeekTo(JNIEnv
*, jobject obj
, jint msec
) {
162 manager_
->FullscreenPlayerSeek(msec
);
165 void ContentVideoView::Play(JNIEnv
*, jobject obj
) {
166 CreatePowerSaveBlocker();
167 manager_
->FullscreenPlayerPlay();
170 void ContentVideoView::Pause(JNIEnv
*, jobject obj
) {
171 power_save_blocker_
.reset();
172 manager_
->FullscreenPlayerPause();
175 void ContentVideoView::ExitFullscreen(
176 JNIEnv
*, jobject
, jboolean release_media_player
) {
177 power_save_blocker_
.reset();
178 j_content_video_view_
.reset();
179 manager_
->ExitFullscreen(release_media_player
);
182 void ContentVideoView::SetSurface(JNIEnv
* env
, jobject obj
,
184 manager_
->SetVideoSurface(
185 gfx::ScopedJavaSurface::AcquireExternalSurface(surface
));
188 void ContentVideoView::RequestMediaMetadata(JNIEnv
* env
, jobject obj
) {
189 base::MessageLoop::current()->PostTask(
191 base::Bind(&ContentVideoView::UpdateMediaMetadata
,
192 weak_factory_
.GetWeakPtr()));
195 ScopedJavaLocalRef
<jobject
> ContentVideoView::GetJavaObject(JNIEnv
* env
) {
196 return j_content_video_view_
.get(env
);
199 gfx::NativeView
ContentVideoView::GetNativeView() {
200 JNIEnv
* env
= AttachCurrentThread();
201 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
202 if (content_video_view
.is_null())
205 return reinterpret_cast<gfx::NativeView
>(
206 Java_ContentVideoView_getNativeViewAndroid(env
,
207 content_video_view
.obj()));
211 JavaObjectWeakGlobalRef
ContentVideoView::CreateJavaObject() {
212 ContentViewCoreImpl
* content_view_core
= manager_
->GetContentViewCore();
213 JNIEnv
* env
= AttachCurrentThread();
214 bool legacyMode
= base::CommandLine::ForCurrentProcess()->HasSwitch(
215 switches::kDisableOverlayFullscreenVideoSubtitle
);
216 return JavaObjectWeakGlobalRef(
218 Java_ContentVideoView_createContentVideoView(
220 content_view_core
->GetContext().obj(),
221 reinterpret_cast<intptr_t>(this),
222 content_view_core
->GetContentVideoViewClient().obj(),
226 void ContentVideoView::CreatePowerSaveBlocker() {
227 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
228 switches::kDisableOverlayFullscreenVideoSubtitle
)) {
232 if (power_save_blocker_
) return;
234 power_save_blocker_
= PowerSaveBlocker::Create(
235 PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep
,
236 "Playing video").Pass();
237 static_cast<PowerSaveBlockerImpl
*>(power_save_blocker_
.get())->
238 InitDisplaySleepBlocker(GetNativeView());
240 } // namespace content