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 "content/browser/android/content_view_core_impl.h"
10 #include "content/browser/media/android/browser_media_player_manager.h"
11 #include "content/common/android/surface_texture_peer.h"
12 #include "content/public/common/content_switches.h"
13 #include "jni/ContentVideoView_jni.h"
15 using base::android::AttachCurrentThread
;
16 using base::android::CheckException
;
17 using base::android::ScopedJavaGlobalRef
;
22 // There can only be one content video view at a time, this holds onto that
23 // singleton instance.
24 ContentVideoView
* g_content_video_view
= NULL
;
28 static jobject
GetSingletonJavaContentVideoView(JNIEnv
*env
, jclass
) {
29 if (g_content_video_view
)
30 return g_content_video_view
->GetJavaObject(env
).Release();
35 bool ContentVideoView::RegisterContentVideoView(JNIEnv
* env
) {
36 return RegisterNativesImpl(env
);
39 ContentVideoView
* ContentVideoView::GetInstance() {
40 return g_content_video_view
;
43 ContentVideoView::ContentVideoView(
44 BrowserMediaPlayerManager
* manager
)
46 fullscreen_state_(ENTERED
) {
47 DCHECK(!g_content_video_view
);
48 j_content_video_view_
= CreateJavaObject();
49 g_content_video_view
= this;
52 ContentVideoView::~ContentVideoView() {
53 DCHECK(g_content_video_view
);
54 DestroyContentVideoView(true);
55 g_content_video_view
= NULL
;
58 void ContentVideoView::OpenVideo() {
59 JNIEnv
*env
= AttachCurrentThread();
60 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
61 if (!content_video_view
.is_null())
62 Java_ContentVideoView_openVideo(env
, content_video_view
.obj());
65 void ContentVideoView::OnMediaPlayerError(int error_type
) {
66 JNIEnv
*env
= AttachCurrentThread();
67 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
68 if (!content_video_view
.is_null()) {
69 Java_ContentVideoView_onMediaPlayerError(env
, content_video_view
.obj(),
74 void ContentVideoView::OnVideoSizeChanged(int width
, int height
) {
75 JNIEnv
*env
= AttachCurrentThread();
76 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
77 if (!content_video_view
.is_null()) {
78 Java_ContentVideoView_onVideoSizeChanged(env
, content_video_view
.obj(),
83 void ContentVideoView::OnBufferingUpdate(int percent
) {
84 JNIEnv
*env
= AttachCurrentThread();
85 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
86 if (!content_video_view
.is_null()) {
87 Java_ContentVideoView_onBufferingUpdate(env
, content_video_view
.obj(),
92 void ContentVideoView::OnPlaybackComplete() {
93 JNIEnv
*env
= AttachCurrentThread();
94 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
95 if (!content_video_view
.is_null())
96 Java_ContentVideoView_onPlaybackComplete(env
, content_video_view
.obj());
99 void ContentVideoView::OnExitFullscreen() {
100 JNIEnv
*env
= AttachCurrentThread();
101 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
102 if (!content_video_view
.is_null()) {
103 Java_ContentVideoView_onExitFullscreen(env
, content_video_view
.obj());
104 j_content_video_view_
.reset();
108 void ContentVideoView::UpdateMediaMetadata() {
109 JNIEnv
*env
= AttachCurrentThread();
110 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
111 if (!content_video_view
.is_null())
112 UpdateMediaMetadata(env
, content_video_view
.obj());
115 int ContentVideoView::GetVideoWidth(JNIEnv
*, jobject obj
) const {
116 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
117 return player
? player
->GetVideoWidth() : 0;
120 int ContentVideoView::GetVideoHeight(JNIEnv
*, jobject obj
) const {
121 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
122 return player
? player
->GetVideoHeight() : 0;
125 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv
*, jobject obj
) const {
126 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
127 return player
? player
->GetDuration().InMilliseconds() : -1;
130 int ContentVideoView::GetCurrentPosition(JNIEnv
*, jobject obj
) const {
131 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
132 return player
? player
->GetCurrentTime().InMilliseconds() : 0;
135 bool ContentVideoView::IsPlaying(JNIEnv
*, jobject obj
) {
136 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
137 return player
? player
->IsPlaying() : false;
140 void ContentVideoView::SeekTo(JNIEnv
*, jobject obj
, jint msec
) {
141 manager_
->FullscreenPlayerSeek(msec
);
144 void ContentVideoView::Play(JNIEnv
*, jobject obj
) {
145 manager_
->FullscreenPlayerPlay();
148 void ContentVideoView::Pause(JNIEnv
*, jobject obj
) {
149 manager_
->FullscreenPlayerPause();
152 void ContentVideoView::ExitFullscreen(
153 JNIEnv
*, jobject
, jboolean release_media_player
) {
154 if (fullscreen_state_
== SUSPENDED
)
156 j_content_video_view_
.reset();
157 manager_
->ExitFullscreen(release_media_player
);
160 void ContentVideoView::SuspendFullscreen() {
161 if (fullscreen_state_
!= ENTERED
)
163 fullscreen_state_
= SUSPENDED
;
164 DestroyContentVideoView(false);
165 manager_
->SuspendFullscreen();
168 void ContentVideoView::ResumeFullscreenIfSuspended() {
169 if (fullscreen_state_
!= SUSPENDED
)
171 JNIEnv
* env
= AttachCurrentThread();
172 DCHECK(!GetJavaObject(env
).obj());
173 fullscreen_state_
= RESUME
;
174 j_content_video_view_
= CreateJavaObject();
177 void ContentVideoView::SetSurface(JNIEnv
* env
, jobject obj
,
179 gfx::ScopedJavaSurface scoped_surface
=
180 gfx::ScopedJavaSurface::AcquireExternalSurface(surface
);
181 if (fullscreen_state_
== RESUME
) {
183 manager_
->ResumeFullscreen(scoped_surface
.Pass());
184 fullscreen_state_
= ENTERED
;
186 manager_
->SetVideoSurface(scoped_surface
.Pass());
190 void ContentVideoView::UpdateMediaMetadata(JNIEnv
* env
, jobject obj
) {
191 media::MediaPlayerAndroid
* player
= manager_
->GetFullscreenPlayer();
192 if (player
&& player
->IsPlayerReady())
193 Java_ContentVideoView_onUpdateMediaMetadata(
194 env
, obj
, player
->GetVideoWidth(), player
->GetVideoHeight(),
195 player
->GetDuration().InMilliseconds(), player
->CanPause(),
196 player
->CanSeekForward(), player
->CanSeekBackward());
199 ScopedJavaLocalRef
<jobject
> ContentVideoView::GetJavaObject(JNIEnv
* env
) {
200 return j_content_video_view_
.get(env
);
203 JavaObjectWeakGlobalRef
ContentVideoView::CreateJavaObject() {
204 ContentViewCoreImpl
* content_view_core
= manager_
->GetContentViewCore();
205 JNIEnv
*env
= AttachCurrentThread();
206 bool legacyMode
= !CommandLine::ForCurrentProcess()->HasSwitch(
207 switches::kEnableOverlayFullscreenVideoSubtitle
);
208 return JavaObjectWeakGlobalRef(
210 Java_ContentVideoView_createContentVideoView(
212 content_view_core
->GetContext().obj(),
213 reinterpret_cast<intptr_t>(this),
214 content_view_core
->GetContentVideoViewClient().obj(),
218 void ContentVideoView::DestroyContentVideoView(bool native_view_destroyed
) {
219 JNIEnv
*env
= AttachCurrentThread();
220 ScopedJavaLocalRef
<jobject
> content_video_view
= GetJavaObject(env
);
221 if (!content_video_view
.is_null()) {
222 Java_ContentVideoView_destroyContentVideoView(env
,
223 content_video_view
.obj(), native_view_destroyed
);
224 j_content_video_view_
.reset();
227 } // namespace content