chromium/chrome/browser/android/browserservices/metrics/java/src/org/chromium/chrome/browser/browserservices/metrics/TrustedWebActivityUmaRecorder.java

// Copyright 2018 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.chrome.browser.browserservices.metrics;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;

import dagger.Reusable;

import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.components.content_settings.ContentSettingValues;
import org.chromium.components.ukm.UkmRecorder;
import org.chromium.content_public.browser.WebContents;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.inject.Inject;

/** Encapsulates Uma recording actions related to Trusted Web Activities. */
@Reusable
public class TrustedWebActivityUmaRecorder {
    @IntDef({
        DelegatedNotificationSmallIconFallback.NO_FALLBACK,
        DelegatedNotificationSmallIconFallback.FALLBACK_ICON_NOT_PROVIDED,
        DelegatedNotificationSmallIconFallback.FALLBACK_FOR_STATUS_BAR,
        DelegatedNotificationSmallIconFallback.FALLBACK_FOR_STATUS_BAR_AND_CONTENT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DelegatedNotificationSmallIconFallback {
        int NO_FALLBACK = 0;
        int FALLBACK_ICON_NOT_PROVIDED = 1;
        int FALLBACK_FOR_STATUS_BAR = 2;
        int FALLBACK_FOR_STATUS_BAR_AND_CONTENT = 3;
        int NUM_ENTRIES = 4;
    }

    @IntDef({ShareRequestMethod.GET, ShareRequestMethod.POST})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ShareRequestMethod {
        int GET = 0;
        int POST = 1;
        int NUM_ENTRIES = 2;
    }

    @IntDef({
        PermissionChanged.NULL_TO_TRUE,
        PermissionChanged.NULL_TO_FALSE,
        PermissionChanged.TRUE_TO_FALSE,
        PermissionChanged.FALSE_TO_TRUE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PermissionChanged {
        int NULL_TO_FALSE = 0;
        int NULL_TO_TRUE = 1;
        int TRUE_TO_FALSE = 2;
        int FALSE_TO_TRUE = 3;
        int NUM_ENTRIES = 4;
    }

    /** A callback for adding task to run when full browser initialization is done. */
    public interface DeferredTaskHandler {
        /* Call to add task to run after full browser started.*/
        void doWhenNativeLoaded(Runnable runnable);
    }

    private final DeferredTaskHandler mDeferredTaskHandler;

    @Inject
    public TrustedWebActivityUmaRecorder(DeferredTaskHandler taskHandler) {
        mDeferredTaskHandler = taskHandler;
    }

    /** Records that a Trusted Web Activity has been opened. */
    public void recordTwaOpened(@Nullable WebContents webContents) {
        RecordUserAction.record("BrowserServices.TwaOpened");
        if (webContents != null) {
            new UkmRecorder.Bridge()
                    .recordEventWithBooleanMetric(
                            webContents, "TrustedWebActivity.Open", "HasOccurred");
        }
    }

    /** Records the time that a Trusted Web Activity has been in resumed state. */
    public void recordTwaOpenTime(long durationMs) {
        recordDuration(durationMs, "BrowserServices.TwaOpenTime.V2");
    }

    /**
     * Records the time spent in verified origin until navigating to unverified one or pausing
     * the Trusted Web Activity.
     */
    public void recordTimeInVerifiedOrigin(long durationMs) {
        recordDuration(durationMs, "TrustedWebActivity.TimeInVerifiedOrigin.V2");
    }

    /**
     * Records the time spent in verified origin until navigating to unverified one or pausing
     * the Trusted Web Activity.
     */
    public void recordTimeOutOfVerifiedOrigin(long durationMs) {
        recordDuration(durationMs, "TrustedWebActivity.TimeOutOfVerifiedOrigin.V2");
    }

    private void recordDuration(long durationMs, String histogramName) {
        RecordHistogram.recordLongTimesHistogram(histogramName, durationMs);
    }

    /** Records the fact that disclosure was shown. */
    public void recordDisclosureShown() {
        RecordUserAction.record("TrustedWebActivity.DisclosureShown");
    }

    /** Records the fact that disclosure was accepted by user. */
    public void recordDisclosureAccepted() {
        RecordUserAction.record("TrustedWebActivity.DisclosureAccepted");
    }

    /**
     * Records which action the user took upon seeing a clear data dialog.
     * @param accepted Whether user proceeded to the settings from the dialog.
     * @param triggeredByUninstall Whether the dialog was triggered by app uninstall as opposed to
     * app data getting cleared.
     */
    public void recordClearDataDialogAction(boolean accepted, boolean triggeredByUninstall) {
        String histogramName =
                triggeredByUninstall
                        ? "TrustedWebActivity.ClearDataDialogOnUninstallAccepted"
                        : "TrustedWebActivity.ClearDataDialogOnClearAppDataAccepted";
        RecordHistogram.recordBooleanHistogram(histogramName, accepted);
    }

    /**
     * Records the fact that site settings were opened via "Manage Space" button in TWA client app's
     * settings.
     */
    public void recordOpenedSettingsViaManageSpace() {
        mDeferredTaskHandler.doWhenNativeLoaded(
                () -> RecordUserAction.record("TrustedWebActivity.OpenedSettingsViaManageSpace"));
    }

    /** Records which fallback (if any) was used for the small icon of a delegated notification. */
    public void recordDelegatedNotificationSmallIconFallback(
            @DelegatedNotificationSmallIconFallback int fallback) {
        RecordHistogram.recordEnumeratedHistogram(
                "TrustedWebActivity.DelegatedNotificationSmallIconFallback",
                fallback,
                DelegatedNotificationSmallIconFallback.NUM_ENTRIES);
    }

    /** Records the notification permission request result for a TWA. */
    public static void recordNotificationPermissionRequestResult(
            @ContentSettingValues int settingValue) {
        RecordHistogram.recordEnumeratedHistogram(
                "TrustedWebActivity.Notification.PermissionRequestResult",
                settingValue,
                ContentSettingValues.NUM_SETTINGS);
    }

    /**
     * Records whether or not a splash screen has been shown when launching a TWA.
     * Uses {@link TaskTraits#BEST_EFFORT} in order to not get in the way of loading the page.
     */
    public void recordSplashScreenUsage(boolean wasShown) {
        mDeferredTaskHandler.doWhenNativeLoaded(
                () ->
                        PostTask.postTask(
                                TaskTraits.BEST_EFFORT,
                                () ->
                                        RecordHistogram.recordBooleanHistogram(
                                                "TrustedWebActivity.SplashScreenShown", wasShown)));
    }

    /** Records the fact that data was shared via a TWA. */
    public void recordShareTargetRequest(@ShareRequestMethod int method) {
        RecordHistogram.recordEnumeratedHistogram(
                "TrustedWebActivity.ShareTargetRequest", method, ShareRequestMethod.NUM_ENTRIES);
    }

    public void recordExtraCommandSuccess(String command, boolean success) {
        RecordHistogram.recordBooleanHistogram(
                "TrustedWebActivity.ExtraCommandSuccess." + command, success);
    }
}