| 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
|
| deleted file mode 100644
|
| index 8ae210f8921c3a21f3fd630890bdf0dae71b8956..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/chromeos/login/wallpaper_manager.cc
|
| +++ /dev/null
|
| @@ -1,1912 +0,0 @@
|
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/chromeos/login/wallpaper_manager.h"
|
| -
|
| -#include <numeric>
|
| -#include <vector>
|
| -
|
| -#include "ash/ash_constants.h"
|
| -#include "ash/ash_switches.h"
|
| -#include "ash/desktop_background/desktop_background_controller.h"
|
| -#include "ash/shell.h"
|
| -#include "base/command_line.h"
|
| -#include "base/debug/trace_event.h"
|
| -#include "base/file_util.h"
|
| -#include "base/files/file_enumerator.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/logging.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/path_service.h"
|
| -#include "base/prefs/pref_registry_simple.h"
|
| -#include "base/prefs/pref_service.h"
|
| -#include "base/prefs/scoped_user_pref_update.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/sys_info.h"
|
| -#include "base/threading/worker_pool.h"
|
| -#include "base/time/time.h"
|
| -#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_image.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"
|
| -#include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "chromeos/chromeos_switches.h"
|
| -#include "chromeos/dbus/dbus_thread_manager.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/notification_service.h"
|
| -#include "third_party/skia/include/core/SkColor.h"
|
| -#include "ui/gfx/codec/jpeg_codec.h"
|
| -#include "ui/gfx/image/image_skia_operations.h"
|
| -#include "ui/gfx/skia_util.h"
|
| -
|
| -using content::BrowserThread;
|
| -
|
| -namespace chromeos {
|
| -
|
| -namespace {
|
| -
|
| -// The amount of delay before starts to move custom wallpapers to the new place.
|
| -const int kMoveCustomWallpaperDelaySeconds = 30;
|
| -
|
| -// Default quality for encoding wallpaper.
|
| -const int kDefaultEncodingQuality = 90;
|
| -
|
| -// A dictionary pref that maps usernames to file paths to their wallpapers.
|
| -// Deprecated. Will remove this const char after done migration.
|
| -const char kUserWallpapers[] = "UserWallpapers";
|
| -
|
| -const int kCacheWallpaperDelayMs = 500;
|
| -
|
| -// A dictionary pref that maps usernames to wallpaper properties.
|
| -const char kUserWallpapersProperties[] = "UserWallpapersProperties";
|
| -
|
| -// Names of nodes with info about wallpaper in |kUserWallpapersProperties|
|
| -// dictionary.
|
| -const char kNewWallpaperDateNodeName[] = "date";
|
| -const char kNewWallpaperLayoutNodeName[] = "layout";
|
| -const char kNewWallpaperFileNodeName[] = "file";
|
| -const char kNewWallpaperTypeNodeName[] = "type";
|
| -
|
| -// Maximum number of wallpapers cached by CacheUsersWallpapers().
|
| -const int kMaxWallpapersToCache = 3;
|
| -
|
| -// Maximum number of entries in WallpaperManager::last_load_times_ .
|
| -const size_t kLastLoadsStatsMsMaxSize = 4;
|
| -
|
| -// Minimum delay between wallpaper loads, milliseconds.
|
| -const unsigned kLoadMinDelayMs = 50;
|
| -
|
| -// Default wallpaper load delay, milliseconds.
|
| -const unsigned kLoadDefaultDelayMs = 200;
|
| -
|
| -// Maximum wallpaper load delay, milliseconds.
|
| -const unsigned kLoadMaxDelayMs = 2000;
|
| -
|
| -// When no wallpaper image is specified, the screen is filled with a solid
|
| -// color.
|
| -const SkColor kDefaultWallpaperColor = SK_ColorGRAY;
|
| -
|
| -// For our scaling ratios we need to round positive numbers.
|
| -int RoundPositive(double x) {
|
| - return static_cast<int>(floor(x + 0.5));
|
| -}
|
| -
|
| -// Returns custom wallpaper directory by appending corresponding |sub_dir|.
|
| -base::FilePath GetCustomWallpaperDir(const char* sub_dir) {
|
| - base::FilePath custom_wallpaper_dir;
|
| - CHECK(PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS,
|
| - &custom_wallpaper_dir));
|
| - return custom_wallpaper_dir.Append(sub_dir);
|
| -}
|
| -
|
| -bool MoveCustomWallpaperDirectory(const char* sub_dir,
|
| - const std::string& user_id,
|
| - const std::string& user_id_hash) {
|
| - base::FilePath base_path = GetCustomWallpaperDir(sub_dir);
|
| - base::FilePath to_path = base_path.Append(user_id_hash);
|
| - base::FilePath from_path = base_path.Append(user_id);
|
| - if (base::PathExists(from_path))
|
| - return base::Move(from_path, to_path);
|
| - 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());
|
| -}
|
| -
|
| -// Deletes everything else except |path| in the same directory.
|
| -void DeleteAllExcept(const base::FilePath& path) {
|
| - base::FilePath dir = path.DirName();
|
| - if (base::DirectoryExists(dir)) {
|
| - base::FileEnumerator files(dir, false, base::FileEnumerator::FILES);
|
| - for (base::FilePath current = files.Next(); !current.empty();
|
| - current = files.Next()) {
|
| - if (current != path)
|
| - base::DeleteFile(current, false);
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Deletes a list of wallpaper files in |file_list|.
|
| -void DeleteWallpaperInList(const std::vector<base::FilePath>& file_list) {
|
| - for (std::vector<base::FilePath>::const_iterator it = file_list.begin();
|
| - it != file_list.end(); ++it) {
|
| - base::FilePath path = *it;
|
| - // Some users may still have legacy wallpapers with png extension. We need
|
| - // to delete these wallpapers too.
|
| - if (!base::DeleteFile(path, true) &&
|
| - !base::DeleteFile(path.AddExtension(".png"), false)) {
|
| - LOG(ERROR) << "Failed to remove user wallpaper at " << path.value();
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Creates all new custom wallpaper directories for |user_id_hash| if not exist.
|
| -void EnsureCustomWallpaperDirectories(const std::string& user_id_hash) {
|
| - base::FilePath dir;
|
| - dir = GetCustomWallpaperDir(kSmallWallpaperSubDir);
|
| - dir = dir.Append(user_id_hash);
|
| - if (!base::PathExists(dir))
|
| - base::CreateDirectory(dir);
|
| - dir = GetCustomWallpaperDir(kLargeWallpaperSubDir);
|
| - dir = dir.Append(user_id_hash);
|
| - if (!base::PathExists(dir))
|
| - base::CreateDirectory(dir);
|
| - dir = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
|
| - dir = dir.Append(user_id_hash);
|
| - if (!base::PathExists(dir))
|
| - base::CreateDirectory(dir);
|
| - dir = GetCustomWallpaperDir(kThumbnailWallpaperSubDir);
|
| - dir = dir.Append(user_id_hash);
|
| - if (!base::PathExists(dir))
|
| - base::CreateDirectory(dir);
|
| -}
|
| -
|
| -// Saves wallpaper image raw |data| to |path| (absolute path) in file system.
|
| -// Returns true on success.
|
| -bool SaveWallpaperInternal(const base::FilePath& path,
|
| - const char* data,
|
| - int size) {
|
| - int written_bytes = base::WriteFile(path, data, size);
|
| - return written_bytes == size;
|
| -}
|
| -
|
| -// Returns index of the first public session user found in |users|
|
| -// or -1 otherwise.
|
| -int FindPublicSession(const chromeos::UserList& users) {
|
| - int index = -1;
|
| - int i = 0;
|
| - for (UserList::const_iterator it = users.begin();
|
| - it != users.end(); ++it, ++i) {
|
| - if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
|
| - index = i;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - return index;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -const char kWallpaperSequenceTokenName[] = "wallpaper-sequence";
|
| -
|
| -const char kSmallWallpaperSuffix[] = "_small";
|
| -const char kLargeWallpaperSuffix[] = "_large";
|
| -
|
| -const char kSmallWallpaperSubDir[] = "small";
|
| -const char kLargeWallpaperSubDir[] = "large";
|
| -const char kOriginalWallpaperSubDir[] = "original";
|
| -const char kThumbnailWallpaperSubDir[] = "thumb";
|
| -
|
| -const int kSmallWallpaperMaxWidth = 1366;
|
| -const int kSmallWallpaperMaxHeight = 800;
|
| -const int kLargeWallpaperMaxWidth = 2560;
|
| -const int kLargeWallpaperMaxHeight = 1700;
|
| -const int kWallpaperThumbnailWidth = 108;
|
| -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_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CustomizedWallpaperRescaledFiles);
|
| -};
|
| -
|
| -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).
|
| -class MovableOnDestroyCallback {
|
| - public:
|
| - explicit MovableOnDestroyCallback(const base::Closure& callback)
|
| - : callback_(callback) {
|
| - }
|
| -
|
| - ~MovableOnDestroyCallback() {
|
| - if (!callback_.is_null())
|
| - callback_.Run();
|
| - }
|
| -
|
| - private:
|
| - base::Closure callback_;
|
| -};
|
| -
|
| -WallpaperManager::PendingWallpaper::PendingWallpaper(
|
| - const base::TimeDelta delay,
|
| - const std::string& user_id)
|
| - : user_id_(user_id),
|
| - default_(false),
|
| - on_finish_(new MovableOnDestroyCallback(
|
| - base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet,
|
| - this))) {
|
| - timer.Start(
|
| - FROM_HERE,
|
| - delay,
|
| - base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest, this));
|
| -}
|
| -
|
| -WallpaperManager::PendingWallpaper::~PendingWallpaper() {}
|
| -
|
| -void WallpaperManager::PendingWallpaper::ResetSetWallpaperImage(
|
| - const gfx::ImageSkia& image,
|
| - const WallpaperInfo& info) {
|
| - SetMode(image, info, base::FilePath(), false);
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::ResetLoadWallpaper(
|
| - const WallpaperInfo& info) {
|
| - SetMode(gfx::ImageSkia(), info, base::FilePath(), false);
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::ResetSetCustomWallpaper(
|
| - const WallpaperInfo& info,
|
| - const base::FilePath& wallpaper_path) {
|
| - SetMode(gfx::ImageSkia(), info, wallpaper_path, false);
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::ResetSetDefaultWallpaper() {
|
| - SetMode(gfx::ImageSkia(), WallpaperInfo(), base::FilePath(), true);
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::SetMode(
|
| - const gfx::ImageSkia& image,
|
| - const WallpaperInfo& info,
|
| - const base::FilePath& wallpaper_path,
|
| - const bool is_default) {
|
| - user_wallpaper_ = image;
|
| - info_ = info;
|
| - wallpaper_path_ = wallpaper_path;
|
| - default_ = is_default;
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::ProcessRequest() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - timer.Stop(); // Erase reference to self.
|
| -
|
| - WallpaperManager* manager = WallpaperManager::Get();
|
| - if (manager->pending_inactive_ == this)
|
| - manager->pending_inactive_ = NULL;
|
| -
|
| - started_load_at_ = base::Time::Now();
|
| -
|
| - if (default_) {
|
| - manager->DoSetDefaultWallpaper(user_id_, on_finish_.Pass());
|
| - } else if (!user_wallpaper_.isNull()) {
|
| - ash::Shell::GetInstance()
|
| - ->desktop_background_controller()
|
| - ->SetWallpaperImage(user_wallpaper_, info_.layout);
|
| - } else if (!wallpaper_path_.empty()) {
|
| - manager->task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::GetCustomWallpaperInternal,
|
| - base::Unretained(manager),
|
| - user_id_,
|
| - info_,
|
| - wallpaper_path_,
|
| - true /* update wallpaper */,
|
| - base::Passed(on_finish_.Pass())));
|
| - } else if (!info_.file.empty()) {
|
| - manager->LoadWallpaper(user_id_, info_, true, on_finish_.Pass());
|
| - } else {
|
| - // PendingWallpaper was created and never initialized?
|
| - NOTREACHED();
|
| - // Error. Do not record time.
|
| - started_load_at_ = base::Time();
|
| - }
|
| - on_finish_.reset();
|
| -}
|
| -
|
| -void WallpaperManager::PendingWallpaper::OnWallpaperSet() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - // The only known case for this check to fail is global destruction during
|
| - // wallpaper load. It should never happen.
|
| - if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
|
| - return; // We are in a process of global destruction.
|
| -
|
| - timer.Stop(); // Erase reference to self.
|
| -
|
| - WallpaperManager* manager = WallpaperManager::Get();
|
| - if (!started_load_at_.is_null()) {
|
| - const base::TimeDelta elapsed = base::Time::Now() - started_load_at_;
|
| - manager->SaveLastLoadTime(elapsed);
|
| - }
|
| - if (manager->pending_inactive_ == this) {
|
| - // ProcessRequest() was never executed.
|
| - manager->pending_inactive_ = NULL;
|
| - }
|
| -
|
| - // Destroy self.
|
| - manager->RemovePendingWallpaperFromList(this);
|
| -}
|
| -
|
| -// WallpaperManager, public: ---------------------------------------------------
|
| -
|
| -// TestApi. For testing purpose
|
| -WallpaperManager::TestApi::TestApi(WallpaperManager* wallpaper_manager)
|
| - : wallpaper_manager_(wallpaper_manager) {
|
| -}
|
| -
|
| -WallpaperManager::TestApi::~TestApi() {
|
| -}
|
| -
|
| -base::FilePath WallpaperManager::TestApi::current_wallpaper_path() {
|
| - return wallpaper_manager_->current_wallpaper_path_;
|
| -}
|
| -
|
| -bool WallpaperManager::TestApi::GetWallpaperFromCache(
|
| - const std::string& user_id, gfx::ImageSkia* image) {
|
| - return wallpaper_manager_->GetWallpaperFromCache(user_id, image);
|
| -}
|
| -
|
| -void WallpaperManager::TestApi::SetWallpaperCache(const std::string& user_id,
|
| - const gfx::ImageSkia& image) {
|
| - DCHECK(!image.isNull());
|
| - wallpaper_manager_->wallpaper_cache_[user_id] = image;
|
| -}
|
| -
|
| -void WallpaperManager::TestApi::ClearDisposableWallpaperCache() {
|
| - wallpaper_manager_->ClearDisposableWallpaperCache();
|
| -}
|
| -
|
| -// static
|
| -WallpaperManager* WallpaperManager::Get() {
|
| - if (!g_wallpaper_manager)
|
| - g_wallpaper_manager = new WallpaperManager();
|
| - return g_wallpaper_manager;
|
| -}
|
| -
|
| -WallpaperManager::WallpaperManager()
|
| - : loaded_wallpapers_(0),
|
| - command_line_for_testing_(NULL),
|
| - should_cache_wallpaper_(false),
|
| - weak_factory_(this),
|
| - pending_inactive_(NULL) {
|
| - SetDefaultWallpaperPathsFromCommandLine(
|
| - base::CommandLine::ForCurrentProcess());
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_LOGIN_USER_CHANGED,
|
| - content::NotificationService::AllSources());
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
|
| - content::NotificationService::AllSources());
|
| - registrar_.Add(this,
|
| - chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED,
|
| - content::NotificationService::AllSources());
|
| - sequence_token_ = BrowserThread::GetBlockingPool()->
|
| - GetNamedSequenceToken(kWallpaperSequenceTokenName);
|
| - task_runner_ = BrowserThread::GetBlockingPool()->
|
| - GetSequencedTaskRunnerWithShutdownBehavior(
|
| - sequence_token_,
|
| - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
|
| - wallpaper_loader_ = new UserImageLoader(ImageDecoder::ROBUST_JPEG_CODEC,
|
| - task_runner_);
|
| -}
|
| -
|
| -WallpaperManager::~WallpaperManager() {
|
| - // TODO(bshe): Lifetime of WallpaperManager needs more consideration.
|
| - // http://crbug.com/171694
|
| - DCHECK(!show_user_name_on_signin_subscription_);
|
| -
|
| - ClearObsoleteWallpaperPrefs();
|
| - weak_factory_.InvalidateWeakPtrs();
|
| -}
|
| -
|
| -void WallpaperManager::Shutdown() {
|
| - show_user_name_on_signin_subscription_.reset();
|
| -}
|
| -
|
| -// static
|
| -void WallpaperManager::RegisterPrefs(PrefRegistrySimple* registry) {
|
| - registry->RegisterDictionaryPref(prefs::kUsersWallpaperInfo);
|
| - registry->RegisterDictionaryPref(kUserWallpapers);
|
| - registry->RegisterDictionaryPref(kUserWallpapersProperties);
|
| -}
|
| -
|
| -void WallpaperManager::AddObservers() {
|
| - show_user_name_on_signin_subscription_ =
|
| - CrosSettings::Get()->AddSettingsObserver(
|
| - kAccountsPrefShowUserNamesOnSignIn,
|
| - base::Bind(&WallpaperManager::InitializeRegisteredDeviceWallpaper,
|
| - base::Unretained(this)));
|
| -}
|
| -
|
| -void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() {
|
| - // Some browser tests do not have a shell instance. As no wallpaper is needed
|
| - // in these tests anyway, avoid loading one, preventing crashes and speeding
|
| - // up the tests.
|
| - if (!ash::Shell::HasInstance())
|
| - return;
|
| -
|
| - WallpaperInfo info;
|
| - if (GetLoggedInUserWallpaperInfo(&info)) {
|
| - // TODO(sschmitz): We need an index for default wallpapers for the new UI.
|
| - RecordUma(info.type, -1);
|
| - if (info == current_user_wallpaper_info_)
|
| - return;
|
| - }
|
| - SetUserWallpaperNow(UserManager::Get()->GetLoggedInUser()->email());
|
| -}
|
| -
|
| -void WallpaperManager::ClearDisposableWallpaperCache() {
|
| - // Cancel callback for previous cache requests.
|
| - weak_factory_.InvalidateWeakPtrs();
|
| - // Keep the wallpaper of logged in users in cache at multi-profile mode.
|
| - std::set<std::string> logged_in_users_names;
|
| - const UserList& logged_users = UserManager::Get()->GetLoggedInUsers();
|
| - for (UserList::const_iterator it = logged_users.begin();
|
| - it != logged_users.end();
|
| - ++it) {
|
| - logged_in_users_names.insert((*it)->email());
|
| - }
|
| -
|
| - CustomWallpaperMap logged_in_users_cache;
|
| - for (CustomWallpaperMap::iterator it = wallpaper_cache_.begin();
|
| - it != wallpaper_cache_.end(); ++it) {
|
| - if (logged_in_users_names.find(it->first) !=
|
| - logged_in_users_names.end()) {
|
| - logged_in_users_cache.insert(*it);
|
| - }
|
| - }
|
| - wallpaper_cache_ = logged_in_users_cache;
|
| -}
|
| -
|
| -base::FilePath WallpaperManager::GetCustomWallpaperPath(
|
| - const char* sub_dir,
|
| - const std::string& user_id_hash,
|
| - const std::string& file) const {
|
| - base::FilePath custom_wallpaper_path = GetCustomWallpaperDir(sub_dir);
|
| - return custom_wallpaper_path.Append(user_id_hash).Append(file);
|
| -}
|
| -
|
| -bool WallpaperManager::GetLoggedInUserWallpaperInfo(WallpaperInfo* info) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (UserManager::Get()->IsLoggedInAsStub()) {
|
| - info->file = current_user_wallpaper_info_.file = "";
|
| - info->layout = current_user_wallpaper_info_.layout =
|
| - ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
|
| - info->type = current_user_wallpaper_info_.type = User::DEFAULT;
|
| - info->date = current_user_wallpaper_info_.date =
|
| - base::Time::Now().LocalMidnight();
|
| - return true;
|
| - }
|
| -
|
| - return GetUserWallpaperInfo(UserManager::Get()->GetLoggedInUser()->email(),
|
| - info);
|
| -}
|
| -
|
| -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.
|
| - // Note: This maybe called before login. So IsLoggedInAsGuest can not be
|
| - // used here to determine if current user is guest.
|
| - return;
|
| - }
|
| -
|
| - if (command_line->HasSwitch(::switches::kTestType))
|
| - WizardController::SetZeroDelays();
|
| -
|
| - // Zero delays is also set in autotests.
|
| - if (WizardController::IsZeroDelayEnabled()) {
|
| - // Ensure tests have some sort of wallpaper.
|
| - ash::Shell::GetInstance()->desktop_background_controller()->
|
| - CreateEmptyWallpaper();
|
| - return;
|
| - }
|
| -
|
| - if (!user_manager->IsUserLoggedIn()) {
|
| - if (!StartupUtils::IsDeviceRegistered())
|
| - SetDefaultWallpaperDelayed(UserManager::kSignInUser);
|
| - else
|
| - InitializeRegisteredDeviceWallpaper();
|
| - return;
|
| - }
|
| - SetUserWallpaperDelayed(user_manager->GetLoggedInUser()->email());
|
| -}
|
| -
|
| -void WallpaperManager::Observe(int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - switch (type) {
|
| - case chrome::NOTIFICATION_LOGIN_USER_CHANGED: {
|
| - ClearDisposableWallpaperCache();
|
| - BrowserThread::PostDelayedTask(
|
| - BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::MoveLoggedInUserCustomWallpaper,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::TimeDelta::FromSeconds(kMoveCustomWallpaperDelaySeconds));
|
| - break;
|
| - }
|
| - case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE: {
|
| - if (!GetCommandLine()->HasSwitch(switches::kDisableBootAnimation)) {
|
| - BrowserThread::PostDelayedTask(
|
| - BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&WallpaperManager::CacheUsersWallpapers,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs));
|
| - } else {
|
| - should_cache_wallpaper_ = true;
|
| - }
|
| - break;
|
| - }
|
| - case chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED: {
|
| - NotifyAnimationFinished();
|
| - if (should_cache_wallpaper_) {
|
| - BrowserThread::PostDelayedTask(
|
| - BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&WallpaperManager::CacheUsersWallpapers,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs));
|
| - should_cache_wallpaper_ = false;
|
| - }
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED() << "Unexpected notification " << type;
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::RemoveUserWallpaperInfo(const std::string& user_id) {
|
| - WallpaperInfo info;
|
| - GetUserWallpaperInfo(user_id, &info);
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - DictionaryPrefUpdate prefs_wallpapers_info_update(prefs,
|
| - prefs::kUsersWallpaperInfo);
|
| - prefs_wallpapers_info_update->RemoveWithoutPathExpansion(user_id, NULL);
|
| - DeleteUserWallpapers(user_id, info.file);
|
| -}
|
| -
|
| -// static
|
| -bool WallpaperManager::ResizeImage(const gfx::ImageSkia& image,
|
| - ash::WallpaperLayout layout,
|
| - int preferred_width,
|
| - int preferred_height,
|
| - scoped_refptr<base::RefCountedBytes>* output,
|
| - gfx::ImageSkia* output_skia) {
|
| - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - int width = image.width();
|
| - int height = image.height();
|
| - int resized_width;
|
| - int resized_height;
|
| - *output = new base::RefCountedBytes();
|
| -
|
| - if (layout == ash::WALLPAPER_LAYOUT_CENTER_CROPPED) {
|
| - // Do not resize custom wallpaper if it is smaller than preferred size.
|
| - if (!(width > preferred_width && height > preferred_height))
|
| - return false;
|
| -
|
| - double horizontal_ratio = static_cast<double>(preferred_width) / width;
|
| - double vertical_ratio = static_cast<double>(preferred_height) / 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::WALLPAPER_LAYOUT_STRETCH) {
|
| - resized_width = preferred_width;
|
| - resized_height = preferred_height;
|
| - } else {
|
| - resized_width = width;
|
| - resized_height = height;
|
| - }
|
| -
|
| - gfx::ImageSkia resized_image = gfx::ImageSkiaOperations::CreateResizedImage(
|
| - image,
|
| - skia::ImageOperations::RESIZE_LANCZOS3,
|
| - gfx::Size(resized_width, resized_height));
|
| -
|
| - SkBitmap bitmap = *(resized_image.bitmap());
|
| - SkAutoLockPixels lock_input(bitmap);
|
| - gfx::JPEGCodec::Encode(
|
| - reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
|
| - gfx::JPEGCodec::FORMAT_SkBitmap,
|
| - bitmap.width(),
|
| - bitmap.height(),
|
| - bitmap.width() * bitmap.bytesPerPixel(),
|
| - kDefaultEncodingQuality,
|
| - &(*output)->data());
|
| -
|
| - if (output_skia) {
|
| - resized_image.MakeThreadSafe();
|
| - *output_skia = resized_image;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// static
|
| -bool WallpaperManager::ResizeAndSaveWallpaper(const gfx::ImageSkia& image,
|
| - const base::FilePath& path,
|
| - ash::WallpaperLayout layout,
|
| - int preferred_width,
|
| - int preferred_height,
|
| - gfx::ImageSkia* output_skia) {
|
| - if (layout == ash::WALLPAPER_LAYOUT_CENTER) {
|
| - // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
|
| - if (base::PathExists(path))
|
| - base::DeleteFile(path, false);
|
| - return false;
|
| - }
|
| - scoped_refptr<base::RefCountedBytes> data;
|
| - if (ResizeImage(image,
|
| - layout,
|
| - preferred_width,
|
| - preferred_height,
|
| - &data,
|
| - output_skia)) {
|
| - return SaveWallpaperInternal(
|
| - path, reinterpret_cast<const char*>(data->front()), data->size());
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool WallpaperManager::IsPolicyControlled(const std::string& user_id) const {
|
| - chromeos::WallpaperInfo info;
|
| - if (!GetUserWallpaperInfo(user_id, &info))
|
| - return false;
|
| - return info.type == chromeos::User::POLICY;
|
| -}
|
| -
|
| -void WallpaperManager::OnPolicySet(const std::string& policy,
|
| - const std::string& user_id) {
|
| - WallpaperInfo info;
|
| - GetUserWallpaperInfo(user_id, &info);
|
| - info.type = User::POLICY;
|
| - SetUserWallpaperInfo(user_id, info, true /* is_persistent */);
|
| -}
|
| -
|
| -void WallpaperManager::OnPolicyCleared(const std::string& policy,
|
| - const std::string& user_id) {
|
| - WallpaperInfo info;
|
| - GetUserWallpaperInfo(user_id, &info);
|
| - info.type = User::DEFAULT;
|
| - SetUserWallpaperInfo(user_id, info, true /* is_persistent */);
|
| - SetDefaultWallpaperNow(user_id);
|
| -}
|
| -
|
| -void WallpaperManager::OnPolicyFetched(const std::string& policy,
|
| - const std::string& user_id,
|
| - scoped_ptr<std::string> data) {
|
| - if (!data)
|
| - return;
|
| -
|
| - wallpaper_loader_->Start(
|
| - data.Pass(),
|
| - 0, // Do not crop.
|
| - base::Bind(&WallpaperManager::SetPolicyControlledWallpaper,
|
| - weak_factory_.GetWeakPtr(),
|
| - user_id));
|
| -}
|
| -
|
| -// static
|
| -WallpaperManager::WallpaperResolution
|
| -WallpaperManager::GetAppropriateResolution() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - gfx::Size size =
|
| - ash::DesktopBackgroundController::GetMaxDisplaySizeInNative();
|
| - return (size.width() > kSmallWallpaperMaxWidth ||
|
| - size.height() > kSmallWallpaperMaxHeight)
|
| - ? WALLPAPER_RESOLUTION_LARGE
|
| - : WALLPAPER_RESOLUTION_SMALL;
|
| -}
|
| -
|
| -void WallpaperManager::SetPolicyControlledWallpaper(
|
| - const std::string& user_id,
|
| - const UserImage& user_image) {
|
| - const User *user = chromeos::UserManager::Get()->FindUser(user_id);
|
| - if (!user) {
|
| - NOTREACHED() << "Unknown user.";
|
| - return;
|
| - }
|
| - SetCustomWallpaper(user_id,
|
| - user->username_hash(),
|
| - "policy-controlled.jpeg",
|
| - ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
|
| - User::POLICY,
|
| - user_image.image(),
|
| - true /* update wallpaper */);
|
| -}
|
| -
|
| -void WallpaperManager::SetCustomWallpaper(const std::string& user_id,
|
| - const std::string& user_id_hash,
|
| - const std::string& file,
|
| - ash::WallpaperLayout layout,
|
| - User::WallpaperType type,
|
| - const gfx::ImageSkia& image,
|
| - bool update_wallpaper) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - DCHECK(UserManager::Get()->IsUserLoggedIn());
|
| -
|
| - // There is no visible background in kiosk mode.
|
| - if (UserManager::Get()->IsLoggedInAsKioskApp())
|
| - return;
|
| -
|
| - // Don't allow custom wallpapers while policy is in effect.
|
| - if (type != User::POLICY && IsPolicyControlled(user_id))
|
| - return;
|
| -
|
| - base::FilePath wallpaper_path =
|
| - GetCustomWallpaperPath(kOriginalWallpaperSubDir, user_id_hash, file);
|
| -
|
| - // If decoded wallpaper is empty, we have probably failed to decode the file.
|
| - // Use default wallpaper in this case.
|
| - if (image.isNull()) {
|
| - SetDefaultWallpaperDelayed(user_id);
|
| - return;
|
| - }
|
| -
|
| - bool is_persistent =
|
| - !UserManager::Get()->IsUserNonCryptohomeDataEphemeral(user_id);
|
| -
|
| - WallpaperInfo wallpaper_info = {
|
| - wallpaper_path.value(),
|
| - layout,
|
| - type,
|
| - // Date field is not used.
|
| - base::Time::Now().LocalMidnight()
|
| - };
|
| - if (is_persistent) {
|
| - image.EnsureRepsForSupportedScales();
|
| - scoped_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
|
| - // 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);
|
| - // TODO(bshe): This may break if RawImage becomes RefCountedMemory.
|
| - blocking_task_runner->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::SaveCustomWallpaper,
|
| - base::Unretained(this),
|
| - user_id_hash,
|
| - base::FilePath(wallpaper_info.file),
|
| - wallpaper_info.layout,
|
| - base::Passed(deep_copy.Pass())));
|
| - }
|
| -
|
| - std::string relative_path = base::FilePath(user_id_hash).Append(file).value();
|
| - // User's custom wallpaper path is determined by relative path and the
|
| - // appropriate wallpaper resolution in GetCustomWallpaperInternal.
|
| - WallpaperInfo info = {
|
| - relative_path,
|
| - layout,
|
| - type,
|
| - base::Time::Now().LocalMidnight()
|
| - };
|
| - SetUserWallpaperInfo(user_id, info, is_persistent);
|
| - if (update_wallpaper) {
|
| - GetPendingWallpaper(user_id, false)->ResetSetWallpaperImage(image, info);
|
| - }
|
| -
|
| - wallpaper_cache_[user_id] = image;
|
| -}
|
| -
|
| -void WallpaperManager::SetDefaultWallpaperNow(const std::string& user_id) {
|
| - GetPendingWallpaper(user_id, false)->ResetSetDefaultWallpaper();
|
| -}
|
| -
|
| -void WallpaperManager::SetDefaultWallpaperDelayed(const std::string& user_id) {
|
| - GetPendingWallpaper(user_id, true)->ResetSetDefaultWallpaper();
|
| -}
|
| -
|
| -void WallpaperManager::DoSetDefaultWallpaper(
|
| - const std::string& user_id,
|
| - MovableOnDestroyCallbackHolder on_finish) {
|
| - // There is no visible background in kiosk mode.
|
| - if (UserManager::Get()->IsLoggedInAsKioskApp())
|
| - return;
|
| - current_wallpaper_path_.clear();
|
| - wallpaper_cache_.erase(user_id);
|
| - // Some browser tests do not have a shell instance. As no wallpaper is needed
|
| - // in these tests anyway, avoid loading one, preventing crashes and speeding
|
| - // up the tests.
|
| - if (!ash::Shell::HasInstance())
|
| - return;
|
| -
|
| - WallpaperResolution resolution = GetAppropriateResolution();
|
| - const bool use_small = (resolution == WALLPAPER_RESOLUTION_SMALL);
|
| -
|
| - const base::FilePath* file = NULL;
|
| -
|
| - if (UserManager::Get()->IsLoggedInAsGuest()) {
|
| - file =
|
| - use_small ? &guest_small_wallpaper_file_ : &guest_large_wallpaper_file_;
|
| - } else {
|
| - file = use_small ? &default_small_wallpaper_file_
|
| - : &default_large_wallpaper_file_;
|
| - }
|
| - ash::WallpaperLayout layout = use_small
|
| - ? ash::WALLPAPER_LAYOUT_CENTER
|
| - : ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
|
| - DCHECK(file);
|
| - if (!default_wallpaper_image_.get() ||
|
| - default_wallpaper_image_->file_path() != file->value()) {
|
| - default_wallpaper_image_.reset();
|
| - if (!file->empty()) {
|
| - loaded_wallpapers_++;
|
| - StartLoadAndSetDefaultWallpaper(
|
| - *file, layout, on_finish.Pass(), &default_wallpaper_image_);
|
| - return;
|
| - }
|
| -
|
| - CreateSolidDefaultWallpaper();
|
| - }
|
| - // 1x1 wallpaper is actually solid color, so it should be stretched.
|
| - if (default_wallpaper_image_->image().width() == 1 &&
|
| - default_wallpaper_image_->image().height() == 1)
|
| - layout = ash::WALLPAPER_LAYOUT_STRETCH;
|
| -
|
| - ash::Shell::GetInstance()->desktop_background_controller()->SetWallpaperImage(
|
| - default_wallpaper_image_->image(), layout);
|
| -}
|
| -
|
| -void WallpaperManager::InitInitialUserWallpaper(const std::string& user_id,
|
| - bool is_persistent) {
|
| - current_user_wallpaper_info_.file = "";
|
| - current_user_wallpaper_info_.layout = ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
|
| - current_user_wallpaper_info_.type = User::DEFAULT;
|
| - current_user_wallpaper_info_.date = base::Time::Now().LocalMidnight();
|
| -
|
| - WallpaperInfo info = current_user_wallpaper_info_;
|
| - SetUserWallpaperInfo(user_id, info, is_persistent);
|
| -}
|
| -
|
| -void WallpaperManager::SetUserWallpaperInfo(const std::string& user_id,
|
| - const WallpaperInfo& info,
|
| - bool is_persistent) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - current_user_wallpaper_info_ = info;
|
| - if (!is_persistent)
|
| - return;
|
| -
|
| - PrefService* local_state = g_browser_process->local_state();
|
| - DictionaryPrefUpdate wallpaper_update(local_state,
|
| - prefs::kUsersWallpaperInfo);
|
| -
|
| - base::DictionaryValue* wallpaper_info_dict = new base::DictionaryValue();
|
| - wallpaper_info_dict->SetString(kNewWallpaperDateNodeName,
|
| - base::Int64ToString(info.date.ToInternalValue()));
|
| - wallpaper_info_dict->SetString(kNewWallpaperFileNodeName, info.file);
|
| - wallpaper_info_dict->SetInteger(kNewWallpaperLayoutNodeName, info.layout);
|
| - wallpaper_info_dict->SetInteger(kNewWallpaperTypeNodeName, info.type);
|
| - wallpaper_update->SetWithoutPathExpansion(user_id, wallpaper_info_dict);
|
| -}
|
| -
|
| -void WallpaperManager::SetUserWallpaperDelayed(const std::string& user_id) {
|
| - ScheduleSetUserWallpaper(user_id, true);
|
| -}
|
| -
|
| -void WallpaperManager::SetUserWallpaperNow(const std::string& user_id) {
|
| - ScheduleSetUserWallpaper(user_id, false);
|
| -}
|
| -
|
| -void WallpaperManager::ScheduleSetUserWallpaper(const std::string& user_id,
|
| - bool delayed) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - // Some unit tests come here without a UserManager or without a pref system.
|
| - if (!UserManager::IsInitialized() || !g_browser_process->local_state())
|
| - return;
|
| - // There is no visible background in kiosk mode.
|
| - if (UserManager::Get()->IsLoggedInAsKioskApp())
|
| - return;
|
| - // Guest user, regular user in ephemeral mode, or kiosk app.
|
| - const User* user = UserManager::Get()->FindUser(user_id);
|
| - if (UserManager::Get()->IsUserNonCryptohomeDataEphemeral(user_id) ||
|
| - (user != NULL && user->GetType() == User::USER_TYPE_KIOSK_APP)) {
|
| - InitInitialUserWallpaper(user_id, false);
|
| - GetPendingWallpaper(user_id, delayed)->ResetSetDefaultWallpaper();
|
| - return;
|
| - }
|
| -
|
| - if (!UserManager::Get()->IsKnownUser(user_id))
|
| - return;
|
| -
|
| - last_selected_user_ = user_id;
|
| -
|
| - WallpaperInfo info;
|
| -
|
| - if (!GetUserWallpaperInfo(user_id, &info)) {
|
| - InitInitialUserWallpaper(user_id, true);
|
| - GetUserWallpaperInfo(user_id, &info);
|
| - }
|
| -
|
| - gfx::ImageSkia user_wallpaper;
|
| - current_user_wallpaper_info_ = info;
|
| - if (GetWallpaperFromCache(user_id, &user_wallpaper)) {
|
| - GetPendingWallpaper(user_id, delayed)
|
| - ->ResetSetWallpaperImage(user_wallpaper, info);
|
| - } else {
|
| - if (info.type == User::CUSTOMIZED || info.type == User::POLICY) {
|
| - const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
|
| - // Wallpaper is not resized when layout is ash::WALLPAPER_LAYOUT_CENTER.
|
| - // Original wallpaper should be used in this case.
|
| - // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
|
| - if (info.layout == ash::WALLPAPER_LAYOUT_CENTER)
|
| - sub_dir = kOriginalWallpaperSubDir;
|
| - base::FilePath wallpaper_path = GetCustomWallpaperDir(sub_dir);
|
| - wallpaper_path = wallpaper_path.Append(info.file);
|
| - if (current_wallpaper_path_ == wallpaper_path)
|
| - return;
|
| - current_wallpaper_path_ = wallpaper_path;
|
| - loaded_wallpapers_++;
|
| -
|
| - GetPendingWallpaper(user_id, delayed)
|
| - ->ResetSetCustomWallpaper(info, wallpaper_path);
|
| - return;
|
| - }
|
| -
|
| - if (info.file.empty()) {
|
| - // Uses default built-in wallpaper when file is empty. Eventually, we
|
| - // will only ship one built-in wallpaper in ChromeOS image.
|
| - GetPendingWallpaper(user_id, delayed)->ResetSetDefaultWallpaper();
|
| - return;
|
| - }
|
| -
|
| - // Load downloaded ONLINE or converted DEFAULT wallpapers.
|
| - GetPendingWallpaper(user_id, delayed)->ResetLoadWallpaper(info);
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::SetWallpaperFromImageSkia(const std::string& user_id,
|
| - const gfx::ImageSkia& image,
|
| - ash::WallpaperLayout layout,
|
| - bool update_wallpaper) {
|
| - DCHECK(UserManager::Get()->IsUserLoggedIn());
|
| -
|
| - // There is no visible background in kiosk mode.
|
| - if (UserManager::Get()->IsLoggedInAsKioskApp())
|
| - return;
|
| - WallpaperInfo info;
|
| - info.layout = layout;
|
| - wallpaper_cache_[user_id] = image;
|
| -
|
| - if (update_wallpaper) {
|
| - GetPendingWallpaper(last_selected_user_, false /* Not delayed */)
|
| - ->ResetSetWallpaperImage(image, info);
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::UpdateWallpaper(bool clear_cache) {
|
| - FOR_EACH_OBSERVER(Observer, observers_, OnUpdateWallpaperForTesting());
|
| - if (clear_cache)
|
| - wallpaper_cache_.clear();
|
| - current_wallpaper_path_.clear();
|
| - // For GAIA login flow, the last_selected_user_ may not be set before user
|
| - // login. If UpdateWallpaper is called at GAIA login screen, no wallpaper will
|
| - // be set. It could result a black screen on external monitors.
|
| - // See http://crbug.com/265689 for detail.
|
| - if (last_selected_user_.empty()) {
|
| - SetDefaultWallpaperNow(UserManager::kSignInUser);
|
| - return;
|
| - }
|
| - SetUserWallpaperNow(last_selected_user_);
|
| -}
|
| -
|
| -void WallpaperManager::AddObserver(WallpaperManager::Observer* observer) {
|
| - observers_.AddObserver(observer);
|
| -}
|
| -
|
| -void WallpaperManager::RemoveObserver(WallpaperManager::Observer* observer) {
|
| - observers_.RemoveObserver(observer);
|
| -}
|
| -
|
| -void WallpaperManager::NotifyAnimationFinished() {
|
| - FOR_EACH_OBSERVER(
|
| - Observer, observers_, OnWallpaperAnimationFinished(last_selected_user_));
|
| -}
|
| -
|
| -// WallpaperManager, private: --------------------------------------------------
|
| -
|
| -bool WallpaperManager::GetWallpaperFromCache(const std::string& user_id,
|
| - gfx::ImageSkia* image) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - CustomWallpaperMap::const_iterator it = wallpaper_cache_.find(user_id);
|
| - if (it != wallpaper_cache_.end()) {
|
| - *image = (*it).second;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -void WallpaperManager::CacheUsersWallpapers() {
|
| - 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 (int cached = 0;
|
| - it != users.end() && cached < kMaxWallpapersToCache;
|
| - ++it, ++cached) {
|
| - std::string user_id = (*it)->email();
|
| - CacheUserWallpaper(user_id);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::CacheUserWallpaper(const std::string& user_id) {
|
| - if (wallpaper_cache_.find(user_id) != wallpaper_cache_.end())
|
| - return;
|
| - WallpaperInfo info;
|
| - if (GetUserWallpaperInfo(user_id, &info)) {
|
| - base::FilePath wallpaper_dir;
|
| - base::FilePath wallpaper_path;
|
| - if (info.type == User::CUSTOMIZED || info.type == User::POLICY) {
|
| - const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
|
| - base::FilePath wallpaper_path = GetCustomWallpaperDir(sub_dir);
|
| - wallpaper_path = wallpaper_path.Append(info.file);
|
| - task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::GetCustomWallpaperInternal,
|
| - base::Unretained(this),
|
| - user_id,
|
| - info,
|
| - wallpaper_path,
|
| - false /* do not update wallpaper */,
|
| - base::Passed(MovableOnDestroyCallbackHolder())));
|
| - return;
|
| - }
|
| - LoadWallpaper(user_id,
|
| - info,
|
| - false /* do not update wallpaper */,
|
| - MovableOnDestroyCallbackHolder().Pass());
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::ClearObsoleteWallpaperPrefs() {
|
| - PrefService* prefs = g_browser_process->local_state();
|
| - DictionaryPrefUpdate wallpaper_properties_pref(prefs,
|
| - kUserWallpapersProperties);
|
| - wallpaper_properties_pref->Clear();
|
| - DictionaryPrefUpdate wallpapers_pref(prefs, kUserWallpapers);
|
| - wallpapers_pref->Clear();
|
| -}
|
| -
|
| -void WallpaperManager::DeleteUserWallpapers(const std::string& user_id,
|
| - const std::string& path_to_file) {
|
| - std::vector<base::FilePath> file_to_remove;
|
| - // Remove small user wallpaper.
|
| - base::FilePath wallpaper_path =
|
| - GetCustomWallpaperDir(kSmallWallpaperSubDir);
|
| - // Remove old directory if exists
|
| - file_to_remove.push_back(wallpaper_path.Append(user_id));
|
| - wallpaper_path = wallpaper_path.Append(path_to_file).DirName();
|
| - file_to_remove.push_back(wallpaper_path);
|
| -
|
| - // Remove large user wallpaper.
|
| - wallpaper_path = GetCustomWallpaperDir(kLargeWallpaperSubDir);
|
| - file_to_remove.push_back(wallpaper_path.Append(user_id));
|
| - wallpaper_path = wallpaper_path.Append(path_to_file);
|
| - file_to_remove.push_back(wallpaper_path);
|
| -
|
| - // Remove user wallpaper thumbnail.
|
| - wallpaper_path = GetCustomWallpaperDir(kThumbnailWallpaperSubDir);
|
| - file_to_remove.push_back(wallpaper_path.Append(user_id));
|
| - wallpaper_path = wallpaper_path.Append(path_to_file);
|
| - file_to_remove.push_back(wallpaper_path);
|
| -
|
| - // Remove original user wallpaper.
|
| - wallpaper_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
|
| - file_to_remove.push_back(wallpaper_path.Append(user_id));
|
| - wallpaper_path = wallpaper_path.Append(path_to_file);
|
| - file_to_remove.push_back(wallpaper_path);
|
| -
|
| - base::WorkerPool::PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&DeleteWallpaperInList, file_to_remove),
|
| - false);
|
| -}
|
| -
|
| -void WallpaperManager::SetCommandLineForTesting(
|
| - base::CommandLine* command_line) {
|
| - command_line_for_testing_ = command_line;
|
| - SetDefaultWallpaperPathsFromCommandLine(command_line);
|
| -}
|
| -
|
| -CommandLine* WallpaperManager::GetCommandLine() {
|
| - CommandLine* command_line = command_line_for_testing_ ?
|
| - command_line_for_testing_ : CommandLine::ForCurrentProcess();
|
| - return command_line;
|
| -}
|
| -
|
| -void WallpaperManager::InitializeRegisteredDeviceWallpaper() {
|
| - if (UserManager::Get()->IsUserLoggedIn())
|
| - return;
|
| -
|
| - bool disable_boot_animation =
|
| - GetCommandLine()->HasSwitch(switches::kDisableBootAnimation);
|
| - bool show_users = true;
|
| - bool result = CrosSettings::Get()->GetBoolean(
|
| - kAccountsPrefShowUserNamesOnSignIn, &show_users);
|
| - DCHECK(result) << "Unable to fetch setting "
|
| - << kAccountsPrefShowUserNamesOnSignIn;
|
| - const chromeos::UserList& users = UserManager::Get()->GetUsers();
|
| - int public_session_user_index = FindPublicSession(users);
|
| - if ((!show_users && public_session_user_index == -1) || users.empty()) {
|
| - // Boot into sign in form, preload default wallpaper.
|
| - SetDefaultWallpaperDelayed(UserManager::kSignInUser);
|
| - return;
|
| - }
|
| -
|
| - if (!disable_boot_animation) {
|
| - int index = public_session_user_index != -1 ? public_session_user_index : 0;
|
| - // Normal boot, load user wallpaper.
|
| - // If normal boot animation is disabled wallpaper would be set
|
| - // asynchronously once user pods are loaded.
|
| - SetUserWallpaperDelayed(users[index]->email());
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::LoadWallpaper(const std::string& user_id,
|
| - const WallpaperInfo& info,
|
| - bool update_wallpaper,
|
| - MovableOnDestroyCallbackHolder on_finish) {
|
| - base::FilePath wallpaper_dir;
|
| - base::FilePath wallpaper_path;
|
| -
|
| - // Do a sanity check that file path information is not empty.
|
| - if (info.type == User::ONLINE || info.type == User::DEFAULT) {
|
| - if (info.file.empty()) {
|
| - if (base::SysInfo::IsRunningOnChromeOS()) {
|
| - NOTREACHED() << "User wallpaper info appears to be broken: " << user_id;
|
| - } else {
|
| - // Filename might be empty on debug configurations when stub users
|
| - // were created directly in Local State (for testing). Ignore such
|
| - // errors i.e. allowsuch type of debug configurations on the desktop.
|
| - LOG(WARNING) << "User wallpaper info is empty: " << user_id;
|
| -
|
| - // |on_finish| callback will get called on destruction.
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (info.type == User::ONLINE) {
|
| - std::string file_name = GURL(info.file).ExtractFileName();
|
| - WallpaperResolution resolution = GetAppropriateResolution();
|
| - // Only solid color wallpapers have stretch layout and they have only one
|
| - // resolution.
|
| - if (info.layout != ash::WALLPAPER_LAYOUT_STRETCH &&
|
| - resolution == WALLPAPER_RESOLUTION_SMALL) {
|
| - file_name = base::FilePath(file_name).InsertBeforeExtension(
|
| - kSmallWallpaperSuffix).value();
|
| - }
|
| - CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
|
| - wallpaper_path = wallpaper_dir.Append(file_name);
|
| - if (current_wallpaper_path_ == wallpaper_path)
|
| - return;
|
| -
|
| - if (update_wallpaper)
|
| - current_wallpaper_path_ = wallpaper_path;
|
| -
|
| - loaded_wallpapers_++;
|
| - StartLoad(
|
| - user_id, info, update_wallpaper, wallpaper_path, on_finish.Pass());
|
| - } else if (info.type == User::DEFAULT) {
|
| - // Default wallpapers are migrated from M21 user profiles. A code refactor
|
| - // overlooked that case and caused these wallpapers not being loaded at all.
|
| - // On some slow devices, it caused login webui not visible after upgrade to
|
| - // M26 from M21. See crosbug.com/38429 for details.
|
| - base::FilePath user_data_dir;
|
| - PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
| - wallpaper_path = user_data_dir.Append(info.file);
|
| - StartLoad(
|
| - user_id, info, update_wallpaper, wallpaper_path, on_finish.Pass());
|
| - } else {
|
| - // In unexpected cases, revert to default wallpaper to fail safely. See
|
| - // crosbug.com/38429.
|
| - LOG(ERROR) << "Wallpaper reverts to default unexpected.";
|
| - DoSetDefaultWallpaper(user_id, on_finish.Pass());
|
| - }
|
| -}
|
| -
|
| -bool WallpaperManager::GetUserWallpaperInfo(const std::string& user_id,
|
| - WallpaperInfo* info) const {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| -
|
| - if (UserManager::Get()->IsUserNonCryptohomeDataEphemeral(user_id)) {
|
| - // Default to the values cached in memory.
|
| - *info = current_user_wallpaper_info_;
|
| -
|
| - // Ephemeral users do not save anything to local state. But we have got
|
| - // wallpaper info from memory. Returns true.
|
| - return true;
|
| - }
|
| -
|
| - const base::DictionaryValue* info_dict;
|
| - if (!g_browser_process->local_state()->
|
| - GetDictionary(prefs::kUsersWallpaperInfo)->
|
| - GetDictionaryWithoutPathExpansion(user_id, &info_dict)) {
|
| - return false;
|
| - }
|
| -
|
| - // Use temporary variables to keep |info| untouched in the error case.
|
| - std::string file;
|
| - if (!info_dict->GetString(kNewWallpaperFileNodeName, &file))
|
| - return false;
|
| - int layout;
|
| - if (!info_dict->GetInteger(kNewWallpaperLayoutNodeName, &layout))
|
| - return false;
|
| - int type;
|
| - if (!info_dict->GetInteger(kNewWallpaperTypeNodeName, &type))
|
| - return false;
|
| - std::string date_string;
|
| - if (!info_dict->GetString(kNewWallpaperDateNodeName, &date_string))
|
| - return false;
|
| - int64 date_val;
|
| - if (!base::StringToInt64(date_string, &date_val))
|
| - return false;
|
| -
|
| - info->file = file;
|
| - info->layout = static_cast<ash::WallpaperLayout>(layout);
|
| - info->type = static_cast<User::WallpaperType>(type);
|
| - info->date = base::Time::FromInternalValue(date_val);
|
| - return true;
|
| -}
|
| -
|
| -void WallpaperManager::MoveCustomWallpapersOnWorker(
|
| - const std::string& user_id,
|
| - const std::string& user_id_hash) {
|
| - DCHECK(BrowserThread::GetBlockingPool()->
|
| - IsRunningSequenceOnCurrentThread(sequence_token_));
|
| - if (MoveCustomWallpaperDirectory(
|
| - kOriginalWallpaperSubDir, user_id, user_id_hash)) {
|
| - // Consider success if the original wallpaper is moved to the new directory.
|
| - // Original wallpaper is the fallback if the correct resolution wallpaper
|
| - // can not be found.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::MoveCustomWallpapersSuccess,
|
| - base::Unretained(this),
|
| - user_id,
|
| - user_id_hash));
|
| - }
|
| - MoveCustomWallpaperDirectory(kLargeWallpaperSubDir, user_id, user_id_hash);
|
| - MoveCustomWallpaperDirectory(kSmallWallpaperSubDir, user_id, user_id_hash);
|
| - MoveCustomWallpaperDirectory(
|
| - kThumbnailWallpaperSubDir, user_id, user_id_hash);
|
| -}
|
| -
|
| -void WallpaperManager::MoveCustomWallpapersSuccess(
|
| - const std::string& user_id,
|
| - const std::string& user_id_hash) {
|
| - WallpaperInfo info;
|
| - GetUserWallpaperInfo(user_id, &info);
|
| - if (info.type == User::CUSTOMIZED) {
|
| - // New file field should include user id hash in addition to file name.
|
| - // This is needed because at login screen, user id hash is not available.
|
| - std::string relative_path =
|
| - base::FilePath(user_id_hash).Append(info.file).value();
|
| - info.file = relative_path;
|
| - bool is_persistent =
|
| - !UserManager::Get()->IsUserNonCryptohomeDataEphemeral(user_id);
|
| - SetUserWallpaperInfo(user_id, info, is_persistent);
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::MoveLoggedInUserCustomWallpaper() {
|
| - const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
|
| - task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::MoveCustomWallpapersOnWorker,
|
| - base::Unretained(this),
|
| - logged_in_user->email(),
|
| - logged_in_user->username_hash()));
|
| -}
|
| -
|
| -void WallpaperManager::GetCustomWallpaperInternal(
|
| - const std::string& user_id,
|
| - const WallpaperInfo& info,
|
| - const base::FilePath& wallpaper_path,
|
| - bool update_wallpaper,
|
| - MovableOnDestroyCallbackHolder on_finish) {
|
| - DCHECK(BrowserThread::GetBlockingPool()->
|
| - IsRunningSequenceOnCurrentThread(sequence_token_));
|
| -
|
| - base::FilePath valid_path = wallpaper_path;
|
| - if (!base::PathExists(wallpaper_path)) {
|
| - // Falls back on original file if the correct resolution file does not
|
| - // exist. This may happen when the original custom wallpaper is small or
|
| - // browser shutdown before resized wallpaper saved.
|
| - valid_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
|
| - valid_path = valid_path.Append(info.file);
|
| - }
|
| -
|
| - if (!base::PathExists(valid_path)) {
|
| - // Falls back to custom wallpaper that uses email as part of its file path.
|
| - // Note that email is used instead of user_id_hash here.
|
| - valid_path =
|
| - GetCustomWallpaperPath(kOriginalWallpaperSubDir, user_id, info.file);
|
| - }
|
| -
|
| - if (!base::PathExists(valid_path)) {
|
| - LOG(ERROR) << "Failed to load previously selected custom wallpaper. " <<
|
| - "Fallback to default wallpaper";
|
| - BrowserThread::PostTask(BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::DoSetDefaultWallpaper,
|
| - base::Unretained(this),
|
| - user_id,
|
| - base::Passed(on_finish.Pass())));
|
| - } else {
|
| - BrowserThread::PostTask(BrowserThread::UI,
|
| - FROM_HERE,
|
| - base::Bind(&WallpaperManager::StartLoad,
|
| - base::Unretained(this),
|
| - user_id,
|
| - info,
|
| - update_wallpaper,
|
| - valid_path,
|
| - base::Passed(on_finish.Pass())));
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::OnWallpaperDecoded(
|
| - const std::string& user_id,
|
| - ash::WallpaperLayout layout,
|
| - bool update_wallpaper,
|
| - MovableOnDestroyCallbackHolder on_finish,
|
| - const UserImage& user_image) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - TRACE_EVENT_ASYNC_END0("ui", "LoadAndDecodeWallpaper", this);
|
| -
|
| - // If decoded wallpaper is empty, we have probably failed to decode the file.
|
| - // Use default wallpaper in this case.
|
| - if (user_image.image().isNull()) {
|
| - // Updates user pref to default wallpaper.
|
| - WallpaperInfo info = {
|
| - "",
|
| - ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
|
| - User::DEFAULT,
|
| - base::Time::Now().LocalMidnight()
|
| - };
|
| - SetUserWallpaperInfo(user_id, info, true);
|
| -
|
| - if (update_wallpaper)
|
| - DoSetDefaultWallpaper(user_id, on_finish.Pass());
|
| - return;
|
| - }
|
| -
|
| - wallpaper_cache_[user_id] = user_image.image();
|
| -
|
| - if (update_wallpaper) {
|
| - ash::Shell::GetInstance()
|
| - ->desktop_background_controller()
|
| - ->SetWallpaperImage(user_image.image(), layout);
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::SaveCustomWallpaper(
|
| - const std::string& user_id_hash,
|
| - const base::FilePath& original_path,
|
| - ash::WallpaperLayout layout,
|
| - scoped_ptr<gfx::ImageSkia> image) const {
|
| - DCHECK(BrowserThread::GetBlockingPool()->
|
| - IsRunningSequenceOnCurrentThread(sequence_token_));
|
| - EnsureCustomWallpaperDirectories(user_id_hash);
|
| - std::string file_name = original_path.BaseName().value();
|
| - base::FilePath small_wallpaper_path =
|
| - GetCustomWallpaperPath(kSmallWallpaperSubDir, user_id_hash, file_name);
|
| - base::FilePath large_wallpaper_path =
|
| - GetCustomWallpaperPath(kLargeWallpaperSubDir, user_id_hash, file_name);
|
| -
|
| - // 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).
|
| - ResizeAndSaveWallpaper(*image,
|
| - original_path,
|
| - ash::WALLPAPER_LAYOUT_STRETCH,
|
| - image->width(),
|
| - image->height(),
|
| - NULL);
|
| - DeleteAllExcept(original_path);
|
| -
|
| - ResizeAndSaveWallpaper(*image,
|
| - small_wallpaper_path,
|
| - layout,
|
| - kSmallWallpaperMaxWidth,
|
| - kSmallWallpaperMaxHeight,
|
| - NULL);
|
| - DeleteAllExcept(small_wallpaper_path);
|
| - ResizeAndSaveWallpaper(*image,
|
| - large_wallpaper_path,
|
| - layout,
|
| - kLargeWallpaperMaxWidth,
|
| - kLargeWallpaperMaxHeight,
|
| - NULL);
|
| - DeleteAllExcept(large_wallpaper_path);
|
| -}
|
| -
|
| -void WallpaperManager::RecordUma(User::WallpaperType type, int index) const {
|
| - UMA_HISTOGRAM_ENUMERATION("Ash.Wallpaper.Type", type,
|
| - User::WALLPAPER_TYPE_COUNT);
|
| -}
|
| -
|
| -void WallpaperManager::StartLoad(const std::string& user_id,
|
| - const WallpaperInfo& info,
|
| - bool update_wallpaper,
|
| - const base::FilePath& wallpaper_path,
|
| - MovableOnDestroyCallbackHolder on_finish) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - TRACE_EVENT_ASYNC_BEGIN0("ui", "LoadAndDecodeWallpaper", this);
|
| -
|
| - wallpaper_loader_->Start(wallpaper_path.value(),
|
| - 0, // Do not crop.
|
| - base::Bind(&WallpaperManager::OnWallpaperDecoded,
|
| - base::Unretained(this),
|
| - user_id,
|
| - info.layout,
|
| - update_wallpaper,
|
| - base::Passed(on_finish.Pass())));
|
| -}
|
| -
|
| -void WallpaperManager::SaveLastLoadTime(const base::TimeDelta elapsed) {
|
| - while (last_load_times_.size() >= kLastLoadsStatsMsMaxSize)
|
| - last_load_times_.pop_front();
|
| -
|
| - if (elapsed > base::TimeDelta::FromMicroseconds(0)) {
|
| - last_load_times_.push_back(elapsed);
|
| - last_load_finished_at_ = base::Time::Now();
|
| - }
|
| -}
|
| -
|
| -base::TimeDelta WallpaperManager::GetWallpaperLoadDelay() const {
|
| - base::TimeDelta delay;
|
| -
|
| - if (last_load_times_.size() == 0) {
|
| - delay = base::TimeDelta::FromMilliseconds(kLoadDefaultDelayMs);
|
| - } else {
|
| - delay = std::accumulate(last_load_times_.begin(),
|
| - last_load_times_.end(),
|
| - base::TimeDelta(),
|
| - std::plus<base::TimeDelta>()) /
|
| - last_load_times_.size();
|
| - }
|
| -
|
| - if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs))
|
| - delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs);
|
| - else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs))
|
| - delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs);
|
| -
|
| - // If we had ever loaded wallpaper, adjust wait delay by time since last load.
|
| - if (!last_load_finished_at_.is_null()) {
|
| - const base::TimeDelta interval = base::Time::Now() - last_load_finished_at_;
|
| - if (interval > delay)
|
| - delay = base::TimeDelta::FromMilliseconds(0);
|
| - else if (interval > base::TimeDelta::FromMilliseconds(0))
|
| - delay -= interval;
|
| - }
|
| - 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_));
|
| -
|
| - *success = true;
|
| -
|
| - *success &= ResizeAndSaveWallpaper(*image,
|
| - rescaled_files->path_rescaled_small(),
|
| - ash::WALLPAPER_LAYOUT_STRETCH,
|
| - kSmallWallpaperMaxWidth,
|
| - kSmallWallpaperMaxHeight,
|
| - small_wallpaper_image);
|
| -
|
| - *success &= ResizeAndSaveWallpaper(*image,
|
| - 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) {
|
| - if (!pending_inactive_) {
|
| - loading_.push_back(new WallpaperManager::PendingWallpaper(
|
| - (delayed ? GetWallpaperLoadDelay()
|
| - : base::TimeDelta::FromMilliseconds(0)),
|
| - user_id));
|
| - pending_inactive_ = loading_.back();
|
| - }
|
| - return pending_inactive_;
|
| -}
|
| -
|
| -void WallpaperManager::RemovePendingWallpaperFromList(
|
| - PendingWallpaper* pending) {
|
| - DCHECK(loading_.size() > 0);
|
| - for (WallpaperManager::PendingList::iterator i = loading_.begin();
|
| - i != loading_.end();
|
| - ++i) {
|
| - if (i->get() == pending) {
|
| - loading_.erase(i);
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (loading_.empty())
|
| - FOR_EACH_OBSERVER(Observer, observers_, OnPendingListEmptyForTesting());
|
| -}
|
| -
|
| -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.";
|
| - }
|
| -}
|
| -
|
| -size_t WallpaperManager::GetPendingListSizeForTesting() const {
|
| - return loading_.size();
|
| -}
|
| -
|
| -void WallpaperManager::SetDefaultWallpaperPathsFromCommandLine(
|
| - base::CommandLine* command_line) {
|
| - default_small_wallpaper_file_ = command_line->GetSwitchValuePath(
|
| - ash::switches::kAshDefaultWallpaperSmall);
|
| - default_large_wallpaper_file_ = command_line->GetSwitchValuePath(
|
| - ash::switches::kAshDefaultWallpaperLarge);
|
| - guest_small_wallpaper_file_ =
|
| - command_line->GetSwitchValuePath(ash::switches::kAshGuestWallpaperSmall);
|
| - guest_large_wallpaper_file_ =
|
| - command_line->GetSwitchValuePath(ash::switches::kAshGuestWallpaperLarge);
|
| - default_wallpaper_image_.reset();
|
| -}
|
| -
|
| -void WallpaperManager::OnDefaultWallpaperDecoded(
|
| - const base::FilePath& path,
|
| - const ash::WallpaperLayout layout,
|
| - scoped_ptr<chromeos::UserImage>* result_out,
|
| - MovableOnDestroyCallbackHolder on_finish,
|
| - const UserImage& user_image) {
|
| - result_out->reset(new UserImage(user_image));
|
| - ash::Shell::GetInstance()->desktop_background_controller()->SetWallpaperImage(
|
| - user_image.image(), layout);
|
| -}
|
| -
|
| -void WallpaperManager::StartLoadAndSetDefaultWallpaper(
|
| - const base::FilePath& path,
|
| - const ash::WallpaperLayout layout,
|
| - MovableOnDestroyCallbackHolder on_finish,
|
| - scoped_ptr<chromeos::UserImage>* result_out) {
|
| - wallpaper_loader_->Start(
|
| - path.value(),
|
| - 0, // Do not crop.
|
| - base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded,
|
| - weak_factory_.GetWeakPtr(),
|
| - path,
|
| - layout,
|
| - base::Unretained(result_out),
|
| - base::Passed(on_finish.Pass())));
|
| -}
|
| -
|
| -const char* WallpaperManager::GetCustomWallpaperSubdirForCurrentResolution() {
|
| - WallpaperResolution resolution = GetAppropriateResolution();
|
| - return resolution == WALLPAPER_RESOLUTION_SMALL ? kSmallWallpaperSubDir
|
| - : 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(),
|
| - 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());
|
| - }
|
| -}
|
| -
|
| -void WallpaperManager::CreateSolidDefaultWallpaper() {
|
| - loaded_wallpapers_++;
|
| - SkBitmap bitmap;
|
| - bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1, 0);
|
| - bitmap.allocPixels();
|
| - bitmap.eraseColor(kDefaultWallpaperColor);
|
| - const gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
|
| - default_wallpaper_image_.reset(new UserImage(image));
|
| -}
|
| -
|
| -} // namespace chromeos
|
|
|