content_video_view.cc revision 010d83a9304c5a91596085d917d248abff47903a
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
17using base::android::AttachCurrentThread;
18using base::android::CheckException;
19using base::android::ScopedJavaGlobalRef;
20
21namespace content {
22
23namespace {
24// There can only be one content video view at a time, this holds onto that
25// singleton instance.
26ContentVideoView* g_content_video_view = NULL;
27
28}  // namespace
29
30static 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
37bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) {
38  return RegisterNativesImpl(env);
39}
40
41ContentVideoView* ContentVideoView::GetInstance() {
42  return g_content_video_view;
43}
44
45ContentVideoView::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
55ContentVideoView::~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
67void 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
76void 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
86void 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
95void 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
104void 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
113void 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
120void 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
136int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
137  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
138  return player ? player->GetVideoWidth() : 0;
139}
140
141int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
142  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
143  return player ? player->GetVideoHeight() : 0;
144}
145
146int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
147  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
148  return player ? player->GetDuration().InMilliseconds() : -1;
149}
150
151int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
152  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
153  return player ? player->GetCurrentTime().InMilliseconds() : 0;
154}
155
156bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
157  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
158  return player ? player->IsPlaying() : false;
159}
160
161void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
162  manager_->FullscreenPlayerSeek(msec);
163}
164
165void ContentVideoView::Play(JNIEnv*, jobject obj) {
166  CreatePowerSaveBlocker();
167  manager_->FullscreenPlayerPlay();
168}
169
170void ContentVideoView::Pause(JNIEnv*, jobject obj) {
171  power_save_blocker_.reset();
172  manager_->FullscreenPlayerPause();
173}
174
175void 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
182void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
183                                  jobject surface) {
184  manager_->SetVideoSurface(
185      gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
186}
187
188void 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
195ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
196  return j_content_video_view_.get(env);
197}
198
199gfx::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
211JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject() {
212  ContentViewCoreImpl* content_view_core = manager_->GetContentViewCore();
213  JNIEnv* env = AttachCurrentThread();
214  bool legacyMode = 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
226void ContentVideoView::CreatePowerSaveBlocker() {
227  if (!CommandLine::ForCurrentProcess()->HasSwitch(
228      switches::kDisableOverlayFullscreenVideoSubtitle)) {
229    return;
230  }
231
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}  // namespace content
241