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

Unified Diff: chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc

Issue 1794323003: Make user_manager::UserImage non-copyable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: just rebase Created 4 years, 8 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/users/avatar/user_image_manager_impl.cc
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
index d96954bc6c1e2b2b1b98a1f29b9c4e643e6af29d..1ad36853b716be1753b702590850f921ad793627 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
@@ -148,29 +148,12 @@ int ImageIndexToHistogramIndex(int image_index) {
}
}
-bool SaveImage(const user_manager::UserImage& user_image,
+bool SaveImage(scoped_ptr<user_manager::UserImage::Bytes> image_bytes,
const base::FilePath& image_path) {
- // This should always be true, because of the following reasons:
- //
- // 1) Profile image from Google account -> UserImage is created with
- // CreateAndEncode() that generates safe bytes representation.
- // 2) Profile image from user-specified image -> The bytes representation
- // is regenerated after the original image is decoded and cropped.
- // 3) Profile image from policy (via OnExternalDataFetched()) -> JPEG is
- // only allowed and ROBUST_JPEG_CODEC is used.
- //
- // However, check the value just in case because an unsafe image should
- // never be saved.
- if (!user_image.is_safe_format()) {
- LOG(ERROR) << "User image is not in safe format";
- return false;
- }
-
- const user_manager::UserImage::Bytes& image_bytes = user_image.image_bytes();
- if (image_bytes.empty() ||
+ if (image_bytes->empty() ||
base::WriteFile(image_path,
- reinterpret_cast<const char*>(image_bytes.data()),
- image_bytes.size()) == -1) {
+ reinterpret_cast<const char*>(image_bytes->data()),
+ image_bytes->size()) == -1) {
LOG(ERROR) << "Failed to save image to file.";
return false;
}
@@ -218,7 +201,8 @@ class UserImageManagerImpl::Job {
// Saves the |user_image| to disk and sets the user image in local
// state to that image. Also updates the user with the new image.
- void SetToImage(int image_index, const user_manager::UserImage& user_image);
+ void SetToImage(int image_index,
+ scoped_ptr<user_manager::UserImage> user_image);
// Decodes the JPEG image |data|, crops and resizes the image, saves
// it to disk and sets the user image in local state to that image.
@@ -237,14 +221,21 @@ class UserImageManagerImpl::Job {
private:
// Called back after an image has been loaded from disk.
- void OnLoadImageDone(bool save, const user_manager::UserImage& user_image);
+ void OnLoadImageDone(bool save,
+ scoped_ptr<user_manager::UserImage> user_image);
// Updates the user object with |user_image|.
- void UpdateUser(const user_manager::UserImage& user_image);
+ void UpdateUser(scoped_ptr<user_manager::UserImage> user_image);
- // Saves |user_image_| to disk in JPEG format. Local state will be updated
- // when a callback indicates that the image has been saved.
- void SaveImageAndUpdateLocalState(const user_manager::UserImage& user_image);
+ // Updates the user object with |user_image|, and saves the image
+ // bytes. Local state will be updated as needed.
+ void UpdateUserAndSaveImage(scoped_ptr<user_manager::UserImage> user_image);
+
+ // Saves |image_bytes| to disk in JPEG format if
+ // |image_is_safe_format|. Local state will be updated as needed.
+ void SaveImageAndUpdateLocalState(
+ bool image_is_safe_format,
+ scoped_ptr<user_manager::UserImage::Bytes> image_bytes);
// Called back after the user image has been saved to
// disk. Updates the user image information in local state. The
@@ -301,9 +292,9 @@ void UserImageManagerImpl::Job::LoadImage(base::FilePath image_path,
if (image_index_ >= 0 &&
image_index_ < default_user_image::kDefaultImagesCount) {
// Load one of the default images. This happens synchronously.
- const user_manager::UserImage user_image(
- default_user_image::GetDefaultImage(image_index_));
- UpdateUser(user_image);
+ scoped_ptr<user_manager::UserImage> user_image(new user_manager::UserImage(
+ default_user_image::GetDefaultImage(image_index_)));
+ UpdateUser(std::move(user_image));
NotifyJobDone();
} else if (image_index_ == user_manager::User::USER_IMAGE_EXTERNAL ||
image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
@@ -331,17 +322,17 @@ void UserImageManagerImpl::Job::SetToDefaultImage(int default_image_index) {
DCHECK_GT(default_user_image::kDefaultImagesCount, default_image_index);
image_index_ = default_image_index;
- const user_manager::UserImage user_image(
- default_user_image::GetDefaultImage(image_index_));
+ scoped_ptr<user_manager::UserImage> user_image(new user_manager::UserImage(
+ default_user_image::GetDefaultImage(image_index_)));
- UpdateUser(user_image);
+ UpdateUser(std::move(user_image));
UpdateLocalState();
NotifyJobDone();
}
void UserImageManagerImpl::Job::SetToImage(
int image_index,
- const user_manager::UserImage& user_image) {
+ scoped_ptr<user_manager::UserImage> user_image) {
DCHECK(!run_);
run_ = true;
@@ -350,8 +341,7 @@ void UserImageManagerImpl::Job::SetToImage(
image_index_ = image_index;
- UpdateUser(user_image);
- SaveImageAndUpdateLocalState(user_image);
+ UpdateUserAndSaveImage(std::move(user_image));
}
void UserImageManagerImpl::Job::SetToImageData(scoped_ptr<std::string> data) {
@@ -395,44 +385,81 @@ void UserImageManagerImpl::Job::SetToPath(const base::FilePath& path,
void UserImageManagerImpl::Job::OnLoadImageDone(
bool save,
- const user_manager::UserImage& user_image) {
- UpdateUser(user_image);
- if (save)
- SaveImageAndUpdateLocalState(user_image);
- else
+ scoped_ptr<user_manager::UserImage> user_image) {
+ if (save) {
+ UpdateUserAndSaveImage(std::move(user_image));
+ } else {
+ UpdateUser(std::move(user_image));
NotifyJobDone();
+ }
}
void UserImageManagerImpl::Job::UpdateUser(
- const user_manager::UserImage& user_image) {
+ scoped_ptr<user_manager::UserImage> user_image) {
user_manager::User* user = parent_->GetUserAndModify();
if (!user)
return;
- if (!user_image.image().isNull()) {
- user->SetImage(user_image, image_index_);
+ if (!user_image->image().isNull()) {
+ user->SetImage(std::move(user_image), image_index_);
} else {
user->SetStubImage(
- user_manager::UserImage(
+ make_scoped_ptr(new user_manager::UserImage(
*ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_PROFILE_PICTURE_LOADING)),
- image_index_,
- false);
+ IDR_PROFILE_PICTURE_LOADING))),
+ image_index_, false);
}
user->SetImageURL(image_url_);
parent_->OnJobChangedUserImage();
}
+void UserImageManagerImpl::Job::UpdateUserAndSaveImage(
+ scoped_ptr<user_manager::UserImage> user_image) {
+ // TODO(crbug.com/593251): Remove the data copy.
+ // Copy the image bytes, before the user image is passed to
+ // UpdateUser(). This is needed to safely save the data bytes to the disk
+ // in the blocking pool. Copying is not desirable but the user image is
+ // JPEG data of 512x512 pixels (usually <100KB) hence it's not enormous.
+ const bool image_is_safe_format = user_image->is_safe_format();
+ scoped_ptr<user_manager::UserImage::Bytes> copied_bytes;
+ if (image_is_safe_format) {
+ copied_bytes.reset(
+ new user_manager::UserImage::Bytes(user_image->image_bytes()));
+ }
+
+ UpdateUser(std::move(user_image));
+
+ SaveImageAndUpdateLocalState(image_is_safe_format, std::move(copied_bytes));
+}
+
void UserImageManagerImpl::Job::SaveImageAndUpdateLocalState(
- const user_manager::UserImage& user_image) {
+ bool image_is_safe_format,
+ scoped_ptr<user_manager::UserImage::Bytes> image_bytes) {
base::FilePath user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
image_path_ = user_data_dir.Append(user_id() + kSafeImagePathExtension);
+ // This should always be true, because of the following reasons:
+ //
+ // 1) Profile image from Google account -> UserImage is created with
+ // CreateAndEncode() that generates safe bytes representation.
+ // 2) Profile image from user-specified image -> The bytes representation
+ // is regenerated after the original image is decoded and cropped.
+ // 3) Profile image from policy (via OnExternalDataFetched()) -> JPEG is
+ // only allowed and ROBUST_JPEG_CODEC is used.
+ //
+ // However, check the value just in case because an unsafe image should
+ // never be saved.
+ if (!image_is_safe_format) {
+ LOG(ERROR) << "User image is not in safe format";
+ OnSaveImageDone(false);
+ return;
+ }
+
base::PostTaskAndReplyWithResult(
parent_->background_task_runner_.get(), FROM_HERE,
- base::Bind(&SaveImage, user_image, image_path_),
+ base::Bind(&SaveImage, base::Passed(std::move(image_bytes)), image_path_),
base::Bind(&Job::OnSaveImageDone, weak_factory_.GetWeakPtr()));
}
@@ -510,8 +537,8 @@ void UserImageManagerImpl::LoadUserImage() {
image_properties->GetInteger(kImageIndexNodeName, &image_index);
if (image_index >= 0 &&
image_index < default_user_image::kDefaultImagesCount) {
- user->SetImage(user_manager::UserImage(
- default_user_image::GetDefaultImage(image_index)),
+ user->SetImage(make_scoped_ptr(new user_manager::UserImage(
+ default_user_image::GetDefaultImage(image_index))),
image_index);
return;
}
@@ -529,11 +556,10 @@ void UserImageManagerImpl::LoadUserImage() {
image_properties->GetString(kImagePathNodeName, &image_path);
user->SetImageURL(image_url);
- user->SetStubImage(user_manager::UserImage(
+ user->SetStubImage(make_scoped_ptr(new user_manager::UserImage(
*ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_PROFILE_PICTURE_LOADING)),
- image_index,
- true);
+ IDR_PROFILE_PICTURE_LOADING))),
+ image_index, true);
DCHECK(!image_path.empty() ||
image_index == user_manager::User::USER_IMAGE_PROFILE);
if (image_path.empty()) {
@@ -602,11 +628,12 @@ void UserImageManagerImpl::SaveUserDefaultImageIndex(int default_image_index) {
}
void UserImageManagerImpl::SaveUserImage(
- const user_manager::UserImage& user_image) {
+ scoped_ptr<user_manager::UserImage> user_image) {
if (IsUserImageManaged())
return;
job_.reset(new Job(this));
- job_->SetToImage(user_manager::User::USER_IMAGE_EXTERNAL, user_image);
+ job_->SetToImage(user_manager::User::USER_IMAGE_EXTERNAL,
+ std::move(user_image));
}
void UserImageManagerImpl::SaveUserImageFromFile(const base::FilePath& path) {
@@ -624,7 +651,7 @@ void UserImageManagerImpl::SaveUserImageFromProfileImage() {
job_.reset(new Job(this));
job_->SetToImage(user_manager::User::USER_IMAGE_PROFILE,
downloaded_profile_image_.isNull()
- ? user_manager::UserImage()
+ ? make_scoped_ptr(new user_manager::UserImage)
: user_manager::UserImage::CreateAndEncode(
downloaded_profile_image_));
// If no profile image has been downloaded yet, ensure that a download is

Powered by Google App Engine
This is Rietveld 408576698