content_video_view.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/android/content_video_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/browser/media/android/browser_media_player_manager.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/android/surface_texture_peer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jni/ContentVideoView_jni.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::CheckException;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ScopedJavaGlobalRef;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// There can only be one content video view at a time, this holds onto that
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// singleton instance.
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ContentVideoView* g_content_video_view = NULL;
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static jobject GetSingletonJavaContentVideoView(JNIEnv*env, jclass) {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_content_video_view)
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return g_content_video_view->GetJavaObject(env).Release();
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  else
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NULL;
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RegisterNativesImpl(env);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ContentVideoView::HasContentVideoView() {
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return g_content_video_view;
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ContentVideoView::ContentVideoView(
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ScopedJavaLocalRef<jobject>& context,
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ScopedJavaLocalRef<jobject>& client,
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    BrowserMediaPlayerManager* manager)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : manager_(manager) {
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!g_content_video_view);
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  j_content_video_view_ = JavaObjectWeakGlobalRef(env,
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Java_ContentVideoView_createContentVideoView(env, context.obj(),
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          reinterpret_cast<int>(this), client.obj()).obj());
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_content_video_view = this;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentVideoView::~ContentVideoView() {
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(g_content_video_view);
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyContentVideoView(true);
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_content_video_view = NULL;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ContentVideoView::OpenVideo() {
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null())
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_openVideo(env, content_video_view.obj());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::OnMediaPlayerError(int error_type) {
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null()) {
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_onMediaPlayerError(env, content_video_view.obj(),
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        error_type);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::OnVideoSizeChanged(int width, int height) {
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null()) {
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_onVideoSizeChanged(env, content_video_view.obj(),
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        width, height);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::OnBufferingUpdate(int percent) {
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null()) {
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_onBufferingUpdate(env, content_video_view.obj(),
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        percent);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::OnPlaybackComplete() {
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null())
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_onPlaybackComplete(env, content_video_view.obj());
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ContentVideoView::OnExitFullscreen() {
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DestroyContentVideoView(false);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::UpdateMediaMetadata() {
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!content_video_view.is_null())
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UpdateMediaMetadata(env, content_video_view.obj());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return player ? player->GetVideoWidth() : 0;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return player ? player->GetVideoHeight() : 0;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return player ? player->GetDuration().InMilliseconds() : -1;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return player ? player->GetCurrentTime().InMilliseconds() : 0;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return player ? player->IsPlaying() : false;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_->FullscreenPlayerSeek(msec);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::Play(JNIEnv*, jobject obj) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_->FullscreenPlayerPlay();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::Pause(JNIEnv*, jobject obj) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_->FullscreenPlayerPause();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::ExitFullscreen(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv*, jobject, jboolean release_media_player) {
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  j_content_video_view_.reset();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_->ExitFullscreen(release_media_player);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  jobject surface) {
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manager_->SetVideoSurface(
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContentVideoView::UpdateMediaMetadata(JNIEnv* env, jobject obj) {
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (player && player->IsPlayerReady())
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Java_ContentVideoView_onUpdateMediaMetadata(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        env, obj, player->GetVideoWidth(), player->GetVideoHeight(),
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        player->GetDuration().InMilliseconds(), player->CanPause(),
168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        player->CanSeekForward(), player->CanSeekBackward());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return j_content_video_view_.get(env);
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ContentVideoView::DestroyContentVideoView(bool native_view_destroyed) {
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  JNIEnv *env = AttachCurrentThread();
177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!content_video_view.is_null()) {
179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Java_ContentVideoView_destroyContentVideoView(env,
180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        content_video_view.obj(), native_view_destroyed);
181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    j_content_video_view_.reset();
182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
185