blob: f057fe9e7345a01e57f62da81a6710a37ee7f766 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/android/content_video_view.h"
#include "base/metrics/histogram_macros.h"
#include "content/public/browser/web_contents.h"
#include "jni/ContentVideoView_jni.h"
using base::android::AttachCurrentThread;
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
namespace content {
namespace {
// There can only be one content video view at a time, this holds onto that
// singleton instance.
ContentVideoView* g_content_video_view = NULL;
} // namespace
static ScopedJavaLocalRef<jobject>
JNI_ContentVideoView_GetSingletonJavaContentVideoView(
JNIEnv* env,
const JavaParamRef<jclass>&) {
if (g_content_video_view)
return g_content_video_view->GetJavaObject(env);
else
return ScopedJavaLocalRef<jobject>();
}
ContentVideoView* ContentVideoView::GetInstance() {
return g_content_video_view;
}
ContentVideoView::ContentVideoView(Client* client,
WebContents* web_contents,
const JavaRef<jobject>& video_embedder,
const gfx::Size& video_natural_size)
: client_(client), weak_factory_(this) {
DCHECK(!g_content_video_view);
j_content_video_view_ =
CreateJavaObject(web_contents, video_embedder, video_natural_size);
g_content_video_view = this;
}
ContentVideoView::~ContentVideoView() {
DCHECK(g_content_video_view);
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
if (!content_video_view.is_null()) {
Java_ContentVideoView_destroyContentVideoView(env, content_video_view,
true);
j_content_video_view_.reset();
}
g_content_video_view = NULL;
}
void ContentVideoView::OpenVideo() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
if (!content_video_view.is_null()) {
Java_ContentVideoView_openVideo(env, content_video_view);
}
}
void ContentVideoView::OnMediaPlayerError(int error_type) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
if (!content_video_view.is_null()) {
Java_ContentVideoView_onMediaPlayerError(env, content_video_view,
error_type);
}
}
void ContentVideoView::OnVideoSizeChanged(int width, int height) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
if (!content_video_view.is_null()) {
Java_ContentVideoView_onVideoSizeChanged(env, content_video_view, width,
height);
}
}
void ContentVideoView::ExitFullscreen() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
bool release_media_player = false;
if (!content_video_view.is_null())
Java_ContentVideoView_exitFullscreen(env, content_video_view,
release_media_player);
}
ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
return j_content_video_view_.get(env);
}
void ContentVideoView::SetSurface(JNIEnv*,
const JavaParamRef<jobject>&,
const JavaParamRef<jobject>& surface) {
client_->SetVideoSurface(
gl::ScopedJavaSurface::AcquireExternalSurface(surface));
}
void ContentVideoView::DidExitFullscreen(JNIEnv*,
const JavaParamRef<jobject>&,
jboolean release_media_player) {
j_content_video_view_.reset();
client_->DidExitFullscreen(release_media_player);
}
void ContentVideoView::RecordFullscreenPlayback(JNIEnv*,
const JavaParamRef<jobject>&,
bool is_portrait_video,
bool is_orientation_portrait) {
UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.OrientationPortrait",
is_orientation_portrait);
UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.VideoPortrait",
is_portrait_video);
}
void ContentVideoView::RecordExitFullscreenPlayback(
JNIEnv*,
const JavaParamRef<jobject>&,
bool is_portrait_video,
long playback_duration_in_milliseconds_before_orientation_change,
long playback_duration_in_milliseconds_after_orientation_change) {
bool orientation_changed = (
playback_duration_in_milliseconds_after_orientation_change != 0);
if (is_portrait_video) {
UMA_HISTOGRAM_COUNTS(
"MobileFullscreenVideo.PortraitDuration",
playback_duration_in_milliseconds_before_orientation_change);
UMA_HISTOGRAM_COUNTS(
"MobileFullscreenVideo.PortraitRotation", orientation_changed);
if (orientation_changed) {
UMA_HISTOGRAM_COUNTS(
"MobileFullscreenVideo.DurationAfterPotraitRotation",
playback_duration_in_milliseconds_after_orientation_change);
}
} else {
UMA_HISTOGRAM_COUNTS(
"MobileFullscreenVideo.LandscapeDuration",
playback_duration_in_milliseconds_before_orientation_change);
UMA_HISTOGRAM_COUNTS(
"MobileFullscreenVideo.LandscapeRotation", orientation_changed);
}
}
JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject(
WebContents* web_contents,
const JavaRef<jobject>& j_content_video_view_embedder,
const gfx::Size& video_natural_size) {
JNIEnv* env = AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> j_web_contents =
web_contents->GetJavaWebContents();
if (j_web_contents.is_null())
return JavaObjectWeakGlobalRef(env, nullptr);
return JavaObjectWeakGlobalRef(
env, Java_ContentVideoView_createContentVideoView(
env, j_web_contents, j_content_video_view_embedder,
reinterpret_cast<intptr_t>(this), video_natural_size.width(),
video_natural_size.height())
.obj());
}
} // namespace content