blob: aabd79afbe52db6a0254af6609b4cdedc01778d6 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/user_education/low_usage_help_controller.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/user_education/user_education_service.h"
#include "chrome/browser/user_education/user_education_service_factory.h"
#include "components/feature_engagement/public/feature_constants.h"
namespace {
const void* const kLowUsageHelpControllerKey = &kLowUsageHelpControllerKey;
constexpr base::TimeDelta kRetryDelay = base::Seconds(1);
}
LowUsageHelpController::LowUsageHelpController(Profile* profile)
: profile_(profile) {
if (UserEducationService* const service =
UserEducationServiceFactory::GetForBrowserContext(profile)) {
if (RecentSessionObserver* const observer =
service->recent_session_observer()) {
subscription_ = observer->AddLowUsageSessionCallback(
base::BindRepeating(&LowUsageHelpController::OnLowUsageSession,
weak_ptr_factory_.GetWeakPtr()));
}
}
}
LowUsageHelpController::~LowUsageHelpController() = default;
// static
LowUsageHelpController* LowUsageHelpController::MaybeCreateForProfile(
Profile* profile) {
if (auto* const data = profile->GetUserData(kLowUsageHelpControllerKey)) {
return static_cast<LowUsageHelpController*>(data);
}
auto new_data_ptr = base::WrapUnique(new LowUsageHelpController(profile));
auto* const new_data = new_data_ptr.get();
profile->SetUserData(kLowUsageHelpControllerKey, std::move(new_data_ptr));
return new_data;
}
LowUsageHelpController* LowUsageHelpController::GetForProfileForTesting(
Profile* profile) {
if (auto* const data = profile->GetUserData(kLowUsageHelpControllerKey)) {
return static_cast<LowUsageHelpController*>(data);
}
return nullptr;
}
void LowUsageHelpController::OnLowUsageSession() {
retrying_ = false;
retry_timer_.Stop();
// Always want to try to show a promo on a fresh call stack.
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, base::BindOnce(&LowUsageHelpController::MaybeShowPromo,
weak_ptr_factory_.GetWeakPtr()));
}
void LowUsageHelpController::MaybeShowPromo() {
// Get the most recent active browser in the profile.
auto* const browser = chrome::FindBrowserWithProfile(profile_);
if (!browser) {
// This can happen if windows are still loading up; that's fine.
// Record the try count.
const int try_count = retrying_ ? 2 : 1;
UMA_HISTOGRAM_EXACT_LINEAR(
"UserEducation.MessageNotShown.DesktopReEngagement.NoBrowser",
try_count, 3);
// Try again with a small delay. If this was already a retry, then just
// don't show the promo.
if (!retrying_) {
retrying_ = true;
retry_timer_.Start(FROM_HERE, kRetryDelay,
base::BindOnce(&LowUsageHelpController::MaybeShowPromo,
weak_ptr_factory_.GetWeakPtr()));
}
// Either way, don't try to show the promo right now without a window.
return;
}
browser->window()->MaybeShowStartupFeaturePromo(
feature_engagement::kIPHDesktopReEngagementFeature);
}