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 a036ca9064fdbf43a1a63d07eba4e94046c9fc0f..d4e8447f88353f5e1cc1a478a72b3e86fd7b76a3 100644 |
| --- a/chrome/browser/chromeos/login/wallpaper_manager.cc |
| +++ b/chrome/browser/chromeos/login/wallpaper_manager.cc |
| @@ -46,6 +46,52 @@ |
| using content::BrowserThread; |
| +namespace chromeos { |
| + |
|
bshe
2014/03/24 21:30:49
nit: these should implemented before testApi class
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| +class WallpaperManager::CustomizedWallpaperRescaledFiles { |
|
bshe
2014/03/24 21:30:49
nit: can you move the definition to .h file. Also,
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + public: |
| + CustomizedWallpaperRescaledFiles(const base::FilePath& path_rescaled_original, |
| + const base::FilePath& path_rescaled_small, |
| + const base::FilePath& path_rescaled_large); |
| + |
| + base::FilePath path_rescaled_original; |
|
bshe
2014/03/24 21:30:49
nit: the name is misleading. The original file is
Alexander Alekseev
2014/03/25 14:38:29
The original file is rescaled to get safe image:
|
| + base::FilePath path_rescaled_small; |
| + base::FilePath path_rescaled_large; |
| +}; |
| + |
| +WallpaperManager::CustomizedWallpaperRescaledFiles:: |
| + CustomizedWallpaperRescaledFiles( |
| + const base::FilePath& path_rescaled_original, |
| + const base::FilePath& path_rescaled_small, |
| + const base::FilePath& path_rescaled_large) |
| + : path_rescaled_original(path_rescaled_original), |
| + path_rescaled_small(path_rescaled_small), |
| + path_rescaled_large(path_rescaled_large) { |
| +} |
| + |
| +class WallpaperManager::CustomizedWallpaperFilesExist { |
| + public: |
| + CustomizedWallpaperFilesExist(); |
| + |
| + bool AllRescaledExist() const; |
| + |
| + bool dowloaded; |
| + bool rescaled_original; |
| + bool rescaled_small; |
| + bool rescaled_large; |
| +}; |
| + |
| +WallpaperManager::CustomizedWallpaperFilesExist::CustomizedWallpaperFilesExist() |
| + : dowloaded(false), |
| + rescaled_original(false), |
| + rescaled_small(false), |
| + rescaled_large(false) { |
| +} |
| + |
| +bool WallpaperManager::CustomizedWallpaperFilesExist::AllRescaledExist() const { |
| + return rescaled_original && rescaled_small && rescaled_large; |
| +} |
| + |
| namespace { |
| // The amount of delay before starts to move custom wallpapers to the new place. |
| @@ -88,6 +134,12 @@ const unsigned kLoadDefaultDelayMs = 200; |
| // Maximum wallpaper load delay, milliseconds. |
| const unsigned kLoadMaxDelayMs = 2000; |
| +// Customized wallpaer is rescaled and resized to three versions |
| +// with given suffixes: |
| +const char kCustomizedWallpaperOriginalFileSuffix[] = ".original.jpg"; |
| +const char kCustomizedWallpaperSmallFileSuffix[] = ".small.jpg"; |
| +const char kCustomizedWallpaperLargeFileSuffix[] = ".large.jpg"; |
|
bshe
2014/03/24 21:30:49
nit: can you reuse kSmallWallpaperSuffix and kLarg
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + |
| // For our scaling ratios we need to round positive numbers. |
| int RoundPositive(double x) { |
| return static_cast<int>(floor(x + 0.5)); |
| @@ -112,10 +164,23 @@ bool MoveCustomWallpaperDirectory(const char* sub_dir, |
| return false; |
| } |
| -} // namespace |
| +void CheckCustomizedWallpaperFilesExist( |
| + const base::FilePath& downloaded_file, |
| + const WallpaperManager::CustomizedWallpaperRescaledFiles* rescaled_files, |
| + WallpaperManager::CustomizedWallpaperFilesExist* exist) { |
| + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
|
bshe
2014/03/24 21:30:49
nit: worker pool thread instead of FILE?
Alexander Alekseev
2014/03/25 14:38:29
Do you know simple way to check for worker pool?
|
| + DCHECK(rescaled_files); |
| + DCHECK(exist); |
| + exist->dowloaded = base::PathExists(downloaded_file); |
| + exist->rescaled_original = |
| + base::PathExists(rescaled_files->path_rescaled_original); |
| + exist->rescaled_small = base::PathExists(rescaled_files->path_rescaled_small); |
| + exist->rescaled_large = base::PathExists(rescaled_files->path_rescaled_large); |
| +} |
| -namespace chromeos { |
| +} // namespace |
| +// namespace chromeos |
| const char kWallpaperSequenceTokenName[] = "wallpaper-sequence"; |
| const char kSmallWallpaperSuffix[] = "_small"; |
| @@ -570,7 +635,7 @@ bool WallpaperManager::ResizeWallpaper( |
| return true; |
| } |
| -void WallpaperManager::ResizeAndSaveWallpaper(const UserImage& wallpaper, |
| +bool WallpaperManager::ResizeAndSaveWallpaper(const UserImage& wallpaper, |
| const base::FilePath& path, |
| ash::WallpaperLayout layout, |
| int preferred_width, |
| @@ -579,15 +644,15 @@ void WallpaperManager::ResizeAndSaveWallpaper(const UserImage& wallpaper, |
| // TODO(bshe): Generates cropped custom wallpaper for CENTER layout. |
| if (base::PathExists(path)) |
| base::DeleteFile(path, false); |
| - return; |
| + return false; |
| } |
| scoped_refptr<base::RefCountedBytes> data; |
| if (ResizeWallpaper(wallpaper, layout, preferred_width, preferred_height, |
| &data)) { |
| - SaveWallpaperInternal(path, |
| - reinterpret_cast<const char*>(data->front()), |
| - data->size()); |
| + return SaveWallpaperInternal( |
| + path, reinterpret_cast<const char*>(data->front()), data->size()); |
| } |
| + return false; |
| } |
| bool WallpaperManager::IsPolicyControlled(const std::string& user_id) const { |
| @@ -1378,11 +1443,12 @@ void WallpaperManager::RecordUma(User::WallpaperType type, int index) const { |
| User::WALLPAPER_TYPE_COUNT); |
| } |
| -void WallpaperManager::SaveWallpaperInternal(const base::FilePath& path, |
| +bool WallpaperManager::SaveWallpaperInternal(const base::FilePath& path, |
| const char* data, |
| int size) const { |
| int written_bytes = base::WriteFile(path, data, size); |
| DCHECK(written_bytes == size); |
|
bshe
2014/03/24 21:30:49
nit: DCHECK is probably not necessary in this case
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + return written_bytes == size; |
| } |
| void WallpaperManager::StartLoad(const std::string& user_id, |
| @@ -1455,4 +1521,212 @@ WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper( |
| return pending_inactive_; |
| } |
| +// static |
|
bshe
2014/03/24 21:30:49
GetCustomizedWallpaperDefaultRescaledSmallFileName
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| +base::FilePath |
| +WallpaperManager::GetCustomizedWallpaperDefaultRescaledSmallFileName() { |
|
bshe
2014/03/24 21:30:49
nit: 4 space indent please
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + 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() + |
| + kCustomizedWallpaperSmallFileSuffix); |
| +} |
| + |
| +// static |
| +base::FilePath |
| +WallpaperManager::GetCustomizedWallpaperDefaultRescaledLargeFileName() { |
|
bshe
2014/03/24 21:30:49
nit: 4 space indent please
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + 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() + |
| + kCustomizedWallpaperLargeFileSuffix); |
| +} |
| + |
| +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() || wallpaper_url.is_empty()); |
|
bshe
2014/03/24 21:30:49
nit: you shouldn't need to handle failed DCHECK ca
Alexander Alekseev
2014/03/25 14:38:29
This is one of a few cases when we should fail in
|
| + if (!wallpaper_url.is_valid()) { |
| + if (!wallpaper_url.is_empty()) { |
| + LOG(WARNING) << "Invalid Customized Wallpaper URL."; |
| + } |
| + return; |
| + } |
| + std::string downloaded_file_name = downloaded_file.BaseName().value(); |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files( |
| + new CustomizedWallpaperRescaledFiles( |
| + resized_directory.Append(downloaded_file_name + |
| + kCustomizedWallpaperOriginalFileSuffix), |
| + resized_directory.Append(downloaded_file_name + |
| + kCustomizedWallpaperSmallFileSuffix), |
| + resized_directory.Append(downloaded_file_name + |
| + kCustomizedWallpaperLargeFileSuffix))); |
| + scoped_ptr<CustomizedWallpaperFilesExist> exist( |
| + new CustomizedWallpaperFilesExist); |
| + |
| + base::Closure check_file_exists = |
| + base::Bind(&CheckCustomizedWallpaperFilesExist, |
| + downloaded_file, |
| + base::Unretained(rescaled_files.get()), |
| + base::Unretained(exist.get())); |
| + base::Closure on_checked_closure = |
| + base::Bind(&WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck, |
| + weak_factory_.GetWeakPtr(), |
| + wallpaper_url, |
| + downloaded_file, |
| + base::Passed(rescaled_files.Pass()), |
| + base::Passed(exist.Pass())); |
| + if (!content::BrowserThread::PostBlockingPoolTaskAndReply( |
| + FROM_HERE, check_file_exists, on_checked_closure)) { |
| + LOG(WARNING) << "Failed to start check CheckCustomizedWallpaperFilesExist."; |
| + } |
| +} |
| + |
| +void WallpaperManager::ResizeCustomizedDefaultWallpaper( |
| + scoped_ptr<gfx::ImageSkia> image, |
| + const UserImage::RawImage& raw_image, |
| + const CustomizedWallpaperRescaledFiles* rescaled_files, |
| + bool* success) { |
| + DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread( |
| + sequence_token_)); |
| + UserImage wallpaper(*image.get(), raw_image); |
| + |
| + *success = false; |
| + |
| + // Re-encode orginal file to jpeg format and saves the result in case that |
| + // resized wallpaper is not generated (i.e. chrome shutdown before resized |
| + // wallpaper is saved). |
| + *success |= ResizeAndSaveWallpaper(wallpaper, |
| + rescaled_files->path_rescaled_original, |
| + ash::WALLPAPER_LAYOUT_STRETCH, |
| + wallpaper.image().width(), |
| + wallpaper.image().height()); |
| + |
| + *success |= ResizeAndSaveWallpaper(wallpaper, |
| + rescaled_files->path_rescaled_small, |
| + ash::WALLPAPER_LAYOUT_STRETCH, |
| + ash::kSmallWallpaperMaxWidth, |
| + ash::kSmallWallpaperMaxHeight); |
| + |
| + *success |= ResizeAndSaveWallpaper(wallpaper, |
| + rescaled_files->path_rescaled_large, |
| + ash::WALLPAPER_LAYOUT_STRETCH, |
| + ash::kLargeWallpaperMaxWidth, |
| + ash::kLargeWallpaperMaxHeight); |
| +} |
| + |
| +void WallpaperManager::OnCustomizedDefaultWallpaperResized( |
| + const GURL& wallpaper_url, |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files, |
| + scoped_ptr<bool> success) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(rescaled_files.get()); |
| + DCHECK(success.get()); |
| + if (!*success) { |
| + LOG(WARNING) << "Failed to save Resized Customized Default Wallpaper"; |
| + return; |
| + } |
| + PrefService* prefService = g_browser_process->local_state(); |
| + DCHECK(prefService); |
|
Mattias Nissler (ping if slow)
2014/03/24 20:38:54
remove redundant DCHECK
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + prefService->SetString(prefs::kCustomizationDefaultWallpaperURL, |
| + wallpaper_url.spec()); |
| + ash::Shell::GetInstance() |
| + ->desktop_background_controller() |
| + ->SetDefaultWallpaperPath(rescaled_files->path_rescaled_small, |
| + rescaled_files->path_rescaled_large); |
| + VLOG(1) << "Customized Default Wallpaper applied."; |
| +} |
| + |
| +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)); |
| + |
| + // 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::Closure on_resized_closure = |
| + base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperResized, |
| + weak_factory_.GetWeakPtr(), |
| + wallpaper_url, |
| + base::Passed(rescaled_files.Pass()), |
| + base::Passed(success.Pass())); |
| + |
| + // Block shutdown on this task. Otherwise, we may lose the custom wallpaper |
| + // that the user selected. |
| + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner = |
| + BrowserThread::GetBlockingPool() |
| + ->GetSequencedTaskRunnerWithShutdownBehavior( |
| + sequence_token_, base::SequencedWorkerPool::BLOCK_SHUTDOWN); |
| + |
| + if (!blocking_task_runner->PostTaskAndReply( |
| + FROM_HERE, resize_closure, on_resized_closure)) { |
| + LOG(WARNING) << "Failed to start Customized Wallpaper resize."; |
| + } |
| +} |
| + |
| +void WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck( |
| + const GURL& wallpaper_url, |
| + const base::FilePath& downloaded_file, |
| + scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files, |
| + scoped_ptr<CustomizedWallpaperFilesExist> exist) { |
| + PrefService* prefService = g_browser_process->local_state(); |
| + DCHECK(prefService); |
|
Mattias Nissler (ping if slow)
2014/03/24 20:38:54
remove redundant DCHECK
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + |
| + std::string current_url = |
| + prefService->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| + if ((current_url != wallpaper_url.spec()) || (!exist->AllRescaledExist())) { |
| + DCHECK(exist->dowloaded); |
| + // Need rescale |
| + 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 { |
| + ash::Shell::GetInstance() |
| + ->desktop_background_controller() |
|
bshe
2014/03/24 21:30:49
nit: this line seems can fit to the previous line
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + ->SetDefaultWallpaperPath(rescaled_files->path_rescaled_small, |
| + rescaled_files->path_rescaled_large); |
| + } |
| +} |
| + |
| +// static |
| +bool WallpaperManager::ShouldUseCustomizedDefaultWallpaper() { |
| + PrefService* prefService = g_browser_process->local_state(); |
| + DCHECK(prefService); |
|
Mattias Nissler (ping if slow)
2014/03/24 20:38:54
remove redundant DCHECK
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| + |
| + const std::string current_url = |
| + prefService->GetString(prefs::kCustomizationDefaultWallpaperURL); |
| + return !current_url.empty(); |
|
Mattias Nissler (ping if slow)
2014/03/24 20:38:54
Is this supposed to be "if not set"? If so, consid
Alexander Alekseev
2014/03/25 14:38:29
Done.
|
| +} |
| + |
| } // namespace chromeos |