Commit 3e6f2e5f authored by Kuo Jen Wei's avatar Kuo Jen Wei Committed by Commit Bot

CCA: Add metrics for tracking paused/resume and video snapshot.

Add 22th, 23th dimension to capture event with value 0/1 indicating
whether it's a video snapshot photo and whether the video ever paused
before its recording ended.

Bug: 1054314
Test: Test through all related user scenario, check the format of sent
out capture event.

Change-Id: Ic21a893b1e6dff29f0eaa8b73dfda4299e87f45c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2255922
Auto-Submit: Kuo Jen Wei <inker@chromium.org>
Reviewed-by: default avatarShik Chen <shik@chromium.org>
Commit-Queue: Kuo Jen Wei <inker@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781705}
parent 38b4d4f1
...@@ -140,16 +140,64 @@ export const ShutterType = { ...@@ -140,16 +140,64 @@ export const ShutterType = {
VOLUME_KEY: 'volume-key', VOLUME_KEY: 'volume-key',
}; };
/**
* Parameters of capture metrics event.
* @record
*/
export class CaptureEventParam {
constructor() {
/**
* @type {!Facing} Camera facing of the capture.
*/
this.facing;
/**
* @type {(number|undefined)} Length of 1 minute buckets for captured video.
*/
this.duration;
/**
* @type {!Resolution} Capture resolution.
*/
this.resolution;
/**
* @type {(IntentResultType|undefined)}
*/
this.intentResult;
/**
* @type {!ShutterType}
*/
this.shutterType;
/**
* Whether the event is for video snapshot.
* @type {(boolean|undefined)}
*/
this.isVideoSnapshot;
/**
* Whether the video have ever paused and resumed in the recording.
* @type {(boolean|undefined)}
*/
this.everPaused;
}
}
/** /**
* Sends capture type event. * Sends capture type event.
* @param {!Facing} facingMode Camera facing-mode of the capture. * @param {!CaptureEventParam} param
* @param {number} length Length of 1 minute buckets for captured video.
* @param {!Resolution} resolution Capture resolution.
* @param {!IntentResultType} intentResult
* @param {!ShutterType} shutterType
*/ */
function sendCaptureEvent( function sendCaptureEvent({
facingMode, length, resolution, intentResult, shutterType) { facing,
duration = 0,
resolution,
intentResult = IntentResultType.NOT_INTENT,
shutterType,
isVideoSnapshot = false,
everPaused = false,
}) {
/** /**
* @param {!Array<state.StateUnion>} states * @param {!Array<state.StateUnion>} states
* @param {state.StateUnion=} cond * @param {state.StateUnion=} cond
...@@ -171,8 +219,8 @@ function sendCaptureEvent( ...@@ -171,8 +219,8 @@ function sendCaptureEvent(
{ {
eventCategory: 'capture', eventCategory: 'capture',
eventAction: condState(Object.values(Mode)), eventAction: condState(Object.values(Mode)),
eventLabel: facingMode, eventLabel: facing,
eventValue: length || 0, eventValue: duration,
}, },
new Map([ new Map([
// Skips 3rd dimension for obsolete 'sound' state. // Skips 3rd dimension for obsolete 'sound' state.
...@@ -190,6 +238,8 @@ function sendCaptureEvent( ...@@ -190,6 +238,8 @@ function sendCaptureEvent(
[11, condState([State.FPS_30, State.FPS_60], Mode.VIDEO, true)], [11, condState([State.FPS_30, State.FPS_60], Mode.VIDEO, true)],
[12, intentResult], [12, intentResult],
[21, shutterType], [21, shutterType],
[22, isVideoSnapshot],
[23, everPaused],
])); ]));
} }
......
...@@ -360,13 +360,15 @@ export class Camera extends View { ...@@ -360,13 +360,15 @@ export class Camera extends View {
* @return {!Promise} Promise for the operation. * @return {!Promise} Promise for the operation.
* @protected * @protected
*/ */
async doSavePhoto_(result, name) { async doSavePhoto_({resolution, blob, isVideoSnapshot = false}, name) {
metrics.log( metrics.log(metrics.Type.CAPTURE, {
metrics.Type.CAPTURE, this.facingMode_, /* length= */ 0, facing: this.facingMode_,
result.resolution, metrics.IntentResultType.NOT_INTENT, resolution,
this.shutterType_); shutterType: this.shutterType_,
isVideoSnapshot,
});
try { try {
await this.resultSaver_.savePhoto(result.blob, name); await this.resultSaver_.savePhoto(blob, name);
} catch (e) { } catch (e) {
toast.show('error_msg_save_file_failed'); toast.show('error_msg_save_file_failed');
throw e; throw e;
...@@ -379,13 +381,16 @@ export class Camera extends View { ...@@ -379,13 +381,16 @@ export class Camera extends View {
* @return {!Promise} Promise for the operation. * @return {!Promise} Promise for the operation.
* @protected * @protected
*/ */
async doSaveVideo_(result) { async doSaveVideo_({resolution, duration, videoSaver, everPaused}) {
metrics.log( metrics.log(metrics.Type.CAPTURE, {
metrics.Type.CAPTURE, this.facingMode_, result.duration, facing: this.facingMode_,
result.resolution, metrics.IntentResultType.NOT_INTENT, duration,
this.shutterType_); resolution,
shutterType: this.shutterType_,
everPaused,
});
try { try {
await this.resultSaver_.finishSaveVideo(result.videoSaver); await this.resultSaver_.finishSaveVideo(videoSaver);
} catch (e) { } catch (e) {
toast.show('error_msg_save_file_failed'); toast.show('error_msg_save_file_failed');
throw e; throw e;
......
...@@ -38,6 +38,7 @@ import {RecordTime} from './recordtime.js'; ...@@ -38,6 +38,7 @@ import {RecordTime} from './recordtime.js';
* resolution: {width: number, height: number}, * resolution: {width: number, height: number},
* duration: number, * duration: number,
* videoSaver: !VideoSaver, * videoSaver: !VideoSaver,
* everPaused: boolean,
* }} * }}
*/ */
export let VideoResult; export let VideoResult;
...@@ -47,6 +48,7 @@ export let VideoResult; ...@@ -47,6 +48,7 @@ export let VideoResult;
* @typedef {{ * @typedef {{
* resolution: {width: number, height: number}, * resolution: {width: number, height: number},
* blob: !Blob, * blob: !Blob,
* isVideoSnapshot: (boolean|undefined),
* }} * }}
*/ */
export let PhotoResult; export let PhotoResult;
...@@ -687,6 +689,11 @@ export class Video extends ModeBase { ...@@ -687,6 +689,11 @@ export class Video extends ModeBase {
* @private * @private
*/ */
this.togglePaused_ = null; this.togglePaused_ = null;
/**
* Whether current recording ever paused/resumed before it ended.
*/
this.everPaused_ = false;
} }
/** /**
...@@ -700,7 +707,8 @@ export class Video extends ModeBase { ...@@ -700,7 +707,8 @@ export class Video extends ModeBase {
const {width, height} = await util.blobToImage(blob); const {width, height} = await util.blobToImage(blob);
const imageName = (new Filenamer()).newImageName(); const imageName = (new Filenamer()).newImageName();
await this.doSaveSnapshot_( await this.doSaveSnapshot_(
{resolution: {width, height}, blob}, imageName); {resolution: {width, height}, blob, isVideoSnapshot: true},
imageName);
}; };
this.snapshots_.push(doSnapshot); this.snapshots_.push(doSnapshot);
return this.snapshots_.flush(); return this.snapshots_.flush();
...@@ -714,6 +722,7 @@ export class Video extends ModeBase { ...@@ -714,6 +722,7 @@ export class Video extends ModeBase {
if (this.togglePaused_ !== null) { if (this.togglePaused_ !== null) {
return this.togglePaused_; return this.togglePaused_;
} }
this.everPaused_ = true;
const waitable = new WaitableEvent(); const waitable = new WaitableEvent();
this.togglePaused_ = waitable.wait(); this.togglePaused_ = waitable.wait();
...@@ -746,6 +755,7 @@ export class Video extends ModeBase { ...@@ -746,6 +755,7 @@ export class Video extends ModeBase {
this.snapshots_ = new AsyncJobQueue(); this.snapshots_ = new AsyncJobQueue();
this.togglePaused_ = null; this.togglePaused_ = null;
this.startSound_ = sound.play('#sound-rec-start'); this.startSound_ = sound.play('#sound-rec-start');
this.everPaused_ = false;
try { try {
await this.startSound_; await this.startSound_;
} finally { } finally {
...@@ -782,7 +792,8 @@ export class Video extends ModeBase { ...@@ -782,7 +792,8 @@ export class Video extends ModeBase {
const resolution = new Resolution(settings.width, settings.height); const resolution = new Resolution(settings.width, settings.height);
state.set(PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, true); state.set(PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, true);
try { try {
await this.doSaveVideo_({resolution, duration, videoSaver}); await this.doSaveVideo_(
{resolution, duration, videoSaver, everPaused: this.everPaused_});
state.set( state.set(
PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, false, PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, false,
{resolution, facing: this.facing_}); {resolution, facing: this.facing_});
......
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