Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(286)

Unified Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 10375010: Implement user selected wallpaper feature. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: James' review Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..5746767d776983cacd429ff0f70b394994b49009 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,18 @@ void UserManagerImpl::SaveUserImageFromFile(const std::string& username,
base::Unretained(this), username));
}
+void UserManagerImpl::SaveUserWallpaperFromFile(const std::string& username,
+ const FilePath& path,
+ ash::WallpaperLayout layout,
+ WallpaperDelegate* delegate) {
+ // For wallpapers, save the image without resize.
flackr 2012/05/09 21:26:16 s/resize/resizing
bshe 2012/05/10 16:10:26 Done.
+ image_loader_->Start(
+ path.value(), 0 /* Original size */,
+ base::Bind(&UserManagerImpl::SaveUserWallpaperInternal,
+ base::Unretained(this), username, layout, User::CUSTOMIZED,
+ delegate));
+}
+
void UserManagerImpl::SaveUserImageFromProfileImage(
const std::string& username) {
if (!downloaded_profile_image_.empty()) {
@@ -754,6 +801,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())
@@ -1042,9 +1098,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 +1213,99 @@ 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,
+ WallpaperDelegate* delegate,
+ const SkBitmap& wallpaper) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&UserManagerImpl::GenerateUserWallpaperThumbnail,
+ base::Unretained(this), username, type, delegate, 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::OnThumbnailUpdated(WallpaperDelegate* delegate) {
+ if (delegate)
+ delegate->SetCustomWallpaperThumbnail();
+}
+
+void UserManagerImpl::GenerateUserWallpaperThumbnail(
+ const std::string& username,
+ User::WallpaperType type,
+ WallpaperDelegate* delegate,
+ const SkBitmap& wallpaper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ SkBitmap thumbnail =
+ skia::ImageOperations::Resize(wallpaper,
+ skia::ImageOperations::RESIZE_LANCZOS3,
+ kThumbnailWidth, kThumbnailHeight);
flackr 2012/05/09 21:26:16 Will this be the correct aspect ratio?
bshe 2012/05/10 16:10:26 No. It just resizes the wallpaper to 128x80. Ideal
+ 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::OnThumbnailUpdated,
+ base::Unretained(this), delegate));
+
+ // 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 +1315,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
flackr 2012/05/09 21:26:16 s/re-encode/re-encoding
bshe 2012/05/10 16:10:26 Done.
+ // it and save it.
flackr 2012/05/09 21:26:16 s/it and save/and saving
bshe 2012/05/10 16:10:26 Done.
+ 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 +1366,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.
flackr 2012/05/09 21:26:16 s/we/We
bshe 2012/05/10 16:10:26 Done.
+ 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 +1539,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);

Powered by Google App Engine
This is Rietveld 408576698