This source file includes following definitions.
- RoundPositive
- GetCustomWallpaperDir
- MoveCustomWallpaperDirectory
- on_finish_
- ResetSetWallpaperImage
- ResetLoadWallpaper
- ResetSetCustomWallpaper
- ResetSetDefaultWallpaper
- SetMode
- ProcessRequest
- OnWallpaperSet
- current_wallpaper_path
- GetWallpaperFromCache
- SetWallpaperCache
- ClearDisposableWallpaperCache
- Get
- pending_inactive_
- Shutdown
- RegisterPrefs
- AddObservers
- EnsureLoggedInUserWallpaperLoaded
- ClearDisposableWallpaperCache
- GetCustomWallpaperPath
- GetOriginalWallpaperPathForUser
- GetLoggedInUserWallpaperInfo
- InitializeWallpaper
- Observe
- RemoveUserWallpaperInfo
- ResizeWallpaper
- ResizeAndSaveWallpaper
- IsPolicyControlled
- OnPolicySet
- OnPolicyCleared
- OnPolicyFetched
- SetPolicyControlledWallpaper
- SetCustomWallpaper
- SetDefaultWallpaperNow
- SetDefaultWallpaperDelayed
- DoSetDefaultWallpaper
- InitInitialUserWallpaper
- SetUserWallpaperInfo
- SetLastSelectedUser
- SetUserWallpaperDelayed
- SetUserWallpaperNow
- ScheduleSetUserWallpaper
- SetWallpaperFromImageSkia
- UpdateWallpaper
- AddObserver
- RemoveObserver
- NotifyAnimationFinished
- GetWallpaperFromCache
- CacheUsersWallpapers
- CacheUserWallpaper
- ClearObsoleteWallpaperPrefs
- DeleteAllExcept
- DeleteWallpaperInList
- DeleteUserWallpapers
- EnsureCustomWallpaperDirectories
- GetComandLine
- InitializeRegisteredDeviceWallpaper
- LoadWallpaper
- GetUserWallpaperInfo
- MoveCustomWallpapersOnWorker
- MoveCustomWallpapersSuccess
- MoveLoggedInUserCustomWallpaper
- GetCustomWallpaperInternal
- OnWallpaperDecoded
- ProcessCustomWallpaper
- SaveCustomWallpaper
- RecordUma
- SaveWallpaperInternal
- StartLoad
- SaveLastLoadTime
- GetWallpaperLoadDelay
- GetPendingWallpaper
#include "chrome/browser/chromeos/login/wallpaper_manager.h"
#include <numeric>
#include <vector>
#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/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/login/startup_utils.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"
#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 "ui/base/resource/resource_bundle.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 {
const int kMoveCustomWallpaperDelaySeconds = 30;
const int kDefaultEncodingQuality = 90;
const char kUserWallpapers[] = "UserWallpapers";
const int kCacheWallpaperDelayMs = 500;
const char kUserWallpapersProperties[] = "UserWallpapersProperties";
const char kNewWallpaperDateNodeName[] = "date";
const char kNewWallpaperLayoutNodeName[] = "layout";
const char kNewWallpaperFileNodeName[] = "file";
const char kNewWallpaperTypeNodeName[] = "type";
const char kOriginalCustomWallpaperSuffix[] = "_wallpaper";
const int kMaxWallpapersToCache = 3;
const size_t kLastLoadsStatsMsMaxSize = 4;
const unsigned kLoadMinDelayMs = 50;
const unsigned kLoadDefaultDelayMs = 200;
const unsigned kLoadMaxDelayMs = 2000;
int RoundPositive(double x) {
return static_cast<int>(floor(x + 0.5));
}
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;
}
}
namespace chromeos {
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";
static WallpaperManager* g_wallpaper_manager = NULL;
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& user_wallpaper,
const WallpaperInfo& info) {
SetMode(user_wallpaper, 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& user_wallpaper,
const WallpaperInfo& info,
const base::FilePath& wallpaper_path,
const bool is_default) {
user_wallpaper_ = user_wallpaper;
info_ = info;
wallpaper_path_ = wallpaper_path;
default_ = is_default;
}
void WallpaperManager::PendingWallpaper::ProcessRequest() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
timer.Stop();
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()->
SetCustomWallpaper(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 ,
base::Passed(on_finish_.Pass())));
} else if (!info_.file.empty()) {
manager->LoadWallpaper(user_id_, info_, true, on_finish_.Pass());
} else {
NOTREACHED();
started_load_at_ = base::Time();
}
on_finish_.reset();
}
void WallpaperManager::PendingWallpaper::OnWallpaperSet() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
return;
timer.Stop();
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) {
manager->pending_inactive_ = NULL;
}
DCHECK(manager->loading_.size() > 0);
for (WallpaperManager::PendingList::iterator i = manager->loading_.begin();
i != manager->loading_.end();
++i)
if (i->get() == this) {
manager->loading_.erase(i);
break;
}
}
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();
}
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) {
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() {
DCHECK(!show_user_name_on_signin_subscription_);
ClearObsoleteWallpaperPrefs();
weak_factory_.InvalidateWeakPtrs();
}
void WallpaperManager::Shutdown() {
show_user_name_on_signin_subscription_.reset();
}
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() {
if (!ash::Shell::HasInstance())
return;
WallpaperInfo info;
if (GetLoggedInUserWallpaperInfo(&info)) {
RecordUma(info.type, -1);
if (info == current_user_wallpaper_info_)
return;
}
SetUserWallpaperNow(UserManager::Get()->GetLoggedInUser()->email());
}
void WallpaperManager::ClearDisposableWallpaperCache() {
weak_factory_.InvalidateWeakPtrs();
if (!UserManager::IsMultipleProfilesAllowed()) {
wallpaper_cache_.clear();
} else {
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);
}
base::FilePath WallpaperManager::GetOriginalWallpaperPathForUser(
const std::string& user_id) {
std::string filename = user_id + kOriginalCustomWallpaperSuffix;
base::FilePath user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
return user_data_dir.AppendASCII(filename);
}
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;
return true;
}
return GetUserWallpaperInfo(UserManager::Get()->GetLoggedInUser()->email(),
info);
}
void WallpaperManager::InitializeWallpaper() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
UserManager* user_manager = UserManager::Get();
CommandLine* command_line = GetComandLine();
if (command_line->HasSwitch(chromeos::switches::kGuestSession)) {
return;
}
if (command_line->HasSwitch(::switches::kTestType))
WizardController::SetZeroDelays();
if (WizardController::IsZeroDelayEnabled()) {
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 (!GetComandLine()->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);
}
bool WallpaperManager::ResizeWallpaper(
const UserImage& wallpaper,
ash::WallpaperLayout layout,
int preferred_width,
int preferred_height,
scoped_refptr<base::RefCountedBytes>* output) const {
DCHECK(BrowserThread::GetBlockingPool()->
IsRunningSequenceOnCurrentThread(sequence_token_));
int width = wallpaper.image().width();
int height = wallpaper.image().height();
int resized_width;
int resized_height;
*output = new base::RefCountedBytes();
if (layout == ash::WALLPAPER_LAYOUT_CENTER_CROPPED) {
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(
wallpaper.image(),
skia::ImageOperations::RESIZE_LANCZOS3,
gfx::Size(resized_width, resized_height));
SkBitmap image = *(resized_image.bitmap());
SkAutoLockPixels lock_input(image);
gfx::JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(image.getAddr32(0, 0)),
gfx::JPEGCodec::FORMAT_SkBitmap,
image.width(),
image.height(),
image.width() * image.bytesPerPixel(),
kDefaultEncodingQuality, &(*output)->data());
return true;
}
void WallpaperManager::ResizeAndSaveWallpaper(const UserImage& wallpaper,
const base::FilePath& path,
ash::WallpaperLayout layout,
int preferred_width,
int preferred_height) const {
if (layout == ash::WALLPAPER_LAYOUT_CENTER) {
if (base::PathExists(path))
base::DeleteFile(path, false);
return;
}
scoped_refptr<base::RefCountedBytes> data;
if (ResizeWallpaper(wallpaper, layout, preferred_width, preferred_height,
&data)) {
SaveWallpaperInternal(path,
reinterpret_cast<const char*>(data->front()),
data->size());
}
}
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 );
}
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 );
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,
base::Bind(&WallpaperManager::SetPolicyControlledWallpaper,
weak_factory_.GetWeakPtr(),
user_id));
}
void WallpaperManager::SetPolicyControlledWallpaper(
const std::string& user_id,
const UserImage& wallpaper) {
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,
wallpaper,
true );
}
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 UserImage& wallpaper,
bool update_wallpaper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(UserManager::Get()->IsUserLoggedIn());
if (UserManager::Get()->IsLoggedInAsKioskApp())
return;
if (type != User::POLICY && IsPolicyControlled(user_id))
return;
base::FilePath wallpaper_path =
GetCustomWallpaperPath(kOriginalWallpaperSubDir, user_id_hash, file);
if (wallpaper.image().isNull()) {
SetDefaultWallpaperDelayed(user_id);
return;
}
bool is_persistent =
!UserManager::Get()->IsUserNonCryptohomeDataEphemeral(user_id);
wallpaper.image().EnsureRepsForSupportedScales();
scoped_ptr<gfx::ImageSkia> deep_copy(wallpaper.image().DeepCopy());
WallpaperInfo wallpaper_info = {
wallpaper_path.value(),
layout,
type,
base::Time::Now().LocalMidnight()
};
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner =
BrowserThread::GetBlockingPool()->
GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
base::SequencedWorkerPool::BLOCK_SHUTDOWN);
blocking_task_runner->PostTask(FROM_HERE,
base::Bind(&WallpaperManager::ProcessCustomWallpaper,
base::Unretained(this),
user_id_hash,
is_persistent,
wallpaper_info,
base::Passed(&deep_copy),
wallpaper.raw_image()));
std::string relative_path = base::FilePath(user_id_hash).Append(file).value();
WallpaperInfo info = {
relative_path,
layout,
type,
base::Time::Now().LocalMidnight()
};
SetUserWallpaperInfo(user_id, info, is_persistent);
if (update_wallpaper) {
GetPendingWallpaper(user_id, false)
->ResetSetWallpaperImage(wallpaper.image(), info);
}
if (UserManager::IsMultipleProfilesAllowed())
wallpaper_cache_[user_id] = wallpaper.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) {
if (UserManager::Get()->IsLoggedInAsKioskApp())
return;
current_wallpaper_path_.clear();
wallpaper_cache_.erase(user_id);
if (!ash::Shell::HasInstance())
return;
if (ash::Shell::GetInstance()->desktop_background_controller()->
SetDefaultWallpaper(UserManager::Get()->IsLoggedInAsGuest()))
loaded_wallpapers_++;
}
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::SetLastSelectedUser(
const std::string& last_selected_user) {
last_selected_user_ = last_selected_user;
}
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));
if (!UserManager::IsInitialized() || !g_browser_process->local_state())
return;
if (UserManager::Get()->IsLoggedInAsKioskApp())
return;
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;
SetLastSelectedUser(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) {
ash::WallpaperResolution resolution =
ash::Shell::GetInstance()->
desktop_background_controller()->
GetAppropriateResolution();
const char* sub_dir = (resolution == ash::WALLPAPER_RESOLUTION_SMALL)
? kSmallWallpaperSubDir
: kLargeWallpaperSubDir;
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()) {
GetPendingWallpaper(user_id, delayed)->ResetSetDefaultWallpaper();
return;
}
GetPendingWallpaper(user_id, delayed)->ResetLoadWallpaper(info);
}
}
void WallpaperManager::SetWallpaperFromImageSkia(
const std::string& user_id,
const gfx::ImageSkia& wallpaper,
ash::WallpaperLayout layout,
bool update_wallpaper) {
DCHECK(UserManager::Get()->IsUserLoggedIn());
if (UserManager::Get()->IsLoggedInAsKioskApp())
return;
WallpaperInfo info;
info.layout = layout;
if (UserManager::IsMultipleProfilesAllowed())
wallpaper_cache_[user_id] = wallpaper;
if (update_wallpaper) {
GetPendingWallpaper(last_selected_user_, false )
->ResetSetWallpaperImage(wallpaper, info);
}
}
void WallpaperManager::UpdateWallpaper(bool clear_cache) {
if (clear_cache)
wallpaper_cache_.clear();
current_wallpaper_path_.clear();
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_));
}
bool WallpaperManager::GetWallpaperFromCache(const std::string& user_id,
gfx::ImageSkia* wallpaper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CustomWallpaperMap::const_iterator it = wallpaper_cache_.find(user_id);
if (it != wallpaper_cache_.end()) {
*wallpaper = (*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();
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) {
ash::WallpaperResolution resolution = ash::Shell::GetInstance()->
desktop_background_controller()->GetAppropriateResolution();
const char* sub_dir = (resolution == ash::WALLPAPER_RESOLUTION_SMALL) ?
kSmallWallpaperSubDir : kLargeWallpaperSubDir;
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 ,
base::Passed(MovableOnDestroyCallbackHolder())));
return;
}
LoadWallpaper(user_id,
info,
false ,
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::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);
}
}
}
void WallpaperManager::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;
if (!base::DeleteFile(path, true) &&
!base::DeleteFile(path.AddExtension(".png"), false)) {
LOG(ERROR) << "Failed to remove user wallpaper at " << path.value();
}
}
}
void WallpaperManager::DeleteUserWallpapers(const std::string& user_id,
const std::string& path_to_file) {
std::vector<base::FilePath> file_to_remove;
base::FilePath wallpaper_path =
GetCustomWallpaperDir(kSmallWallpaperSubDir);
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);
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);
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);
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(&WallpaperManager::DeleteWallpaperInList,
base::Unretained(this),
file_to_remove),
false);
}
void WallpaperManager::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);
}
CommandLine* WallpaperManager::GetComandLine() {
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 = GetComandLine()->
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();
if (!show_users || users.empty()) {
SetDefaultWallpaperDelayed(UserManager::kSignInUser);
return;
}
if (!disable_boot_animation) {
SetUserWallpaperDelayed(users[0]->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;
if (info.type == User::ONLINE) {
std::string file_name = GURL(info.file).ExtractFileName();
ash::WallpaperResolution resolution = ash::Shell::GetInstance()->
desktop_background_controller()->GetAppropriateResolution();
if (info.layout != ash::WALLPAPER_LAYOUT_STRETCH &&
resolution == ash::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) {
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 {
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)) {
*info = current_user_wallpaper_info_;
return true;
}
const base::DictionaryValue* user_wallpapers =
g_browser_process->local_state()->
GetDictionary(prefs::kUsersWallpaperInfo);
const base::DictionaryValue* wallpaper_info_dict;
if (user_wallpapers->GetDictionaryWithoutPathExpansion(
user_id, &wallpaper_info_dict)) {
info->file = "";
info->layout = ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
info->type = User::UNKNOWN;
info->date = base::Time::Now().LocalMidnight();
wallpaper_info_dict->GetString(kNewWallpaperFileNodeName, &(info->file));
int temp;
wallpaper_info_dict->GetInteger(kNewWallpaperLayoutNodeName, &temp);
info->layout = static_cast<ash::WallpaperLayout>(temp);
wallpaper_info_dict->GetInteger(kNewWallpaperTypeNodeName, &temp);
info->type = static_cast<User::WallpaperType>(temp);
std::string date_string;
int64 val;
if (!(wallpaper_info_dict->GetString(kNewWallpaperDateNodeName,
&date_string) &&
base::StringToInt64(date_string, &val)))
val = 0;
info->date = base::Time::FromInternalValue(val);
return true;
}
return false;
}
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)) {
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) {
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)) {
valid_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
valid_path = valid_path.Append(info.file);
}
if (!base::PathExists(valid_path)) {
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& wallpaper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
TRACE_EVENT_ASYNC_END0("ui", "LoadAndDecodeWallpaper", this);
if (wallpaper.image().isNull()) {
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;
}
if (!UserManager::Get()->IsUserLoggedIn() ||
UserManager::IsMultipleProfilesAllowed()) {
wallpaper_cache_[user_id] = wallpaper.image();
}
if (update_wallpaper) {
ash::Shell::GetInstance()->desktop_background_controller()->
SetCustomWallpaper(wallpaper.image(), layout);
}
}
void WallpaperManager::ProcessCustomWallpaper(
const std::string& user_id_hash,
bool persistent,
const WallpaperInfo& info,
scoped_ptr<gfx::ImageSkia> image,
const UserImage::RawImage& raw_image) {
DCHECK(BrowserThread::GetBlockingPool()->
IsRunningSequenceOnCurrentThread(sequence_token_));
UserImage wallpaper(*image.get(), raw_image);
if (persistent) {
SaveCustomWallpaper(user_id_hash, base::FilePath(info.file), info.layout,
wallpaper);
}
}
void WallpaperManager::SaveCustomWallpaper(const std::string& user_id_hash,
const base::FilePath& original_path,
ash::WallpaperLayout layout,
const UserImage& wallpaper) {
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);
ResizeAndSaveWallpaper(wallpaper, original_path,
ash::WALLPAPER_LAYOUT_STRETCH,
wallpaper.image().width(),
wallpaper.image().height());
DeleteAllExcept(original_path);
ResizeAndSaveWallpaper(wallpaper, small_wallpaper_path, layout,
ash::kSmallWallpaperMaxWidth,
ash::kSmallWallpaperMaxHeight);
DeleteAllExcept(small_wallpaper_path);
ResizeAndSaveWallpaper(wallpaper, large_wallpaper_path, layout,
ash::kLargeWallpaperMaxWidth,
ash::kLargeWallpaperMaxHeight);
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::SaveWallpaperInternal(const base::FilePath& path,
const char* data,
int size) const {
int written_bytes = base::WriteFile(path, data, size);
DCHECK(written_bytes == size);
}
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,
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 (!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;
}
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_;
}
}