Commit d81a8daf authored by qinmin's avatar qinmin Committed by Commit bot

Add UMA to study the effect of defaulting fullscreen video to landscape mode

Added UMAs for:
1) The % of fullscreen video that is opened in portrait mode
2) The % of the video is suited for portrait mode
3) How long does a video play before user rotate the screen to landscape mode
4) How long video plays after user rotate the screen to landscape mode
5) How long does a video play before user rotate to portrait mode
6) The % of a video that the user switched from portrait to landscape mode

BUG=326572

Review URL: https://codereview.chromium.org/297773004

Cr-Commit-Position: refs/heads/master@{#293045}
parent 95edbdf1
......@@ -7,16 +7,20 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/media/android/browser_media_player_manager.h"
#include "content/browser/power_save_blocker_impl.h"
#include "content/common/android/surface_texture_peer.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "jni/ContentVideoView_jni.h"
using base::android::AttachCurrentThread;
using base::android::CheckException;
using base::android::ScopedJavaGlobalRef;
using base::UserMetricsAction;
using content::RecordAction;
namespace content {
......@@ -117,6 +121,40 @@ void ContentVideoView::OnExitFullscreen() {
Java_ContentVideoView_onExitFullscreen(env, content_video_view.obj());
}
void ContentVideoView::RecordFullscreenPlayback(
JNIEnv*, 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*, 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);
}
}
void ContentVideoView::UpdateMediaMetadata() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
......@@ -237,4 +275,5 @@ void ContentVideoView::CreatePowerSaveBlocker() {
static_cast<PowerSaveBlockerImpl*>(power_save_blocker_.get())->
InitDisplaySleepBlocker(GetNativeView());
}
} // namespace content
......@@ -72,6 +72,14 @@ class ContentVideoView {
void OnPlaybackComplete();
void OnExitFullscreen();
// Functions called to record fullscreen playback UMA metrics.
void RecordFullscreenPlayback(
JNIEnv*, jobject, bool is_portrait_video, bool is_orientation_portrait);
void RecordExitFullscreenPlayback(
JNIEnv*, jobject, bool is_portrait_video,
long playback_duration_in_milliseconds_before_orientation_change,
long playback_duration_in_milliseconds_after_orientation_change);
// Return the corresponing ContentVideoView Java object if any.
base::android::ScopedJavaLocalRef<jobject> GetJavaObject(JNIEnv* env);
......
......@@ -9,7 +9,10 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.graphics.Point;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Surface;
......@@ -17,6 +20,7 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
......@@ -93,6 +97,12 @@ public class ContentVideoView extends FrameLayout
private final ContentVideoViewClient mClient;
private boolean mInitialOrientation;
private boolean mPossibleAccidentalChange;
private boolean mUmaRecorded;
private long mOrientationChangedTime;
private long mPlaybackStartTime;
private class VideoSurfaceView extends SurfaceView {
public VideoSurfaceView(Context context) {
......@@ -114,6 +124,23 @@ public class ContentVideoView extends FrameLayout
width = height * mVideoWidth / mVideoHeight;
}
}
if (mUmaRecorded) {
// If we have never switched orientation, record the orientation
// time.
if (mPlaybackStartTime == mOrientationChangedTime) {
if (isOrientationPortrait() != mInitialOrientation) {
mOrientationChangedTime = System.currentTimeMillis();
}
} else {
// if user quickly switched the orientation back and force, don't
// count it in UMA.
if (!mPossibleAccidentalChange &&
isOrientationPortrait() == mInitialOrientation &&
System.currentTimeMillis() - mOrientationChangedTime < 5000) {
mPossibleAccidentalChange = true;
}
}
}
setMeasuredDimension(width, height);
}
}
......@@ -150,6 +177,8 @@ public class ContentVideoView extends FrameLayout
mNativeContentVideoView = nativeContentVideoView;
mViewAndroid = new ViewAndroid(new WindowAndroid(context.getApplicationContext()), this);
mClient = client;
mUmaRecorded = false;
mPossibleAccidentalChange = false;
initResources(context);
mVideoSurfaceView = new VideoSurfaceView(context);
showContentVideoView();
......@@ -276,6 +305,21 @@ public class ContentVideoView extends FrameLayout
mProgressView.setVisibility(View.GONE);
mCurrentState = isPlaying() ? STATE_PLAYING : STATE_PAUSED;
onVideoSizeChanged(videoWidth, videoHeight);
if (mUmaRecorded) return;
try {
if (Settings.System.getInt(getContext().getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION) == 0) {
return;
}
} catch (Settings.SettingNotFoundException e) {
return;
}
mInitialOrientation = isOrientationPortrait();
mUmaRecorded = true;
mPlaybackStartTime = System.currentTimeMillis();
mOrientationChangedTime = mPlaybackStartTime;
nativeRecordFullscreenPlayback(
mNativeContentVideoView, videoHeight > videoWidth, mInitialOrientation);
}
@Override
......@@ -414,6 +458,17 @@ public class ContentVideoView extends FrameLayout
public void exitFullscreen(boolean relaseMediaPlayer) {
destroyContentVideoView(false);
if (mNativeContentVideoView != 0) {
if (mUmaRecorded && !mPossibleAccidentalChange) {
long currentTime = System.currentTimeMillis();
long timeBeforeOrientationChange = mOrientationChangedTime - mPlaybackStartTime;
long timeAfterOrientationChange = currentTime - mOrientationChangedTime;
if (timeBeforeOrientationChange == 0) {
timeBeforeOrientationChange = timeAfterOrientationChange;
timeAfterOrientationChange = 0;
}
nativeRecordExitFullscreenPlayback(mNativeContentVideoView, mInitialOrientation,
timeBeforeOrientationChange, timeAfterOrientationChange);
}
nativeExitFullscreen(mNativeContentVideoView, relaseMediaPlayer);
mNativeContentVideoView = 0;
}
......@@ -477,6 +532,15 @@ public class ContentVideoView extends FrameLayout
return mViewAndroid.getNativePointer();
}
private boolean isOrientationPortrait() {
Context context = getContext();
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point outputSize = new Point(0, 0);
display.getSize(outputSize);
return outputSize.x <= outputSize.y;
}
private static native ContentVideoView nativeGetSingletonJavaContentVideoView();
private native void nativeExitFullscreen(long nativeContentVideoView,
boolean relaseMediaPlayer);
......@@ -490,4 +554,10 @@ public class ContentVideoView extends FrameLayout
private native void nativePlay(long nativeContentVideoView);
private native void nativeSeekTo(long nativeContentVideoView, int msec);
private native void nativeSetSurface(long nativeContentVideoView, Surface surface);
private native void nativeRecordFullscreenPlayback(
long nativeContentVideoView, boolean isVideoPortrait, boolean isOrientationPortrait);
private native void nativeRecordExitFullscreenPlayback(
long nativeContentVideoView, boolean isOrientationPortrait,
long playbackDurationBeforeOrientationChange,
long playbackDurationAfterOrientationChange);
}
......@@ -12459,6 +12459,76 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.DurationAfterPotraitRotation"
units="milliseconds">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records the duration that a fullscreen video is played after device
rotates from portrait to landscape mode for the first time, and before it
exits fullscreen. If there is no device rotation or if the video starts with
landscape mode, it is not recorded. If there are mutiple rotations between
portrait and landscape mode, only one record is emitted and it is equal to
the time period from the first rotation to the moment when the video exits
fullscreen.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.LandscapeDuration" units="milliseconds">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records the duration that a fullscreen video is played in landscape
mode. If a video starts playing in landscape mode, and then it is switched
back and forth between landscape and portrait mode, only the time period
before the first switch is accounted. If a video starts playing in portrait
mode, it is not recorded.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.LandscapeRotation" enum="BooleanEnabled">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records whether a fullscreen video is switched from landscape to
portrait mode at any point during playback.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.OrientationPortrait"
enum="BooleanEnabled">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records the device orientation when a video enters fullscreen. The
value is true if device orientation is portrait, or false otherwise. The
video doesn't necessarily needs to be in a playing state.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.PortraitDuration" units="milliseconds">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records the duration that a fullscreen video is played in portrait
mode. If a video starts playing in portrait mode, and then it is switched
back and forth between landscape and portrait mode, only the time period
before the first switch is accounted. If a video starts playing in landscape
mode, it is not recorded.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.PortraitRotation" enum="BooleanEnabled">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records whether a fullscreen video is switched from portrait to
landscape mode at any point during playback.
</summary>
</histogram>
<histogram name="MobileFullscreenVideo.VideoPortrait" enum="BooleanEnabled">
<owner>qinmin@chromium.org</owner>
<summary>
Android: Records whether a video has a larger height than width when it
enters the fullscreen mode.
</summary>
</histogram>
<histogram name="MobileStartup.MobileMultiWindowInstances">
<owner>dtrainor@chromium.org</owner>
<summary>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment