| // 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, PdfOcrUserSelection} 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); |
| } |
| } |
| } |
| |
| /** |
| * Records when the user selects to turn on or off PDF OCR. |
| * @param userSelection the new UserSelection. |
| */ |
| export function recordPdfOcrUserSelection(pdfOcrAlwaysActive: boolean) { |
| // Need to divide Object.keys().length by 2 to get the enum size due to enum |
| // reverse mapping in TypeScript. |
| const enumSize = Object.keys(PdfOcrUserSelection).length / 2; |
| const enumValue = pdfOcrAlwaysActive ? |
| PdfOcrUserSelection.TURN_ON_ALWAYS_FROM_MORE_ACTIONS : |
| PdfOcrUserSelection.TURN_OFF_FROM_MORE_ACTIONS; |
| recordEnumeration('Accessibility.PdfOcr.UserSelection', enumValue, enumSize); |
| } |
| |
| /** Records the given enumeration to chrome.metricsPrivate. */ |
| export function recordEnumeration( |
| enumKey: string, enumValue: number, enumSize: number) { |
| if (!chrome.metricsPrivate) { |
| return; |
| } |
| chrome.metricsPrivate.recordEnumerationValue(enumKey, enumValue, enumSize); |
| } |
| |
| export function resetForTesting() { |
| firstActionRecorded.clear(); |
| actionsMetric = null; |
| } |
| |
| let actionsMetric: chrome.metricsPrivate.MetricType|null = null; |
| const firstActionRecorded: Set<UserAction> = new Set(); |
| |
| /** |
| * Keep in sync with the values for enum ChromePDFViewerActions in |
| * tools/metrics/histograms/metadata/pdf/enums.xml. |
| * These values are persisted to logs. Entries should not be renumbered, removed |
| * or reused. |
| * |
| * 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, |
| |
| // Recorded when the attachment button in the sidenav is clicked. |
| SELECT_SIDENAV_ATTACHMENT_FIRST = 65, |
| SELECT_SIDENAV_ATTACHMENT = 66, |
| |
| NUMBER_OF_ACTIONS = 67, |
| } |
| |
| function createFirstMap(): Map<UserAction, UserAction> { |
| 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<UserAction, UserAction> = createFirstMap(); |