content_video_view.cc revision 4ad1aa43a48567659193a298fad74f55e00b3dd9
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(), player->GetDuration().InMilliseconds(),
131        player->CanPause(),player->CanSeekForward(), player->CanSeekBackward());
132  }
133}
134
135int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
136  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
137  return player ? player->GetVideoWidth() : 0;
138}
139
140int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
141  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
142  return player ? player->GetVideoHeight() : 0;
143}
144
145int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
146  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
147  return player ? player->GetDuration().InMilliseconds() : -1;
148}
149
150int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
151  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
152  return player ? player->GetCurrentTime().InMilliseconds() : 0;
153}
154
155bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
156  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
157  return player ? player->IsPlaying() : false;
158}
159
160void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
161  manager_->FullscreenPlayerSeek(msec);
162}
163
164void ContentVideoView::Play(JNIEnv*, jobject obj) {
165  CreatePowerSaveBlocker();
166  manager_->FullscreenPlayerPlay();
167}
168
169void ContentVideoView::Pause(JNIEnv*, jobject obj) {
170  power_save_blocker_.reset();
171  manager_->FullscreenPlayerPause();
172}
173
174void ContentVideoView::ExitFullscreen(
175    JNIEnv*, jobject, jboolean release_media_player) {
176  power_save_blocker_.reset();
177  j_content_video_view_.reset();
178  manager_->ExitFullscreen(release_media_player);
179}
180
181void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
182                                  jobject surface) {
183  manager_->SetVideoSurface(
184      gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
185}
186
187void ContentVideoView::RequestMediaMetadata(JNIEnv* env, jobject obj) {
188  base::MessageLoop::current()->PostTask(
189      FROM_HERE,
190      base::Bind(&ContentVideoView::UpdateMediaMetadata,
191                 weak_factory_.GetWeakPtr()));
192}
193
194ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
195  return j_content_video_view_.get(env);
196}
197
198gfx::NativeView ContentVideoView::GetNativeView() {
199  JNIEnv* env = AttachCurrentThread();
200  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
201  if (content_video_view.is_null())
202    return NULL;
203
204  return reinterpret_cast<gfx::NativeView>(
205      Java_ContentVideoView_getNativeViewAndroid(env,
206                                                 content_video_view.obj()));
207
208}
209
210JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject() {
211  ContentViewCoreImpl* content_view_core = manager_->GetContentViewCore();
212  JNIEnv* env = AttachCurrentThread();
213  bool legacyMode = CommandLine::ForCurrentProcess()->HasSwitch(
214      switches::kDisableOverlayFullscreenVideoSubtitle);
215  return JavaObjectWeakGlobalRef(
216      env,
217      Java_ContentVideoView_createContentVideoView(
218          env,
219          content_view_core->GetContext().obj(),
220          reinterpret_cast<intptr_t>(this),
221          content_view_core->GetContentVideoViewClient().obj(),
222          legacyMode).obj());
223}
224
225void ContentVideoView::CreatePowerSaveBlocker() {
226  if (power_save_blocker_) return;
227
228  power_save_blocker_ = PowerSaveBlocker::Create(
229      PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
230      "Playing video").Pass();
231  static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())->
232      InitDisplaySleepBlocker(GetNativeView());
233}
234}  // namespace content
235