Commit fe2d480f authored by Kuo Jen Wei's avatar Kuo Jen Wei Committed by Commit Bot

[CCA] Add intentResult dimension to GA capture event.

Bug: 1014829
Test: Verify capture event metrics is collected correctly under both
intent/non-intent mode.

Change-Id: I84833c4b6b58ddfe848434dcfdee0d26051b8e4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1863060
Commit-Queue: Kuo Jen Wei <inker@chromium.org>
Auto-Submit: Kuo Jen Wei <inker@chromium.org>
Reviewed-by: default avatarShik Chen <shik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706894}
parent a744331c
......@@ -89,15 +89,27 @@ cca.metrics.launchType_ = function(ackMigrate) {
.label(ackMigrate ? 'ack-migrate' : '');
};
/**
* Types of intent result dimension.
* @enum {string}
*/
cca.metrics.IntentResultType = {
NOT_INTENT: '',
CANCELED: 'canceled',
CONFIRMED: 'confirmed',
};
/**
* Returns event builder for the metrics type: capture.
* @param {?string} facingMode Camera facing-mode of the capture.
* @param {number} length Length of 1 minute buckets for captured video.
* @param {!{width: number, height: number}} resolution Capture resolution.
* @param {!cca.metrics.IntentResultType} intentResult
* @return {!analytics.EventBuilder}
* @private
*/
cca.metrics.captureType_ = function(facingMode, length, {width, height}) {
cca.metrics.captureType_ = function(
facingMode, length, {width, height}, intentResult) {
var condState = (states, cond = undefined, strict = undefined) => {
// Return the first existing state among the given states only if there is
// no gate condition or the condition is met.
......@@ -122,6 +134,7 @@ cca.metrics.captureType_ = function(facingMode, length, {width, height}) {
.dimen(9, condState(['tall']))
.dimen(10, `${width}x${height}`)
.dimen(11, condState(['_30fps', '_60fps'], 'video-mode', true))
.dimen(12, intentResult)
.value(length || 0);
};
......
......@@ -29,10 +29,10 @@ cca.views.CameraSuspendedError = class extends Error {
/**
* Creates the camera-view controller.
* @param {cca.models.ResultSaver} resultSaver
* @param {cca.device.DeviceInfoUpdater} infoUpdater
* @param {cca.device.PhotoResolPreferrer} photoPreferrer
* @param {cca.device.VideoConstraintsPreferrer} videoPreferrer
* @param {!cca.models.ResultSaver} resultSaver
* @param {!cca.device.DeviceInfoUpdater} infoUpdater
* @param {!cca.device.PhotoResolPreferrer} photoPreferrer
* @param {!cca.device.VideoConstraintsPreferrer} videoPreferrer
* @constructor
*/
cca.views.Camera = function(
......@@ -67,28 +67,13 @@ cca.views.Camera = function(
this.options_ =
new cca.views.camera.Options(infoUpdater, this.restart.bind(this));
const doSavePhoto = async (result, name) => {
cca.metrics.log(
cca.metrics.Type.CAPTURE, this.facingMode_, 0, result.resolution);
try {
await resultSaver.savePhoto(result.blob, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
};
/**
* @type {!cca.models.ResultSaver}
* @protected
*/
this.resultSaver_ = resultSaver;
const createVideoSaver = async () => resultSaver.startSaveVideo();
const doSaveVideo = async (result, name) => {
cca.metrics.log(
cca.metrics.Type.CAPTURE, this.facingMode_, result.duration,
result.resolution);
try {
await resultSaver.finishSaveVideo(result.videoSaver, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
};
/**
* Modes for the camera.
......@@ -97,7 +82,8 @@ cca.views.Camera = function(
*/
this.modes_ = new cca.views.camera.Modes(
this.defaultMode, photoPreferrer, videoPreferrer, this.restart.bind(this),
doSavePhoto, createVideoSaver, doSaveVideo);
this.doSavePhoto_.bind(this), createVideoSaver,
this.doSaveVideo_.bind(this));
/**
* @type {?string}
......@@ -227,6 +213,44 @@ cca.views.Camera.prototype.endTake_ = function() {
return Promise.resolve(this.take_);
};
/**
* Handles captured photo result.
* @param {!cca.views.camera.PhotoResult} result Captured photo result.
* @param {string} name Name of the photo result to be saved as.
* @return {!Promise} Promise for the operation.
* @protected
*/
cca.views.Camera.prototype.doSavePhoto_ = async function(result, name) {
cca.metrics.log(
cca.metrics.Type.CAPTURE, this.facingMode_, /* length= */ 0,
result.resolution, cca.metrics.IntentResultType.NOT_INTENT);
try {
await this.resultSaver_.savePhoto(result.blob, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
};
/**
* Handles captured video result.
* @param {!cca.views.camera.VideoResult} result Captured video result.
* @param {string} name Name of the video result to be saved as.
* @return {!Promise} Promise for the operation.
* @protected
*/
cca.views.Camera.prototype.doSaveVideo_ = async function(result, name) {
cca.metrics.log(
cca.metrics.Type.CAPTURE, this.facingMode_, result.duration,
result.resolution, cca.metrics.IntentResultType.NOT_INTENT);
try {
await this.resultSaver_.finishSaveVideo(result.videoSaver, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
};
/**
* @override
*/
......
......@@ -35,7 +35,6 @@ cca.views.CameraIntent = class extends cca.views.Camera {
constructor(intent, infoUpdater, photoPreferrer, videoPreferrer) {
const resultSaver = {
savePhoto: async (blob) => {
this.photoResult_ = blob;
if (intent.shouldDownScale) {
const image = await cca.util.blobToImage(blob);
const ratio = Math.sqrt(
......@@ -52,7 +51,7 @@ cca.views.CameraIntent = class extends cca.views.Camera {
return await cca.models.IntentVideoSaver.create(intent);
},
finishSaveVideo: async (video, savedName) => {
this.videoResult_ = await video.endWrite();
this.videoResultFile_ = await video.endWrite();
},
};
super(resultSaver, infoUpdater, photoPreferrer, videoPreferrer);
......@@ -64,17 +63,23 @@ cca.views.CameraIntent = class extends cca.views.Camera {
this.intent_ = intent;
/**
* @type {?Blob}
* @type {?cca.views.camera.PhotoResult}
* @private
*/
this.photoResult_ = null;
/**
* @type {?FileEntry}
* @type {?cca.views.camera.VideoResult}
* @private
*/
this.videoResult_ = null;
/**
* @type {?FileEntry}
* @private
*/
this.videoResultFile_ = null;
/**
* @type {!cca.views.camera.ReviewResult}
* @private
......@@ -82,12 +87,38 @@ cca.views.CameraIntent = class extends cca.views.Camera {
this.reviewResult_ = new cca.views.camera.ReviewResult();
}
/**
* @override
*/
async doSavePhoto_(result, name) {
this.photoResult_ = result;
try {
await this.resultSaver_.savePhoto(result.blob, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
}
/**
* @override
*/
async doSaveVideo_(result, name) {
this.videoResult_ = result;
try {
await this.resultSaver_.finishSaveVideo(result.videoSaver, name);
} catch (e) {
cca.toast.show('error_msg_save_file_failed');
throw e;
}
}
/**
* @override
*/
beginTake_() {
if (this.photoResult_ !== null) {
URL.revokeObjectURL(this.photoResult_);
URL.revokeObjectURL(this.photoResult_.blob);
}
this.photoResult_ = null;
this.videoResult_ = null;
......@@ -107,8 +138,14 @@ cca.views.CameraIntent = class extends cca.views.Camera {
await this.restart();
const confirmed = await (
this.photoResult_ !== null ?
this.reviewResult_.openPhoto(this.photoResult_) :
this.reviewResult_.openVideo(this.videoResult_));
this.reviewResult_.openPhoto(this.photoResult_.blob) :
this.reviewResult_.openVideo(this.videoResultFile_));
const result = this.photoResult_ || this.videoResult_;
cca.metrics.log(
cca.metrics.Type.CAPTURE, this.facingMode_, result.duration || 0,
result.resolution,
confirmed ? cca.metrics.IntentResultType.CONFIRMED :
cca.metrics.IntentResultType.CANCELED);
if (confirmed) {
await this.intent_.finish();
window.close();
......
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