| Index: chrome/browser/chromeos/login/user_manager_impl.cc
|
| diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
|
| index 7f2d39efd7a8661ada49e8f469455dc2297a772f..cfbe19f530090585ced1d276cad8a40ad1891ffe 100644
|
| --- a/chrome/browser/chromeos/login/user_manager_impl.cc
|
| +++ b/chrome/browser/chromeos/login/user_manager_impl.cc
|
| @@ -54,6 +54,7 @@
|
| #include "content/public/browser/notification_service.h"
|
| #include "content/public/common/url_constants.h"
|
| #include "crypto/nss_util.h"
|
| +#include "skia/ext/image_operations.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| #include "ui/gfx/codec/png_codec.h"
|
|
|
| @@ -79,6 +80,9 @@ const char kImageIndexNodeName[] = "index";
|
| const char kWallpaperTypeNodeName[] = "type";
|
| const char kWallpaperIndexNodeName[] = "index";
|
|
|
| +const int kThumbnailWidth = 128;
|
| +const int kThumbnailHeight = 80;
|
| +
|
| // Index of the default image used for the |kStubUser| user.
|
| const int kStubDefaultImageIndex = 0;
|
|
|
| @@ -460,6 +464,20 @@ void UserManagerImpl::UserSelected(const std::string& email) {
|
| // RANDOM wallpaper.
|
| index = ash::GetRandomWallpaperIndex();
|
| SaveUserWallpaperProperties(email, User::RANDOM, index);
|
| + } else if (type == User::CUSTOMIZED) {
|
| + std::string wallpaper_path =
|
| + GetWallpaperPathForUser(email, false).value();
|
| + // In customized mode, we use index pref to save the user selected
|
| + // wallpaper layout. See function SaveWallpaperToLocalState().
|
| + ash::WallpaperLayout layout = static_cast<ash::WallpaperLayout>(index);
|
| + // Load user image asynchronously.
|
| + image_loader_->Start(
|
| + wallpaper_path, 0,
|
| + base::Bind(&UserManagerImpl::LoadCustomWallpaperThumbnail,
|
| + base::Unretained(this),
|
| + email,
|
| + layout));
|
| + return;
|
| }
|
| ash::Shell::GetInstance()->desktop_background_controller()->
|
| SetDefaultWallpaper(index);
|
| @@ -609,6 +627,23 @@ void UserManagerImpl::SaveUserImage(const std::string& username,
|
| SaveUserImageInternal(username, User::kExternalImageIndex, image);
|
| }
|
|
|
| +void UserManagerImpl::SetLoggedInUserCustomWallpaperLayout(
|
| + ash::WallpaperLayout layout) {
|
| + // TODO(bshe): We current disabled the customized wallpaper feature for
|
| + // Ephemeral user. As we dont want to keep a copy of customized wallpaper in
|
| + // memory. Need a smarter way to solve this.
|
| + if (IsCurrentUserEphemeral())
|
| + return;
|
| + const chromeos::User& user = GetLoggedInUser();
|
| + std::string username = user.email();
|
| + DCHECK(!username.empty());
|
| +
|
| + std::string file_path = GetWallpaperPathForUser(username, false).value();
|
| + SaveWallpaperToLocalState(username, file_path, layout, User::CUSTOMIZED);
|
| + // Load wallpaper from file.
|
| + UserSelected(username);
|
| +}
|
| +
|
| void UserManagerImpl::SaveUserImageFromFile(const std::string& username,
|
| const FilePath& path) {
|
| image_loader_->Start(
|
| @@ -617,6 +652,17 @@ void UserManagerImpl::SaveUserImageFromFile(const std::string& username,
|
| base::Unretained(this), username));
|
| }
|
|
|
| +void UserManagerImpl::SaveUserWallpaperFromFile(const std::string& username,
|
| + const FilePath& path,
|
| + ash::WallpaperLayout layout) {
|
| + // For wallpapers, save the image without resize.
|
| + LOG(ERROR) << "---------------Start to load file--------" << path.value();
|
| + image_loader_->Start(
|
| + path.value(), 0 /* Original size */,
|
| + base::Bind(&UserManagerImpl::SaveUserWallpaperInternal,
|
| + base::Unretained(this), username, layout, User::CUSTOMIZED));
|
| +}
|
| +
|
| void UserManagerImpl::SaveUserImageFromProfileImage(
|
| const std::string& username) {
|
| if (!downloaded_profile_image_.empty()) {
|
| @@ -754,6 +800,15 @@ FilePath UserManagerImpl::GetImagePathForUser(const std::string& username) {
|
| return user_data_dir.AppendASCII(filename);
|
| }
|
|
|
| +FilePath UserManagerImpl::GetWallpaperPathForUser(const std::string& username,
|
| + bool is_thumbnail) {
|
| + std::string filename = username +
|
| + (is_thumbnail ? "_wallpaper_thumb.png" : "_wallpaper.png");
|
| + FilePath user_data_dir;
|
| + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
|
| + return user_data_dir.AppendASCII(filename);
|
| +}
|
| +
|
| void UserManagerImpl::EnsureUsersLoaded() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| if (!users_.empty())
|
| @@ -927,6 +982,14 @@ void UserManagerImpl::NotifyOnLogin() {
|
| base::Unretained(this)));
|
| }
|
|
|
| +void UserManagerImpl::NotifyThumbnailUpdated() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + content::NotificationService::current()->Notify(
|
| + chrome::NOTIFICATION_LOGIN_USER_WALLPAPER_THUMBNAIL_UPDATED,
|
| + content::Source<UserManagerImpl>(this),
|
| + content::NotificationService::NoDetails());
|
| +}
|
| +
|
| void UserManagerImpl::LoadKeyStore() {
|
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| if (key_store_loaded_)
|
| @@ -1042,9 +1105,8 @@ void UserManagerImpl::SaveLoggedInUserWallpaperProperties(
|
| current_user_wallpaper_index_ = index;
|
| // Ephemeral users can not save data to local state. We just cache the index
|
| // in memory for them.
|
| - if (IsCurrentUserEphemeral() || !IsUserLoggedIn()) {
|
| + if (IsCurrentUserEphemeral() || !IsUserLoggedIn())
|
| return;
|
| - }
|
|
|
| const chromeos::User& user = GetLoggedInUser();
|
| std::string username = user.email();
|
| @@ -1158,24 +1220,96 @@ void UserManagerImpl::SaveUserImageInternal(const std::string& username,
|
| username, image, image_path, image_index));
|
| }
|
|
|
| -void UserManagerImpl::SaveImageToFile(const std::string& username,
|
| - const SkBitmap& image,
|
| - const FilePath& image_path,
|
| - int image_index) {
|
| +void UserManagerImpl::SaveUserWallpaperInternal(const std::string& username,
|
| + ash::WallpaperLayout layout,
|
| + User::WallpaperType type,
|
| + const SkBitmap& wallpaper) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::GenerateUserWallpaperThumbnail,
|
| + base::Unretained(this),
|
| + username, type, wallpaper));
|
| +
|
| + ash::Shell::GetInstance()->desktop_background_controller()->
|
| + SetCustomWallpaper(wallpaper, layout);
|
| +
|
| + // Ignore for ephemeral users.
|
| + if (IsEphemeralUser(username))
|
| + return;
|
| +
|
| + FilePath wallpaper_path = GetWallpaperPathForUser(username, false);
|
| + DVLOG(1) << "Saving user image to " << wallpaper_path.value();
|
| +
|
| + last_image_set_async_ = true;
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::SaveWallpaperToFile,
|
| + base::Unretained(this),
|
| + username, wallpaper,
|
| + wallpaper_path,
|
| + layout,
|
| + User::CUSTOMIZED));
|
| +}
|
| +
|
| +void UserManagerImpl::LoadCustomWallpaperThumbnail(const std::string& email,
|
| + ash::WallpaperLayout layout,
|
| + const SkBitmap& wallpaper) {
|
| + ash::Shell::GetInstance()->desktop_background_controller()->
|
| + SetCustomWallpaper(wallpaper, layout);
|
| + // Load wallpaper thumbnail
|
| + std::string wallpaper_path = GetWallpaperPathForUser(email, true).value();
|
| + image_loader_->Start(
|
| + wallpaper_path, 0,
|
| + base::Bind(&UserManagerImpl::OnCustomWallpaperThumbnailLoaded,
|
| + base::Unretained(this), email));
|
| +}
|
| +
|
| +void UserManagerImpl::OnCustomWallpaperThumbnailLoaded(
|
| + const std::string& email,
|
| + const SkBitmap& wallpaper) {
|
| + User* user = const_cast<User*>(FindUser(email));
|
| + // User may have been removed by now.
|
| + if (user && !wallpaper.empty())
|
| + user->SetWallpaperThumbnail(wallpaper);
|
| +}
|
| +
|
| +void UserManagerImpl::GenerateUserWallpaperThumbnail(
|
| + const std::string& username,
|
| + User::WallpaperType type,
|
| + const SkBitmap& wallpaper) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| + SkBitmap thumbnail =
|
| + skia::ImageOperations::Resize(wallpaper,
|
| + skia::ImageOperations::RESIZE_LANCZOS3,
|
| + kThumbnailWidth, kThumbnailHeight);
|
| + logged_in_user_->SetWallpaperThumbnail(thumbnail);
|
|
|
| - std::vector<unsigned char> encoded_image;
|
| - if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &encoded_image)) {
|
| - LOG(ERROR) << "Failed to PNG encode the image.";
|
| + // Notify thumbnail is ready.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::NotifyThumbnailUpdated,
|
| + base::Unretained(this)));
|
| +
|
| + // Ignore for ephemeral users.
|
| + if (IsEphemeralUser(username))
|
| return;
|
| - }
|
|
|
| - if (file_util::WriteFile(image_path,
|
| - reinterpret_cast<char*>(&encoded_image[0]),
|
| - encoded_image.size()) == -1) {
|
| - LOG(ERROR) << "Failed to save image to file.";
|
| + FilePath thumbnail_path = GetWallpaperPathForUser(username, true);
|
| + SaveBitmapToFile(thumbnail, thumbnail_path);
|
| +}
|
| +
|
| +void UserManagerImpl::SaveImageToFile(const std::string& username,
|
| + const SkBitmap& image,
|
| + const FilePath& image_path,
|
| + int image_index) {
|
| + if (!SaveBitmapToFile(image, image_path))
|
| return;
|
| - }
|
|
|
| BrowserThread::PostTask(
|
| BrowserThread::UI,
|
| @@ -1185,6 +1319,24 @@ void UserManagerImpl::SaveImageToFile(const std::string& username,
|
| username, image_path.value(), image_index, true));
|
| }
|
|
|
| +void UserManagerImpl::SaveWallpaperToFile(const std::string& username,
|
| + const SkBitmap& wallpaper,
|
| + const FilePath& wallpaper_path,
|
| + ash::WallpaperLayout layout,
|
| + User::WallpaperType type) {
|
| + // TODO(bshe): We should save the original file unchanged instead of re-encode
|
| + // it and save it.
|
| + if (!SaveBitmapToFile(wallpaper, wallpaper_path))
|
| + return;
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::SaveWallpaperToLocalState,
|
| + base::Unretained(this),
|
| + username, wallpaper_path.value(), layout, type));
|
| +}
|
| +
|
| void UserManagerImpl::SaveImageToLocalState(const std::string& username,
|
| const std::string& image_path,
|
| int image_index,
|
| @@ -1218,6 +1370,33 @@ void UserManagerImpl::SaveImageToLocalState(const std::string& username,
|
| NotifyLocalStateChanged();
|
| }
|
|
|
| +void UserManagerImpl::SaveWallpaperToLocalState(const std::string& username,
|
| + const std::string& wallpaper_path,
|
| + ash::WallpaperLayout layout,
|
| + User::WallpaperType type) {
|
| + // TODO(bshe): we probably need to save wallpaper_path instead of index.
|
| + SaveUserWallpaperProperties(username, type, layout);
|
| +}
|
| +
|
| +bool UserManagerImpl::SaveBitmapToFile(const SkBitmap& image,
|
| + const FilePath& image_path) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + std::vector<unsigned char> encoded_image;
|
| + if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &encoded_image)) {
|
| + LOG(ERROR) << "Failed to PNG encode the image.";
|
| + return false;
|
| + }
|
| +
|
| + if (file_util::WriteFile(image_path,
|
| + reinterpret_cast<char*>(&encoded_image[0]),
|
| + encoded_image.size()) == -1) {
|
| + LOG(ERROR) << "Failed to save image to file.";
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void UserManagerImpl::InitDownloadedProfileImage() {
|
| DCHECK(logged_in_user_);
|
| if (downloaded_profile_image_.empty() && !logged_in_user_->image_is_stub()) {
|
| @@ -1364,6 +1543,23 @@ void UserManagerImpl::RemoveUserFromListInternal(const std::string& email) {
|
| kUserWallpapersProperties);
|
| prefs_wallpapers_update->RemoveWithoutPathExpansion(email, NULL);
|
|
|
| + // Remove user wallpaper thumbnail
|
| + FilePath wallpaper_thumb_path = GetWallpaperPathForUser(email, true);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::DeleteUserImage,
|
| + base::Unretained(this),
|
| + wallpaper_thumb_path));
|
| + // Remove user wallpaper
|
| + FilePath wallpaper_path = GetWallpaperPathForUser(email, false);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&UserManagerImpl::DeleteUserImage,
|
| + base::Unretained(this),
|
| + wallpaper_path));
|
| +
|
| DictionaryPrefUpdate prefs_images_update(prefs, kUserImages);
|
| std::string image_path_string;
|
| prefs_images_update->GetStringWithoutPathExpansion(email, &image_path_string);
|
|
|