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
15 using base::android::AttachCurrentThread;
16 using base::android::CheckException;
17 using base::android::ScopedJavaGlobalRef;
18
19 namespace content {
20
21 namespace {
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;
25
26 } // namespace
27
GetSingletonJavaContentVideoView(JNIEnv * env,jclass)28 static 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
RegisterContentVideoView(JNIEnv * env)35 bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) {
36 return RegisterNativesImpl(env);
37 }
38
HasContentVideoView()39 bool ContentVideoView::HasContentVideoView() {
40 return g_content_video_view;
41 }
42
ContentVideoView(const ScopedJavaLocalRef<jobject> & context,const ScopedJavaLocalRef<jobject> & client,BrowserMediaPlayerManager * manager)43 ContentVideoView::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
~ContentVideoView()57 ContentVideoView::~ContentVideoView() {
58 DCHECK(g_content_video_view);
59 DestroyContentVideoView(true);
60 g_content_video_view = NULL;
61 }
62
OpenVideo()63 void 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
OnMediaPlayerError(int error_type)72 void 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
OnVideoSizeChanged(int width,int height)82 void 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
OnBufferingUpdate(int percent)91 void 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
OnPlaybackComplete()100 void 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
OnExitFullscreen()109 void ContentVideoView::OnExitFullscreen() {
110 DestroyContentVideoView(false);
111 }
112
UpdateMediaMetadata()113 void 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
GetVideoWidth(JNIEnv *,jobject obj) const120 int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
121 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
122 return player ? player->GetVideoWidth() : 0;
123 }
124
GetVideoHeight(JNIEnv *,jobject obj) const125 int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
126 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
127 return player ? player->GetVideoHeight() : 0;
128 }
129
GetDurationInMilliSeconds(JNIEnv *,jobject obj) const130 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
131 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
132 return player ? player->GetDuration().InMilliseconds() : -1;
133 }
134
GetCurrentPosition(JNIEnv *,jobject obj) const135 int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
136 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
137 return player ? player->GetCurrentTime().InMilliseconds() : 0;
138 }
139
IsPlaying(JNIEnv *,jobject obj)140 bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
141 media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
142 return player ? player->IsPlaying() : false;
143 }
144
SeekTo(JNIEnv *,jobject obj,jint msec)145 void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
146 manager_->FullscreenPlayerSeek(msec);
147 }
148
Play(JNIEnv *,jobject obj)149 void ContentVideoView::Play(JNIEnv*, jobject obj) {
150 CreatePowerSaveBlocker();
151 manager_->FullscreenPlayerPlay();
152 }
153
Pause(JNIEnv *,jobject obj)154 void ContentVideoView::Pause(JNIEnv*, jobject obj) {
155 power_save_blocker_.reset();
156 manager_->FullscreenPlayerPause();
157 }
158
ExitFullscreen(JNIEnv *,jobject,jboolean release_media_player)159 void 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
SetSurface(JNIEnv * env,jobject obj,jobject surface)166 void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
167 jobject surface) {
168 manager_->SetVideoSurface(
169 gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
170 }
171
UpdateMediaMetadata(JNIEnv * env,jobject obj)172 void 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
GetJavaObject(JNIEnv * env)181 ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
182 return j_content_video_view_.get(env);
183 }
184
GetNativeView()185 gfx::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
CreatePowerSaveBlocker()197 void 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
DestroyContentVideoView(bool native_view_destroyed)207 void 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