Commit 75ea49e0 authored by Malay Keshav's avatar Malay Keshav Committed by Commit Bot

HaTS: Add UMA to track survey progress

This patch adds UMA metrics to track the stages of HaTS that users go
through. This helps keep track of number of users who view the UMA
survey. Since Chrome OS uses client side logic to roll dice for survey,
UMA metrics is required.

Test: Manually
Bug: 1134413
Change-Id: Ic4981ab97ba3f1b99a588b5a32279bfca03009d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2444511
Commit-Queue: Malay Keshav <malaykeshav@chromium.org>
Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815314}
parent 12893215
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/app/vector_icons/vector_icons.h"
...@@ -102,6 +103,8 @@ HatsNotificationController::HatsNotificationController(Profile* profile) ...@@ -102,6 +103,8 @@ HatsNotificationController::HatsNotificationController(Profile* profile)
HatsNotificationController::~HatsNotificationController() { HatsNotificationController::~HatsNotificationController() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::UmaHistogramEnumeration("Browser.ChromeOS.HatsStatus", state_);
if (network_portal_detector::IsInitialized()) if (network_portal_detector::IsInitialized())
network_portal_detector::GetInstance()->RemoveObserver(this); network_portal_detector::GetInstance()->RemoveObserver(this);
} }
...@@ -113,6 +116,8 @@ void HatsNotificationController::Initialize(bool is_new_device) { ...@@ -113,6 +116,8 @@ void HatsNotificationController::Initialize(bool is_new_device) {
// This device has been chosen for a survey, but it is too new. Instead // This device has been chosen for a survey, but it is too new. Instead
// of showing the user the survey, just mark it as completed. // of showing the user the survey, just mark it as completed.
UpdateLastInteractionTime(); UpdateLastInteractionTime();
state_ = HatsState::kNewDevice;
return; return;
} }
...@@ -167,8 +172,11 @@ bool HatsNotificationController::ShouldShowSurveyToProfile(Profile* profile) { ...@@ -167,8 +172,11 @@ bool HatsNotificationController::ShouldShowSurveyToProfile(Profile* profile) {
: kHatsThreshold; : kHatsThreshold;
// Do not show survey to user if user has interacted with HaTS within the past // Do not show survey to user if user has interacted with HaTS within the past
// |threshold_time| time delta. // |threshold_time| time delta.
if (DidShowSurveyToProfileRecently(profile, threshold_time)) if (DidShowSurveyToProfileRecently(profile, threshold_time)) {
base::UmaHistogramEnumeration("Browser.ChromeOS.HatsStatus",
HatsState::kSurveyShownRecently);
return false; return false;
}
return true; return true;
} }
...@@ -182,6 +190,8 @@ void HatsNotificationController::Click( ...@@ -182,6 +190,8 @@ void HatsNotificationController::Click(
hats_dialog_ = HatsDialog::CreateAndShow(); hats_dialog_ = HatsDialog::CreateAndShow();
state_ = HatsState::kNotificationClicked;
// Remove the notification. // Remove the notification.
network_portal_detector::GetInstance()->RemoveObserver(this); network_portal_detector::GetInstance()->RemoveObserver(this);
notification_.reset(nullptr); notification_.reset(nullptr);
...@@ -197,6 +207,7 @@ void HatsNotificationController::Close(bool by_user) { ...@@ -197,6 +207,7 @@ void HatsNotificationController::Close(bool by_user) {
UpdateLastInteractionTime(); UpdateLastInteractionTime();
network_portal_detector::GetInstance()->RemoveObserver(this); network_portal_detector::GetInstance()->RemoveObserver(this);
notification_.reset(nullptr); notification_.reset(nullptr);
state_ = HatsState::kNotificationDismissed;
} }
} }
...@@ -227,6 +238,8 @@ void HatsNotificationController::OnPortalDetectionCompleted( ...@@ -227,6 +238,8 @@ void HatsNotificationController::OnPortalDetectionCompleted(
NotificationDisplayService::GetForProfile(profile_)->Display( NotificationDisplayService::GetForProfile(profile_)->Display(
NotificationHandler::Type::TRANSIENT, *notification_, NotificationHandler::Type::TRANSIENT, *notification_,
/*metadata=*/nullptr); /*metadata=*/nullptr);
state_ = HatsState::kNotificationDisplayed;
} else if (notification_) { } else if (notification_) {
// Hide the notification if device loses its connection to the internet. // Hide the notification if device loses its connection to the internet.
NotificationDisplayService::GetForProfile(profile_)->Close( NotificationDisplayService::GetForProfile(profile_)->Close(
......
...@@ -53,6 +53,18 @@ class HatsNotificationController : public message_center::NotificationDelegate, ...@@ -53,6 +53,18 @@ class HatsNotificationController : public message_center::NotificationDelegate,
~HatsNotificationController() override; ~HatsNotificationController() override;
enum class HatsState {
kDeviceSelected = 0, // Device was selected in roll of dice.
kSurveyShownRecently = 1, // A survey was shown recently on device.
kNewDevice = 2, // Device is too new to show the survey.
kNotificationDisplayed = 3, // Pop up for survey was presented to user.
kNotificationDismissed = 4, // Notification was dismissed by user.
kNotificationClicked = 5, // User clicked on notification to open the
// survey.
kMaxValue = kNotificationClicked
};
// NotificationDelegate overrides: // NotificationDelegate overrides:
void Initialize(bool is_new_device); void Initialize(bool is_new_device);
void Close(bool by_user) override; void Close(bool by_user) override;
...@@ -69,6 +81,9 @@ class HatsNotificationController : public message_center::NotificationDelegate, ...@@ -69,6 +81,9 @@ class HatsNotificationController : public message_center::NotificationDelegate,
Profile* const profile_; Profile* const profile_;
std::unique_ptr<message_center::Notification> notification_; std::unique_ptr<message_center::Notification> notification_;
std::unique_ptr<HatsDialog> hats_dialog_; std::unique_ptr<HatsDialog> hats_dialog_;
HatsState state_ = HatsState::kDeviceSelected;
base::WeakPtrFactory<HatsNotificationController> weak_pointer_factory_{this}; base::WeakPtrFactory<HatsNotificationController> weak_pointer_factory_{this};
DISALLOW_COPY_AND_ASSIGN(HatsNotificationController); DISALLOW_COPY_AND_ASSIGN(HatsNotificationController);
......
...@@ -35528,6 +35528,15 @@ Called by update_gpu_driver_bug_workaround_entries.py.--> ...@@ -35528,6 +35528,15 @@ Called by update_gpu_driver_bug_workaround_entries.py.-->
<int value="2" label="Unknown"/> <int value="2" label="Unknown"/>
</enum> </enum>
<enum name="HatsStatus">
<int value="0" label="Device selected"/>
<int value="1" label="Survey was shown recently"/>
<int value="2" label="New device detected"/>
<int value="3" label="Notification displayed"/>
<int value="4" label="User dismissed notification"/>
<int value="5" label="User opened survey"/>
</enum>
<enum name="HeapProfilingMode"> <enum name="HeapProfilingMode">
<int value="0" label="None"/> <int value="0" label="None"/>
<int value="1" label="Minimal"/> <int value="1" label="Minimal"/>
...@@ -39,6 +39,19 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -39,6 +39,19 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram name="Browser.ChromeOS.HatsStatus" enum="HatsStatus"
expires_after="2021-10-01">
<owner>aalsum@chromium.org</owner>
<owner>malaykeshav@chromium.org</owner>
<summary>
Records the stage up to which the user interacted with the HaTS Chrome OS
survey. This is needed in addition to the Hats metrics data since Chrome OS
relies on client side logic to roll the dice for device selection. This is
recorded when the Hats pipeline ends processing, which is usually when the
controller is destroyed.
</summary>
</histogram>
<histogram name="Browser.DarkModeStatus" enum="DarkModeStatus" <histogram name="Browser.DarkModeStatus" enum="DarkModeStatus"
expires_after="2021-02-21"> expires_after="2021-02-21">
<owner>lgrey@chromium.org</owner> <owner>lgrey@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment