blob: 3e0d874cf137910a1f61d0df0868685e8070bd07 [file] [log] [blame]
// Copyright 2017 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.
import {FittingType} from './constants.js';
// Handles events specific to the PDF viewer and logs the corresponding metrics.
/**
* Records when the zoom mode is changed to fit a FittingType.
* @param {FittingType} fittingType the new FittingType.
*/
export function recordFitTo(fittingType) {
if (fittingType === FittingType.FIT_TO_PAGE) {
record(UserAction.FIT_TO_PAGE);
} else if (fittingType === FittingType.FIT_TO_WIDTH) {
record(UserAction.FIT_TO_WIDTH);
}
// There is no user action to do a fit-to-height, this only happens with
// the open param "view=FitV".
}
/**
* Records the given action to chrome.metricsPrivate.
* @param {UserAction} action
*/
export function record(action) {
if (!chrome.metricsPrivate) {
return;
}
if (!actionsMetric) {
actionsMetric = {
'metricName': 'PDF.Actions',
'type': chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LOG,
'min': 1,
'max': UserAction.NUMBER_OF_ACTIONS,
'buckets': UserAction.NUMBER_OF_ACTIONS + 1
};
}
chrome.metricsPrivate.recordValue(actionsMetric, action);
if (firstMap.has(action)) {
const firstAction = firstMap.get(action);
if (!firstActionRecorded.has(firstAction)) {
chrome.metricsPrivate.recordValue(actionsMetric, firstAction);
firstActionRecorded.add(firstAction);
}
}
}
export function resetForTesting() {
firstActionRecorded.clear();
actionsMetric = null;
}
/** @type {?chrome.metricsPrivate.MetricType} */
let actionsMetric = null;
/** @type {!Set<!UserAction>} */
const firstActionRecorded = new Set();
// Keep in sync with enums.xml.
// Do not change the numeric values or reuse them since these numbers are
// persisted to logs.
/**
* User Actions that can be recorded by calling record.
* The *_FIRST values are recorded automaticlly,
* eg. record(...ROTATE) will also record ROTATE_FIRST
* on the first instance.
* @enum {number}
*/
export const UserAction = {
// Recorded when the document is first loaded. This event serves as
// denominator to determine percentages of documents in which an action was
// taken as well as average number of each action per document.
DOCUMENT_OPENED: 0,
// Recorded when the document is rotated clockwise or counter-clockwise.
ROTATE_FIRST: 1,
ROTATE: 2,
FIT_TO_WIDTH_FIRST: 3,
FIT_TO_WIDTH: 4,
FIT_TO_PAGE_FIRST: 5,
FIT_TO_PAGE: 6,
// Recorded when a bookmark is followed.
FOLLOW_BOOKMARK_FIRST: 9,
FOLLOW_BOOKMARK: 10,
// Recorded when the page selection is used to navigate to another page.
PAGE_SELECTOR_NAVIGATE_FIRST: 11,
PAGE_SELECTOR_NAVIGATE: 12,
// Recorded when the user triggers a save of the document.
SAVE_FIRST: 13,
SAVE: 14,
// Recorded when the user triggers a save of the document and the document
// has been modified by annotations.
SAVE_WITH_ANNOTATION_FIRST: 15,
SAVE_WITH_ANNOTATION: 16,
PRINT_FIRST: 17,
PRINT: 18,
ENTER_ANNOTATION_MODE_FIRST: 19,
ENTER_ANNOTATION_MODE: 20,
EXIT_ANNOTATION_MODE_FIRST: 21,
EXIT_ANNOTATION_MODE: 22,
// Recorded when a pen stroke is made.
ANNOTATE_STROKE_TOOL_PEN_FIRST: 23,
ANNOTATE_STROKE_TOOL_PEN: 24,
// Recorded when an eraser stroke is made.
ANNOTATE_STROKE_TOOL_ERASER_FIRST: 25,
ANNOTATE_STROKE_TOOL_ERASER: 26,
// Recorded when a highlighter stroke is made.
ANNOTATE_STROKE_TOOL_HIGHLIGHTER_FIRST: 27,
ANNOTATE_STROKE_TOOL_HIGHLIGHTER: 28,
// Recorded when a stroke is made using touch.
ANNOTATE_STROKE_DEVICE_TOUCH_FIRST: 29,
ANNOTATE_STROKE_DEVICE_TOUCH: 30,
// Recorded when a stroke is made using mouse.
ANNOTATE_STROKE_DEVICE_MOUSE_FIRST: 31,
ANNOTATE_STROKE_DEVICE_MOUSE: 32,
// Recorded when a stroke is made using pen.
ANNOTATE_STROKE_DEVICE_PEN_FIRST: 33,
ANNOTATE_STROKE_DEVICE_PEN: 34,
// Recorded when two-up view mode is enabled.
TWO_UP_VIEW_ENABLE_FIRST: 35,
TWO_UP_VIEW_ENABLE: 36,
// Recorded when two-up view mode is disabled.
TWO_UP_VIEW_DISABLE_FIRST: 37,
TWO_UP_VIEW_DISABLE: 38,
// Recorded when zoom in button is clicked.
ZOOM_IN_FIRST: 39,
ZOOM_IN: 40,
// Recorded when zoom out button is clicked.
ZOOM_OUT_FIRST: 41,
ZOOM_OUT: 42,
// Recorded when the custom zoom input field is modified.
ZOOM_CUSTOM_FIRST: 43,
ZOOM_CUSTOM: 44,
// Recorded when a thumbnail is used for navigation.
THUMBNAIL_NAVIGATE_FIRST: 45,
THUMBNAIL_NAVIGATE: 46,
// Recorded when the user triggers a save of the document and the document
// has never been modified.
SAVE_ORIGINAL_ONLY_FIRST: 47,
SAVE_ORIGINAL_ONLY: 48,
// Recorded when the user triggers a save of the original document, even
// though the document has been modified.
SAVE_ORIGINAL_FIRST: 49,
SAVE_ORIGINAL: 50,
// Recorded when the user triggers a save of the edited document.
SAVE_EDITED_FIRST: 51,
SAVE_EDITED: 52,
// Recorded when the sidenav menu button is clicked.
TOGGLE_SIDENAV_FIRST: 53,
TOGGLE_SIDENAV: 54,
// Recorded when the thumbnails button in the sidenav is clicked.
SELECT_SIDENAV_THUMBNAILS_FIRST: 55,
SELECT_SIDENAV_THUMBNAILS: 56,
// Recorded when the outline button in the sidenav is clicked.
SELECT_SIDENAV_OUTLINE_FIRST: 57,
SELECT_SIDENAV_OUTLINE: 58,
// Recorded when the show/hide annotations overflow menu item is clicked.
TOGGLE_DISPLAY_ANNOTATIONS_FIRST: 59,
TOGGLE_DISPLAY_ANNOTATIONS: 60,
// Recorded when the present menu item is clicked.
PRESENT_FIRST: 61,
PRESENT: 62,
// Recorded when the document properties menu item is clicked.
PROPERTIES_FIRST: 63,
PROPERTIES: 64,
NUMBER_OF_ACTIONS: 65,
};
/** @return {!Map<!UserAction, !UserAction>} */
function createFirstMap() {
const entries = Object.entries(UserAction).sort((a, b) => a[1] - b[1]);
// Exclude the first and last entries (DOCUMENT_OPENED, and NUMBER_OF_ACTIONS)
// which don't have an equivalent "_FIRST" UserAction.
const entriesWithFirst = entries.slice(1, entries.length - 1);
const map = new Map();
for (let i = 0; i < entriesWithFirst.length; i += 2) {
map.set(entriesWithFirst[i + 1][1], entriesWithFirst[i][1]);
}
return map;
}
// Map from UserAction to the 'FIRST' action. These metrics are recorded
// by PDFMetrics.log the first time each corresponding action occurs.
/** @type {!Map<!UserAction, !UserAction>} */
const firstMap = createFirstMap();