1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// 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.
#include "ash/public/cpp/feature_discovery_duration_reporter.h"
#include "ash/public/cpp/feature_discovery_metric_util.h"
#include "base/json/values_util.h"
#include "base/metrics/histogram_base.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/ash/login/login_manager_test.h"
#include "chrome/browser/ash/login/test/login_manager_mixin.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/login/user_adding_screen.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "content/public/test/browser_test.h"
namespace ash {
namespace {
// The mock feature's discovery duration histogram.
constexpr char kMockHistogram[] = "FeatureDiscoveryTestMockFeature";
} // namespace
class FeatureDiscoveryDurationReporterBrowserTest : public LoginManagerTest {
public:
FeatureDiscoveryDurationReporterBrowserTest() {
login_mixin_.AppendRegularUsers(2);
account_id1_ = login_mixin_.users()[0].account_id;
account_id2_ = login_mixin_.users()[1].account_id;
}
FeatureDiscoveryDurationReporterBrowserTest(
const FeatureDiscoveryDurationReporterBrowserTest&) = delete;
FeatureDiscoveryDurationReporterBrowserTest& operator=(
const FeatureDiscoveryDurationReporterBrowserTest&) = delete;
~FeatureDiscoveryDurationReporterBrowserTest() override = default;
// LoginManagerTest:
void SetUpOnMainThread() override {
LoginManagerTest::SetUpOnMainThread();
LoginUser(account_id1_);
EXPECT_EQ(
account_id1_,
user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId());
}
void TearDownOnMainThread() override {
LoginManagerTest::TearDownOnMainThread();
}
AccountId account_id1_;
AccountId account_id2_;
ash::LoginManagerMixin login_mixin_{&mixin_host_};
};
// Verifies that the feature discovery duration is recorded on a single active
// session.
IN_PROC_BROWSER_TEST_F(FeatureDiscoveryDurationReporterBrowserTest,
RecordFeatureDiscovery) {
base::HistogramTester histogram_tester;
auto* reporter = ash::FeatureDiscoveryDurationReporter::GetInstance();
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 1);
// Record the feature discovery for the mock feature again. Verify that
// duplicate recordings should not be made.
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 1);
}
// Verifies that the feature discovery duration recording works as expected
// when the active account is switched.
IN_PROC_BROWSER_TEST_F(FeatureDiscoveryDurationReporterBrowserTest,
RecordFeatureDiscoveryWithAccountSwitch) {
base::HistogramTester histogram_tester;
auto* reporter = ash::FeatureDiscoveryDurationReporter::GetInstance();
// Switch to another account. Because user 2 is not primary, the feature
// discovery duration should not be recorded.
ash::UserAddingScreen::Get()->Start();
AddUser(account_id2_);
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 0);
// Switch back to the primary account. Verify that the feature discovery
// duration is recorded.
user_manager::UserManager::Get()->SwitchActiveUser(account_id1_);
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 1);
}
// Verifies that switching to another account then switching back should resume
// feature discovery duration recordings.
IN_PROC_BROWSER_TEST_F(FeatureDiscoveryDurationReporterBrowserTest,
ResumeMetricRecording) {
base::HistogramTester histogram_tester;
auto* reporter = ash::FeatureDiscoveryDurationReporter::GetInstance();
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
// Switch to another account without ending the observation explicitly.
// Because user 2 is not primary, the feature discovery duration should not
// be recorded.
ash::UserAddingScreen::Get()->Start();
AddUser(account_id2_);
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 0);
// Switch back to the onboarding account. Finish the observation without
// starting explicitly. Verify that the metric is recorded.
user_manager::UserManager::Get()->SwitchActiveUser(account_id1_);
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 1);
}
IN_PROC_BROWSER_TEST_F(FeatureDiscoveryDurationReporterBrowserTest,
PRE_SaveCumulatedTimeWhenSignout) {
auto* reporter = ash::FeatureDiscoveryDurationReporter::GetInstance();
reporter->MaybeActivateObservation(
feature_discovery::TrackableFeature::kMockFeature);
// Wait for some time so that the cumulated time is not zero.
base::RunLoop run_loop;
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(100));
run_loop.Run();
}
// Verifies that unfinished observations should resume after re-login.
IN_PROC_BROWSER_TEST_F(FeatureDiscoveryDurationReporterBrowserTest,
SaveCumulatedTimeWhenSignout) {
auto* reporter = ash::FeatureDiscoveryDurationReporter::GetInstance();
// Fetch the cumulated time from the pref service and check it is non-zero.
PrefService* primary_user_pref =
ash::ProfileHelper::Get()
->GetProfileByUser(user_manager::UserManager::Get()->GetPrimaryUser())
->GetPrefs();
const base::Value* duration_value =
primary_user_pref->GetDict("FeatureDiscoveryReporterObservedFeatures")
.FindDict("kMockFeature")
->Find("cumulative_duration");
std::optional<base::TimeDelta> duration =
base::ValueToTimeDelta(duration_value);
EXPECT_NE(base::TimeDelta(), *duration);
// Finish the observation. Verify that the discovery duration is recorded.
base::HistogramTester histogram_tester;
reporter->MaybeFinishObservation(
feature_discovery::TrackableFeature::kMockFeature);
histogram_tester.ExpectTotalCount(kMockHistogram, 1);
}
} // namespace ash
|