Chromium Code Reviews| Index: chrome/browser/chromeos/login/wallpaper_manager.cc |
| diff --git a/chrome/browser/chromeos/login/wallpaper_manager.cc b/chrome/browser/chromeos/login/wallpaper_manager.cc |
| index 4f9351fa816dfd6323ae9aafcde387309ccdee12..9be96fea644e1d899f4882aabec031172ec9bc5e 100644 |
| --- a/chrome/browser/chromeos/login/wallpaper_manager.cc |
| +++ b/chrome/browser/chromeos/login/wallpaper_manager.cc |
| @@ -19,6 +19,7 @@ |
| #include "base/time.h" |
| #include "base/values.h" |
| #include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/chromeos/login/simple_png_encoder.h" |
| #include "chrome/browser/chromeos/login/user.h" |
| #include "chrome/browser/chromeos/login/user_manager.h" |
| #include "chrome/browser/chromeos/login/wizard_controller.h" |
| @@ -97,6 +98,11 @@ gfx::ImageSkia ImageSkiaDeepCopy(const gfx::ImageSkia& image) { |
| return copy; |
| } |
| +// For our scaling ratios we need to round positive numbers. |
| +int RoundPositive(double x) { |
| + return static_cast<int>(floor(x + 0.5)); |
| +} |
| + |
| } // namespace |
| namespace chromeos { |
| @@ -165,18 +171,24 @@ void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() { |
| SetUserWallpaper(UserManager::Get()->GetLoggedInUser().email()); |
| } |
| -void WallpaperManager::FetchCustomWallpaper(const std::string& email) { |
| +void WallpaperManager::GetCustomWallpaper(const std::string& email) { |
| User::WallpaperType type; |
| int index; |
| base::Time date; |
| GetUserWallpaperProperties(email, &type, &index, &date); |
| ash::WallpaperLayout layout = static_cast<ash::WallpaperLayout>(index); |
| - |
| - std::string wallpaper_path = GetWallpaperPathForUser(email, false).value(); |
| - |
| - wallpaper_loader_->Start(wallpaper_path, 0, |
| - base::Bind(&WallpaperManager::FetchWallpaper, |
| - base::Unretained(this), email, layout)); |
| + // Initializes file name to a dummy string here. The real file path will |
| + // be set in GetCustomWallpaperInternal. |
| + WallpaperInfo info = { |
| + "DUMMY", |
| + layout, |
| + type, |
| + date |
| + }; |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&WallpaperManager::GetCustomWallpaperInternal, |
| + base::Unretained(this), email, info)); |
| } |
| bool WallpaperManager::GetCustomWallpaperFromCache(const std::string& email, |
| @@ -190,9 +202,17 @@ bool WallpaperManager::GetCustomWallpaperFromCache(const std::string& email, |
| return false; |
| } |
| +FilePath WallpaperManager::GetOriginalWallpaperPathForUser( |
| + const std::string& username) { |
| + std::string filename = username + "_wallpaper.png"; |
| + FilePath user_data_dir; |
| + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| + return user_data_dir.AppendASCII(filename); |
| +} |
| + |
| FilePath WallpaperManager::GetWallpaperPathForUser(const std::string& username, |
| - bool is_thumbnail) { |
| - const char* suffix = is_thumbnail ? "_thumb" : ""; |
| + bool is_small) { |
| + const char* suffix = is_small ? "_small" : "_large"; |
|
Ivan Korotkov
2012/08/28 16:16:13
Please move these suffices to constants.
bshe
2012/08/29 14:30:07
Done.
|
| std::string filename = base::StringPrintf("%s_wallpaper%s.png", |
| username.c_str(), |
| suffix); |
| @@ -382,7 +402,7 @@ void WallpaperManager::SetUserWallpaperFromFile( |
| // For wallpapers, save the image without resizing. |
| wallpaper_loader_->Start( |
| path.value(), 0, |
| - base::Bind(&WallpaperManager::SetWallpaper, |
| + base::Bind(&WallpaperManager::SetCustomWallpaper, |
| base::Unretained(this), username, layout, User::CUSTOMIZED, |
| delegate)); |
| } |
| @@ -464,6 +484,19 @@ void WallpaperManager::SetUserWallpaper(const std::string& email) { |
| if (new_wallpaper_ui_enabled && |
| GetUserWallpaperInfo(email, &info)) { |
| + if (info.type == User::CUSTOMIZED) { |
| + if (!UserManager::Get()->IsUserLoggedIn()) { |
| + ash::Shell::GetInstance()->desktop_background_controller()-> |
| + SetDefaultWallpaper(ash::GetDefaultWallpaperIndex(), false); |
| + } else { |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&WallpaperManager::GetCustomWallpaperInternal, |
| + base::Unretained(this), email, info)); |
| + } |
| + return; |
| + } |
| + |
| if (info.file_name.empty()) { |
| // Uses default built-in wallpaper when file name is empty. Eventually, |
| // we will only ship one built-in wallpaper in ChromeOS image. |
| @@ -471,6 +504,7 @@ void WallpaperManager::SetUserWallpaper(const std::string& email) { |
| SetDefaultWallpaper(ash::GetDefaultWallpaperIndex(), false); |
| return; |
| } |
| + |
| LoadWallpaper(email, info); |
| } else { |
| User::WallpaperType type; |
| @@ -488,7 +522,7 @@ void WallpaperManager::SetUserWallpaper(const std::string& email) { |
| if (!UserManager::Get()->IsUserLoggedIn()) { |
| index = ash::GetDefaultWallpaperIndex(); |
| } else { |
| - FetchCustomWallpaper(email); |
| + GetCustomWallpaper(email); |
| return; |
| } |
| } |
| @@ -516,6 +550,7 @@ void WallpaperManager::OnUserSelected(const std::string& email) { |
| WallpaperManager::~WallpaperManager() { |
| DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); |
| system::TimezoneSettings::GetInstance()->RemoveObserver(this); |
| + weak_factory_.InvalidateWeakPtrs(); |
| } |
| void WallpaperManager::BatchUpdateWallpaper() { |
| @@ -588,11 +623,17 @@ void WallpaperManager::CacheUserWallpaper(const std::string& email) { |
| CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, |
| &wallpaper_dir)); |
| wallpaper_path = wallpaper_dir.Append(info.file_name); |
| - } else { |
| + } else if (info.type == User::DEFAULT) { |
| + // Current wallpaper is converted from built-in wallpaper. |
| ash::WallpaperResolution resolution = ash::Shell::GetInstance()-> |
| desktop_background_controller()->GetAppropriateResolution(); |
| bool small_resolution = (resolution == ash::SMALL); |
| wallpaper_path = GetWallpaperPathForUser(email, small_resolution); |
| + } else { |
| + // Cache default wallpaper when user selected a custom wallpaper. |
| + ash::Shell::GetInstance()->desktop_background_controller()-> |
| + CacheDefaultWallpaper(ash::GetDefaultWallpaperIndex()); |
| + return; |
| } |
| wallpaper_loader_->Start(wallpaper_path.value(), 0, |
| base::Bind(&WallpaperManager::CacheWallpaper, |
| @@ -645,10 +686,9 @@ void WallpaperManager::LoadWallpaper(const std::string& email, |
| CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir)); |
| wallpaper_path = wallpaper_dir.Append(info.file_name); |
| } else { |
| - ash::WallpaperResolution resolution = ash::Shell::GetInstance()-> |
| - desktop_background_controller()->GetAppropriateResolution(); |
| - bool small_resolution = (resolution == ash::SMALL); |
| - wallpaper_path = GetWallpaperPathForUser(email, small_resolution); |
| + FilePath user_data_dir; |
| + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| + wallpaper_path = user_data_dir.Append(info.file_name); |
| } |
| wallpaper_loader_->Start(wallpaper_path.value(), 0, |
| @@ -767,6 +807,32 @@ void WallpaperManager::GenerateUserWallpaperThumbnail( |
| base::Unretained(this), delegate)); |
| } |
| +void WallpaperManager::GetCustomWallpaperInternal(const std::string& email, |
| + const WallpaperInfo& info) { |
| + ash::WallpaperResolution resolution = ash::Shell::GetInstance()-> |
| + desktop_background_controller()->GetAppropriateResolution(); |
| + bool is_small = (resolution == ash::SMALL); |
| + FilePath wallpaper_path = GetWallpaperPathForUser(email, is_small); |
| + std::string file_name = wallpaper_path.BaseName().value(); |
| + // Falls back on original file if the correct resoltuion file does not |
| + // exisit. This may happen when the original custom wallpaper is small or |
|
Ivan Korotkov
2012/08/28 16:16:13
exist
bshe
2012/08/29 14:30:07
Done.
|
| + // browser shutdown before resized wallpaper saved. |
| + if (!file_util::PathExists(wallpaper_path)) |
| + file_name = GetOriginalWallpaperPathForUser(email).BaseName().value(); |
| + |
| + WallpaperInfo new_info = { |
| + file_name, |
| + info.layout, |
| + info.type, |
| + info.date |
| + }; |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + base::Bind(&WallpaperManager::LoadWallpaper, |
| + base::Unretained(this), email, new_info)); |
| +} |
| + |
| void WallpaperManager::MigrateBuiltInWallpaper(const std::string& email) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| if (!email.empty() && UserManager::Get()->IsKnownUser(email)) { |
| @@ -822,10 +888,6 @@ void WallpaperManager::MigrateBuiltInWallpaper(const std::string& email) { |
| base::Unretained(this), wallpaper_path, |
| reinterpret_cast<const char*>(wallpaper->front()), |
| wallpaper->size())); |
| - } else { |
| - // Since we only have one resolution for custom wallpaper, always |
| - // use LARGE resolution for custom wallpaper. |
| - resolution = ash::LARGE; |
| } |
| bool small_resolution = (resolution == ash::SMALL); |
| @@ -848,11 +910,89 @@ void WallpaperManager::OnThumbnailUpdated( |
| delegate->SetCustomWallpaperThumbnail(); |
| } |
| -void WallpaperManager::SaveWallpaper(const FilePath& path, |
| - const UserImage& wallpaper) { |
| +void WallpaperManager::OnWallpaperEncoded(const FilePath& path, |
| + scoped_refptr<base::RefCountedBytes> data) { |
| + SaveWallpaperInternal(path, |
| + reinterpret_cast<const char*>(data->front()), |
| + data->size()); |
| +} |
| + |
| +void WallpaperManager::SaveCustomWallpaper(const std::string& email, |
| + const FilePath& path, |
| + ash::WallpaperLayout layout, |
| + const UserImage& wallpaper) { |
| + FilePath small_wallpaper_path = GetWallpaperPathForUser(email, true); |
| + // Delete previous saved wallpapers. |
| + if (file_util::PathExists(small_wallpaper_path)) |
| + file_util::Delete(small_wallpaper_path, false); |
| + FilePath large_wallpaper_path = GetWallpaperPathForUser(email, false); |
| + if (file_util::PathExists(large_wallpaper_path)) |
| + file_util::Delete(large_wallpaper_path, false); |
| + |
| std::vector<unsigned char> image_data = wallpaper.raw_image(); |
| + // Saves the original file in case that resized wallpaper is not generated |
| + // (i.e. chrome shutdown before resized wallpaper is saved). |
| SaveWallpaperInternal(path, reinterpret_cast<char*>(&*image_data.begin()), |
| image_data.size()); |
| + |
| + ResizeAndSaveCustomWallpaper(wallpaper, small_wallpaper_path, layout, |
| + ash::kSmallWallpaperMaximalWidth, |
| + ash::kSmallWallpaperMaximalHeight); |
| + ResizeAndSaveCustomWallpaper(wallpaper, large_wallpaper_path, layout, |
| + ash::kLargeWallpaperMaximalWidth, |
| + ash::kLargeWallpaperMaximalHeight); |
| +} |
| + |
| +void WallpaperManager::ResizeAndSaveCustomWallpaper(const UserImage& wallpaper, |
| + const FilePath& path, |
| + ash::WallpaperLayout layout, |
| + int preferred_width, |
| + int preferred_height) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + int width = wallpaper.image().width(); |
| + int height = wallpaper.image().height(); |
| + int resized_width; |
| + int resized_height; |
| + |
| + if (layout == ash::CENTER_CROPPED) { |
| + if (!(width > preferred_width && height > preferred_height)) |
| + return; |
| + |
| + double horizontal_ratio = static_cast<double>(preferred_width) / |
|
Ivan Korotkov
2012/08/28 16:16:13
You actually need only the first static_cast
bshe
2012/08/29 14:30:07
Done.
|
| + static_cast<double>(width); |
| + double vertical_ratio = static_cast<double>(preferred_height) / |
| + static_cast<double>(height); |
| + if (vertical_ratio > horizontal_ratio) { |
| + resized_width = |
| + RoundPositive(static_cast<double>(width) * vertical_ratio); |
| + resized_height = preferred_height; |
| + } else { |
| + resized_width = preferred_width; |
| + resized_height = |
| + RoundPositive(static_cast<double>(height) * horizontal_ratio); |
| + } |
| + } else if (layout == ash::STRETCH) { |
| + resized_width = preferred_width; |
| + resized_height = preferred_height; |
| + } else { |
| + // TODO(bshe): Generates cropped custom wallpaper for CENTER layout. |
|
Ivan Korotkov
2012/08/28 16:16:13
This TODO looks strange. What does the else branch
bshe
2012/08/29 14:30:07
We only support three layout settings for custom w
|
| + if (file_util::PathExists(path)) |
| + file_util::Delete(path, false); |
| + return; |
| + } |
| + |
| + gfx::ImageSkia resized_image = gfx::ImageSkiaOperations::CreateResizedImage( |
| + wallpaper.image(), |
| + skia::ImageOperations::RESIZE_LANCZOS3, |
| + gfx::Size(resized_width, resized_height)); |
| + |
| + scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); |
| + SimplePngEncoder* png_encoder = new SimplePngEncoder( |
| + data, *(resized_image.bitmap())); |
| + png_encoder->Run( |
| + base::Bind(&WallpaperManager::OnWallpaperEncoded, |
| + weak_factory_.GetWeakPtr(), |
| + path)); |
| } |
| void WallpaperManager::SaveWallpaperInternal(const FilePath& path, |
| @@ -862,35 +1002,37 @@ void WallpaperManager::SaveWallpaperInternal(const FilePath& path, |
| DCHECK(written_bytes == size); |
| } |
| -void WallpaperManager::SetWallpaper(const std::string& username, |
| - ash::WallpaperLayout layout, |
| - User::WallpaperType type, |
| - base::WeakPtr<WallpaperDelegate> delegate, |
| - const UserImage& wallpaper) { |
| +void WallpaperManager::SetCustomWallpaper(const std::string& username, |
| + ash::WallpaperLayout layout, |
| + User::WallpaperType type, |
| + base::WeakPtr<WallpaperDelegate> delegate, |
| + const UserImage& wallpaper) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| std::string wallpaper_path = |
| - GetWallpaperPathForUser(username, false).value(); |
| + GetOriginalWallpaperPathForUser(username).value(); |
| bool is_persistent = ShouldPersistDataForUser(username); |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(&WallpaperManager::GenerateUserWallpaperThumbnail, |
| + base::Unretained(this), username, type, delegate, |
| + wallpaper.image())); |
| + |
| if (is_persistent) { |
| BrowserThread::PostTask( |
| BrowserThread::FILE, |
| FROM_HERE, |
| - base::Bind(&WallpaperManager::SaveWallpaper, |
| + base::Bind(&WallpaperManager::SaveCustomWallpaper, |
| base::Unretained(this), |
| + username, |
| FilePath(wallpaper_path), |
| + layout, |
| wallpaper)); |
| } |
| - BrowserThread::PostTask( |
| - BrowserThread::FILE, |
| - FROM_HERE, |
| - base::Bind(&WallpaperManager::GenerateUserWallpaperThumbnail, |
| - base::Unretained(this), username, type, delegate, |
| - wallpaper.image())); |
| - |
| ash::Shell::GetInstance()->desktop_background_controller()-> |
| SetCustomWallpaper(wallpaper.image(), layout); |
| SetUserWallpaperProperties(username, type, layout, is_persistent); |