diff options
author | avayvod@chromium.org <avayvod@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 18:56:43 +0000 |
---|---|---|
committer | avayvod@chromium.org <avayvod@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 18:56:43 +0000 |
commit | 68a194e24379a991cfdfd914b71a41bde9963648 (patch) | |
tree | 806c7e9204a65ecb49e15cafad62089b0c4dd8a9 | |
parent | de0a151c343d00ff53f4be32a8a11f2c79d2e3f0 (diff) | |
download | chromium_src-68a194e24379a991cfdfd914b71a41bde9963648.zip chromium_src-68a194e24379a991cfdfd914b71a41bde9963648.tar.gz chromium_src-68a194e24379a991cfdfd914b71a41bde9963648.tar.bz2 |
Implemented default images for users who skip profile image screen.
BUG=chromium-os:5780
TEST=Verify that the default image belongs to the set of four images of four colors. The least used color should be chosen each time in the following order: blue, green, yellow, red.
Review URL: http://codereview.chromium.org/3619011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61992 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/theme/theme_resources.grd | 4 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/user_image_screen.cc | 20 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/user_manager.cc | 137 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/user_manager.h | 4 |
4 files changed, 131 insertions, 34 deletions
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 9525860..85e5a60 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -475,6 +475,10 @@ <include name="IDR_COMPACTNAV_SEPARATOR" file="compactnav_separator.png" type="BINDATA" /> <include name="IDR_INCOGNITO_GUY" file="incognito_guy.png" type="BINDATA" /> <include name="IDR_LOGIN_DEFAULT_USER" file="login_default.png" type="BINDATA" /> + <include name="IDR_LOGIN_DEFAULT_USER_1" file="login_default_blue.png" type="BINDATA" /> + <include name="IDR_LOGIN_DEFAULT_USER_2" file="login_default_green.png" type="BINDATA" /> + <include name="IDR_LOGIN_DEFAULT_USER_3" file="login_default_yellow.png" type="BINDATA" /> + <include name="IDR_LOGIN_DEFAULT_USER_4" file="login_default_red.png" type="BINDATA" /> <include name="IDR_LOGIN_GUEST" file="login_guest.png" type="BINDATA" /> <include name="IDR_LOGIN_ADD_USER" file="login_add_user.png" type="BINDATA" /> <include name="IDR_NOTIFICATION_BARS_EMPTY" file="notification_bars_empty.png" type="BINDATA" /> diff --git a/chrome/browser/chromeos/login/user_image_screen.cc b/chrome/browser/chromeos/login/user_image_screen.cc index 3edfdaf..7f1a6a4 100644 --- a/chrome/browser/chromeos/login/user_image_screen.cc +++ b/chrome/browser/chromeos/login/user_image_screen.cc @@ -93,12 +93,12 @@ void UserImageScreen::OnOK(const SkBitmap& image) { if (camera_.get()) camera_->Uninitialize(); UserManager* user_manager = UserManager::Get(); - if (user_manager) { - // TODO(avayvod): Check that there's logged in user actually. - user_manager->SetLoggedInUserImage(image); - const UserManager::User& user = user_manager->logged_in_user(); - user_manager->SaveUserImage(user.email(), image); - } + DCHECK(user_manager); + + const UserManager::User& user = user_manager->logged_in_user(); + DCHECK(!user.email().empty()); + + user_manager->SaveUserImage(user.email(), image); if (delegate()) delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SELECTED); } @@ -106,7 +106,13 @@ void UserImageScreen::OnOK(const SkBitmap& image) { void UserImageScreen::OnSkip() { if (camera_.get()) camera_->Uninitialize(); - // TODO(avayvod): Use one of the default images. See http://crosbug.com/5780. + UserManager* user_manager = UserManager::Get(); + DCHECK(user_manager); + + const UserManager::User& user = user_manager->logged_in_user(); + DCHECK(!user.email().empty()); + + user_manager->SetDefaultUserImage(user.email()); if (delegate()) delegate()->GetObserver(this)->OnExit(ScreenObserver::USER_IMAGE_SKIPPED); } diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc index f6edcbe..f1b6b3c 100644 --- a/chrome/browser/chromeos/login/user_manager.cc +++ b/chrome/browser/chromeos/login/user_manager.cc @@ -41,27 +41,43 @@ const char kUserImages[] = "UserImages"; // depends on that and it's hard to figure out what). const char kIncognitoUser[] = ""; +// Special pathes to default user images. +const char* kDefaultImageNames[] = { + "default:blue", + "default:green", + "default:yellow", + "default:red", +}; + +// Resource IDs of default user images. +const int kDefaultImageResources[] = { + IDR_LOGIN_DEFAULT_USER_1, + IDR_LOGIN_DEFAULT_USER_2, + IDR_LOGIN_DEFAULT_USER_3, + IDR_LOGIN_DEFAULT_USER_4 +}; + // The one true UserManager. static UserManager* user_manager_ = NULL; // Stores path to the image in local state. Runs on UI thread. -void save_path_to_local_state(const std::string& username, - const std::string& image_path) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); +void SavePathToLocalState(const std::string& username, + const std::string& image_path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); PrefService* local_state = g_browser_process->local_state(); DictionaryValue* images = local_state->GetMutableDictionary(kUserImages); images->SetWithoutPathExpansion(username, new StringValue(image_path)); - LOG(INFO) << "Saving path to user image in Local State."; + DLOG(INFO) << "Saving path to user image in Local State."; local_state->SavePersistentPrefs(); } // Saves image to file with specified path. Runs on FILE thread. // Posts task for saving image path to local state on UI thread. -void save_image_to_file(const SkBitmap& image, - const FilePath& image_path, - const std::string& username) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); +void SaveImageToFile(const SkBitmap& image, + const FilePath& image_path, + const std::string& username) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); std::vector<unsigned char> encoded_image; if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, true, &encoded_image)) { LOG(ERROR) << "Failed to PNG encode the image."; @@ -75,16 +91,30 @@ void save_image_to_file(const SkBitmap& image, return; } - ChromeThread::PostTask( - ChromeThread::UI, + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, - NewRunnableFunction(&save_path_to_local_state, + NewRunnableFunction(&SavePathToLocalState, username, image_path.value())); } +// Checks if given path is one of the default ones. If it is, returns true +// and its index in kDefaultImageNames through |image_id|. If not, returns +// false. +bool IsDefaultImagePath(const std::string& path, size_t* image_id) { + DCHECK(image_id); + for (size_t i = 0; i < arraysize(kDefaultImageNames); ++i) { + if (path == kDefaultImageNames[i]) { + *image_id = i; + return true; + } + } + return false; +} + // Checks current user's ownership on file thread. void CheckOwnership() { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); UserManager::Get()->set_current_user_is_owner( OwnershipService::GetSharedInstance()->CurrentUserIsOwner()); @@ -130,7 +160,7 @@ std::vector<UserManager::User> UserManager::GetUsers() const { if (prefs_users) { for (ListValue::const_iterator it = prefs_users->begin(); - it < prefs_users->end(); + it != prefs_users->end(); ++it) { std::string email; if ((*it)->GetAsString(&email)) { @@ -141,10 +171,20 @@ std::vector<UserManager::User> UserManager::GetUsers() const { if (image_it == user_images_.end()) { if (prefs_images && prefs_images->GetStringWithoutPathExpansion(email, &image_path)) { - // Insert the default image so we don't send another request if - // GetUsers is called twice. - user_images_[email] = user.image(); - image_loader_->Start(email, image_path); + size_t default_image_id = arraysize(kDefaultImageNames); + if (IsDefaultImagePath(image_path, &default_image_id)) { + DCHECK(default_image_id < arraysize(kDefaultImageNames)); + int resource_id = kDefaultImageResources[default_image_id]; + user.set_image( + *ResourceBundle::GetSharedInstance().GetBitmapNamed( + resource_id)); + user_images_[email] = user.image(); + } else { + // Insert the default image so we don't send another request if + // GetUsers is called twice. + user_images_[email] = user.image(); + image_loader_->Start(email, image_path); + } } } else { user.set_image(image_it->second); @@ -181,7 +221,7 @@ void UserManager::UserLoggedIn(const std::string& email) { // Make sure this user is first. prefs_users->Append(Value::CreateStringValue(email)); for (std::vector<User>::iterator it = users.begin(); - it < users.end(); + it != users.end(); ++it) { std::string user_email = it->email(); // Skip the most recent user. @@ -205,7 +245,7 @@ void UserManager::RemoveUser(const std::string& email) { prefs_users->Clear(); for (std::vector<User>::iterator it = users.begin(); - it < users.end(); + it != users.end(); ++it) { std::string user_email = it->email(); // Skip user that we would like to delete. @@ -236,23 +276,66 @@ void UserManager::SetLoggedInUserImage(const SkBitmap& image) { void UserManager::SaveUserImage(const std::string& username, const SkBitmap& image) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); std::string filename = username + ".png"; FilePath user_data_dir; PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); FilePath image_path = user_data_dir.AppendASCII(filename); - LOG(INFO) << "Saving user image to " << image_path.value(); + DLOG(INFO) << "Saving user image to " << image_path.value(); - ChromeThread::PostTask( - ChromeThread::FILE, + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, - NewRunnableFunction(&save_image_to_file, + NewRunnableFunction(&SaveImageToFile, image, image_path, username)); } +void UserManager::SetDefaultUserImage(const std::string& username) { + if (!g_browser_process) + return; + + PrefService* local_state = g_browser_process->local_state(); + DCHECK(local_state); + const ListValue* prefs_users = local_state->GetList(kLoggedInUsers); + DCHECK(prefs_users); + const DictionaryValue* prefs_images = + local_state->GetDictionary(kUserImages); + DCHECK(prefs_images); + + // We want to distribute default images between users uniformly so that if + // there're more users with red image, we won't add red one for sure. + // Thus we count how many default images of each color are used and choose + // the first color with minimal usage. + std::vector<int> colors_count(arraysize(kDefaultImageNames), 0); + for (ListValue::const_iterator it = prefs_users->begin(); + it != prefs_users->end(); + ++it) { + std::string email; + if ((*it)->GetAsString(&email)) { + std::string image_path; + size_t default_image_id = arraysize(kDefaultImageNames); + if (prefs_images->GetStringWithoutPathExpansion(email, &image_path) && + IsDefaultImagePath(image_path, &default_image_id)) { + DCHECK(default_image_id < arraysize(kDefaultImageNames)); + ++colors_count[default_image_id]; + } + } + } + std::vector<int>::const_iterator min_it = + std::min_element(colors_count.begin(), colors_count.end()); + int selected_id = min_it - colors_count.begin(); + std::string user_image_path = kDefaultImageNames[selected_id]; + int resource_id = kDefaultImageResources[selected_id]; + SkBitmap user_image = *ResourceBundle::GetSharedInstance().GetBitmapNamed( + resource_id); + + SavePathToLocalState(username, user_image_path); + SetLoggedInUserImage(user_image); +} + void UserManager::OnImageLoaded(const std::string& username, const SkBitmap& image) { - LOG(INFO) << "Loaded image for " << username; + DLOG(INFO) << "Loaded image for " << username; user_images_[username] = image; User user; user.set_email(username); @@ -292,7 +375,7 @@ void UserManager::NotifyOnLogin() { base::OpenPersistentNSSDB(); // Schedules current user ownership check on file thread. - ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableFunction(&CheckOwnership)); } @@ -300,7 +383,7 @@ void UserManager::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { if (type == NotificationType::OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) { - ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableFunction(&CheckOwnership)); } } diff --git a/chrome/browser/chromeos/login/user_manager.h b/chrome/browser/chromeos/login/user_manager.h index d3e40be..b115119 100644 --- a/chrome/browser/chromeos/login/user_manager.h +++ b/chrome/browser/chromeos/login/user_manager.h @@ -85,6 +85,10 @@ class UserManager : public UserImageLoader::Delegate, void SaveUserImage(const std::string& username, const SkBitmap& image); + // Sets one of the default images to the specified user and saves this + // setting in local state. + void SetDefaultUserImage(const std::string& username); + // chromeos::UserImageLoader::Delegate implementation. virtual void OnImageLoaded(const std::string& username, const SkBitmap& image); |