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 d59ae0a73bc81ef7fe553538e3b1f7f486cbaf51..0b16adeb2df9b0163654c07e21b0a99cfc6d5ab1 100644 |
| --- a/chrome/browser/chromeos/login/wallpaper_manager.cc |
| +++ b/chrome/browser/chromeos/login/wallpaper_manager.cc |
| @@ -29,6 +29,7 @@ |
| #include "base/values.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| +#include "chrome/browser/chromeos/customization_document.h" |
| #include "chrome/browser/chromeos/login/startup_utils.h" |
| #include "chrome/browser/chromeos/login/user.h" |
| #include "chrome/browser/chromeos/login/user_manager.h" |
| @@ -117,6 +118,30 @@ bool MoveCustomWallpaperDirectory(const char* sub_dir, |
| return false; |
| } |
| +// These global default values are used to set customized default |
| +// wallpaper path in WallpaperManager::InitializeWallpaper(). |
| +base::FilePath GetCustomizedWallpaperDefaultRescaledFileName( |
| + const std::string& suffix) { |
| + const base::FilePath default_downloaded_file_name = |
| + ServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName(); |
| + const base::FilePath default_cache_dir = |
| + ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir(); |
| + if (default_downloaded_file_name.empty() || default_cache_dir.empty()) |
| + return base::FilePath(); |
| + return default_cache_dir.Append( |
| + default_downloaded_file_name.BaseName().value() + suffix); |
| +} |
| + |
| +// Whether DesktopBackgroundController should start with customized default |
| +// wallpaper in WallpaperManager::InitializeWallpaper() or not. |
| +bool ShouldUseCustomizedDefaultWallpaper() { |
| + PrefService* pref_service = g_browser_process->local_state(); |
| + |
| + return !(pref_service->FindPreference( |
| + prefs::kCustomizationDefaultWallpaperURL) |
| + ->IsDefaultValue()); |
| +} |
| + |
| } // namespace |
| const char kWallpaperSequenceTokenName[] = "wallpaper-sequence"; |
| @@ -138,6 +163,75 @@ const int kWallpaperThumbnailHeight = 68; |
| static WallpaperManager* g_wallpaper_manager = NULL; |
| +class WallpaperManager::CustomizedWallpaperRescaledFiles { |
| + public: |
| + CustomizedWallpaperRescaledFiles(const base::FilePath& path_downloaded, |
| + const base::FilePath& path_rescaled_small, |
| + const base::FilePath& path_rescaled_large); |
| + |
| + bool AllSizesExist() const; |
| + |
| + // Closure will hold unretained pointer to this object. So caller must |
| + // make sure that the closure will be destoyed before this object. |
| + // Closure must be called on BlockingPool. |
| + base::Closure CreateCheckerClosure(); |
| + |
| + const base::FilePath& path_downloaded() const { return path_downloaded_; } |
| + const base::FilePath& path_rescaled_small() const { |
| + return path_rescaled_small_; |
| + } |
| + const base::FilePath& path_rescaled_large() const { |
| + return path_rescaled_large_; |
| + } |
| + |
| + const bool downloaded_exists() const { return downloaded_exists_; } |
| + const bool rescaled_small_exists() const { return rescaled_small_exists_; } |
| + const bool rescaled_large_exists() const { return rescaled_large_exists_; } |
| + |
| + private: |
| + // Must be called on BlockingPool. |
| + void CheckCustomizedWallpaperFilesExist(); |
| + |
| + const base::FilePath path_downloaded_; |
| + const base::FilePath path_rescaled_small_; |
| + const base::FilePath path_rescaled_large_; |
| + |
| + bool downloaded_exists_; |
| + bool rescaled_small_exists_; |
| + bool rescaled_large_exists_; |
| +}; |
|
Daniel Erat
2014/04/17 16:24:22
add DISALLOW_COPY_AND_ASSIGN
Alexander Alekseev
2014/04/17 20:02:56
Done.
|
| + |
| +WallpaperManager::CustomizedWallpaperRescaledFiles:: |
| + CustomizedWallpaperRescaledFiles(const base::FilePath& path_downloaded, |
| + const base::FilePath& path_rescaled_small, |
| + const base::FilePath& path_rescaled_large) |
| + : path_downloaded_(path_downloaded), |
| + path_rescaled_small_(path_rescaled_small), |
| + path_rescaled_large_(path_rescaled_large), |
| + downloaded_exists_(false), |
| + rescaled_small_exists_(false), |
| + rescaled_large_exists_(false) { |
| +} |
| + |
| +base::Closure |
| +WallpaperManager::CustomizedWallpaperRescaledFiles::CreateCheckerClosure() { |
| + return base::Bind(&WallpaperManager::CustomizedWallpaperRescaledFiles:: |
| + CheckCustomizedWallpaperFilesExist, |
| + base::Unretained(this)); |
| +} |
| + |
| +void WallpaperManager::CustomizedWallpaperRescaledFiles:: |
| + CheckCustomizedWallpaperFilesExist() { |
| + DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| + downloaded_exists_ = base::PathExists(path_downloaded_); |
| + rescaled_small_exists_ = base::PathExists(path_rescaled_small_); |
| + rescaled_large_exists_ = base::PathExists(path_rescaled_large_); |
| +} |
| + |
| +bool WallpaperManager::CustomizedWallpaperRescaledFiles::AllSizesExist() const { |
| + return rescaled_small_exists_ && rescaled_large_exists_; |
| +} |
| + |
| // This object is passed between several threads while wallpaper is being |
| // loaded. It will notify callback when last reference to it is removed |
| // (thus indicating that the last load action has finished). |
| @@ -444,6 +538,15 @@ void WallpaperManager::InitializeWallpaper() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| UserManager* user_manager = UserManager::Get(); |
| + // Apply device customization. |
| + if (ShouldUseCustomizedDefaultWallpaper()) { |
| + SetDefaultWallpaperPath( |
| + GetCustomizedWallpaperDefaultRescaledFileName(kSmallWallpaperSuffix), |
| + scoped_ptr<gfx::ImageSkia>().Pass(), |
| + GetCustomizedWallpaperDefaultRescaledFileName(kLargeWallpaperSuffix), |
| + scoped_ptr<gfx::ImageSkia>().Pass()); |
| + } |
| + |
| CommandLine* command_line = GetCommandLine(); |
| if (command_line->HasSwitch(chromeos::switches::kGuestSession)) { |
| // Guest wallpaper should be initialized when guest login. |
| @@ -797,7 +900,7 @@ void WallpaperManager::DoSetDefaultWallpaper( |
| : ash::WALLPAPER_LAYOUT_CENTER_CROPPED; |
| DCHECK(file); |
| if (!default_wallpaper_image_.get() || |
| - default_wallpaper_image_->url().spec() != file->value()) { |
| + default_wallpaper_image_->file_path() != file->value()) { |
| default_wallpaper_image_.reset(); |
| if (!file->empty()) { |
| loaded_wallpapers_++; |
| @@ -1520,6 +1623,129 @@ base::TimeDelta WallpaperManager::GetWallpaperLoadDelay() const { |
| return delay; |
| } |
| +void WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck( |
| + const GURL& wallpaper_url, |
| + const base::FilePath& downloaded_file, |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files) { |
| + PrefService* pref_service = g_browser_process->local_state(); |
| + |
| + std::string current_url = |
| + pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| + if (current_url != wallpaper_url.spec() || !rescaled_files->AllSizesExist()) { |
| + DCHECK(rescaled_files->downloaded_exists()); |
| + |
| + // Either resized images do not exist or cached version is incorrect. |
| + // Need to start resize again. |
| + wallpaper_loader_->Start( |
| + downloaded_file.value(), |
| + 0, // Do not crop. |
| + base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded, |
| + weak_factory_.GetWeakPtr(), |
| + wallpaper_url, |
| + base::Passed(rescaled_files.Pass()))); |
| + } else { |
| + SetDefaultWallpaperPath(rescaled_files->path_rescaled_small(), |
| + scoped_ptr<gfx::ImageSkia>().Pass(), |
| + rescaled_files->path_rescaled_large(), |
| + scoped_ptr<gfx::ImageSkia>().Pass()); |
| + } |
| +} |
| + |
| +void WallpaperManager::OnCustomizedDefaultWallpaperDecoded( |
| + const GURL& wallpaper_url, |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files, |
| + const UserImage& wallpaper) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + // If decoded wallpaper is empty, we have probably failed to decode the file. |
| + if (wallpaper.image().isNull()) { |
| + LOG(WARNING) << "Failed to decode customized wallpaper."; |
| + return; |
| + } |
| + |
| + wallpaper.image().EnsureRepsForSupportedScales(); |
| + scoped_ptr<gfx::ImageSkia> deep_copy(wallpaper.image().DeepCopy()); |
| + |
| + scoped_ptr<bool> success(new bool(false)); |
| + scoped_ptr<gfx::ImageSkia> small_wallpaper_image(new gfx::ImageSkia); |
| + scoped_ptr<gfx::ImageSkia> large_wallpaper_image(new gfx::ImageSkia); |
| + |
| + // TODO(bshe): This may break if RawImage becomes RefCountedMemory. |
| + base::Closure resize_closure = |
| + base::Bind(&WallpaperManager::ResizeCustomizedDefaultWallpaper, |
| + base::Unretained(this), |
| + base::Passed(&deep_copy), |
| + wallpaper.raw_image(), |
| + base::Unretained(rescaled_files.get()), |
| + base::Unretained(success.get()), |
| + base::Unretained(small_wallpaper_image.get()), |
| + base::Unretained(large_wallpaper_image.get())); |
| + base::Closure on_resized_closure = |
| + base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperResized, |
| + weak_factory_.GetWeakPtr(), |
| + wallpaper_url, |
| + base::Passed(rescaled_files.Pass()), |
| + base::Passed(success.Pass()), |
| + base::Passed(small_wallpaper_image.Pass()), |
| + base::Passed(large_wallpaper_image.Pass())); |
| + |
| + if (!task_runner_->PostTaskAndReply( |
| + FROM_HERE, resize_closure, on_resized_closure)) { |
| + LOG(WARNING) << "Failed to start Customized Wallpaper resize."; |
| + } |
| +} |
| + |
| +void WallpaperManager::ResizeCustomizedDefaultWallpaper( |
| + scoped_ptr<gfx::ImageSkia> image, |
| + const UserImage::RawImage& raw_image, |
| + const CustomizedWallpaperRescaledFiles* rescaled_files, |
| + bool* success, |
| + gfx::ImageSkia* small_wallpaper_image, |
| + gfx::ImageSkia* large_wallpaper_image) { |
| + DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
| + sequence_token_)); |
| + UserImage wallpaper(*image.get(), raw_image); |
| + |
| + *success = true; |
| + |
| + *success &= ResizeAndSaveWallpaper(wallpaper, |
| + rescaled_files->path_rescaled_small(), |
| + ash::WALLPAPER_LAYOUT_STRETCH, |
| + kSmallWallpaperMaxWidth, |
| + kSmallWallpaperMaxHeight, |
| + small_wallpaper_image); |
| + |
| + *success &= ResizeAndSaveWallpaper(wallpaper, |
| + rescaled_files->path_rescaled_large(), |
| + ash::WALLPAPER_LAYOUT_STRETCH, |
| + kLargeWallpaperMaxWidth, |
| + kLargeWallpaperMaxHeight, |
| + large_wallpaper_image); |
| +} |
| + |
| +void WallpaperManager::OnCustomizedDefaultWallpaperResized( |
| + const GURL& wallpaper_url, |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files, |
| + scoped_ptr<bool> success, |
| + scoped_ptr<gfx::ImageSkia> small_wallpaper_image, |
| + scoped_ptr<gfx::ImageSkia> large_wallpaper_image) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(rescaled_files); |
| + DCHECK(success.get()); |
| + if (!*success) { |
| + LOG(WARNING) << "Failed to save resized customized default wallpaper"; |
| + return; |
| + } |
| + PrefService* pref_service = g_browser_process->local_state(); |
| + pref_service->SetString(prefs::kCustomizationDefaultWallpaperURL, |
| + wallpaper_url.spec()); |
| + SetDefaultWallpaperPath(rescaled_files->path_rescaled_small(), |
| + small_wallpaper_image.Pass(), |
| + rescaled_files->path_rescaled_large(), |
| + large_wallpaper_image.Pass()); |
| + VLOG(1) << "Customized default wallpaper applied."; |
| +} |
| + |
| WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper( |
| const std::string& user_id, |
| bool delayed) { |
| @@ -1533,6 +1759,41 @@ WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper( |
| return pending_inactive_; |
| } |
| +void WallpaperManager::SetCustomizedDefaultWallpaper( |
| + const GURL& wallpaper_url, |
| + const base::FilePath& downloaded_file, |
| + const base::FilePath& resized_directory) { |
| + // Should fail if this ever happens in tests. |
| + DCHECK(wallpaper_url.is_valid()); |
| + if (!wallpaper_url.is_valid()) { |
| + if (!wallpaper_url.is_empty()) { |
| + LOG(WARNING) << "Invalid Customized Wallpaper URL '" |
| + << wallpaper_url.spec() << "'"; |
| + } |
| + return; |
| + } |
| + std::string downloaded_file_name = downloaded_file.BaseName().value(); |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files( |
| + new CustomizedWallpaperRescaledFiles( |
| + downloaded_file, |
| + resized_directory.Append(downloaded_file_name + |
| + kSmallWallpaperSuffix), |
| + resized_directory.Append(downloaded_file_name + |
| + kLargeWallpaperSuffix))); |
| + |
| + base::Closure check_file_exists = rescaled_files->CreateCheckerClosure(); |
| + base::Closure on_checked_closure = |
| + base::Bind(&WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck, |
| + weak_factory_.GetWeakPtr(), |
| + wallpaper_url, |
| + downloaded_file, |
| + base::Passed(rescaled_files.Pass())); |
| + if (!BrowserThread::PostBlockingPoolTaskAndReply( |
| + FROM_HERE, check_file_exists, on_checked_closure)) { |
| + LOG(WARNING) << "Failed to start check CheckCustomizedWallpaperFilesExist."; |
| + } |
| +} |
| + |
| void WallpaperManager::SetDefaultWallpaperPathsFromCommandLine( |
| base::CommandLine* command_line) { |
| default_small_wallpaper_file_ = command_line->GetSwitchValuePath( |
| @@ -1552,8 +1813,7 @@ void WallpaperManager::OnDefaultWallpaperDecoded( |
| scoped_ptr<chromeos::UserImage>* result_out, |
| MovableOnDestroyCallbackHolder on_finish, |
| const UserImage& wallpaper) { |
| - result_out->reset(new UserImage(wallpaper.image())); |
| - (*result_out)->set_url(GURL(path.value())); |
| + result_out->reset(new UserImage(wallpaper)); |
| ash::Shell::GetInstance()->desktop_background_controller()->SetWallpaperImage( |
| wallpaper.image(), layout); |
| } |
| @@ -1580,4 +1840,49 @@ const char* WallpaperManager::GetCustomWallpaperSubdirForCurrentResolution() { |
| : kLargeWallpaperSubDir; |
| } |
| +void WallpaperManager::SetDefaultWallpaperPath( |
| + const base::FilePath& default_small_wallpaper_file, |
| + scoped_ptr<gfx::ImageSkia> small_wallpaper_image, |
| + const base::FilePath& default_large_wallpaper_file, |
| + scoped_ptr<gfx::ImageSkia> large_wallpaper_image) { |
| + default_small_wallpaper_file_ = default_small_wallpaper_file; |
| + default_large_wallpaper_file_ = default_large_wallpaper_file; |
| + |
| + ash::DesktopBackgroundController* dbc = |
| + ash::Shell::GetInstance()->desktop_background_controller(); |
| + |
| + // |need_update_screen| is true if the previous default wallpaper is visible |
| + // now, so we need to update wallpaper on the screen. |
| + // |
| + // Layout is ignored here, so ash::WALLPAPER_LAYOUT_CENTER is used |
| + // as a placeholder only. |
| + const bool need_update_screen = |
| + default_wallpaper_image_.get() && |
| + dbc->WallpaperIsAlreadyLoaded( |
| + &(default_wallpaper_image_->image()), |
| + ash::DesktopBackgroundController::kInvalidResourceID, |
| + false /* compare_layouts */, |
| + ash::WALLPAPER_LAYOUT_CENTER); |
| + |
| + default_wallpaper_image_.reset(); |
| + if (GetAppropriateResolution() == WALLPAPER_RESOLUTION_SMALL) { |
| + if (small_wallpaper_image) { |
| + default_wallpaper_image_.reset(new UserImage(*small_wallpaper_image)); |
| + default_wallpaper_image_->set_file_path( |
| + default_small_wallpaper_file.value()); |
| + } |
| + } else { |
| + if (large_wallpaper_image) { |
| + default_wallpaper_image_.reset(new UserImage(*large_wallpaper_image)); |
| + default_wallpaper_image_->set_file_path( |
| + default_large_wallpaper_file.value()); |
| + } |
| + } |
| + |
| + if (need_update_screen) { |
| + DoSetDefaultWallpaper(std::string(), |
| + MovableOnDestroyCallbackHolder().Pass()); |
| + } |
| +} |
| + |
| } // namespace chromeos |