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

Reland "[Profiles] Use new colored default avatars for taskbar badges"

This is a reland of 6b7290b3

Compared to the original CL, the reland sticks more to the previous
behavior of AvatarMenu::GetImageForMenuButton(), it does not download
high res avatar. The only change in behavior is on Windows where it uses
2x built-in avatars instead of 1x avatars which is beneficial for the
large taskbar of Win10.

Original change's description:
> [Profiles] Use new colored default avatars for taskbar badges
>
> Recently, all logic around profile avatars has been integrated into
> ProfileAttributesEntry::GetAvatarIcon() incl. new features such as
> colored default avatars.
>
> This CL updates code that generates taskbar badges on Windows to
> delegate most of its logic to GetAvatarIcon(). Only the pieces needed
> for obtaining ImageLoadStatus remained in this code.
>
> The only behavioral change is for non-GAIA avatars: high-res /
> 2x windows old avatars are returned instead of low-res avatars. This
> means more downscaling is needed than before. This will be addressed
> by further CLs that will make GetAvatarIcon() respect preferred_size in
> more cases.
>
> Bug: 1122559
> Change-Id: I5eecc7c6647dc78f9ff92d74edb64214a48e8e63
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2514153
> Commit-Queue: Jan Krcal <jkrcal@chromium.org>
> Reviewed-by: David Roger <droger@chromium.org>
> Auto-Submit: Jan Krcal <jkrcal@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#824494}

Bug: 1122559
Change-Id: I5814c801165fde00bb20694561e5b94db0e12cbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521735
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Auto-Submit: Jan Krcal <jkrcal@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824901}
parent fa012ced
......@@ -111,11 +111,11 @@ class AvatarMenu :
~AvatarMenu() override;
// Sets |image| to the avatar corresponding to the profile at |profile_path|.
// For built-in profile avatars, returns the non-high res version. Returns the
// image load status.
// Returns the image load status.
static ImageLoadStatus GetImageForMenuButton(
const base::FilePath& profile_path,
gfx::Image* image);
gfx::Image* image,
int preferred_size);
// Opens a Browser with the specified profile in response to the user
// selecting an item. If |always_create| is true then a new window is created
......
......@@ -12,12 +12,12 @@
#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 "ui/base/resource/resource_bundle.h"
// static
AvatarMenu::ImageLoadStatus AvatarMenu::GetImageForMenuButton(
const base::FilePath& profile_path,
gfx::Image* image) {
gfx::Image* image,
int preferred_size) {
if (!g_browser_process->profile_manager())
return ImageLoadStatus::BROWSER_SHUTTING_DOWN;
ProfileAttributesEntry* entry;
......@@ -28,30 +28,14 @@ AvatarMenu::ImageLoadStatus AvatarMenu::GetImageForMenuButton(
}
ImageLoadStatus status = ImageLoadStatus::LOADED;
// If there is a Gaia image available, try to use that.
if (entry->IsUsingGAIAPicture()) {
// The GetGAIAPicture API call will trigger an async image load from disk if
// it has not been loaded into memory.
const gfx::Image* gaia_image = entry->GetGAIAPicture();
if (gaia_image) {
*image = *gaia_image;
return ImageLoadStatus::LOADED;
}
// We need to specifically report GAIA images that are not available yet.
if (entry->IsUsingGAIAPicture() && !entry->GetGAIAPicture()) {
if (entry->IsGAIAPictureLoaded())
status = ImageLoadStatus::MISSING;
else
status = ImageLoadStatus::LOADING;
}
// Otherwise, use the default resource, not the downloaded high-res one.
const size_t icon_index = entry->GetAvatarIconIndex();
const int resource_id =
profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index);
*image =
ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
*image = entry->GetAvatarIcon(preferred_size, /*use_high_res_file=*/false);
return status;
}
......@@ -296,7 +296,8 @@ base::string16 ProfileAttributesEntry::GetUserName() const {
}
gfx::Image ProfileAttributesEntry::GetAvatarIcon(
int size_for_placeholder_avatar) const {
int size_for_placeholder_avatar,
bool use_high_res_file) const {
if (IsUsingGAIAPicture()) {
const gfx::Image* image = GetGAIAPicture();
if (image)
......@@ -312,9 +313,11 @@ gfx::Image ProfileAttributesEntry::GetAvatarIcon(
#if !defined(OS_ANDROID)
// Use the high resolution version of the avatar if it exists. Mobile doesn't
// need the high resolution version so no need to fetch it.
const gfx::Image* image = GetHighResAvatar();
if (image)
return *image;
if (use_high_res_file) {
const gfx::Image* image = GetHighResAvatar();
if (image)
return *image;
}
#endif
const int icon_index = GetAvatarIconIndex();
......
......@@ -84,13 +84,16 @@ class ProfileAttributesEntry {
// address used to sign in and the empty string for profiles that aren't
// signed in to chrome.
base::string16 GetUserName() const;
// Gets the icon used as this profile's avatar.
// Gets the icon used as this profile's avatar. High res icon are downloaded
// only if `download_high_res` is true, otherwise a low-res fallback is
// returned.
// TODO(crbug.com/1100835): Rename |size_for_placeholder_avatar| to |size| and
// make this function resize all avatars appropriately. Remove the default
// value of |size_for_placeholder_avatar| when all callsites pass some value.
// Consider adding a |shape| parameter and get rid of
// profiles::GetSizedAvatarIcon().
gfx::Image GetAvatarIcon(int size_for_placeholder_avatar = 74) const;
gfx::Image GetAvatarIcon(int size_for_placeholder_avatar = 74,
bool use_high_res_file = true) const;
std::string GetLocalAuthCredentials() const;
std::string GetPasswordChangeDetectionToken() const;
// Returns true if the profile is currently running any background apps. Note
......
......@@ -54,6 +54,9 @@
namespace {
#if defined(OS_WIN)
const int kOldAvatarIconWidth = 38;
const int kOldAvatarIconHeight = 31;
// 2x sized versions of the old profile avatar icons.
// TODO(crbug.com/937834): Clean this up.
const int kProfileAvatarIconResources2x[] = {
......@@ -86,9 +89,6 @@ SkBitmap GetSkBitmapCopy(const gfx::Image& image) {
}
#endif // OS_WIN
const int kOldAvatarIconWidth = 38;
const int kOldAvatarIconHeight = 31;
// Determine what the scaled height of the avatar icon should be for a
// specified width, to preserve the aspect ratio.
int GetScaledAvatarHeightForWidth(int width, const gfx::ImageSkia& avatar) {
......@@ -419,13 +419,15 @@ gfx::Image GetAvatarIconForTitleBar(const gfx::Image& image,
#if defined(OS_MAC)
gfx::Image GetAvatarIconForNSMenu(const base::FilePath& profile_path) {
// Always use the low-res, small default avatars in the menu.
// TODO(crbug.com/857064): Call ProfileAttributesEntry::GetAvatarIcon()
// directly and pass in in larger desired size so that it can be smoothly
// clipped to a circle.
constexpr int kMenuAvatarIconSize = 38;
gfx::Image icon;
AvatarMenu::GetImageForMenuButton(profile_path, &icon);
AvatarMenu::GetImageForMenuButton(profile_path, &icon, kMenuAvatarIconSize);
// The image might be too large and need to be resized, e.g. if this is a
// signed-in user using the GAIA profile photo.
constexpr int kMenuAvatarIconSize = 38;
if (icon.Width() > kMenuAvatarIconSize ||
icon.Height() > kMenuAvatarIconSize) {
icon = profiles::GetSizedAvatarIcon(
......@@ -435,26 +437,6 @@ gfx::Image GetAvatarIconForNSMenu(const base::FilePath& profile_path) {
}
#endif
SkBitmap GetAvatarIconAsSquare(const SkBitmap& source_bitmap,
int scale_factor) {
SkBitmap square_bitmap;
if ((source_bitmap.width() == scale_factor * kOldAvatarIconWidth) &&
(source_bitmap.height() == scale_factor * kOldAvatarIconHeight)) {
// If |source_bitmap| matches the old avatar icon dimensions, i.e. it's an
// old avatar icon, shave a couple of columns so the |source_bitmap| is more
// square. So when resized to a square aspect ratio it looks pretty.
gfx::Rect frame(scale_factor * profiles::kAvatarIconSize,
scale_factor * profiles::kAvatarIconSize);
frame.Inset(scale_factor * 2, 0, scale_factor * 2, 0);
source_bitmap.extractSubset(&square_bitmap, gfx::RectToSkIRect(frame));
} else {
// If it's not an old avatar icon, the image should be square.
DCHECK_EQ(source_bitmap.width(), source_bitmap.height());
square_bitmap = source_bitmap;
}
return square_bitmap;
}
// Helper methods for accessing, transforming and drawing avatar icons.
size_t GetDefaultAvatarIconCount() {
return kDefaultAvatarIconsCount;
......@@ -729,13 +711,30 @@ SkBitmap GetWin2xAvatarImage(ProfileAttributesEntry* entry) {
return GetSkBitmapCopy(entry->GetAvatarIcon(IconUtil::kLargeIconSize));
}
SkBitmap GetWin2xAvatarIconAsSquare(const SkBitmap& source_bitmap) {
constexpr int kIconScaleFactor = 2;
if ((source_bitmap.width() != kIconScaleFactor * kOldAvatarIconWidth) ||
(source_bitmap.height() != kIconScaleFactor * kOldAvatarIconHeight)) {
// It's not an old avatar icon, the image should be square.
DCHECK_EQ(source_bitmap.width(), source_bitmap.height());
return source_bitmap;
}
// If |source_bitmap| matches the old avatar icon dimensions, i.e. it's an
// old avatar icon, shave a couple of columns so the |source_bitmap| is more
// square. So when resized to a square aspect ratio it looks pretty.
gfx::Rect frame(gfx::SkIRectToRect(source_bitmap.bounds()));
frame.Inset(/*horizontal=*/kIconScaleFactor * 2, /*vertical=*/0);
SkBitmap cropped_bitmap;
source_bitmap.extractSubset(&cropped_bitmap, gfx::RectToSkIRect(frame));
return cropped_bitmap;
}
SkBitmap GetBadgedWinIconBitmapForAvatar(const SkBitmap& app_icon_bitmap,
const SkBitmap& avatar_bitmap) {
constexpr int kAvatarBitmapScaleFactor = 2;
// TODO(dfried): This function often doesn't actually do the thing it claims
// to. We should probably fix it.
SkBitmap source_bitmap =
profiles::GetAvatarIconAsSquare(avatar_bitmap, kAvatarBitmapScaleFactor);
SkBitmap source_bitmap = profiles::GetWin2xAvatarIconAsSquare(avatar_bitmap);
int avatar_badge_width = kProfileAvatarBadgeSizeWin;
if (app_icon_bitmap.width() != kShortcutIconSizeWin) {
......
......@@ -92,10 +92,6 @@ gfx::Image GetAvatarIconForTitleBar(const gfx::Image& image,
gfx::Image GetAvatarIconForNSMenu(const base::FilePath& profile_path);
#endif
// Returns a bitmap with a couple of columns shaved off so it is more square,
// so that when resized to a square aspect ratio it looks pretty.
SkBitmap GetAvatarIconAsSquare(const SkBitmap& source_bitmap, int scale_factor);
// Gets the number of default avatar icons that exist.
size_t GetDefaultAvatarIconCount();
......@@ -167,6 +163,10 @@ size_t GetRandomAvatarIconIndex(
// Get the 2x avatar image for a ProfileAttributesEntry.
SkBitmap GetWin2xAvatarImage(ProfileAttributesEntry* entry);
// Returns a bitmap with a couple of columns shaved off so it is more square,
// so that when resized to a square aspect ratio it looks pretty.
SkBitmap GetWin2xAvatarIconAsSquare(const SkBitmap& source_bitmap);
// Badges |app_icon_bitmap| with |avatar_bitmap| at the bottom right corner and
// returns the resulting SkBitmap.
SkBitmap GetBadgedWinIconBitmapForAvatar(const SkBitmap& app_icon_bitmap,
......
......@@ -889,8 +889,10 @@ TEST_F(ProfileInfoCacheTest, GetGaiaImageForAvatarMenu) {
// Try to get the GAIA image. For the first time, it triggers an async image
// load from disk. The load status indicates the image is still being loaded.
constexpr int kArbitraryPreferredSize = 96;
EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADING,
AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded));
AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded,
kArbitraryPreferredSize));
EXPECT_FALSE(gfx::test::AreImagesEqual(gaia_image, image_loaded));
// Wait until the async image load finishes.
......@@ -898,7 +900,8 @@ TEST_F(ProfileInfoCacheTest, GetGaiaImageForAvatarMenu) {
// Since the GAIA image is loaded now, we can get it this time.
EXPECT_EQ(AvatarMenu::ImageLoadStatus::LOADED,
AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded));
AvatarMenu::GetImageForMenuButton(profile_path, &image_loaded,
kArbitraryPreferredSize));
EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, image_loaded));
}
#endif
......
......@@ -178,8 +178,10 @@ void DrawTaskbarDecoration(gfx::NativeWindow window, const gfx::Image* image) {
// gfx::Image isn't thread safe.
std::unique_ptr<SkBitmap> bitmap;
if (image) {
bitmap.reset(
new SkBitmap(profiles::GetAvatarIconAsSquare(*image->ToSkBitmap(), 1)));
// If `image` is an old avatar, then it's guaranteed to by 2x by code in
// ProfileAttributesEntry::GetAvatarIcon().
bitmap.reset(new SkBitmap(
profiles::GetWin2xAvatarIconAsSquare(*image->ToSkBitmap())));
}
PostSetOverlayIcon(hwnd, std::move(bitmap), "");
......@@ -204,8 +206,8 @@ void UpdateTaskbarDecoration(Profile* profile, gfx::NativeWindow window) {
// with the default shortcut being pinned, we add the runtime badge for
// safety. See crbug.com/313800.
gfx::Image decoration;
AvatarMenu::ImageLoadStatus status =
AvatarMenu::GetImageForMenuButton(profile->GetPath(), &decoration);
AvatarMenu::ImageLoadStatus status = AvatarMenu::GetImageForMenuButton(
profile->GetPath(), &decoration, kOverlayIconSize);
// If the user is using a Gaia picture and the picture is still being loaded,
// wait until the load finishes. This taskbar decoration will be triggered
......
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