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 e54b3ac16e92735a5efe1223c7a7eaaea7d0bfa4..04064a91a066753c703b1a32d0def8625eab8b96 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 { |
+ |
+class WallpaperManager::CustomizedWallpaperRescaledFiles { |
+ 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; |
+ 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"; |
+ |
// 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)); |
+ 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); |
+ return written_bytes == size; |
} |
void WallpaperManager::StartLoad(const std::string& user_id, |
@@ -1455,4 +1521,212 @@ WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper( |
return pending_inactive_; |
} |
+// static |
+base::FilePath |
+WallpaperManager::GetCustomizedWallpaperDefaultRescaledSmallFileName() { |
+ 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() { |
+ 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()); |
+ 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); |
+ 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); |
+ |
+ 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() |
+ ->SetDefaultWallpaperPath(rescaled_files->path_rescaled_small, |
+ rescaled_files->path_rescaled_large); |
+ } |
+} |
+ |
+// static |
+bool WallpaperManager::ShouldUseCustomizedDefaultWallpaper() { |
+ PrefService* prefService = g_browser_process->local_state(); |
+ DCHECK(prefService); |
+ |
+ const std::string current_url = |
+ prefService->GetString(prefs::kCustomizationDefaultWallpaperURL); |
+ return !current_url.empty(); |
+} |
+ |
} // namespace chromeos |