chromium/chrome/browser/ui/views/profiles/avatar_toolbar_button_delegate.cc

// Copyright 2019 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/views/profiles/avatar_toolbar_button_delegate.h"

#include <optional>

#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "base/scoped_observation.h"
#include "base/strings/utf_string_conversions.h"
#include "base/supports_user_data.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/util/managed_browser_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_ui_util.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/profiles/profile_colors_util.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/dotted_icon.h"
#include "chrome/browser/ui/views/profiles/avatar_toolbar_button.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/policy/core/common/management/management_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/base/signin_prefs.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/primary_account_change_event.h"
#include "components/sync/base/features.h"
#include "components/sync/service/sync_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/views/accessibility/view_accessibility.h"

namespace {

// Timings used for testing purposes. Infinite time for the tests to confidently
// test the behaviors while a delay is ongoing.
constexpr base::TimeDelta kInfiniteTimeForTesting =;

constexpr float kAvatarIconSigninPendingShrinkRatio =;

constexpr base::TimeDelta kShowNameDuration =;
static std::optional<base::TimeDelta> g_show_name_duration_for_testing;

constexpr base::TimeDelta kShowSigninPendingTextDelay =;
static std::optional<base::TimeDelta>
    g_show_signin_pending_text_delay_for_testing;

#if BUILDFLAG(ENABLE_DICE_SUPPORT)
constexpr base::TimeDelta kEnterpriseTextTransientDuration =;
static std::optional<base::TimeDelta>
    g_enterprise_text_transient_duration_for_testing;
#endif

ProfileAttributesStorage& GetProfileAttributesStorage() {}

ProfileAttributesEntry* GetProfileAttributesEntry(Profile* profile) {}

gfx::Image GetGaiaAccountImage(Profile* profile) {}

// Expected to be called when Management is set.
// Returns:
// - true for Work.
// - false for School.
bool IsManagementWork(Profile* profile) {}

}  // namespace

namespace internal {

// States of the button ordered in priority of getting displayed.
// The order of those values is used with the `StateManager` to make sure the
// active state with the highest priority is shown.
// The lower the value of the enum, the higher the priority.
enum class ButtonState {};

namespace {

class StateProvider;
class ExplicitStateProvider;
class SyncErrorStateProvider;
class SigninPendingStateProvider;
class ShowIdentityNameStateProvider;
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
class ManagementStateProvider;
#endif

// Allows getting data from the underlying implementation of a `StateProvider`.
// `StateVisitor::visit()` overrides to be added based on the need.
class StateVisitor {};

class StateObserver {};

// Each implementation of StateProvider should be able to manage itself with the
// appropriate initial values such as a profile and observe/listen to changes in
// order to affect their active status.
class StateProvider {};

// Used for Guest and Incognito sessions.
class PrivateStateProvider : public StateProvider, public BrowserListObserver {};

class ExplicitStateProvider : public StateProvider {};

class ShowIdentityNameStateProvider : public StateProvider,
                                      public signin::IdentityManager::Observer,
                                      public AvatarToolbarButton::Observer {};

class SyncErrorStateProvider : public StateProvider,
                               public syncer::SyncServiceObserver {};

const void* const kSigninPendingTimestampStartKey =;

// Helper struct to store a `base::TimeTicks` as a Profile user data.
struct TimeStampData : public base::SupportsUserData::Data {};

// This state has two modes when active; extended and collapsed. This states is
// active when the Signed in account is in error. Based on the source of the
// error, a mode is active:
// - collapsed: error originates from a web signout action from the user, the
// avatar button will not show a text.
// - extended version: any other error or after 50 minutes past a web signout or
// on Chrome restart, the button will extend to show a "Verify it's you" text.
//
// In both modes, the avatar icon is shrunk slightly and surrounded by a dotted
// circle to show the pending state.
class SigninPendingStateProvider : public StateProvider,
                                   public signin::IdentityManager::Observer {};

#if BUILDFLAG(ENABLE_DICE_SUPPORT)
class ManagementStateProvider : public StateProvider,
                                public ProfileAttributesStorage::Observer,
                                public BrowserListObserver {};
#endif

// Regular State, should always have the lowest priority.
class NormalStateProvider : public StateProvider {};

// Allows getting the underlying implementation of `StateProvider` given a
// generic `StateProvider`.
class StateProviderGetter : public StateVisitor {};

}  // namespace

// Container of all the states and returns the active state with the highest
// priority.
// All states are initialized at construction based on the Profile type.
// Exception for `ButtonState::kExplicitTextShowing` with
// `ExplicitStateProvider`  which is the only state that can be added
// dynamically and controlled externally. It has to be part of the
// `StateManager` however to properly compute the current active state.
// This class also listens to Profile changes that should affect the global
// state of the button, for chanhges that should occur regardless of the current
// active state for Regular Profiles.
class StateManager : public StateObserver,
                     public signin::IdentityManager::Observer,
                     public ProfileAttributesStorage::Observer {};

}  // namespace internal

ButtonState;
ExplicitStateProvider;

AvatarToolbarButtonDelegate::AvatarToolbarButtonDelegate(
    AvatarToolbarButton* button,
    Browser* browser)
    :{}

AvatarToolbarButtonDelegate::~AvatarToolbarButtonDelegate() = default;

void AvatarToolbarButtonDelegate::InitializeStateManager() {}

bool AvatarToolbarButtonDelegate::IsStateManagerInitialized() const {}

std::u16string AvatarToolbarButtonDelegate::GetProfileName() const {}

std::u16string AvatarToolbarButtonDelegate::GetShortProfileName() const {}

gfx::Image AvatarToolbarButtonDelegate::GetGaiaAccountImage() const {}

gfx::Image AvatarToolbarButtonDelegate::GetProfileAvatarImage(
    int preferred_size) const {}

int AvatarToolbarButtonDelegate::GetWindowCount() const {}

void AvatarToolbarButtonDelegate::OnThemeChanged(
    const ui::ColorProvider* color_provider) {}

base::ScopedClosureRunner AvatarToolbarButtonDelegate::ShowExplicitText(
    const std::u16string& new_text,
    std::optional<std::u16string> accessibility_label) {}

std::pair<std::u16string, std::optional<SkColor>>
AvatarToolbarButtonDelegate::GetTextAndColor(
    const ui::ColorProvider* const color_provider) const {}

std::optional<std::u16string>
AvatarToolbarButtonDelegate::GetAccessibilityLabel() const {}

SkColor AvatarToolbarButtonDelegate::GetHighlightTextColor(
    const ui::ColorProvider* const color_provider) const {}

std::u16string AvatarToolbarButtonDelegate::GetAvatarTooltipText() const {}

std::pair<ChromeColorIds, ChromeColorIds>
AvatarToolbarButtonDelegate::GetInkdropColors() const {}

ui::ImageModel AvatarToolbarButtonDelegate::GetAvatarIcon(
    int icon_size,
    SkColor icon_color) const {}

bool AvatarToolbarButtonDelegate::ShouldPaintBorder() const {}

void AvatarToolbarButtonDelegate::OnPrimaryAccountChanged(
    const signin::PrimaryAccountChangeEvent& event_details) {}

void AvatarToolbarButtonDelegate::OnExtendedAccountInfoUpdated(
    const AccountInfo& info) {}

void AvatarToolbarButtonDelegate::OnErrorStateOfRefreshTokenUpdatedForAccount(
    const CoreAccountInfo& account_info,
    const GoogleServiceAuthError& error,
    signin_metrics::SourceForRefreshTokenOperation token_operation_source) {}

void AvatarToolbarButtonDelegate::PaintIcon(
    gfx::Canvas* canvas,
    const gfx::Rect& icon_bounds) const {}

// static
base::AutoReset<std::optional<base::TimeDelta>>
AvatarToolbarButtonDelegate::CreateScopedInfiniteDelayOverrideForTesting(
    AvatarDelayType delay_type) {}

void AvatarToolbarButtonDelegate::TriggerTimeoutForTesting(
    AvatarDelayType delay_type) {}

// static
base::AutoReset<std::optional<base::TimeDelta>> AvatarToolbarButtonDelegate::
    CreateScopedZeroDelayOverrideSigninPendingTextForTesting() {}