Skip to content

Commit

Permalink
[Page Zoom] Add UMA histograms
Browse files Browse the repository at this point in the history
* Enabled state of page zoom option on app menu
* When the page zoom option is opened from the app menu
* When the zoom level is changed from the app menu slider
* The zoom level value at slider dismissal when changed, in buckets
of 5% in the range from min to max zoom value, currently 50% to 300%.
* When the default zoom level is changed from the settings
* The default zoom level value at settings closure when changed, in
buckets of 5% in the range from min to max zoom value, currently 50%
to 300%.


Bug: 1232536
Change-Id: I8e00dae78b202cc7681af84972981c06ded99180
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3995858
Reviewed-by: Evan Liu <evliu@google.com>
Reviewed-by: Mark Schillaci <mschillaci@google.com>
Commit-Queue: Amanda Lin Dietz <aldietz@google.com>
Cr-Commit-Position: refs/heads/main@{#1067679}
  • Loading branch information
aldietz authored and Chromium LUCI CQ committed Nov 4, 2022
1 parent b9891ca commit 88a3ef8
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 14 deletions.
1 change: 1 addition & 0 deletions components/browser_ui/accessibility/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ android_library("java") {
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomMediator.java",
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomPreference.java",
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomProperties.java",
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomUma.java",
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomUtils.java",
"java/src/org/chromium/components/browser_ui/accessibility/PageZoomViewBinder.java",
"java/src/org/chromium/components/browser_ui/accessibility/TextScalePreference.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class AccessibilitySettings
private AccessibilitySettingsDelegate mDelegate;
private BooleanPreferenceDelegate mReaderForAccessibilityDelegate;
private BooleanPreferenceDelegate mAccessibilityTabSwitcherDelegate;
private double mPageZoomLatestDefaultZoomPrefValue;

private FontSizePrefs mFontSizePrefs;
private FontSizePrefsObserver mFontSizePrefsObserver = new FontSizePrefsObserver() {
Expand Down Expand Up @@ -143,6 +144,14 @@ public void onStop() {
mFontSizePrefs.recordUserFontPrefChange();
mRecordFontSizeChangeOnStop = false;
}

// Ensure that the user has set a default zoom value during this session.
if (mPageZoomLatestDefaultZoomPrefValue != 0.0) {
PageZoomUma.logSettingsDefaultZoomLevelChangedHistogram();
PageZoomUma.logSettingsDefaultZoomLevelValueHistogram(
mPageZoomLatestDefaultZoomPrefValue);
}

super.onStop();
}

Expand All @@ -158,6 +167,8 @@ public boolean onPreferenceChange(Preference preference, Object newValue) {
mReaderForAccessibilityDelegate.setEnabled((Boolean) newValue);
}
} else if (PREF_PAGE_ZOOM_DEFAULT_ZOOM.equals(preference.getKey())) {
mPageZoomLatestDefaultZoomPrefValue =
PageZoomUtils.convertSeekBarValueToZoomLevel((Integer) newValue);
PageZoomUtils.setDefaultZoomBySeekBarValue(
mDelegate.getBrowserContextHandle(), (Integer) newValue);
} else if (PREF_PAGE_ZOOM_ALWAYS_SHOW.equals(preference.getKey())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public static boolean shouldShowMenuItem() {
* @param webContents WebContents that this zoom UI will control.
*/
public void show(WebContents webContents) {
PageZoomUma.logAppMenuSliderOpenedHistogram();

// If inflating for the first time or showing from hidden, start animation
if (mView == null) {
// If the view has not been created, lazily inflate from the view stub.
Expand Down Expand Up @@ -125,6 +127,13 @@ public void hide() {
Animation animation = getOutAnimation();
mView.startAnimation(animation);
mView.setVisibility(View.GONE);

// Ensure that the user has set a zoom value during this session.
double zoomValue = mMediator.latestZoomValue();
if (zoomValue != 0.0) {
PageZoomUma.logAppMenuSliderZoomLevelChangedHistogram();
PageZoomUma.logAppMenuSliderZoomLevelValueHistogram(zoomValue);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
public class PageZoomMediator {
private final PropertyModel mModel;
private WebContents mWebContents;
private double mLatestZoomValue;

public PageZoomMediator(PropertyModel model) {
mModel = model;
Expand Down Expand Up @@ -59,16 +60,26 @@ protected static boolean shouldShowMenuItem() {

// Always show the menu item if the user has set this in Accessibility Settings.
if (PageZoomUtils.shouldAlwaysShowZoomMenuItem()) {
PageZoomUma.logAppMenuEnabledStateHistogram(
PageZoomUma.AccessibilityPageZoomAppMenuEnabledState.USER_ENABLED);
return true;
}

// The default (float) |fontScale| is 1, the default page zoom is 1.
// If the user has a system font scale other than the default, always show the menu item.
boolean isUsingDefaultSystemFontScale = MathUtils.areFloatsEqual(SYSTEM_FONT_SCALE, 1f);
if (!isUsingDefaultSystemFontScale) {
PageZoomUma.logAppMenuEnabledStateHistogram(
PageZoomUma.AccessibilityPageZoomAppMenuEnabledState.OS_ENABLED);
return true;
}

// TODO(mschillaci): Replace with a delegate call, cannot depend directly on Profile.
boolean isUsingDefaultPageZoom = true;

return !isUsingDefaultSystemFontScale || !isUsingDefaultPageZoom;
// TODO(mschillaci): Decide whether to additionally enable app menu item depending on
// default page zoom. If yes, then replace with a delegate call, cannot depend directly on
// Profile.
PageZoomUma.logAppMenuEnabledStateHistogram(
PageZoomUma.AccessibilityPageZoomAppMenuEnabledState.NOT_ENABLED);
return false;
}

/**
Expand All @@ -80,17 +91,23 @@ protected void setWebContents(WebContents webContents) {
initialize();
}

/**
* Returns the latest updated user selected zoom value during this session.
* @return double representing latest updated zoom value. Returns placeholder 0.0 if user did
* not select a zoom value during this session.
*/
protected double latestZoomValue() {
return mLatestZoomValue;
}

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void handleDecreaseClicked(Void unused) {
// When decreasing zoom, "snap" to the greatest preset value that is less than the current.
double currentZoomFactor = getZoomLevel(mWebContents);
int index = PageZoomUtils.getNextIndex(true, currentZoomFactor);

if (index >= 0) {
mModel.set(PageZoomProperties.CURRENT_SEEK_VALUE,
PageZoomUtils.convertZoomFactorToSeekBarValue(AVAILABLE_ZOOM_FACTORS[index]));
setZoomLevel(mWebContents, AVAILABLE_ZOOM_FACTORS[index]);
updateButtonStates(AVAILABLE_ZOOM_FACTORS[index]);
handleIndexChanged(index);
}
}

Expand All @@ -101,10 +118,7 @@ void handleIncreaseClicked(Void unused) {
int index = PageZoomUtils.getNextIndex(false, currentZoomFactor);

if (index <= AVAILABLE_ZOOM_FACTORS.length - 1) {
mModel.set(PageZoomProperties.CURRENT_SEEK_VALUE,
PageZoomUtils.convertZoomFactorToSeekBarValue(AVAILABLE_ZOOM_FACTORS[index]));
setZoomLevel(mWebContents, AVAILABLE_ZOOM_FACTORS[index]);
updateButtonStates(AVAILABLE_ZOOM_FACTORS[index]);
handleIndexChanged(index);
}
}

Expand All @@ -113,6 +127,7 @@ void handleSeekBarValueChanged(int newValue) {
setZoomLevel(mWebContents, PageZoomUtils.convertSeekBarValueToZoomFactor(newValue));
mModel.set(PageZoomProperties.CURRENT_SEEK_VALUE, newValue);
updateButtonStates(PageZoomUtils.convertSeekBarValueToZoomFactor(newValue));
mLatestZoomValue = PageZoomUtils.convertSeekBarValueToZoomLevel(newValue);
}

private void initialize() {
Expand All @@ -124,6 +139,18 @@ private void initialize() {
convertZoomFactorToSeekBarValue(currentZoomFactor));

updateButtonStates(currentZoomFactor);

// Reset latest zoom value when initializing
mLatestZoomValue = 0.0;
}

private void handleIndexChanged(int index) {
double zoomFactor = AVAILABLE_ZOOM_FACTORS[index];
int seekBarValue = PageZoomUtils.convertZoomFactorToSeekBarValue(zoomFactor);
mModel.set(PageZoomProperties.CURRENT_SEEK_VALUE, seekBarValue);
setZoomLevel(mWebContents, zoomFactor);
updateButtonStates(zoomFactor);
mLatestZoomValue = PageZoomUtils.convertSeekBarValueToZoomLevel(seekBarValue);
}

private void updateButtonStates(double newZoomFactor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.components.browser_ui.accessibility;

import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;

import org.chromium.base.metrics.RecordHistogram;

/**
* Centralizes UMA data collection for Page Zoom.
*/
public class PageZoomUma {
private static int sMinZoomValue = (int) (PageZoomUtils.PAGE_ZOOM_MINIMUM_ZOOM_LEVEL * 100);
private static int sMaxZoomValue = (int) (PageZoomUtils.PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL * 100);
private static int sZoomValueBucketCount = (int) ((sMaxZoomValue - sMinZoomValue) / 5) + 2;

// AccessibilityPageZoomAppMenuEnabledState defined in tools/metrics/histograms/enums.xml.
// Add new values before MAX_VALUE.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
@IntDef({AccessibilityPageZoomAppMenuEnabledState.NOT_ENABLED,
AccessibilityPageZoomAppMenuEnabledState.USER_ENABLED,
AccessibilityPageZoomAppMenuEnabledState.OS_ENABLED,
AccessibilityPageZoomAppMenuEnabledState.MAX_VALUE})
public @interface AccessibilityPageZoomAppMenuEnabledState {
int NOT_ENABLED = 0;
int USER_ENABLED = 1;
int OS_ENABLED = 2;

// Be sure to also update enums.xml when updating these values.
int MAX_VALUE = 3;
}

// Page Zoom histogram values
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_APP_MENU_ENABLED_STATE_HISTOGRAM =
"Accessibility.Android.PageZoom.AppMenuEnabledState";
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_APP_MENU_SLIDER_OPENED_HISTOGRAM =
"Accessibility.Android.PageZoom.AppMenuSliderOpened";
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_APP_MENU_SLIDER_ZOOM_LEVEL_CHANGED_HISTOGRAM =
"Accessibility.Android.PageZoom.AppMenuSliderZoomLevelChanged";
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_APP_MENU_SLIDER_ZOOM_LEVEL_VALUE_HISTOGRAM =
"Accessibility.Android.PageZoom.AppMenuSliderZoomLevelValue";
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_SETTINGS_DEFAULT_ZOOM_LEVEL_CHANGED_HISTOGRAM =
"Accessibility.Android.PageZoom.SettingsDefaultZoomLevelChanged";
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static final String PAGE_ZOOM_SETTINGS_DEFAULT_ZOOM_LEVEL_VALUE_HISTOGRAM =
"Accessibility.Android.PageZoom.SettingsDefaultZoomLevelValue";

/**
* Log the enabled state of the page zoom slider option in the app menu.
* @param value the enum value representing whether the zoom option is not enabled, enabled by
* the user, or enabled due to the OS font settings.
*/
public static void logAppMenuEnabledStateHistogram(
@AccessibilityPageZoomAppMenuEnabledState int value) {
RecordHistogram.recordEnumeratedHistogram(PAGE_ZOOM_APP_MENU_ENABLED_STATE_HISTOGRAM, value,
AccessibilityPageZoomAppMenuEnabledState.MAX_VALUE);
}

/**
* Log that the user opened the slider from the app menu.
*/
public static void logAppMenuSliderOpenedHistogram() {
RecordHistogram.recordBooleanHistogram(PAGE_ZOOM_APP_MENU_SLIDER_OPENED_HISTOGRAM, true);
}

/**
* Log that the user changed the zoom level from the app menu slider.
*/
public static void logAppMenuSliderZoomLevelChangedHistogram() {
RecordHistogram.recordBooleanHistogram(
PAGE_ZOOM_APP_MENU_SLIDER_ZOOM_LEVEL_CHANGED_HISTOGRAM, true);
}

/**
* Log the value of the zoom level chosen by the user from the app menu slider.
* @param value the zoom level to log in the form of a double, with 1.0 equivalent to 100%, 1.5
* equivalent to 150%, etc.
*/
public static void logAppMenuSliderZoomLevelValueHistogram(double value) {
RecordHistogram.recordLinearCountHistogram(
PAGE_ZOOM_APP_MENU_SLIDER_ZOOM_LEVEL_VALUE_HISTOGRAM, (int) Math.round(100 * value),
sMinZoomValue, sMaxZoomValue, sZoomValueBucketCount);
}

/**
* Log that the user changed the default zoom level from the settings page.
*/
public static void logSettingsDefaultZoomLevelChangedHistogram() {
RecordHistogram.recordBooleanHistogram(
PAGE_ZOOM_SETTINGS_DEFAULT_ZOOM_LEVEL_CHANGED_HISTOGRAM, true);
}

/**
* Log the value of the default zoom level chosen by the user from the settings page.
* @param value the default zoom level to log in the form of a double, with 1.0 equivalent to
* 100%, 1.5 equivalent to 150%, etc.
*/
public static void logSettingsDefaultZoomLevelValueHistogram(double value) {
RecordHistogram.recordLinearCountHistogram(
PAGE_ZOOM_SETTINGS_DEFAULT_ZOOM_LEVEL_VALUE_HISTOGRAM,
(int) Math.round(100 * value), sMinZoomValue, sMaxZoomValue, sZoomValueBucketCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public class PageZoomUtils {
public static final int PAGE_ZOOM_MAXIMUM_SEEKBAR_VALUE = 250;

// The minimum and maximum zoom values as a percentage (e.g. 50% = 0.50, 300% = 3.0)
private static final float PAGE_ZOOM_MINIMUM_ZOOM_LEVEL = 0.50f;
private static final float PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL = 3.00f;
protected static final float PAGE_ZOOM_MINIMUM_ZOOM_LEVEL = 0.50f;
protected static final float PAGE_ZOOM_MAXIMUM_ZOOM_LEVEL = 3.00f;

/**
* Returns whether the Accessibility Settings page should include the 'Zoom' UI. The page
Expand Down
12 changes: 12 additions & 0 deletions tools/metrics/histograms/enums.xml
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,18 @@ uploading your change for review. These are checked by presubmit scripts.
<int value="7" label="PDF"/>
</enum>

<enum name="AccessibilityPageZoomAppMenuEnabledState">
<summary>Track enabled state of page zoom option on app menu.</summary>
<!-- This must be kept in sync with
PageZoomUma.AccessibilityPageZoomAppMenuEnabledState in
components/browser_ui/accessibility/android/java/src/org/chromium/
components/browser_ui/accessibility/PageZoomUma.java -->

<int value="0" label="Not Enabled"/>
<int value="1" label="User Enabled"/>
<int value="2" label="OS Enabled"/>
</enum>

<enum name="AccessibilityTreeUnserializeError">
<summary>
Tracks the type of failure that occured when unserializing the accessibility
Expand Down
78 changes: 78 additions & 0 deletions tools/metrics/histograms/metadata/accessibility/histograms.xml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,84 @@ chromium-metrics-reviews@google.com.
</token>
</histogram>

<histogram name="Accessibility.Android.PageZoom.AppMenuEnabledState"
enum="AccessibilityPageZoomAppMenuEnabledState" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
Tracks the enabled state for the Page Zoom option on the main app menu. The
state will be one of the following enumerated states: 0) not enabled, 1)
enabled explicitly by the user on the Accessibility Page Zoom setting, 2)
enabled automatically if the user has an Android OS-wide default font size.
Recorded each time the app menu is opened.
</summary>
</histogram>

<histogram name="Accessibility.Android.PageZoom.AppMenuSliderOpened"
enum="Boolean" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
Tracks whether the user opened the Page Zoom slider from the app menu
option. Recorded each time the slider is opened from the app menu.
</summary>
</histogram>

<histogram name="Accessibility.Android.PageZoom.AppMenuSliderZoomLevelChanged"
enum="Boolean" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
Tracks whether the user changed the individual page zoom level on at least
one webpage from the app menu slider view. Recorded each time the slider is
dismissed if the user changed the zoom level before dismissal.
</summary>
</histogram>

<histogram name="Accessibility.Android.PageZoom.AppMenuSliderZoomLevelValue"
units="%" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
For users who changed the individual page zoom level on at least one webpage
from the app menu slider view, tracks what zoom level has been set on the
page. Recorded each time the slider is dismissed if the user changed the
zoom level before dismissal.
</summary>
</histogram>

<histogram
name="Accessibility.Android.PageZoom.SettingsDefaultZoomLevelChanged"
enum="Boolean" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
Tracks whether the user changed the default page zoom level from the
Accessibility Page Zoom settings page. Recorded each time the user closes
the Accessibility Page Zoom settings page if the user changed the zoom level
while the settings page was showing.
</summary>
</histogram>

<histogram name="Accessibility.Android.PageZoom.SettingsDefaultZoomLevelValue"
units="%" expires_after="2023-07-01">
<owner>mschillaci@google.com</owner>
<owner>aldietz@google.com</owner>
<owner>chrome-a11y-core@google.com</owner>
<summary>
For users who changed the default page zoom level from the Accessibility
Page Zoom settings page, tracks what default zoom level has been set in the
settings. Recorded each time the user closes the Accessibility Page Zoom
settings page if the user changed the zoom level while the settings page was
showing.
</summary>
</histogram>

<histogram name="Accessibility.Android.ScreenReader{AccessibilityEveryReport}"
enum="BooleanEnabled" expires_after="never">
<!-- expires-never: usage drives a11y prioritization in browser and content. -->
Expand Down

0 comments on commit 88a3ef8

Please sign in to comment.