diff options
5 files changed, 128 insertions, 33 deletions
diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc index 51c2d29..2d49b4d 100644 --- a/ash/desktop_background/desktop_background_controller.cc +++ b/ash/desktop_background/desktop_background_controller.cc @@ -151,6 +151,18 @@ void DesktopBackgroundController::OnRootWindowAdded( InstallComponent(root_window); } +void DesktopBackgroundController::CacheDefaultWallpaper(int index) { + DCHECK(index >= 0); + + WallpaperResolution resolution = GetAppropriateResolution(); + scoped_refptr<WallpaperOperation> wallpaper_op = + new WallpaperOperation(index, resolution); + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&WallpaperOperation::Run, wallpaper_op), + true); +} + void DesktopBackgroundController::SetDefaultWallpaper(int index, bool force_reload) { // We should not change background when index is invalid. For instance, at @@ -169,15 +181,7 @@ void DesktopBackgroundController::SetDefaultWallpaper(int index, CancelPendingWallpaperOperation(); - WallpaperResolution resolution = SMALL; - Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); - for (Shell::RootWindowList::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - gfx::Size root_window_size = (*iter)->GetHostSize(); - if (root_window_size.width() > kSmallWallpaperMaximalWidth || - root_window_size.height() > kSmallWallpaperMaximalHeight) - resolution = LARGE; - } + WallpaperResolution resolution = GetAppropriateResolution(); wallpaper_op_ = new WallpaperOperation(index, resolution); base::WorkerPool::PostTaskAndReply( @@ -355,4 +359,17 @@ int DesktopBackgroundController::GetBackgroundContainerId(bool locked) { internal::kShellWindowId_DesktopBackgroundContainer; } +WallpaperResolution DesktopBackgroundController::GetAppropriateResolution() { + WallpaperResolution resolution = SMALL; + Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); + for (Shell::RootWindowList::iterator iter = root_windows.begin(); + iter != root_windows.end(); ++iter) { + gfx::Size root_window_size = (*iter)->GetHostSize(); + if (root_window_size.width() > kSmallWallpaperMaximalWidth || + root_window_size.height() > kSmallWallpaperMaximalHeight) + resolution = LARGE; + } + return resolution; +} + } // namespace ash diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h index ec9fcab..edcd803 100644 --- a/ash/desktop_background/desktop_background_controller.h +++ b/ash/desktop_background/desktop_background_controller.h @@ -76,6 +76,11 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver { // Initialize root window's background. void OnRootWindowAdded(aura::RootWindow* root_window); + // Loads default wallpaper at |index| asynchronously but does not set the + // loaded image to current wallpaper. Resource bundle will cache the loaded + // image. + void CacheDefaultWallpaper(int index); + // Loads default wallpaper at |index| asynchronously and sets to current // wallpaper after loaded. When |force_reload| is true, reload wallpaper // for all root windows even if |index| is the same as current wallpaper. It @@ -145,6 +150,9 @@ class ASH_EXPORT DesktopBackgroundController : public aura::WindowObserver { // Returns id for background container for unlocked and locked states. int GetBackgroundContainerId(bool locked); + // Returns the appropriate wallpaper resolution for all root windows. + WallpaperResolution GetAppropriateResolution(); + // Can change at runtime. bool locked_; diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc index dd32d4f5..6cb8443 100644 --- a/chrome/browser/chromeos/login/user_manager_impl.cc +++ b/chrome/browser/chromeos/login/user_manager_impl.cc @@ -731,8 +731,6 @@ void UserManagerImpl::EnsureUsersLoaded() { User* user = CreateUser(email, /* is_ephemeral= */ false); users_.push_back(user); - WallpaperManager::Get()->CacheIfCustomWallpaper(email); - if (prefs_images) { // Get account image path. // TODO(avayvod): Reading image path as a string is here for diff --git a/chrome/browser/chromeos/login/wallpaper_manager.cc b/chrome/browser/chromeos/login/wallpaper_manager.cc index 0356019..06837af 100644 --- a/chrome/browser/chromeos/login/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/wallpaper_manager.cc @@ -17,6 +17,7 @@ #include "base/time.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/settings/cros_settings.h" @@ -47,6 +48,8 @@ const char kWallpaperDateNodeName[] = "date"; const int kThumbnailWidth = 128; const int kThumbnailHeight = 80; +const int kCacheWallpaperDelayMs = 500; + // Default wallpaper index used in OOBE (first boot). // Defined here because Chromium default index differs. // Also see ash::WallpaperInfo kDefaultWallpapers in @@ -83,11 +86,18 @@ WallpaperManager::WallpaperManager() current_user_wallpaper_type_(User::UNKNOWN), ALLOW_THIS_IN_INITIALIZER_LIST(current_user_wallpaper_index_( ash::GetInvalidWallpaperIndex())), + should_cache_wallpaper_(false), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { RestartTimer(); registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_CHANGED, content::NotificationService::AllSources()); + registrar_.Add(this, + chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE, + content::NotificationService::AllSources()); + registrar_.Add(this, + chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED, + content::NotificationService::AllSources()); } // static @@ -102,21 +112,6 @@ void WallpaperManager::AddObservers() { system::TimezoneSettings::GetInstance()->AddObserver(this); } -void WallpaperManager::CacheIfCustomWallpaper(const std::string& email) { - User::WallpaperType type; - int index; - base::Time date; - GetUserWallpaperProperties(email, &type, &index, &date); - if (type == User::CUSTOMIZED) { - std::string wallpaper_path = GetWallpaperPathForUser(email, false).value(); - - // Uses WeakPtr here to make the request cancelable. - wallpaper_loader_->Start(wallpaper_path, 0, - base::Bind(&WallpaperManager::CacheWallpaper, - weak_factory_.GetWeakPtr(), email)); - } -} - void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() { User::WallpaperType type; int index; @@ -245,10 +240,39 @@ void WallpaperManager::Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { - // Cancel callback for previous cache requests. - weak_factory_.InvalidateWeakPtrs(); - custom_wallpaper_cache_.clear(); + switch (type) { + case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { + // Cancel callback for previous cache requests. + weak_factory_.InvalidateWeakPtrs(); + custom_wallpaper_cache_.clear(); + break; + } + case chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE: { + if (!CommandLine::ForCurrentProcess()-> + HasSwitch(switches::kDisableBootAnimation)) { + BrowserThread::PostDelayedTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&WallpaperManager::CacheAllUsersWallpapers, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs)); + } else { + should_cache_wallpaper_ = true; + } + break; + } + case chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED: { + if (should_cache_wallpaper_) { + BrowserThread::PostDelayedTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&WallpaperManager::CacheAllUsersWallpapers, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs)); + should_cache_wallpaper_ = false; + } + break; + } + default: + NOTREACHED() << "Unexpected notification " << type; } } @@ -445,6 +469,39 @@ void WallpaperManager::BatchUpdateWallpaper() { RestartTimer(); } +void WallpaperManager::CacheAllUsersWallpapers() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + UserList users = UserManager::Get()->GetUsers(); + + if (!users.empty()) { + UserList::const_iterator it = users.begin(); + // Skip the wallpaper of first user in the list. It should have been cached. + it++; + for (; it != users.end(); ++it) { + std::string user_email = (*it)->email(); + CacheUserWallpaper(user_email); + } + } +} + +void WallpaperManager::CacheUserWallpaper(const std::string& email) { + User::WallpaperType type; + int index; + base::Time date; + GetUserWallpaperProperties(email, &type, &index, &date); + if (type == User::CUSTOMIZED) { + std::string wallpaper_path = GetWallpaperPathForUser(email, false).value(); + + // Uses WeakPtr here to make the request cancelable. + wallpaper_loader_->Start(wallpaper_path, 0, + base::Bind(&WallpaperManager::CacheWallpaper, + weak_factory_.GetWeakPtr(), email)); + } else { + ash::Shell::GetInstance()->desktop_background_controller()-> + CacheDefaultWallpaper(index); + } +} + void WallpaperManager::CacheWallpaper(const std::string& email, const UserImage& wallpaper) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -480,6 +537,7 @@ void WallpaperManager::FetchWallpaper(const std::string& email, base::Bind(&WallpaperManager::CacheThumbnail, base::Unretained(this), email, wallpaper.image())); + custom_wallpaper_cache_.insert(std::make_pair(email, wallpaper.image())); ash::Shell::GetInstance()->desktop_background_controller()-> SetCustomWallpaper(wallpaper.image(), layout); } diff --git a/chrome/browser/chromeos/login/wallpaper_manager.h b/chrome/browser/chromeos/login/wallpaper_manager.h index 80db2aa..a47e2be 100644 --- a/chrome/browser/chromeos/login/wallpaper_manager.h +++ b/chrome/browser/chromeos/login/wallpaper_manager.h @@ -45,9 +45,6 @@ class WallpaperManager: public system::TimezoneSettings::Observer, // added after PowerManagerClient initialized. void AddObservers(); - // Caches |email|'s wallpaper to memory if it is custom wallpaper. - void CacheIfCustomWallpaper(const std::string& email); - // Loads wallpaper asynchronously if the current wallpaper is not the // wallpaper of logged in user. void EnsureLoggedInUserWallpaperLoaded(); @@ -134,6 +131,21 @@ class WallpaperManager: public system::TimezoneSettings::Observer, // at 0am if chromeos device is on. void BatchUpdateWallpaper(); + // Cache all logged in users' wallpapers to memory at login screen. It should + // not compete with first wallpaper loading when boot up/initialize login + // WebUI page. + // There are two ways the first wallpaper might be loaded: + // 1. Loaded on boot. Login WebUI waits for it. + // 2. When flag --disable-boot-animation is passed. Login WebUI is loaded + // right away and in 500ms after. Wallpaper started to load. + // For case 2, should_cache_wallpaper_ is used to indicate if we need to + // cache wallpapers on wallpaper animation finished. The cache operation + // should be only executed once. + void CacheAllUsersWallpapers(); + + // Caches |email|'s wallpaper to memory. + void CacheUserWallpaper(const std::string& email); + // Caches the decoded wallpaper to memory. void CacheWallpaper(const std::string& email, const UserImage& wallpaper); @@ -200,6 +212,8 @@ class WallpaperManager: public system::TimezoneSettings::Observer, // The last selected user on user pod row. std::string last_selected_user_; + bool should_cache_wallpaper_; + base::WeakPtrFactory<WallpaperManager> weak_factory_; content::NotificationRegistrar registrar_; |