0

[PDF Ink Signatures] Add enter and exit annotation mode metrics

Add metrics for entering and exiting Ink2 annotation mode. Use an
existing MockMetricsPrivate class for testing.

Bug: 377488931
Change-Id: I8a2a67ce6d8cfd231190e662d3ecf4f9bf0b85a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6006335
Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Andy Phan <andyphan@chromium.org>
Reviewed-by: Alan Screen <awscreen@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1380768}
This commit is contained in:
Andy Phan
2024-11-09 02:13:31 +00:00
committed by Chromium LUCI CQ
parent 91a9bdbfda
commit 1a565efd3e
6 changed files with 66 additions and 34 deletions
chrome
tools/metrics/histograms/metadata/pdf

@ -220,7 +220,15 @@ export enum UserAction {
FIND_IN_PAGE_SEARCHIFIED_FIRST = 77,
FIND_IN_PAGE_SEARCHIFIED = 78,
NUMBER_OF_ACTIONS = 79,
// Recorded when the user enters Ink2 annotation mode.
ENTER_INK2_ANNOTATION_MODE_FIRST = 79,
ENTER_INK2_ANNOTATION_MODE = 80,
// Recorded when the user exits Ink2 annotation mode.
EXIT_INK2_ANNOTATION_MODE_FIRST = 81,
EXIT_INK2_ANNOTATION_MODE = 82,
NUMBER_OF_ACTIONS = 83,
}
function createFirstMap(): Map<UserAction, UserAction> {

@ -514,8 +514,8 @@ export class PdfViewerElement extends PdfViewerBaseElement {
if (this.pdfInk2Enabled_) {
if (!this.restoreAnnotationMode_) {
record(
annotationMode ? UserAction.ENTER_ANNOTATION_MODE :
UserAction.EXIT_ANNOTATION_MODE);
annotationMode ? UserAction.ENTER_INK2_ANNOTATION_MODE :
UserAction.EXIT_INK2_ANNOTATION_MODE);
}
this.pluginController_.setAnnotationMode(annotationMode);
if (!this.hasInitializedBrush_) {

@ -2,15 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {UserAction} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {assert} from 'chrome://resources/js/assert.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {isVisible, microtasksFinished} from 'chrome://webui-test/test_util.js';
import {setupTestMockPluginForInk} from './test_util.js';
import {setupMockMetricsPrivate, setupTestMockPluginForInk} from './test_util.js';
const viewer = document.body.querySelector('pdf-viewer')!;
const viewerToolbar = viewer.$.toolbar;
setupTestMockPluginForInk();
const mockMetricsPrivate = setupMockMetricsPrivate();
chrome.test.runTests([
// Test that PDF annotations and the new ink mode are enabled.
@ -23,25 +25,32 @@ chrome.test.runTests([
// Test that annotation mode can be toggled.
async function testToggleAnnotationMode() {
mockMetricsPrivate.reset();
chrome.test.assertFalse(viewerToolbar.annotationMode);
viewer.$.toolbar.toggleAnnotation();
await microtasksFinished();
chrome.test.assertTrue(viewerToolbar.annotationMode);
mockMetricsPrivate.assertCount(UserAction.ENTER_INK2_ANNOTATION_MODE, 1);
viewer.$.toolbar.toggleAnnotation();
await microtasksFinished();
chrome.test.assertFalse(viewerToolbar.annotationMode);
mockMetricsPrivate.assertCount(UserAction.EXIT_INK2_ANNOTATION_MODE, 1);
chrome.test.succeed();
},
// Test that the side panel is shown when annotation mode is enabled and
// hidden when annotation mode is disabled.
async function testSidePanelVisible() {
mockMetricsPrivate.reset();
chrome.test.assertFalse(viewerToolbar.annotationMode);
viewerToolbar.toggleAnnotation();
await microtasksFinished();
mockMetricsPrivate.assertCount(UserAction.ENTER_INK2_ANNOTATION_MODE, 1);
const sidePanel = viewer.shadowRoot!.querySelector('viewer-side-panel');
assert(sidePanel);
@ -51,6 +60,7 @@ chrome.test.runTests([
viewerToolbar.toggleAnnotation();
await microtasksFinished();
mockMetricsPrivate.assertCount(UserAction.EXIT_INK2_ANNOTATION_MODE, 1);
// The side panel should be hidden when annotation mode is disabled.
chrome.test.assertFalse(viewerToolbar.annotationMode);

@ -2,33 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {FittingType, record, recordFitTo, resetForTesting as resetMetricsForTesting, UserAction} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {FittingType, record, recordFitTo, UserAction} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {setupMockMetricsPrivate} from './test_util.js';
chrome.test.runTests(function() {
'use strict';
class MockMetricsPrivate {
actionCounter: Map<UserAction, number> = new Map();
recordValue(metric: chrome.metricsPrivate.MetricType, value: number) {
chrome.test.assertEq('PDF.Actions', metric.metricName);
chrome.test.assertEq(
chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LOG, metric.type);
chrome.test.assertEq(1, metric.min);
chrome.test.assertEq(UserAction.NUMBER_OF_ACTIONS, metric.max);
chrome.test.assertEq(UserAction.NUMBER_OF_ACTIONS + 1, metric.buckets);
const counter = this.actionCounter.get(value) || 0;
this.actionCounter.set(value, counter + 1);
}
}
return [
function testMetricsDocumentOpened() {
resetMetricsForTesting();
const mockMetricsPrivate = new MockMetricsPrivate();
chrome.metricsPrivate.recordValue =
mockMetricsPrivate.recordValue.bind(mockMetricsPrivate);
const mockMetricsPrivate = setupMockMetricsPrivate();
record(UserAction.DOCUMENT_OPENED);
@ -41,10 +24,7 @@ chrome.test.runTests(function() {
// Test that for every UserAction.<action> recorded an equivalent
// UserAction.<action>_FIRST is recorded only once.
function testMetricsFirstRecorded() {
resetMetricsForTesting();
const mockMetricsPrivate = new MockMetricsPrivate();
chrome.metricsPrivate.recordValue =
mockMetricsPrivate.recordValue.bind(mockMetricsPrivate);
const mockMetricsPrivate = setupMockMetricsPrivate();
const keys = (Object.keys(UserAction) as Array<keyof typeof UserAction>)
.filter(key => Number.isInteger(UserAction[key]))
@ -73,10 +53,7 @@ chrome.test.runTests(function() {
},
function testMetricsFitTo() {
resetMetricsForTesting();
const mockMetricsPrivate = new MockMetricsPrivate();
chrome.metricsPrivate.recordValue =
mockMetricsPrivate.recordValue.bind(mockMetricsPrivate);
const mockMetricsPrivate = setupMockMetricsPrivate();
record(UserAction.DOCUMENT_OPENED);
recordFitTo(FittingType.FIT_TO_HEIGHT);

@ -5,7 +5,7 @@
// Utilities that are used in multiple tests.
import type {Bookmark, DocumentDimensions, LayoutOptions, PdfViewerElement, ViewerToolbarElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {resetForTesting as resetMetricsForTesting, UserAction, Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
// <if expr="enable_pdf_ink2">
import type {AnnotationBrush, BeforeUnloadProxy, InkBrushSelectorElement, InkColorSelectorElement, InkSizeSelectorElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
import {AnnotationBrushType, BeforeUnloadProxyImpl, PluginController, PluginControllerEventType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
@ -268,6 +268,39 @@ export function createBookmarksForTest(): TestBookmarksElement {
return document.createElement('test-bookmarks');
}
export class MockMetricsPrivate {
actionCounter: Map<UserAction, number> = new Map();
recordValue(metric: chrome.metricsPrivate.MetricType, value: number) {
chrome.test.assertEq('PDF.Actions', metric.metricName);
chrome.test.assertEq(
chrome.metricsPrivate.MetricTypeType.HISTOGRAM_LOG, metric.type);
chrome.test.assertEq(1, metric.min);
chrome.test.assertEq(UserAction.NUMBER_OF_ACTIONS, metric.max);
chrome.test.assertEq(UserAction.NUMBER_OF_ACTIONS + 1, metric.buckets);
const counter = this.actionCounter.get(value) || 0;
this.actionCounter.set(value, counter + 1);
}
assertCount(action: UserAction, count: number) {
chrome.test.assertEq(count, this.actionCounter.get(action) || 0);
}
reset() {
resetMetricsForTesting();
this.actionCounter.clear();
}
}
export function setupMockMetricsPrivate(): MockMetricsPrivate {
resetMetricsForTesting();
const mockMetricsPrivate = new MockMetricsPrivate();
chrome.metricsPrivate.recordValue =
mockMetricsPrivate.recordValue.bind(mockMetricsPrivate);
return mockMetricsPrivate;
}
/**
* Checks if the PDF title matches the expected title.
* @param expectedTitle The expected title of the PDF.

@ -106,6 +106,10 @@ chromium-metrics-reviews@google.com.
<int value="76" label="CopySearchified"/>
<int value="77" label="FindInPageSearchifiedFirst"/>
<int value="78" label="FindInPageSearchified"/>
<int value="79" label="EnterInk2AnnotationModeFirst"/>
<int value="80" label="EnterInk2AnnotationMode"/>
<int value="81" label="ExitInk2AnnotationModeFirst"/>
<int value="82" label="ExitInk2AnnotationMode"/>
</enum>
<enum name="ChromePDFViewerLoadStatus">