Commit aaf394b2 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Video Tutorials : Added metrics

This CL adds metrics for the video player, which includes user clicks
on various buttons, video latency, and various video playback states.
Some more metrics will be added in the next CL.

Bug: 1117155
Change-Id: I6ef8a515dfff43c66ca2197cf8db087b058db236
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2434096Reviewed-by: default avatarMark Pearson <mpearson@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812565}
parent a203a548
......@@ -58,6 +58,12 @@ public class VideoPlayerActivity extends Activity {
return Pair.create(webContents, contentView);
}
@Override
public void onBackPressed() {
if (mCoordinator.onBackPressed()) return;
super.onBackPressed();
}
@Override
protected void onDestroy() {
mCoordinator.destroy();
......
......@@ -20,6 +20,9 @@ public interface VideoPlayerCoordinator {
/** @return The Android {@link View} representing this widget. */
View getView();
/** To be called when the back button is pressed. */
boolean onBackPressed();
/** Tears down this coordinator. */
void destroy();
}
......@@ -71,6 +71,7 @@ if (is_android) {
"android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediator.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerProperties.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerView.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/metrics/VideoTutorialMetrics.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerCoordinatorImpl.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java",
"android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerProperties.java",
......
// Copyright 2020 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.
package org.chromium.chrome.browser.video_tutorials.metrics;
import androidx.annotation.IntDef;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.video_tutorials.FeatureType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Responsible for collecting metrics associated with video tutorials.
*/
public class VideoTutorialMetrics {
// Please treat this list as append only and keep it in sync with
// VideoTutorials.WatchState in enums.xml.
@IntDef({WatchState.STARTED, WatchState.COMPLETED, WatchState.PAUSED, WatchState.RESUMED})
@Retention(RetentionPolicy.SOURCE)
public @interface WatchState {
int STARTED = 0;
int COMPLETED = 1;
int PAUSED = 2;
int RESUMED = 3;
int NUM_ENTRIES = 4;
}
// Please treat this list as append only and keep it in sync with
// VideoTutorials.UserAction in enums.xml.
@IntDef({UserAction.CHANGE_LANGUAGE, UserAction.WATCH_NEXT_VIDEO, UserAction.TRY_NOW,
UserAction.SHARE, UserAction.CLOSE, UserAction.BACK_PRESS_WHEN_SHOWING_VIDEO_PLAYER})
@Retention(RetentionPolicy.SOURCE)
public @interface UserAction {
int CHANGE_LANGUAGE = 0;
int WATCH_NEXT_VIDEO = 1;
int TRY_NOW = 2;
int SHARE = 3;
int CLOSE = 4;
int BACK_PRESS_WHEN_SHOWING_VIDEO_PLAYER = 5;
int NUM_ENTRIES = 6;
}
/** Called to record various user actions on the video player. */
public static void recordUserAction(@FeatureType int feature, @UserAction int action) {
String histogramSuffix = histogramSuffixFromFeatureType(feature);
RecordHistogram.recordEnumeratedHistogram(
"VideoTutorials." + histogramSuffix + ".Player.UserAction", action,
UserAction.NUM_ENTRIES);
}
public static void recordVideoLoadTimeLatency(long videoLoadTime) {
RecordHistogram.recordMediumTimesHistogram(
"VideoTutorials.Player.LoadTimeLatency", videoLoadTime);
}
public static void recordWatchStateUpdate(@FeatureType int feature, @WatchState int state) {
String histogramSuffix = histogramSuffixFromFeatureType(feature);
RecordHistogram.recordEnumeratedHistogram(
"VideoTutorials." + histogramSuffix + ".Player.Progress", state,
FeatureType.MAX_VALUE);
}
private static String histogramSuffixFromFeatureType(@FeatureType int feature) {
switch (feature) {
case FeatureType.DOWNLOAD:
return "Download";
case FeatureType.SEARCH:
return "Search";
default:
return "Unknown";
}
}
}
......@@ -69,6 +69,12 @@ public class VideoPlayerCoordinatorImpl implements VideoPlayerCoordinator {
return mView.getView();
}
@Override
public boolean onBackPressed() {
if (mMediator.handleBackPressed()) return true;
return false;
}
@Override
public void destroy() {
mMediaSessionObserver.stopObserving();
......
......@@ -14,6 +14,9 @@ import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialUtils;
import org.chromium.chrome.browser.video_tutorials.languages.LanguagePickerCoordinator;
import org.chromium.chrome.browser.video_tutorials.metrics.VideoTutorialMetrics;
import org.chromium.chrome.browser.video_tutorials.metrics.VideoTutorialMetrics.UserAction;
import org.chromium.chrome.browser.video_tutorials.metrics.VideoTutorialMetrics.WatchState;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -30,6 +33,7 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
private final WebContents mWebContents;
private Tutorial mTutorial;
private final Runnable mCloseCallback;
private long mVideoStartTime;
/** Constructor. */
public VideoPlayerMediator(Context context, PropertyModel model,
......@@ -49,7 +53,20 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
mModel.set(VideoPlayerProperties.CALLBACK_CHANGE_LANGUAGE, this::changeLanguage);
mModel.set(VideoPlayerProperties.CALLBACK_TRY_NOW, this::tryNow);
mModel.set(VideoPlayerProperties.CALLBACK_SHARE, this::share);
mModel.set(VideoPlayerProperties.CALLBACK_CLOSE, closeCallback);
mModel.set(VideoPlayerProperties.CALLBACK_CLOSE, this::close);
}
boolean handleBackPressed() {
boolean isShowingLanguagePicker = mModel.get(VideoPlayerProperties.SHOW_LANGUAGE_PICKER);
boolean isShowingLoadingScreen = mModel.get(VideoPlayerProperties.SHOW_LOADING_SCREEN);
boolean isShowingVideoPlayer = !isShowingLanguagePicker && !isShowingLoadingScreen;
if (isShowingVideoPlayer) {
VideoTutorialMetrics.recordUserAction(
mTutorial.featureType, UserAction.BACK_PRESS_WHEN_SHOWING_VIDEO_PLAYER);
}
return true;
}
/**
......@@ -69,12 +86,21 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
@Override
public void onPlay() {
VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.RESUMED);
if (mVideoStartTime != 0) {
VideoTutorialMetrics.recordVideoLoadTimeLatency(
System.currentTimeMillis() - mVideoStartTime);
// Set it to zero to ignore subsequent pause/resume events.
mVideoStartTime = 0;
}
mModel.set(VideoPlayerProperties.SHOW_LOADING_SCREEN, false);
mModel.set(VideoPlayerProperties.SHOW_MEDIA_CONTROLS, false);
}
@Override
public void onPause() {
VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.PAUSED);
mModel.set(VideoPlayerProperties.SHOW_MEDIA_CONTROLS, true);
mModel.set(VideoPlayerProperties.SHOW_WATCH_NEXT, false);
mModel.set(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE, false);
......@@ -82,6 +108,7 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
@Override
public void onEnded() {
VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.COMPLETED);
mModel.set(VideoPlayerProperties.SHOW_MEDIA_CONTROLS, true);
mModel.set(VideoPlayerProperties.SHOW_WATCH_NEXT, true);
mModel.set(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE, true);
......@@ -95,6 +122,7 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
private void changeLanguage() {
mModel.set(VideoPlayerProperties.SHOW_LANGUAGE_PICKER, true);
mLanguagePicker.showLanguagePicker(this::onLanguageSelected, () -> {} /* closeCallback */);
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.CHANGE_LANGUAGE);
}
private void updateChangeLanguageButtonText() {
......@@ -114,11 +142,22 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
mVideoTutorialService.getTutorial(mTutorial.featureType, this::startVideo);
}
private void tryNow() {}
private void tryNow() {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.TRY_NOW);
}
private void share() {}
private void share() {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.SHARE);
}
private void close() {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.CLOSE);
mCloseCallback.run();
}
private void startVideo(Tutorial tutorial) {
VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.STARTED);
mVideoStartTime = System.currentTimeMillis();
LoadUrlParams loadUrlParams =
new LoadUrlParams(VideoPlayerURLBuilder.buildFromTutorial(tutorial));
loadUrlParams.setHasUserGesture(true);
......@@ -128,6 +167,7 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
}
private void onWatchNextClicked() {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.WATCH_NEXT_VIDEO);
VideoTutorialUtils.getNextTutorial(mVideoTutorialService, mTutorial, this::startVideo);
}
}
......@@ -73817,6 +73817,22 @@ Full version information for the fingerprint enum values:
<int value="3" label="Video thumbnail request completed"/>
</enum>
<enum name="VideoTutorials.UserAction">
<int value="0" label="Change language"/>
<int value="1" label="Watch next video"/>
<int value="2" label="Try now"/>
<int value="3" label="Share"/>
<int value="4" label="Close"/>
<int value="5" label="Back pressed when showing video player"/>
</enum>
<enum name="VideoTutorials.WatchState">
<int value="0" label="Started"/>
<int value="1" label="Completed"/>
<int value="2" label="Paused"/>
<int value="3" label="Resumed"/>
</enum>
<enum name="ViewFileType">
<int value="0" label="other"/>
<int value="1" label=".3ga"/>
......@@ -105,6 +105,7 @@ tools/metrics/histograms/histograms_xml/uma/histograms.xml
tools/metrics/histograms/histograms_xml/update_engine/histograms.xml
tools/metrics/histograms/histograms_xml/v8/histograms.xml
tools/metrics/histograms/histograms_xml/variations/histograms.xml
tools/metrics/histograms/histograms_xml/video_tutorials/histograms.xml
tools/metrics/histograms/histograms_xml/web_apk/histograms.xml
tools/metrics/histograms/histograms_xml/web_audio/histograms.xml
tools/metrics/histograms/histograms_xml/web_core/histograms.xml
......
<!--
Copyright 2020 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.
-->
<!--
This file is used to generate a comprehensive list of histograms
related to video tutorials along with a detailed description for each histogram.
For best practices on writing histogram descriptions, see
https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md
Please send CLs to chromium-metrics-reviews@google.com rather than to specific
individuals. These CLs will be automatically reassigned to a reviewer within
about 5 minutes. This approach helps the metrics team to load-balance incoming
reviews. Googlers can read more about this at go/gwsq-gerrit.
-->
<histogram-configuration>
<histograms>
<variants name="VideoTutorialFeatureTopic">
<variant name="Download"/>
<variant name="Search"/>
<variant name="Unknown"/>
</variants>
<histogram name="VideoTutorials.Player.LoadTimeLatency" units="ms"
expires_after="2021-02-01">
<owner>shaktisahu@chromium.org</owner>
<owner>chrome-upboarding-eng@google.com</owner>
<summary>
Records the latency in bringing up the video player for video tutorials.
Measures the time difference between user clicking on a video to the time
when it actually starts playing.
</summary>
</histogram>
<histogram name="VideoTutorials.{Feature}.Player.Progress"
enum="VideoTutorials.WatchState" expires_after="2021-02-01">
<owner>shaktisahu@chromium.org</owner>
<owner>chrome-upboarding-eng@google.com</owner>
<summary>
Records video watch progress events such as play, pause, resume, completion,
failure etc. encountered during when watching video tutorial for the
{Feature} feature.
</summary>
<token key="Feature" variants="VideoTutorialFeatureTopic"/>
</histogram>
<histogram name="VideoTutorials.{Feature}.Player.UserAction"
enum="VideoTutorials.UserAction" expires_after="2021-02-01">
<owner>shaktisahu@chromium.org</owner>
<owner>chrome-upboarding-eng@google.com</owner>
<summary>
Records user actions on the video player UI, such as clicking on various
buttons, encountered when watching video tutorial for the {Feature} feature.
</summary>
<token key="Feature" variants="VideoTutorialFeatureTopic"/>
</histogram>
</histograms>
</histogram-configuration>
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