// Copyright 2017 The Chromium Authors // 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 the new FittingType. */ export function recordFitTo(fittingType: 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 // the open param "view=FitV". } /** Records the given action to chrome.metricsPrivate. */ export function record(action: UserAction) { 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; } let actionsMetric: chrome.metricsPrivate.MetricType|null = null; const firstActionRecorded: Set = 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. */ export enum 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, } function createFirstMap(): Map { const entries = (Object.entries(UserAction) as Array<[string, number]>) .filter(x => Number.isInteger(x[1])) .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. const firstMap: Map = createFirstMap();