Home | History | Annotate | Download | only in android
      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 
     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 
     35 bool ContentVideoView::RegisterContentVideoView(JNIEnv* env) {
     36   return RegisterNativesImpl(env);
     37 }
     38 
     39 bool ContentVideoView::HasContentVideoView() {
     40   return g_content_video_view;
     41 }
     42 
     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 
     57 ContentVideoView::~ContentVideoView() {
     58   DCHECK(g_content_video_view);
     59   DestroyContentVideoView(true);
     60   g_content_video_view = NULL;
     61 }
     62 
     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 
     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 
     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 
     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 
    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 
    109 void ContentVideoView::OnExitFullscreen() {
    110   DestroyContentVideoView(false);
    111 }
    112 
    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 
    120 int ContentVideoView::GetVideoWidth(JNIEnv*, jobject obj) const {
    121   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
    122   return player ? player->GetVideoWidth() : 0;
    123 }
    124 
    125 int ContentVideoView::GetVideoHeight(JNIEnv*, jobject obj) const {
    126   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
    127   return player ? player->GetVideoHeight() : 0;
    128 }
    129 
    130 int ContentVideoView::GetDurationInMilliSeconds(JNIEnv*, jobject obj) const {
    131   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
    132   return player ? player->GetDuration().InMilliseconds() : -1;
    133 }
    134 
    135 int ContentVideoView::GetCurrentPosition(JNIEnv*, jobject obj) const {
    136   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
    137   return player ? player->GetCurrentTime().InMilliseconds() : 0;
    138 }
    139 
    140 bool ContentVideoView::IsPlaying(JNIEnv*, jobject obj) {
    141   media::MediaPlayerAndroid* player = manager_->GetFullscreenPlayer();
    142   return player ? player->IsPlaying() : false;
    143 }
    144 
    145 void ContentVideoView::SeekTo(JNIEnv*, jobject obj, jint msec) {
    146   manager_->FullscreenPlayerSeek(msec);
    147 }
    148 
    149 void ContentVideoView::Play(JNIEnv*, jobject obj) {
    150   CreatePowerSaveBlocker();
    151   manager_->FullscreenPlayerPlay();
    152 }
    153 
    154 void ContentVideoView::Pause(JNIEnv*, jobject obj) {
    155   power_save_blocker_.reset();
    156   manager_->FullscreenPlayerPause();
    157 }
    158 
    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 
    166 void ContentVideoView::SetSurface(JNIEnv* env, jobject obj,
    167                                   jobject surface) {
    168   manager_->SetVideoSurface(
    169       gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
    170 }
    171 
    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 
    181 ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
    182   return j_content_video_view_.get(env);
    183 }
    184 
    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 
    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 
    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