Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / content / browser / android / content_video_view.cc
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
17 using base::android::AttachCurrentThread;
18 using base::android::CheckException;
19 using base::android::ScopedJavaGlobalRef;
20
21 namespace content {
22
23 namespace {
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;
27
28 }  // namespace
29
30 static 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
37 bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) {
38   return RegisterNativesImpl(env);
39 }
40
41 ContentVideoView* ContentVideoView::GetInstance() {
42   return g_content_video_view;
43 }
44
45 ContentVideoView::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
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();
63   }
64   g_content_video_view = NULL;
65 }
66
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());
73   }
74 }
75
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(),
82         error_type);
83   }
84 }
85
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(),
91         width, height);
92   }
93 }
94
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(),
100         percent);
101   }
102 }
103
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());
110   }
111 }
112
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());
118 }
119
120 void ContentVideoView::UpdateMediaMetadata() {
121   JNIEnv* env = AttachCurrentThread();
122   ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
123   if (content_video_view.is_null())
124     return;
125
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());
133   }
134 }
135
136 int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
137   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
138   return player ? player->GetVideoWidth() : 0;
139 }
140
141 int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
142   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
143   return player ? player->GetVideoHeight() : 0;
144 }
145
146 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
147   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
148   return player ? player->GetDuration().InMilliseconds() : -1;
149 }
150
151 int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
152   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
153   return player ? player->GetCurrentTime().InMilliseconds() : 0;
154 }
155
156 bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
157   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
158   return player ? player->IsPlaying() : false;
159 }
160
161 void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
162   manager_->FullscreenPlayerSeek(msec);
163 }
164
165 void ContentVideoView::Play(JNIEnv*, jobject obj) {
166   CreatePowerSaveBlocker();
167   manager_->FullscreenPlayerPlay();
168 }
169
170 void ContentVideoView::Pause(JNIEnv*, jobject obj) {
171   power_save_blocker_.reset();
172   manager_->FullscreenPlayerPause();
173 }
174
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);
180 }
181
182 void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
183                                   jobject surface) {
184   manager_->SetVideoSurface(
185       gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
186 }
187
188 void ContentVideoView::RequestMediaMetadata(JNIEnv* env, jobject obj) {
189   base::MessageLoop::current()->PostTask(
190       FROM_HERE,
191       base::Bind(&ContentVideoView::UpdateMediaMetadata,
192                  weak_factory_.GetWeakPtr()));
193 }
194
195 ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
196   return j_content_video_view_.get(env);
197 }
198
199 gfx::NativeView ContentVideoView::GetNativeView() {
200   JNIEnv* env = AttachCurrentThread();
201   ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
202   if (content_video_view.is_null())
203     return NULL;
204
205   return reinterpret_cast<gfx::NativeView>(
206       Java_ContentVideoView_getNativeViewAndroid(env,
207                                                  content_video_view.obj()));
208
209 }
210
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(
217       env,
218       Java_ContentVideoView_createContentVideoView(
219           env,
220           content_view_core->GetContext().obj(),
221           reinterpret_cast<intptr_t>(this),
222           content_view_core->GetContentVideoViewClient().obj(),
223           legacyMode).obj());
224 }
225
226 void ContentVideoView::CreatePowerSaveBlocker() {
227   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
228       switches::kEnableContentVideoViewPowerSaveBlocker)) {
229     // In fullscreen Clank reuses the power save blocker attached to the
230     // container view that was created for embedded video. The WebView cannot
231     // reuse that so we create a new blocker instead.
232     if (power_save_blocker_) return;
233
234     power_save_blocker_ = PowerSaveBlocker::Create(
235         PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
236         "Playing video").Pass();
237     static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())->
238         InitDisplaySleepBlocker(GetNativeView());
239   }
240 }
241 }  // namespace content