Commit 67538934 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

[Identity pill] Show the pill on sign-in / startup (no animation)

This CL adds the first version of identity pill -- only the triggering
logic to show and to hide the pill. No animation nor UI changes are
included in this CL.

Bug: 967317
Change-Id: I76c98e9963ba97606bc9458eb111d3a6bc0872ae
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1679764Reviewed-by: default avatarThomas Tangl <tangltom@chromium.org>
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682648}
parent 4e3ce924
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "base/feature_list.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/app/vector_icons/vector_icons.h"
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
...@@ -41,6 +43,9 @@ ...@@ -41,6 +43,9 @@
namespace { namespace {
constexpr base::TimeDelta kEmailExpansionDuration =
base::TimeDelta::FromSeconds(3);
ProfileAttributesEntry* GetProfileAttributesEntry(Profile* profile) { ProfileAttributesEntry* GetProfileAttributesEntry(Profile* profile) {
ProfileAttributesEntry* entry; ProfileAttributesEntry* entry;
if (!g_browser_process->profile_manager() if (!g_browser_process->profile_manager()
...@@ -62,7 +67,8 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser) ...@@ -62,7 +67,8 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser)
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
browser_list_observer_(this), browser_list_observer_(this),
profile_observer_(this), profile_observer_(this),
identity_manager_observer_(this) { identity_manager_observer_(this),
weak_ptr_factory_(this) {
if (IsIncognitoCounterActive()) if (IsIncognitoCounterActive())
browser_list_observer_.Add(BrowserList::GetInstance()); browser_list_observer_.Add(BrowserList::GetInstance());
...@@ -100,6 +106,12 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser) ...@@ -100,6 +106,12 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser)
SetEnabled(!IsIncognito() || IsIncognitoCounterActive()); SetEnabled(!IsIncognito() || IsIncognitoCounterActive());
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
if (base::FeatureList::IsEnabled(features::kAnimatedAvatarButton)) {
// For consistency with identity representation, we need to have the avatar
// on the left and the (potential) user-name / email on the right.
SetHorizontalAlignment(gfx::ALIGN_LEFT);
}
// Set initial text and tooltip. UpdateIcon() needs to be called from the // Set initial text and tooltip. UpdateIcon() needs to be called from the
// outside as GetThemeProvider() is not available until the button is added to // outside as GetThemeProvider() is not available until the button is added to
// ToolbarView's hierarchy. // ToolbarView's hierarchy.
...@@ -111,7 +123,15 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser) ...@@ -111,7 +123,15 @@ AvatarToolbarButton::AvatarToolbarButton(Browser* browser)
AvatarToolbarButton::~AvatarToolbarButton() {} AvatarToolbarButton::~AvatarToolbarButton() {}
void AvatarToolbarButton::UpdateIcon() { void AvatarToolbarButton::UpdateIcon() {
SetImage(views::Button::STATE_NORMAL, GetAvatarIcon()); gfx::Image gaia_image = GetGaiaImage();
SetImage(views::Button::STATE_NORMAL, GetAvatarIcon(gaia_image));
// TODO(crbug.com/983182): Move this logic to OnExtendedAccountInfoUpdated()
// once GetGaiaImage() is updated to use GetUnconsentedPrimaryAccountInfo().
if (waiting_for_image_to_show_user_email_ && !gaia_image.IsEmpty()) {
waiting_for_image_to_show_user_email_ = false;
ExpandToShowEmail();
}
} }
void AvatarToolbarButton::UpdateText() { void AvatarToolbarButton::UpdateText() {
...@@ -155,6 +175,14 @@ void AvatarToolbarButton::UpdateText() { ...@@ -155,6 +175,14 @@ void AvatarToolbarButton::UpdateText() {
gfx::kGoogleBlue050, gfx::kGoogleBlue900); gfx::kGoogleBlue050, gfx::kGoogleBlue900);
text = l10n_util::GetStringUTF16(IDS_AVATAR_BUTTON_SYNC_PAUSED); text = l10n_util::GetStringUTF16(IDS_AVATAR_BUTTON_SYNC_PAUSED);
} else if (user_email_to_show_.has_value() &&
!waiting_for_image_to_show_user_email_) {
text = base::UTF8ToUTF16(*user_email_to_show_);
if (GetThemeProvider()) {
const SkColor text_color =
GetThemeProvider()->GetColor(ThemeProperties::COLOR_TAB_TEXT);
SetEnabledTextColors(text_color);
}
} }
SetInsets(); SetInsets();
...@@ -239,6 +267,18 @@ void AvatarToolbarButton::OnProfileNameChanged( ...@@ -239,6 +267,18 @@ void AvatarToolbarButton::OnProfileNameChanged(
UpdateText(); UpdateText();
} }
void AvatarToolbarButton::OnUnconsentedPrimaryAccountChanged(
const CoreAccountInfo& unconsented_primary_account_info) {
if (!unconsented_primary_account_info.IsEmpty() &&
base::FeatureList::IsEnabled(features::kAnimatedAvatarButton)) {
user_email_to_show_ = unconsented_primary_account_info.email;
// If we already have a gaia image, the pill will be immediately
// displayed by UpdateIcon().
waiting_for_image_to_show_user_email_ = true;
UpdateIcon();
}
}
void AvatarToolbarButton::OnAccountsInCookieUpdated( void AvatarToolbarButton::OnAccountsInCookieUpdated(
const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) { const GoogleServiceAuthError& error) {
...@@ -260,6 +300,29 @@ void AvatarToolbarButton::OnTouchUiChanged() { ...@@ -260,6 +300,29 @@ void AvatarToolbarButton::OnTouchUiChanged() {
PreferredSizeChanged(); PreferredSizeChanged();
} }
void AvatarToolbarButton::ExpandToShowEmail() {
DCHECK(user_email_to_show_.has_value());
DCHECK(!waiting_for_image_to_show_user_email_);
UpdateText();
// Hide the pill after a while.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&AvatarToolbarButton::ResetUserEmailToShow,
weak_ptr_factory_.GetWeakPtr()),
kEmailExpansionDuration);
}
void AvatarToolbarButton::ResetUserEmailToShow() {
DCHECK(user_email_to_show_.has_value());
user_email_to_show_ = base::nullopt;
// Update the text to the pre-shown state. This also makes sure that we now
// reflect changes that happened while the identity pill was shown.
UpdateText();
}
bool AvatarToolbarButton::IsIncognito() const { bool AvatarToolbarButton::IsIncognito() const {
return profile_->IsIncognitoProfile(); return profile_->IsIncognitoProfile();
} }
...@@ -300,6 +363,9 @@ base::string16 AvatarToolbarButton::GetAvatarTooltipText() const { ...@@ -300,6 +363,9 @@ base::string16 AvatarToolbarButton::GetAvatarTooltipText() const {
if (ShouldShowGenericIcon()) if (ShouldShowGenericIcon())
return l10n_util::GetStringUTF16(IDS_GENERIC_USER_AVATAR_LABEL); return l10n_util::GetStringUTF16(IDS_GENERIC_USER_AVATAR_LABEL);
if (user_email_to_show_.has_value() && !waiting_for_image_to_show_user_email_)
return base::UTF8ToUTF16(*user_email_to_show_);
const base::string16 profile_name = const base::string16 profile_name =
profiles::GetAvatarNameForProfile(profile_->GetPath()); profiles::GetAvatarNameForProfile(profile_->GetPath());
switch (GetSyncState()) { switch (GetSyncState()) {
...@@ -317,7 +383,8 @@ base::string16 AvatarToolbarButton::GetAvatarTooltipText() const { ...@@ -317,7 +383,8 @@ base::string16 AvatarToolbarButton::GetAvatarTooltipText() const {
return base::string16(); return base::string16();
} }
gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const { gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon(
const gfx::Image& gaia_image) const {
// Note that the non-touchable icon size is larger than the default to // Note that the non-touchable icon size is larger than the default to
// make the avatar icon easier to read. // make the avatar icon easier to read.
const int icon_size = const int icon_size =
...@@ -333,8 +400,14 @@ gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const { ...@@ -333,8 +400,14 @@ gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const {
return gfx::CreateVectorIcon(kUserMenuGuestIcon, icon_size, icon_color); return gfx::CreateVectorIcon(kUserMenuGuestIcon, icon_size, icon_color);
gfx::Image avatar_icon; gfx::Image avatar_icon;
if (!ShouldShowGenericIcon()) ProfileAttributesEntry* entry = GetProfileAttributesEntry(profile_);
avatar_icon = GetIconImageFromProfile(); if (!ShouldShowGenericIcon() && entry) {
if (!gaia_image.IsEmpty()) {
avatar_icon = gaia_image;
} else {
avatar_icon = entry->GetAvatarIcon();
}
}
if (!avatar_icon.IsEmpty()) { if (!avatar_icon.IsEmpty()) {
return profiles::GetSizedAvatarIcon(avatar_icon, true, icon_size, icon_size, return profiles::GetSizedAvatarIcon(avatar_icon, true, icon_size, icon_size,
...@@ -345,7 +418,7 @@ gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const { ...@@ -345,7 +418,7 @@ gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const {
return gfx::CreateVectorIcon(kUserAccountAvatarIcon, icon_size, icon_color); return gfx::CreateVectorIcon(kUserAccountAvatarIcon, icon_size, icon_color);
} }
gfx::Image AvatarToolbarButton::GetIconImageFromProfile() const { gfx::Image AvatarToolbarButton::GetGaiaImage() const {
ProfileAttributesEntry* entry = GetProfileAttributesEntry(profile_); ProfileAttributesEntry* entry = GetProfileAttributesEntry(profile_);
if (!entry) { if (!entry) {
// This can happen if the user deletes the current profile. // This can happen if the user deletes the current profile.
...@@ -372,6 +445,10 @@ gfx::Image AvatarToolbarButton::GetIconImageFromProfile() const { ...@@ -372,6 +445,10 @@ gfx::Image AvatarToolbarButton::GetIconImageFromProfile() const {
if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_) && if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_) &&
!IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount() && !IdentityManagerFactory::GetForProfile(profile_)->HasPrimaryAccount() &&
entry->IsUsingDefaultAvatar()) { entry->IsUsingDefaultAvatar()) {
// TODO(crbug.com/983182): Update to use GetUnconsentedPrimaryAccountInfo()
// and maybe move this whole logic to OnExtendedAccountInfoUpdated() which
// is the only callback where the image can change (and cache the resulting
// image as and cache it as |unconsented_primary_account_gaia_image_|).
std::vector<AccountInfo> promo_accounts = std::vector<AccountInfo> promo_accounts =
signin_ui_util::GetAccountsForDicePromos(profile_); signin_ui_util::GetAccountsForDicePromos(profile_);
if (!promo_accounts.empty()) { if (!promo_accounts.empty()) {
...@@ -379,8 +456,7 @@ gfx::Image AvatarToolbarButton::GetIconImageFromProfile() const { ...@@ -379,8 +456,7 @@ gfx::Image AvatarToolbarButton::GetIconImageFromProfile() const {
} }
} }
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
return gfx::Image();
return entry->GetAvatarIcon();
} }
AvatarToolbarButton::SyncState AvatarToolbarButton::GetSyncState() const { AvatarToolbarButton::SyncState AvatarToolbarButton::GetSyncState() const {
......
...@@ -63,6 +63,8 @@ class AvatarToolbarButton : public ToolbarButton, ...@@ -63,6 +63,8 @@ class AvatarToolbarButton : public ToolbarButton,
// IdentityManager::Observer: // IdentityManager::Observer:
// Needed if the first sync promo account should be displayed. // Needed if the first sync promo account should be displayed.
void OnUnconsentedPrimaryAccountChanged(
const CoreAccountInfo& unconsented_primary_account_info) override;
void OnAccountsInCookieUpdated( void OnAccountsInCookieUpdated(
const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info, const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override; const GoogleServiceAuthError& error) override;
...@@ -72,12 +74,15 @@ class AvatarToolbarButton : public ToolbarButton, ...@@ -72,12 +74,15 @@ class AvatarToolbarButton : public ToolbarButton,
// ui::MaterialDesignControllerObserver: // ui::MaterialDesignControllerObserver:
void OnTouchUiChanged() override; void OnTouchUiChanged() override;
void ExpandToShowEmail();
void ResetUserEmailToShow();
bool IsIncognito() const; bool IsIncognito() const;
bool IsIncognitoCounterActive() const; bool IsIncognitoCounterActive() const;
bool ShouldShowGenericIcon() const; bool ShouldShowGenericIcon() const;
base::string16 GetAvatarTooltipText() const; base::string16 GetAvatarTooltipText() const;
gfx::ImageSkia GetAvatarIcon() const; gfx::ImageSkia GetAvatarIcon(const gfx::Image& gaia_image) const;
gfx::Image GetIconImageFromProfile() const; gfx::Image GetGaiaImage() const;
SyncState GetSyncState() const; SyncState GetSyncState() const;
void SetInsets(); void SetInsets();
...@@ -89,6 +94,12 @@ class AvatarToolbarButton : public ToolbarButton, ...@@ -89,6 +94,12 @@ class AvatarToolbarButton : public ToolbarButton,
// when sync state is not normal. // when sync state is not normal.
bool suppress_avatar_button_state_ = false; bool suppress_avatar_button_state_ = false;
// The user email that we're currently showing in an animation or empty if no
// animation is in progress.
base::Optional<std::string> user_email_to_show_;
// We cannot show the animation before we fetch the new avatar.
bool waiting_for_image_to_show_user_email_ = false;
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
AvatarButtonErrorController error_controller_; AvatarButtonErrorController error_controller_;
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
...@@ -100,6 +111,7 @@ class AvatarToolbarButton : public ToolbarButton, ...@@ -100,6 +111,7 @@ class AvatarToolbarButton : public ToolbarButton,
ScopedObserver<ui::MaterialDesignController, AvatarToolbarButton> ScopedObserver<ui::MaterialDesignController, AvatarToolbarButton>
md_observer_{this}; md_observer_{this};
base::WeakPtrFactory<AvatarToolbarButton> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AvatarToolbarButton); DISALLOW_COPY_AND_ASSIGN(AvatarToolbarButton);
}; };
......
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