Add metrics DemoMode.SignedIn.Account{Clean|Set}upResult
Add two new histograms DemoMode.SignedIn.AccountSetupResult and DemoMode.SignedIn.AccountCleanupResult to report the demo account request results, and tie the enum class DemoSessionMetricsRecorder::ResultCode to it. In some unit tests, we still need to utilize {set|clean}up_failed_callback_for_testing to wait for the request to report error, but the extra unnecessary parameter is removed. ResultCode is moved from DemoLoginController to DemoSessionMetricsRecorder because ash/ can't depend on chrome/browser/ for DemoSessionMetricsRecorder to access ResultCode in DemoLoginController. TEST= unit tests DemoLoginControllerTest.* Bug: 390232961 Change-Id: I3b499676a35f7336d700cf728db4e43e447565db Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6177880 Commit-Queue: Haifan Wang <wanghaifan@google.com> Reviewed-by: Xiqi Ruan <xiqiruan@chromium.org> Reviewed-by: Daniel Classon <dclasson@google.com> Cr-Commit-Position: refs/heads/main@{#1414460}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
5a917486a5
commit
f3a48238b7
ash/metrics
chrome/browser/ash/login/demo_mode
tools/metrics/histograms
@ -49,6 +49,11 @@ constexpr char kHelpAppId[] = "nbljnnecbjbmifnoehiemkgefbnpoeak";
|
|||||||
constexpr char kDemoModeSignedInShopperDwellTime[] =
|
constexpr char kDemoModeSignedInShopperDwellTime[] =
|
||||||
"DemoMode.SignedIn.Shopper.DwellTime";
|
"DemoMode.SignedIn.Shopper.DwellTime";
|
||||||
|
|
||||||
|
constexpr char kSetupDemoAccountRequestResult[] =
|
||||||
|
"DemoMode.SignedIn.Request.SetupResult";
|
||||||
|
constexpr char kCleanupDemoAccountRequestResult[] =
|
||||||
|
"DemoMode.SignedIn.Request.CleanupResult";
|
||||||
|
|
||||||
// How many periods to wait for user activity before discarding samples.
|
// How many periods to wait for user activity before discarding samples.
|
||||||
// This timeout is low because demo sessions tend to be very short. If we
|
// This timeout is low because demo sessions tend to be very short. If we
|
||||||
// recorded samples for a full minute while the device is in between uses, we
|
// recorded samples for a full minute while the device is in between uses, we
|
||||||
@ -610,6 +615,16 @@ void DemoSessionMetricsRecorder::ReportShopperSessionDwellTime() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DemoSessionMetricsRecorder::ReportDemoAccountSetupResult(
|
||||||
|
DemoAccountRequestResultCode result_code) {
|
||||||
|
base::UmaHistogramEnumeration(kSetupDemoAccountRequestResult, result_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoSessionMetricsRecorder::ReportDemoAccountCleanupResult(
|
||||||
|
DemoAccountRequestResultCode result_code) {
|
||||||
|
base::UmaHistogramEnumeration(kCleanupDemoAccountRequestResult, result_code);
|
||||||
|
}
|
||||||
|
|
||||||
void DemoSessionMetricsRecorder::StartRecording() {
|
void DemoSessionMetricsRecorder::StartRecording() {
|
||||||
unique_apps_launched_recording_enabled_ = true;
|
unique_apps_launched_recording_enabled_ = true;
|
||||||
timer_->Start(FROM_HERE, kSamplePeriod, this,
|
timer_->Start(FROM_HERE, kSamplePeriod, this,
|
||||||
|
@ -95,6 +95,25 @@ class ASH_EXPORT DemoSessionMetricsRecorder
|
|||||||
kSystemTrayPowerButton = 2,
|
kSystemTrayPowerButton = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The types of the result of the demo account setup or cleanup request.
|
||||||
|
// This enum is tied directly to a UMA enum
|
||||||
|
// `DemoModeSignedInAccountRequestResult`, and should always reflect it (do
|
||||||
|
// not change one without changing the other). Entries should never be
|
||||||
|
// modified or reordered. Entries can only be removed by deprecating it and
|
||||||
|
// its value should never be reused. New ones should be added to the end
|
||||||
|
// (right before the max value).
|
||||||
|
enum class DemoAccountRequestResultCode {
|
||||||
|
kSuccess = 0, // Demo account request success.
|
||||||
|
kResponseParsingError = 1, // Malformat Http response.
|
||||||
|
kInvalidCreds = 2, // Missing required credential for login.
|
||||||
|
kEmptyReponse = 3, // Empty Http response.
|
||||||
|
kNetworkError = 4, // Network error.
|
||||||
|
kRequestFailed = 5, // Server side error or out of quota.
|
||||||
|
kCannotObtainDMTokenAndClientID =
|
||||||
|
6, // Unable to obtain the DM Token and the Client ID.
|
||||||
|
kMaxValue = kCannotObtainDMTokenAndClientID,
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr char kUserClicksAndPressesMetric[] =
|
static constexpr char kUserClicksAndPressesMetric[] =
|
||||||
"DemoMode.UserClicksAndPresses";
|
"DemoMode.UserClicksAndPresses";
|
||||||
|
|
||||||
@ -131,6 +150,12 @@ class ASH_EXPORT DemoSessionMetricsRecorder
|
|||||||
// last user activity.
|
// last user activity.
|
||||||
void ReportShopperSessionDwellTime();
|
void ReportShopperSessionDwellTime();
|
||||||
|
|
||||||
|
// Records the result of demo account setup request.
|
||||||
|
void ReportDemoAccountSetupResult(DemoAccountRequestResultCode result_code);
|
||||||
|
|
||||||
|
// Records the result of demo account cleanup request.
|
||||||
|
void ReportDemoAccountCleanupResult(DemoAccountRequestResultCode result_code);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Starts the timer for periodic sampling.
|
// Starts the timer for periodic sampling.
|
||||||
void StartRecording();
|
void StartRecording();
|
||||||
|
@ -381,12 +381,12 @@ void DemoLoginController::TriggerDemoAccountLoginFlow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DemoLoginController::SetSetupFailedCallbackForTest(
|
void DemoLoginController::SetSetupFailedCallbackForTest(
|
||||||
base::OnceCallback<void(const ResultCode result_code)> callback) {
|
FailedRequestCallback callback) {
|
||||||
setup_failed_callback_for_testing_ = std::move(callback);
|
setup_failed_callback_for_testing_ = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoLoginController::SetCleanUpFailedCallbackForTest(
|
void DemoLoginController::SetCleanUpFailedCallbackForTest(
|
||||||
base::OnceCallback<void(const ResultCode result_code)> callback) {
|
FailedRequestCallback callback) {
|
||||||
clean_up_failed_callback_for_testing_ = std::move(callback);
|
clean_up_failed_callback_for_testing_ = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,6 +453,10 @@ void DemoLoginController::HandleSetupDemoAcountResponse(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report success to the metrics.
|
||||||
|
DemoSessionMetricsRecorder::Get()->ReportDemoAccountSetupResult(
|
||||||
|
ResultCode::kSuccess);
|
||||||
|
|
||||||
UserLoginPermissionTracker::Get()->SetDemoUser(
|
UserLoginPermissionTracker::Get()->SetDemoUser(
|
||||||
gaia::CanonicalizeEmail(*email));
|
gaia::CanonicalizeEmail(*email));
|
||||||
DCHECK_EQ(State::kSetupDemoAccountInProgress, state_);
|
DCHECK_EQ(State::kSetupDemoAccountInProgress, state_);
|
||||||
@ -469,7 +473,7 @@ void DemoLoginController::HandleSetupDemoAcountResponse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DemoLoginController::OnSetupDemoAccountError(
|
void DemoLoginController::OnSetupDemoAccountError(
|
||||||
const DemoLoginController::ResultCode result_code) {
|
const ResultCode result_code) {
|
||||||
// TODO(crbug.com/372333479): Instruct how to do retry on failed according to
|
// TODO(crbug.com/372333479): Instruct how to do retry on failed according to
|
||||||
// the error code.
|
// the error code.
|
||||||
|
|
||||||
@ -478,12 +482,15 @@ void DemoLoginController::OnSetupDemoAccountError(
|
|||||||
|
|
||||||
DCHECK_EQ(State::kSetupDemoAccountInProgress, state_);
|
DCHECK_EQ(State::kSetupDemoAccountInProgress, state_);
|
||||||
|
|
||||||
|
// Report error to the metrics.
|
||||||
|
DemoSessionMetricsRecorder::Get()->ReportDemoAccountSetupResult(result_code);
|
||||||
|
|
||||||
// Login public account session when set up failed.
|
// Login public account session when set up failed.
|
||||||
state_ = State::kLoginToMGS;
|
state_ = State::kLoginToMGS;
|
||||||
configure_auto_login_callback_.Run();
|
configure_auto_login_callback_.Run();
|
||||||
|
|
||||||
if (setup_failed_callback_for_testing_) {
|
if (setup_failed_callback_for_testing_) {
|
||||||
std::move(setup_failed_callback_for_testing_).Run(result_code);
|
std::move(setup_failed_callback_for_testing_).Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +561,11 @@ void DemoLoginController::MaybeCleanupPreviousDemoAccount() {
|
|||||||
void DemoLoginController::OnCleanUpDemoAccountComplete(
|
void DemoLoginController::OnCleanUpDemoAccountComplete(
|
||||||
std::unique_ptr<std::string> response_body) {
|
std::unique_ptr<std::string> response_body) {
|
||||||
auto result = GetDemoAccountRequestResult(url_loader_.get(), *response_body);
|
auto result = GetDemoAccountRequestResult(url_loader_.get(), *response_body);
|
||||||
if (result != ResultCode::kSuccess) {
|
|
||||||
|
if (result == ResultCode::kSuccess) {
|
||||||
|
// Report success to the metrics.
|
||||||
|
DemoSessionMetricsRecorder::Get()->ReportDemoAccountCleanupResult(result);
|
||||||
|
} else {
|
||||||
LogServerResponseError(*response_body, /*is_setup*/ false);
|
LogServerResponseError(*response_body, /*is_setup*/ false);
|
||||||
OnCleanUpDemoAccountError(result);
|
OnCleanUpDemoAccountError(result);
|
||||||
}
|
}
|
||||||
@ -564,14 +575,17 @@ void DemoLoginController::OnCleanUpDemoAccountComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DemoLoginController::OnCleanUpDemoAccountError(
|
void DemoLoginController::OnCleanUpDemoAccountError(
|
||||||
const DemoLoginController::ResultCode result_code) {
|
const ResultCode result_code) {
|
||||||
if (clean_up_failed_callback_for_testing_) {
|
// Report error to the metrics.
|
||||||
std::move(clean_up_failed_callback_for_testing_).Run(result_code);
|
DemoSessionMetricsRecorder::Get()->ReportDemoAccountCleanupResult(
|
||||||
}
|
result_code);
|
||||||
|
|
||||||
// TODO(crbug.com/364214790): Record metric for the failure.
|
|
||||||
LOG(ERROR) << "Failed to clean up demo account. Result code: "
|
LOG(ERROR) << "Failed to clean up demo account. Result code: "
|
||||||
<< static_cast<int>(result_code);
|
<< static_cast<int>(result_code);
|
||||||
|
|
||||||
|
if (clean_up_failed_callback_for_testing_) {
|
||||||
|
std::move(clean_up_failed_callback_for_testing_).Run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<base::Value::Dict> DemoLoginController::GetDeviceIdentifier(
|
std::optional<base::Value::Dict> DemoLoginController::GetDeviceIdentifier(
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "ash/metrics/demo_session_metrics_recorder.h"
|
||||||
#include "base/functional/callback.h"
|
#include "base/functional/callback.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
@ -22,17 +23,6 @@ namespace ash {
|
|||||||
class DemoLoginController
|
class DemoLoginController
|
||||||
: public policy::DeviceCloudPolicyManagerAsh::Observer {
|
: public policy::DeviceCloudPolicyManagerAsh::Observer {
|
||||||
public:
|
public:
|
||||||
enum class ResultCode {
|
|
||||||
kSuccess = 0, // Demo account request success.
|
|
||||||
kResponseParsingError = 1, // Malformat Http response.
|
|
||||||
kInvalidCreds = 2, // Missing required credential for login.
|
|
||||||
kEmptyReponse = 3, // Empty Http response.
|
|
||||||
kNetworkError = 4, // Network error.
|
|
||||||
kRequestFailed = 5, // Server side error or out of quota.
|
|
||||||
kCannotObtainDMTokenAndClientID =
|
|
||||||
6, // Unbale to obtain the DM Token and the Client ID.
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
// `DemoLoginController` is not initialized properly.
|
// `DemoLoginController` is not initialized properly.
|
||||||
kUnknown = 0,
|
kUnknown = 0,
|
||||||
@ -56,8 +46,9 @@ class DemoLoginController
|
|||||||
kLoginToMGS = 5,
|
kLoginToMGS = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
using FailedRequestCallback =
|
using FailedRequestCallback = base::OnceCallback<void()>;
|
||||||
base::OnceCallback<void(const ResultCode result_code)>;
|
|
||||||
|
using ResultCode = DemoSessionMetricsRecorder::DemoAccountRequestResultCode;
|
||||||
|
|
||||||
explicit DemoLoginController(base::RepeatingClosure auto_login_mgs_callback);
|
explicit DemoLoginController(base::RepeatingClosure auto_login_mgs_callback);
|
||||||
DemoLoginController(const DemoLoginController&) = delete;
|
DemoLoginController(const DemoLoginController&) = delete;
|
||||||
@ -69,10 +60,8 @@ class DemoLoginController
|
|||||||
// Trigger Demo account login flow.
|
// Trigger Demo account login flow.
|
||||||
void TriggerDemoAccountLoginFlow();
|
void TriggerDemoAccountLoginFlow();
|
||||||
|
|
||||||
void SetSetupFailedCallbackForTest(
|
void SetSetupFailedCallbackForTest(FailedRequestCallback callback);
|
||||||
base::OnceCallback<void(const ResultCode result_code)> callback);
|
void SetCleanUpFailedCallbackForTest(FailedRequestCallback callback);
|
||||||
void SetCleanUpFailedCallbackForTest(
|
|
||||||
base::OnceCallback<void(const ResultCode result_code)> callback);
|
|
||||||
void SetDeviceCloudPolicyManagerForTesting(
|
void SetDeviceCloudPolicyManagerForTesting(
|
||||||
policy::CloudPolicyManager* policy_manager);
|
policy::CloudPolicyManager* policy_manager);
|
||||||
|
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include "ash/constants/ash_features.h"
|
#include "ash/constants/ash_features.h"
|
||||||
#include "ash/constants/ash_pref_names.h"
|
#include "ash/constants/ash_pref_names.h"
|
||||||
|
#include "ash/metrics/demo_session_metrics_recorder.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
#include "base/test/bind.h"
|
#include "base/test/bind.h"
|
||||||
|
#include "base/test/metrics/histogram_tester.h"
|
||||||
#include "base/test/mock_callback.h"
|
#include "base/test/mock_callback.h"
|
||||||
#include "base/test/mock_log.h"
|
#include "base/test/mock_log.h"
|
||||||
#include "base/test/scoped_feature_list.h"
|
#include "base/test/scoped_feature_list.h"
|
||||||
@ -84,6 +86,11 @@ constexpr char kPublicAccountUserId[] = "public_session_user@localhost";
|
|||||||
constexpr GaiaId::Literal kTestGaiaId("123");
|
constexpr GaiaId::Literal kTestGaiaId("123");
|
||||||
constexpr char kTestEmail[] = "example@gmail.com";
|
constexpr char kTestEmail[] = "example@gmail.com";
|
||||||
|
|
||||||
|
constexpr char kSetupDemoAccountRequestResultHistogram[] =
|
||||||
|
"DemoMode.SignedIn.Request.SetupResult";
|
||||||
|
constexpr char kCleanupDemoAccountRequestResultHistogram[] =
|
||||||
|
"DemoMode.SignedIn.Request.CleanupResult";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class DemoLoginControllerTest : public testing::Test {
|
class DemoLoginControllerTest : public testing::Test {
|
||||||
@ -232,6 +239,7 @@ class DemoLoginControllerTest : public testing::Test {
|
|||||||
EXPECT_TRUE(user_list[0]->IsDeviceLocalAccount());
|
EXPECT_TRUE(user_list[0]->IsDeviceLocalAccount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::HistogramTester histogram_tester_;
|
||||||
network::TestURLLoaderFactory test_url_loader_factory_;
|
network::TestURLLoaderFactory test_url_loader_factory_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -297,16 +305,21 @@ TEST_F(DemoLoginControllerTest, OnSetupDemoAccountSuccessFirstTime) {
|
|||||||
|
|
||||||
TEST_F(DemoLoginControllerTest, InValidGaia) {
|
TEST_F(DemoLoginControllerTest, InValidGaia) {
|
||||||
test_url_loader_factory_.AddResponse(GetSetupUrl().spec(), kInValidGaiaCreds);
|
test_url_loader_factory_.AddResponse(GetSetupUrl().spec(), kInValidGaiaCreds);
|
||||||
base::RunLoop loop;
|
|
||||||
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
|
||||||
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
|
||||||
base::BindLambdaForTesting(
|
|
||||||
[&](const DemoLoginController::ResultCode result_code) {
|
|
||||||
EXPECT_EQ(result_code,
|
|
||||||
DemoLoginController::ResultCode::kInvalidCreds);
|
|
||||||
loop.Quit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
||||||
|
base::RunLoop loop;
|
||||||
|
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
||||||
|
base::BindLambdaForTesting([&]() {
|
||||||
|
// Expect the setup request to fail by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram, 1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kInvalidCreds,
|
||||||
|
1);
|
||||||
|
loop.Quit();
|
||||||
|
}));
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
loop.Run();
|
loop.Run();
|
||||||
@ -321,20 +334,17 @@ TEST_F(DemoLoginControllerTest,
|
|||||||
// base::Value::Dict), causing the request to fail.
|
// base::Value::Dict), causing the request to fail.
|
||||||
GetDemoLoginController()->SetDeviceCloudPolicyManagerForTesting(nullptr);
|
GetDemoLoginController()->SetDeviceCloudPolicyManagerForTesting(nullptr);
|
||||||
|
|
||||||
base::RunLoop loop;
|
|
||||||
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
|
||||||
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
|
||||||
base::BindLambdaForTesting([&](const DemoLoginController::ResultCode
|
|
||||||
result_code) {
|
|
||||||
EXPECT_EQ(
|
|
||||||
result_code,
|
|
||||||
DemoLoginController::ResultCode::kCannotObtainDMTokenAndClientID);
|
|
||||||
loop.Quit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
loop.Run();
|
|
||||||
|
// Expect the setup request to fail by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(kSetupDemoAccountRequestResultHistogram,
|
||||||
|
1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kCannotObtainDMTokenAndClientID,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DemoLoginControllerTest, ServerCleanUpSuccess) {
|
TEST_F(DemoLoginControllerTest, ServerCleanUpSuccess) {
|
||||||
@ -343,12 +353,6 @@ TEST_F(DemoLoginControllerTest, ServerCleanUpSuccess) {
|
|||||||
local_state->SetString(prefs::kDemoAccountGaiaId, kTestGaiaId.ToString());
|
local_state->SetString(prefs::kDemoAccountGaiaId, kTestGaiaId.ToString());
|
||||||
const std::string last_session_id = "device_id";
|
const std::string last_session_id = "device_id";
|
||||||
local_state->SetString(prefs::kDemoModeSessionIdentifier, last_session_id);
|
local_state->SetString(prefs::kDemoModeSessionIdentifier, last_session_id);
|
||||||
base::MockCallback<DemoLoginController::FailedRequestCallback>
|
|
||||||
cleanup_failed_callback;
|
|
||||||
// `cleanup_failed_callback` not called means no failure for the cleanup.
|
|
||||||
EXPECT_CALL(cleanup_failed_callback, Run(testing::_)).Times(0);
|
|
||||||
GetDemoLoginController()->SetCleanUpFailedCallbackForTest(
|
|
||||||
cleanup_failed_callback.Get());
|
|
||||||
|
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
@ -362,6 +366,13 @@ TEST_F(DemoLoginControllerTest, ServerCleanUpSuccess) {
|
|||||||
local_state->GetString(prefs::kDemoModeSessionIdentifier);
|
local_state->GetString(prefs::kDemoModeSessionIdentifier);
|
||||||
EXPECT_NE(new_session_id, last_session_id);
|
EXPECT_NE(new_session_id, last_session_id);
|
||||||
|
|
||||||
|
// Expect the cleanup request to succeed by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(kCleanupDemoAccountRequestResultHistogram,
|
||||||
|
1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kCleanupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::kSuccess, 1);
|
||||||
|
|
||||||
ExpectOnlyDeviceLocalAccountInUserList();
|
ExpectOnlyDeviceLocalAccountInUserList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,13 +386,17 @@ TEST_F(DemoLoginControllerTest, ServerCleanUpFailed) {
|
|||||||
net::HTTP_UNAUTHORIZED);
|
net::HTTP_UNAUTHORIZED);
|
||||||
base::RunLoop loop;
|
base::RunLoop loop;
|
||||||
GetDemoLoginController()->SetCleanUpFailedCallbackForTest(
|
GetDemoLoginController()->SetCleanUpFailedCallbackForTest(
|
||||||
base::BindLambdaForTesting(
|
base::BindLambdaForTesting([&]() {
|
||||||
[&](const DemoLoginController::ResultCode result_code) {
|
// Expect the cleanup request to fail by checking metrics.
|
||||||
EXPECT_EQ(result_code,
|
histogram_tester_.ExpectTotalCount(
|
||||||
DemoLoginController::ResultCode::kRequestFailed);
|
kCleanupDemoAccountRequestResultHistogram, 1);
|
||||||
loop.Quit();
|
histogram_tester_.ExpectBucketCount(
|
||||||
}));
|
kCleanupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kRequestFailed,
|
||||||
|
1);
|
||||||
|
loop.Quit();
|
||||||
|
}));
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
loop.Run();
|
loop.Run();
|
||||||
@ -413,46 +428,59 @@ TEST_F(DemoLoginControllerTest,
|
|||||||
const std::string last_session_id = "device_id";
|
const std::string last_session_id = "device_id";
|
||||||
local_state->SetString(prefs::kDemoModeSessionIdentifier, last_session_id);
|
local_state->SetString(prefs::kDemoModeSessionIdentifier, last_session_id);
|
||||||
|
|
||||||
// Right after the account cleanup failed, it'll try to set up the demo
|
|
||||||
// account regardless of the cleanup result. However, it's still
|
|
||||||
// unable to obtain the DM Token and the Client ID, so it will fail again and
|
|
||||||
// fall back to MGS.
|
|
||||||
base::RunLoop loop;
|
|
||||||
GetDemoLoginController()->SetCleanUpFailedCallbackForTest(
|
|
||||||
base::BindLambdaForTesting([&](const DemoLoginController::ResultCode
|
|
||||||
result_code) {
|
|
||||||
EXPECT_EQ(
|
|
||||||
result_code,
|
|
||||||
DemoLoginController::ResultCode::kCannotObtainDMTokenAndClientID);
|
|
||||||
loop.Quit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
loop.Run();
|
|
||||||
|
|
||||||
// Expect the test account to be removed even if the cleanup failed.
|
// Expect the test account to be removed even if the cleanup failed.
|
||||||
ExpectOnlyDeviceLocalAccountInUserList();
|
ExpectOnlyDeviceLocalAccountInUserList();
|
||||||
|
|
||||||
// Expect auto login managed guest session to start.
|
// Expect the cleanup request to fail by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(kCleanupDemoAccountRequestResultHistogram,
|
||||||
|
1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kCleanupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kCannotObtainDMTokenAndClientID,
|
||||||
|
1);
|
||||||
|
|
||||||
|
// Right after the account cleanup failed, it'll try to set up the demo
|
||||||
|
// account regardless of the cleanup result. However, it's still
|
||||||
|
// unable to obtain the DM Token and the Client ID, so it will fail again and
|
||||||
|
// fall back to MGS. Therefore, we expect the auto login managed guest session
|
||||||
|
// to start.
|
||||||
EXPECT_TRUE(existing_user_controller()->IsAutoLoginTimerRunningForTesting());
|
EXPECT_TRUE(existing_user_controller()->IsAutoLoginTimerRunningForTesting());
|
||||||
|
// Also expect the setup request to fail for the same reason by checking
|
||||||
|
// metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(kSetupDemoAccountRequestResultHistogram,
|
||||||
|
1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kCannotObtainDMTokenAndClientID,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DemoLoginControllerTest, FallbackToMGS) {
|
TEST_F(DemoLoginControllerTest, FallbackToMGS) {
|
||||||
// Mock setup failed by returning invalid credential.
|
// Mock setup failed by returning invalid credential.
|
||||||
test_url_loader_factory_.AddResponse(GetSetupUrl().spec(), kInValidGaiaCreds);
|
test_url_loader_factory_.AddResponse(GetSetupUrl().spec(), kInValidGaiaCreds);
|
||||||
|
|
||||||
base::RunLoop loop;
|
|
||||||
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
||||||
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
|
||||||
base::BindLambdaForTesting(
|
|
||||||
[&](const DemoLoginController::ResultCode result_code) {
|
|
||||||
loop.Quit();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
base::RunLoop loop;
|
||||||
|
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
||||||
|
base::BindLambdaForTesting([&]() {
|
||||||
|
// Expect the setup request to fail by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram, 1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kInvalidCreds,
|
||||||
|
1);
|
||||||
|
loop.Quit();
|
||||||
|
}));
|
||||||
// Verify demo account login gets triggered by `ExistingUserController`.
|
// Verify demo account login gets triggered by `ExistingUserController`.
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
|
|
||||||
loop.Run();
|
loop.Run();
|
||||||
|
|
||||||
// Expect auto login managed guest session to start.
|
// Expect auto login managed guest session to start.
|
||||||
@ -470,20 +498,24 @@ TEST_F(DemoLoginControllerTest, LogServerError) {
|
|||||||
testing::HasSubstr("Setup response error: error code: 500; message: "
|
testing::HasSubstr("Setup response error: error code: 500; message: "
|
||||||
"Internal error encountered.; status: INTERNAL.")))
|
"Internal error encountered.; status: INTERNAL.")))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
base::RunLoop loop;
|
|
||||||
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
EXPECT_CALL(login_display_host(), CompleteLogin).Times(0);
|
||||||
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
|
||||||
base::BindLambdaForTesting(
|
|
||||||
[&](const DemoLoginController::ResultCode result_code) {
|
|
||||||
EXPECT_EQ(result_code,
|
|
||||||
DemoLoginController::ResultCode::kRequestFailed);
|
|
||||||
loop.Quit();
|
|
||||||
log.StartCapturingLogs();
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
base::RunLoop loop;
|
||||||
|
GetDemoLoginController()->SetSetupFailedCallbackForTest(
|
||||||
|
base::BindLambdaForTesting([&]() {
|
||||||
|
// Expect the setup request to fail by checking metrics.
|
||||||
|
histogram_tester_.ExpectTotalCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram, 1);
|
||||||
|
histogram_tester_.ExpectBucketCount(
|
||||||
|
kSetupDemoAccountRequestResultHistogram,
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode::
|
||||||
|
kRequestFailed,
|
||||||
|
1);
|
||||||
|
loop.Quit();
|
||||||
|
log.StartCapturingLogs();
|
||||||
|
}));
|
||||||
// Trigger auto sign in:
|
// Trigger auto sign in:
|
||||||
ConfigureAutoLoginSetting();
|
ConfigureAutoLoginSetting();
|
||||||
|
|
||||||
loop.Run();
|
loop.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3749,6 +3749,19 @@ to ensure that the crash string is shown properly on the user-facing crash UI.
|
|||||||
<int value="33" label="Success. No error."/>
|
<int value="33" label="Success. No error."/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
|
<enum name="DemoModeSignedInAccountRequestResult">
|
||||||
|
<summary>
|
||||||
|
The result of account cleanup request in demo mode signed in experience.
|
||||||
|
</summary>
|
||||||
|
<int value="0" label="Success."/>
|
||||||
|
<int value="1" label="Malformat Http response."/>
|
||||||
|
<int value="2" label="Missing required credential for login."/>
|
||||||
|
<int value="3" label="Empty Http response."/>
|
||||||
|
<int value="4" label="Network error."/>
|
||||||
|
<int value="5" label="Server side error or out of quota."/>
|
||||||
|
<int value="6" label="Unbale to obtain the DM Token and the Client ID."/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
<enum name="DeprecatedArcKioskUserStatus">
|
<enum name="DeprecatedArcKioskUserStatus">
|
||||||
<int value="0" label="Hide ARC kiosk user on the login screen"/>
|
<int value="0" label="Hide ARC kiosk user on the login screen"/>
|
||||||
<int value="1" label="Attempt to delete cryptohome for ARC kiosk user"/>
|
<int value="1" label="Attempt to delete cryptohome for ARC kiosk user"/>
|
||||||
|
@ -3685,6 +3685,32 @@ chromium-metrics-reviews@google.com.
|
|||||||
</summary>
|
</summary>
|
||||||
</histogram>
|
</histogram>
|
||||||
|
|
||||||
|
<histogram name="DemoMode.SignedIn.AccountCleanupResult"
|
||||||
|
enum="DemoModeSignedInAccountRequestResult" expires_after="2026-01-15">
|
||||||
|
<owner>wanghaifan@google.com</owner>
|
||||||
|
<owner>cros-demo-mode-eng@google.com</owner>
|
||||||
|
<summary>
|
||||||
|
This records the result of the account cleanup request in demo mode signed
|
||||||
|
in experience. It can be success or one of the possible failure reasons,
|
||||||
|
such as the network error. Please refer to the enum class
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode for more
|
||||||
|
information.
|
||||||
|
</summary>
|
||||||
|
</histogram>
|
||||||
|
|
||||||
|
<histogram name="DemoMode.SignedIn.AccountSetupResult"
|
||||||
|
enum="DemoModeSignedInAccountRequestResult" expires_after="2026-01-15">
|
||||||
|
<owner>wanghaifan@google.com</owner>
|
||||||
|
<owner>cros-demo-mode-eng@google.com</owner>
|
||||||
|
<summary>
|
||||||
|
This records the result of the account setup request in demo mode signed in
|
||||||
|
experience. It can be success or one of the possible failure reasons, such
|
||||||
|
as the network error. Please refer to the enum class
|
||||||
|
DemoSessionMetricsRecorder::DemoAccountRequestResultCode for more
|
||||||
|
information.
|
||||||
|
</summary>
|
||||||
|
</histogram>
|
||||||
|
|
||||||
<histogram name="DemoMode.SignedIn.Shopper.DwellTime" units="seconds"
|
<histogram name="DemoMode.SignedIn.Shopper.DwellTime" units="seconds"
|
||||||
expires_after="2026-01-21">
|
expires_after="2026-01-21">
|
||||||
<owner>wanghaifan@google.com</owner>
|
<owner>wanghaifan@google.com</owner>
|
||||||
|
Reference in New Issue
Block a user